decloaking damage

cloaking +damage occurs for 2 seconds after decloaking
  need to cloak for 4 seconds to get the full 2 seconds of +damage
  ambush 666% -> 555% damage
boson composite drains 25% more energy when you move through mobs

nail gun gets 20% more ammo
harpoons now properly do damage on the frame before they retract
  smelting removes 10% more ammo to get another harpoon for railgun
grenade fireworks explosive petals are 25% closer together
This commit is contained in:
landgreen
2022-07-21 10:51:33 -07:00
parent f3a115b237
commit 7a66ea922c
6 changed files with 63 additions and 426 deletions

View File

@@ -813,14 +813,14 @@ const b = {
const color = `hsla(${360*Math.random()},100%,66%,0.6)` const color = `hsla(${360*Math.random()},100%,66%,0.6)`
for (let i = 0, len = 6; i < len; i++) { for (let i = 0, len = 6; i < len; i++) {
const unit = Vector.rotate({ x: 1, y: 0 }, 6.28 * i / len) const unit = Vector.rotate({ x: 1, y: 0 }, 6.28 * i / len)
b.explosion(Vector.add(where, Vector.mult(unit, 1.2 * range)), size * 0.6, color); //makes bullet do explosive damage at end b.explosion(Vector.add(where, Vector.mult(unit, 1.1 * range)), size * 0.6, color); //makes bullet do explosive damage at end
} }
} }
if (count === 16) { if (count === 16) {
const color = `hsla(${360*Math.random()},100%,66%,0.6)` const color = `hsla(${360*Math.random()},100%,66%,0.6)`
for (let i = 0, len = 10; i < len; i++) { for (let i = 0, len = 10; i < len; i++) {
const unit = Vector.rotate({ x: 1, y: 0 }, 6.28 * i / len) const unit = Vector.rotate({ x: 1, y: 0 }, 6.28 * i / len)
b.explosion(Vector.add(where, Vector.mult(unit, 1.75 * range)), size * 0.45, color); //makes bullet do explosive damage at end b.explosion(Vector.add(where, Vector.mult(unit, 1.4 * range)), size * 0.45, color); //makes bullet do explosive damage at end
} }
} }
count++ count++
@@ -1792,7 +1792,6 @@ const b = {
returnToPlayer() { returnToPlayer() {
if (Vector.magnitude(Vector.sub(this.position, m.pos)) < returnRadius) { //near player if (Vector.magnitude(Vector.sub(this.position, m.pos)) < returnRadius) { //near player
this.endCycle = 0; this.endCycle = 0;
if (m.energy < 0.05) { if (m.energy < 0.05) {
m.fireCDcycle = m.cycle + 120; //fire cooldown m.fireCDcycle = m.cycle + 120; //fire cooldown
} else if (m.cycle + 25 * b.fireCDscale < m.fireCDcycle) { } else if (m.cycle + 25 * b.fireCDscale < m.fireCDcycle) {
@@ -1854,23 +1853,20 @@ const b = {
this.do = this.returnToPlayer this.do = this.returnToPlayer
if (this.angularSpeed < 0.5) this.torque += this.inertia * 0.001 * (Math.random() - 0.5) //(Math.round(Math.random()) ? 1 : -1) if (this.angularSpeed < 0.5) this.torque += this.inertia * 0.001 * (Math.random() - 0.5) //(Math.round(Math.random()) ? 1 : -1)
Matter.Sleeping.set(this, false) Matter.Sleeping.set(this, false)
this.collisionFilter.category = 0
this.collisionFilter.mask = 0
this.endCycle = simulation.cycle + 60 this.endCycle = simulation.cycle + 60
//recoil on jerking line const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (input.down ? 0.00015 : 0.0003)) //recoil on jerking line
const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (input.down ? 0.00015 : 0.0003))
player.force.x += momentum.x player.force.x += momentum.x
player.force.y += momentum.y player.force.y += momentum.y
requestAnimationFrame(() => { //delay this for 1 cycle to get the proper hit graphics
this.collisionFilter.category = 0
this.collisionFilter.mask = 0
});
} else { } else {
this.grabPowerUp() this.grabPowerUp()
} }
} }
if (target) { //rotate towards the target if (target) { //rotate towards the target
const face = { const face = { x: Math.cos(this.angle), y: Math.sin(this.angle) };
x: Math.cos(this.angle),
y: Math.sin(this.angle)
};
const vectorGoal = Vector.normalise(Vector.sub(this.position, target.position)); const vectorGoal = Vector.normalise(Vector.sub(this.position, target.position));
if (Vector.cross(vectorGoal, face) > 0) { if (Vector.cross(vectorGoal, face) > 0) {
Matter.Body.rotate(this, this.turnRate); Matter.Body.rotate(this, this.turnRate);
@@ -1878,75 +1874,9 @@ const b = {
Matter.Body.rotate(this, -this.turnRate); Matter.Body.rotate(this, -this.turnRate);
} }
} }
//grappling hook
// if (input.fire && !input.down && Matter.Query.collides(this, map).length) {
// const pull = Vector.mult(Vector.normalise(Vector.sub(this.position, m.pos)), 0.1)
// player.force.x += pull.x
// player.force.y += pull.y - player.mass * 0.02
// Matter.Body.setStatic(this, true)
// this.endCycle = simulation.cycle + 5
// this.dropCaughtPowerUp()
// this.do = () => {
// const sub = Vector.sub(this.position, m.pos)
// const dist = Vector.magnitude(sub)
// if (input.fire) {
// m.fireCDcycle = m.cycle + 30; // cool down if out of energy
// this.endCycle = simulation.cycle + 10
// const pull = Vector.mult(Vector.normalise(sub), 0.001 * Math.min(Math.max(1, dist), 100))
// player.force.x += pull.x
// player.force.y += pull.y
// Matter.Body.setVelocity(player, { x: player.velocity.x * 0.8, y: player.velocity.y * 0.8 });
// } else { //if (Vector.magnitude(Vector.sub(this.position, m.pos)) < returnRadius + 200)
// //automatically get ammo back
// this.endCycle = 0;
// if (m.cycle + 15 * b.fireCDscale < m.fireCDcycle) m.fireCDcycle = m.cycle + 15 * b.fireCDscale //lower cd to 15 if it is above 15
// // refund ammo
// for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
// if (b.guns[i].name === "harpoon") {
// b.guns[i].ammo++;
// simulation.updateGunHUD();
// break;
// }
// }
// }
// if (dist > returnRadius) this.draw();
// }
// }
this.force.x += this.thrustMag * this.mass * Math.cos(this.angle); this.force.x += this.thrustMag * this.mass * Math.cos(this.angle);
this.force.y += this.thrustMag * this.mass * Math.sin(this.angle); this.force.y += this.thrustMag * this.mass * Math.sin(this.angle);
} }
// else if (!(this.cycle % 2)) { //look for a target if you don't have one
// simulation.drawList.push({ //add dmg to draw queue
// x: this.position.x,
// y: this.position.y,
// radius: 10,
// color: simulation.mobDmgColor,
// time: simulation.drawTime
// });
// let closest = {
// distance: 2000,
// target: null
// }
// const dir = Vector.normalise(this.velocity) //make a vector for direction of length 1
// for (let i = 0, len = mob.length; i < len; ++i) {
// if (
// mob[i].alive && !mob[i].isBadTarget &&
// Matter.Query.ray(map, this.position, mob[i].position).length === 0 && //check for map in Line of sight
// Vector.dot(dir, Vector.normalise(Vector.sub(mob[i].position, this.position))) > 0.55 //the dot product of diff and dir will return how much over lap between the vectors
// ) {
// const dist = Vector.magnitude(Vector.sub(this.position, mob[i].position))
// if (dist < closest.distance) {
// closest.distance = dist
// closest.target = mob[i]
// }
// }
// }
// if (closest.target) {
// target = closest.target
// this.turnRate = 0.05
// this.frictionAir = 0.8
// }
// }
this.draw() this.draw()
}, },
}); });
@@ -5131,8 +5061,8 @@ const b = {
name: "nail gun", // 0 name: "nail gun", // 0
description: "use compressed air to fire a stream of <strong>nails</strong><br><strong><em>delay</em></strong> after firing <strong>decreases</strong> as you shoot", description: "use compressed air to fire a stream of <strong>nails</strong><br><strong><em>delay</em></strong> after firing <strong>decreases</strong> as you shoot",
ammo: 0, ammo: 0,
ammoPack: 50, ammoPack: 60,
defaultAmmoPack: 50, defaultAmmoPack: 60,
recordedAmmo: 0, recordedAmmo: 0,
have: false, have: false,
nextFireCycle: 0, //use to remember how longs its been since last fire, used to reset count nextFireCycle: 0, //use to remember how longs its been since last fire, used to reset count
@@ -6854,7 +6784,7 @@ const b = {
} }
//look for closest mob in player's LoS //look for closest mob in player's LoS
const harpoonSize = (tech.isLargeHarpoon ? 1 + 0.1 * Math.sqrt(this.ammo) : 1) //* (input.down ? 0.7 : 1) const harpoonSize = (tech.isLargeHarpoon ? 1 + 0.1 * Math.sqrt(this.ammo) : 1) //* (input.down ? 0.7 : 1)
const totalCycles = 6 * (tech.isFilament ? 1 + 0.012 * Math.min(110, this.ammo) : 1) * Math.sqrt(harpoonSize) const totalCycles = 5 * (tech.isFilament ? 1 + 0.012 * Math.min(110, this.ammo) : 1) * Math.sqrt(harpoonSize)
if (tech.extraHarpoons && !input.down) { //multiple harpoons if (tech.extraHarpoons && !input.down) { //multiple harpoons
const SPREAD = 0.1 const SPREAD = 0.1
@@ -6913,7 +6843,7 @@ const b = {
} }
} }
} }
if (input.down) { if (input.down && m.onGround) {
b.harpoon(where, null, m.angle, harpoonSize, true, 1.5 * totalCycles, (input.down && tech.crouchAmmoCount && (tech.crouchAmmoCount - 1) % 2) ? false : true) b.harpoon(where, null, m.angle, harpoonSize, true, 1.5 * totalCycles, (input.down && tech.crouchAmmoCount && (tech.crouchAmmoCount - 1) % 2) ? false : true)
} else { } else {
b.harpoon(where, closest.target, m.angle, harpoonSize, true, totalCycles) b.harpoon(where, closest.target, m.angle, harpoonSize, true, totalCycles)
@@ -6925,226 +6855,6 @@ const b = {
player.force.y -= recoil.y player.force.y -= recoil.y
tech.harpoonDensity = 0.004 //0.001 is normal for blocks, 0.004 is normal for harpoon, 0.004*6 when buffed tech.harpoonDensity = 0.004 //0.001 is normal for blocks, 0.004 is normal for harpoon, 0.004*6 when buffed
}, },
// railGun2() {
// const where = {
// x: m.pos.x + 30 * Math.cos(m.angle),
// y: m.pos.y + 30 * Math.sin(m.angle)
// }
// const closest = {
// distance: 10000,
// target: null
// }
// //look for closest mob in player's LoS
// const dir = { x: Math.cos(m.angle), y: Math.sin(m.angle) }; //make a vector for the player's direction of length 1; used in dot product
// const harpoonSize = tech.isLargeHarpoon ? 1 + 0.1 * Math.sqrt(this.ammo) : 1
// const totalCycles = 7 * (tech.isFilament ? 1 + 0.01 * Math.min(110, this.ammo) : 1) * Math.sqrt(harpoonSize)
// function pushAway(range) { //push away blocks when firing
// for (let i = 0, len = mob.length; i < len; ++i) {
// const SUB = Vector.sub(mob[i].position, m.pos)
// const DISTANCE = Vector.magnitude(SUB)
// if (DISTANCE < range) {
// const DEPTH = Math.min(range - DISTANCE, 1500)
// const FORCE = Vector.mult(Vector.normalise(SUB), 0.001 * Math.sqrt(DEPTH) * mob[i].mass)
// mob[i].force.x += FORCE.x;
// mob[i].force.y += FORCE.y;
// }
// }
// for (let i = 0, len = body.length; i < len; ++i) {
// const SUB = Vector.sub(body[i].position, m.pos)
// const DISTANCE = Vector.magnitude(SUB)
// if (DISTANCE < range) {
// const DEPTH = Math.min(range - DISTANCE, 500)
// const FORCE = Vector.mult(Vector.normalise(SUB), 0.002 * Math.sqrt(DEPTH) * body[i].mass)
// body[i].force.x += FORCE.x;
// body[i].force.y += FORCE.y - body[i].mass * simulation.g * 1.5; //kick up a bit to give them some arc
// }
// }
// }
// const me = bullet.length;
// bullet[me] = Bodies.rectangle(0, 0, 0.015, 0.0015, { //start as a small shape that can't even be seen
// vertexGoal: [{ x: -40 * harpoonSize, y: 2 * harpoonSize, index: 0, isInternal: false }, { x: -40 * harpoonSize, y: -2 * harpoonSize, index: 1, isInternal: false }, { x: 50 * harpoonSize, y: -3 * harpoonSize, index: 3, isInternal: false }, { x: 30 * harpoonSize, y: 2 * harpoonSize, index: 4, isInternal: false }],
// density: 0.03, //0.001 is normal
// restitution: 0,
// frictionAir: 0,
// dmg: 0, //damage done in addition to the damage from momentum
// classType: "bullet",
// collisionFilter: {
// category: 0,
// mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield
// },
// minDmgSpeed: 5,
// beforeDmg(who) {
// if (tech.isShieldPierce && who.isShielded) { //disable shields
// who.isShielded = false
// requestAnimationFrame(() => { who.isShielded = true });
// }
// if (who.shield && !tech.isShieldPierce) {
// for (let i = 0, len = mob.length; i < len; i++) {
// if (mob[i].id === who.shieldTargetID) { //apply some knock back to shield mob before shield breaks
// Matter.Body.setVelocity(mob[i], Vector.mult(Vector.normalise(this.velocity), 10));
// break
// }
// }
// Matter.Body.setVelocity(this, { x: -0.4 * this.velocity.x, y: -0.4 * this.velocity.y });
// } else {
// if (tech.fragments && this.speed > 10) {
// b.targetedNail(this.position, tech.fragments * 13)
// this.endCycle = 0 //triggers despawn
// }
// }
// },
// onEnd() {}
// });
// m.fireCDcycle = Infinity; // cool down
// Composite.add(engine.world, bullet[me]); //add bullet to world
// bullet[me].endCycle = Infinity
// bullet[me].charge = 0;
// bullet[me].do = function() {
// if ((m.energy < 0.005 && !tech.isRailEnergyGain) || (!input.down && !tech.isRailGun)) {
// m.energy += 0.05 + this.charge * 0.2
// m.fireCDcycle = m.cycle + 120; // cool down if out of energy
// this.endCycle = 0;
// b.refundAmmo()
// return
// }
// if ((!input.fire && this.charge > 0.6)) { //fire on mouse release or on low energy
// Matter.Body.setVertices(this, this.vertexGoal) //take on harpoon shape
// m.fireCDcycle = m.cycle + 2; // set fire cool down
// //normal bullet behavior occurs after firing, overwrites this function
// this.endCycle = simulation.cycle + 140
// this.collisionFilter.category = cat.bullet
// Matter.Body.setPosition(this, { x: m.pos.x, y: m.pos.y })
// Matter.Body.setAngle(this, m.angle)
// const speed = 120
// Matter.Body.setVelocity(this, {
// x: m.Vx / 2 + speed * this.charge * Math.cos(m.angle),
// y: m.Vy / 2 + speed * this.charge * Math.sin(m.angle)
// });
// this.do = function() {
// this.force.y += this.mass * 0.0003 / this.charge; // low gravity that scales with charge
// }
// const KNOCK = ((input.down) ? 0.1 : 0.5) * this.charge * this.charge
// player.force.x -= KNOCK * Math.cos(m.angle)
// player.force.y -= KNOCK * Math.sin(m.angle) * 0.35 //reduce knock back in vertical direction to stop super jumps
// pushAway(1200 * this.charge)
// } else { // charging on mouse down
// if (tech.isFireMoveLock) {
// Matter.Body.setVelocity(player, {
// x: 0,
// y: -55 * player.mass * simulation.g //undo gravity before it is added
// });
// player.force.x = 0
// player.force.y = 0
// }
// m.fireCDcycle = Infinity //can't fire until mouse is released
// const previousCharge = this.charge
// //small b.fireCDscale = faster shots, b.fireCDscale=1 = normal shot, big b.fireCDscale = slower chot
// let smoothRate = tech.isCapacitor ? 0.85 : Math.min(0.998, 0.985 * (0.98 + 0.02 * b.fireCDscale))
// this.charge = this.charge * smoothRate + 1 - smoothRate
// m.energy += (this.charge - previousCharge) * (tech.isRailEnergyGain ? 1 : -0.25) //energy drain is proportional to charge gained, but doesn't stop normal m.fieldRegen
// //draw targeting
// let best;
// let range = 3000
// const dir = m.angle
// const path = [{
// x: m.pos.x + 20 * Math.cos(dir),
// y: m.pos.y + 20 * Math.sin(dir)
// },
// {
// x: m.pos.x + range * Math.cos(dir),
// y: m.pos.y + range * Math.sin(dir)
// }
// ];
// const vertexCollision = function(v1, v1End, domain) {
// for (let i = 0; i < domain.length; ++i) {
// let vertices = domain[i].vertices;
// const len = vertices.length - 1;
// for (let j = 0; j < len; j++) {
// results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
// if (results.onLine1 && results.onLine2) {
// const dx = v1.x - results.x;
// const dy = v1.y - results.y;
// const dist2 = dx * dx + dy * dy;
// if (dist2 < best.dist2) {
// best = {
// x: results.x,
// y: results.y,
// dist2: dist2,
// who: domain[i],
// v1: vertices[j],
// v2: vertices[j + 1]
// };
// }
// }
// }
// results = simulation.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
// if (results.onLine1 && results.onLine2) {
// const dx = v1.x - results.x;
// const dy = v1.y - results.y;
// const dist2 = dx * dx + dy * dy;
// if (dist2 < best.dist2) {
// best = {
// x: results.x,
// y: results.y,
// dist2: dist2,
// who: domain[i],
// v1: vertices[0],
// v2: vertices[len]
// };
// }
// }
// }
// };
// //check for collisions
// best = { x: null, y: null, dist2: Infinity, who: null, v1: null, v2: null };
// vertexCollision(path[0], path[1], mob);
// vertexCollision(path[0], path[1], map);
// vertexCollision(path[0], path[1], body);
// if (best.dist2 != Infinity) path[path.length - 1] = { x: best.x, y: best.y }; //if hitting something
// //draw beam
// ctx.beginPath();
// ctx.moveTo(path[0].x, path[0].y);
// ctx.lineTo(path[1].x, path[1].y);
// ctx.strokeStyle = `rgba(100,0,180,0.7)`;
// ctx.lineWidth = this.charge * 1
// ctx.setLineDash([10, 20]);
// ctx.stroke();
// ctx.setLineDash([]);
// //draw magnetic field
// const X = m.pos.x
// const Y = m.pos.y
// const unitVector = { x: Math.cos(m.angle), y: Math.sin(m.angle) }
// const unitVectorPerp = Vector.perp(unitVector)
// function magField(mag, arc) {
// ctx.moveTo(X, Y);
// ctx.bezierCurveTo(
// X + unitVector.x * mag, Y + unitVector.y * mag,
// X + unitVector.x * mag + unitVectorPerp.x * arc, Y + unitVector.y * mag + unitVectorPerp.y * arc,
// X + unitVectorPerp.x * arc, Y + unitVectorPerp.y * arc)
// ctx.bezierCurveTo(
// X - unitVector.x * mag + unitVectorPerp.x * arc, Y - unitVector.y * mag + unitVectorPerp.y * arc,
// X - unitVector.x * mag, Y - unitVector.y * mag,
// X, Y)
// }
// ctx.fillStyle = `rgba(50,0,100,0.05)`;
// for (let i = 3; i < 7; i++) {
// const MAG = 8 * i * i * this.charge * (0.93 + 0.07 * Math.random())
// const ARC = 6 * i * i * this.charge * (0.93 + 0.07 * Math.random())
// ctx.beginPath();
// magField(MAG, ARC)
// magField(MAG, -ARC)
// ctx.fill();
// }
// }
// }
// },
}, { }, {
name: "mine", //10 name: "mine", //10
description: "toss a <strong>proximity</strong> mine that <strong>sticks</strong> to walls<br>refund <strong>undetonated</strong> mines on <strong>exiting</strong> a level", //fires <strong>nails</strong> at mobs within range description: "toss a <strong>proximity</strong> mine that <strong>sticks</strong> to walls<br>refund <strong>undetonated</strong> mines on <strong>exiting</strong> a level", //fires <strong>nails</strong> at mobs within range

View File

@@ -24,8 +24,8 @@ const level = {
// powerUps.research.changeRerolls(100) // powerUps.research.changeRerolls(100)
// tech.tech[297].frequency = 100 // tech.tech[297].frequency = 100
// b.guns[0].ammo = 10000 // b.guns[0].ammo = 10000
// m.setField("perfect diamagnetism") //molecular assembler time dilation perfect diamagnetism // m.setField("metamaterial cloaking") //molecular assembler time dilation perfect diamagnetism
// b.giveGuns("shotgun") //0 nail gun 1 shotgun 2 super balls 3 matter wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser // b.giveGuns("harpoon") //0 nail gun 1 shotgun 2 super balls 3 matter wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// tech.giveTech("siphonaptera") // tech.giveTech("siphonaptera")
// tech.giveTech("fleas") // tech.giveTech("fleas")
// tech.giveTech("colony") // tech.giveTech("colony")
@@ -35,7 +35,7 @@ const level = {
// for (let i = 0; i < 1; i++) tech.giveTech("cryodesiccation") // for (let i = 0; i < 1; i++) tech.giveTech("cryodesiccation")
// for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "tech"); // for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "tech");
// for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "research"); // for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "research");
// spawn.starter(1900, -500, 200) // spawn.starter(1900, -500)
// spawn.laserTargetingBoss(1900, -500) // spawn.laserTargetingBoss(1900, -500)
// for (let i = 0; i < 10; ++i) spawn.grower(1900, -500) // for (let i = 0; i < 10; ++i) spawn.grower(1900, -500)
// level.testing(); //not in rotation, used for testing // level.testing(); //not in rotation, used for testing
@@ -2763,7 +2763,7 @@ const level = {
document.body.style.backgroundColor = "#ddd"; document.body.style.backgroundColor = "#ddd";
spawn.mapRect(-950, 0, 8200, 800); //ground spawn.mapRect(-950, 0, 8200, 800); //ground
spawn.mapRect(-950, -1200, 800, 1400); //left wall spawn.mapRect(-950, -1200, 800, 1400); //left wall
// spawn.mapRect(-950, -1800, 8200, 800); //roof spawn.mapRect(-950, -1800, 8200, 800); //roof
spawn.mapRect(-250, -400, 1000, 600); // shelf spawn.mapRect(-250, -400, 1000, 600); // shelf
spawn.mapRect(-250, -1200, 1000, 550); // shelf roof spawn.mapRect(-250, -1200, 1000, 550); // shelf roof
// for (let i = 0; i < 10; ++i) powerUps.spawn(550, -800, "ammo", false); // for (let i = 0; i < 10; ++i) powerUps.spawn(550, -800, "ammo", false);

View File

@@ -906,6 +906,8 @@ const m = {
fieldShieldingScale: 1, fieldShieldingScale: 1,
// fieldDamage: 1, // fieldDamage: 1,
isSneakAttack: false, isSneakAttack: false,
sneakAttackCycle: 0,
enterCloakCycle: 0,
duplicateChance: 0, duplicateChance: 0,
energy: 0, energy: 0,
fieldRegen: 0.001, fieldRegen: 0.001,
@@ -1554,13 +1556,14 @@ const m = {
{ {
name: "standing wave", name: "standing wave",
//<strong>deflecting</strong> protects you in every <strong>direction</strong> //<strong>deflecting</strong> protects you in every <strong>direction</strong>
description: "<strong>3</strong> oscillating <strong>shields</strong> are permanently active<br> <strong>+60</strong> max <strong class='color-f'>energy</strong><br>generate <strong>6</strong> <strong class='color-f'>energy</strong> per second", //drains <strong class='color-f'>energy</strong> //<strong>deflecting</strong> has <strong>50%</strong> less <strong>recoil</strong> description: "<strong>3</strong> oscillating <strong>shields</strong> are permanently active<br><strong>+60</strong> max <strong class='color-f'>energy</strong><br>generate <strong>6</strong> <strong class='color-f'>energy</strong> per second", //drains <strong class='color-f'>energy</strong> //<strong>deflecting</strong> has <strong>50%</strong> less <strong>recoil</strong>
drainCD: 0, drainCD: 0,
effect: () => { effect: () => {
m.fieldBlockCD = 0; m.fieldBlockCD = 0;
m.blockingRecoil = 2 //4 is normal m.blockingRecoil = 2 //4 is normal
m.fieldRange = 175 m.fieldRange = 175
m.fieldShieldingScale = (tech.isStandingWaveExpand ? 0.9 : 1.3) * Math.pow(0.6, (tech.harmonics - 2)) m.fieldShieldingScale = (tech.isStandingWaveExpand ? 0.9 : 1.3) * Math.pow(0.6, (tech.harmonics - 2))
// m.fieldHarmReduction = 0.66; //33% reduction
m.harmonic3Phase = () => { //normal standard 3 different 2-d circles m.harmonic3Phase = () => { //normal standard 3 different 2-d circles
const fieldRange1 = (0.75 + 0.3 * Math.sin(m.cycle / 23)) * m.fieldRange * m.harmonicRadius const fieldRange1 = (0.75 + 0.3 * Math.sin(m.cycle / 23)) * m.fieldRange * m.harmonicRadius
@@ -2735,9 +2738,8 @@ const m = {
} }
}, },
{ {
name: "metamaterial cloaking", //"weak photonic coupling" "electromagnetically induced transparency" "optical non-coupling" "slow light field" "electro-optic transparency" name: "metamaterial cloaking",
//<br><strong>collisions</strong> do <strong>50%</strong> less <strong class='color-defense'>harm</strong> when <strong class='color-cloaked'>cloaked</strong> description: "when not firing activate <strong class='color-cloaked'>cloaking</strong><br><span style = 'font-size:90%;'><strong>+333%</strong> <strong class='color-d'>damage</strong> for <strong>2</strong> seconds after <strong class='color-cloaked'>decloaking</strong></span><br>generate <strong>6</strong> <strong class='color-f'>energy</strong> per second",
description: "when not firing activate <strong class='color-cloaked'>cloaking</strong><br><span style = 'font-size:95%;'><strong>+333%</strong> <strong class='color-d'>damage</strong> if no mob has <strong>died</strong> in <strong>4</strong> seconds</span><br>generate <strong>6</strong> <strong class='color-f'>energy</strong> per second",
effect: () => { effect: () => {
m.fieldFire = true; m.fieldFire = true;
m.fieldMeterColor = "#333"; m.fieldMeterColor = "#333";
@@ -2748,6 +2750,8 @@ const m = {
// m.fieldDamage = 2.46 // 1 + 146/100 // m.fieldDamage = 2.46 // 1 + 146/100
m.fieldDrawRadius = 0 m.fieldDrawRadius = 0
m.isSneakAttack = true; m.isSneakAttack = true;
m.sneakAttackCycle = 0;
m.enterCloakCycle = 0
const drawRadius = 800 const drawRadius = 800
m.drawCloak = function() { m.drawCloak = function() {
m.fieldPhase += 0.007 m.fieldPhase += 0.007
@@ -2765,27 +2769,6 @@ const m = {
ctx.globalCompositeOperation = "source-over"; ctx.globalCompositeOperation = "source-over";
ctx.clip(); ctx.clip();
} }
// m.drawCloak = function() { //controlled by player look direction
// m.fieldPhase = m.angle
// const wiggle = 0.15 * Math.sin(m.angle)
// const off = {
// x: Math.cos(m.angle),
// y: Math.sin(m.angle)
// }
// const look = Vector.add(m.pos, Vector.mult(off, 500))
// ctx.beginPath();
// ctx.ellipse(look.x, look.y, m.fieldDrawRadius * (1 - wiggle), m.fieldDrawRadius * (1 + wiggle), m.fieldPhase, 0, 2 * Math.PI);
// // if (m.fireCDcycle > m.cycle && (input.field)) {}
// ctx.fillStyle = "#fff"
// ctx.lineWidth = 2;
// ctx.strokeStyle = "#000"
// ctx.stroke()
// // ctx.fillStyle = "#fff" //`rgba(0,0,0,${0.5+0.5*m.energy})`;
// ctx.globalCompositeOperation = "destination-in";
// ctx.fill();
// ctx.globalCompositeOperation = "source-over";
// ctx.clip();
// }
m.hold = function() { m.hold = function() {
if (m.isHolding) { if (m.isHolding) {
m.drawHold(m.holdingTarget); m.drawHold(m.holdingTarget);
@@ -2804,6 +2787,8 @@ const m = {
if (m.fireCDcycle + 30 < m.cycle && !input.fire) { //automatically cloak if not firing if (m.fireCDcycle + 30 < m.cycle && !input.fire) { //automatically cloak if not firing
if (!m.isCloak) { if (!m.isCloak) {
m.isCloak = true //enter cloak m.isCloak = true //enter cloak
m.enterCloakCycle = m.cycle
// console.log(m.enterCloakCycle)
if (tech.isIntangible) { if (tech.isIntangible) {
for (let i = 0; i < bullet.length; i++) { for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType && bullet[i].botType !== "orbit") bullet[i].collisionFilter.mask = cat.map | cat.bullet | cat.mobBullet | cat.mobShield if (bullet[i].botType && bullet[i].botType !== "orbit") bullet[i].collisionFilter.mask = cat.map | cat.bullet | cat.mobBullet | cat.mobShield
@@ -2811,6 +2796,7 @@ const m = {
} }
} }
} else if (m.isCloak) { //exit cloak } else if (m.isCloak) { //exit cloak
m.sneakAttackCycle = m.cycle
m.isCloak = false m.isCloak = false
if (tech.isIntangible) { if (tech.isIntangible) {
for (let i = 0; i < bullet.length; i++) { for (let i = 0; i < bullet.length; i++) {
@@ -2842,25 +2828,6 @@ const m = {
} }
} }
} }
// function drawField() {
// m.fieldPhase += 0.007
// const wiggle = 0.15 * Math.sin(m.fieldPhase * 0.5)
// ctx.beginPath();
// ctx.ellipse(m.pos.x, m.pos.y, m.fieldDrawRadius * (1 - wiggle), m.fieldDrawRadius * (1 + wiggle), m.fieldPhase, 0, 2 * Math.PI);
// // if (m.fireCDcycle > m.cycle && (input.field)) {}
// ctx.fillStyle = "#fff"
// ctx.lineWidth = 2;
// ctx.strokeStyle = "#000"
// ctx.stroke()
// // ctx.fillStyle = "#fff" //`rgba(0,0,0,${0.5+0.5*m.energy})`;
// ctx.globalCompositeOperation = "destination-in";
// ctx.fill();
// ctx.globalCompositeOperation = "source-over";
// ctx.clip();
// }
// const energy = Math.max(0.01, Math.min(m.energy, 1))
if (m.isCloak) { if (m.isCloak) {
this.fieldRange = this.fieldRange * 0.9 + 0.1 * drawRadius this.fieldRange = this.fieldRange * 0.9 + 0.1 * drawRadius
m.fieldDrawRadius = this.fieldRange * 0.88 //* Math.min(1, 0.3 + 0.5 * Math.min(1, energy * energy)); m.fieldDrawRadius = this.fieldRange * 0.88 //* Math.min(1, 0.3 + 0.5 * Math.min(1, energy * energy));
@@ -2877,8 +2844,8 @@ const m = {
if (inPlayer.length > 0) { if (inPlayer.length > 0) {
for (let i = 0; i < inPlayer.length; i++) { for (let i = 0; i < inPlayer.length; i++) {
if (m.energy > 0) { if (m.energy > 0) {
if (!inPlayer[i].isUnblockable) m.energy -= 0.004; if (!inPlayer[i].isUnblockable) m.energy -= 0.007;
if (inPlayer[i].shield) m.energy -= 0.012; if (inPlayer[i].shield) m.energy -= 0.025;
} }
} }
} }
@@ -2886,15 +2853,14 @@ const m = {
player.collisionFilter.mask = cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield //normal collisions player.collisionFilter.mask = cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield //normal collisions
} }
} }
this.drawFieldMeterCloaking() this.drawFieldMeterCloaking()
//show sneak attack status //show sneak attack status
// if (m.cycle > m.lastKillCycle + 240) {
if (m.cycle > m.lastKillCycle + 240) { if (m.sneakAttackCycle + Math.min(120, 0.3 * (m.cycle - m.enterCloakCycle)) > m.cycle) {
ctx.strokeStyle = "rgba(0,0,0,0.4)" //m.fieldMeterColor; //"rgba(255,255,0,0.2)" //ctx.strokeStyle = `rgba(0,0,255,${0.5+0.5*Math.random()})` ctx.strokeStyle = "rgba(0,0,0,0.5)" //m.fieldMeterColor; //"rgba(255,255,0,0.2)" //ctx.strokeStyle = `rgba(0,0,255,${0.5+0.5*Math.random()})`
ctx.beginPath(); ctx.beginPath();
ctx.arc(m.pos.x, m.pos.y, 28, 0, 2 * Math.PI); ctx.arc(m.pos.x, m.pos.y, 28, 0, 2 * Math.PI);
ctx.lineWidth = 2 ctx.lineWidth = 3
ctx.stroke(); ctx.stroke();
} }
} }

View File

@@ -245,7 +245,7 @@ const spawn = {
me.showHealthBar = false; me.showHealthBar = false;
me.collisionFilter.category = 0; me.collisionFilter.category = 0;
me.collisionFilter.mask = 0; //cat.player //| cat.body me.collisionFilter.mask = 0; //cat.player //| cat.body
me.chaseSpeed = 1 + 1.5 * Math.random() me.chaseSpeed = 1 + 2 * Math.random()
me.awake = function() { me.awake = function() {
//chase player //chase player
@@ -275,35 +275,11 @@ const spawn = {
}); });
} }
} }
//aoe damage to mobs
// for (let i = 0, len = mob.length; i < len; i++) {
// if (!mob[i].isShielded && Vector.magnitude(Vector.sub(mob[i].position, this.position)) < this.radius) {
// let dmg = m.dmgScale * 0.082
// if (Matter.Query.ray(map, mob[i].position, this.position).length > 0) dmg *= 0.25 //reduce damage if a wall is in the way
// if (mob[i].shield) dmg *= 4 //x5 to make up for the /5 that shields normally take
// mob[i].damage(dmg);
// if (tech.isNeutronSlow) {
// Matter.Body.setVelocity(mob[i], {
// x: mob[i].velocity.x * this.vacuumSlow,
// y: mob[i].velocity.y * this.vacuumSlow
// });
// }
// }
// }
//draw
ctx.beginPath(); ctx.beginPath();
ctx.arc(this.position.x, this.position.y, this.radius, 0, 2 * Math.PI); ctx.arc(this.position.x, this.position.y, this.radius, 0, 2 * Math.PI);
// ctx.fillStyle = "hsla(160, 100%, 35%,0.75)" //"rgba(255,0,255,0.2)";
// ctx.globalCompositeOperation = "lighter"
ctx.fillStyle = `rgba(25,139,170,${0.2 + 0.12 * Math.random()})`; ctx.fillStyle = `rgba(25,139,170,${0.2 + 0.12 * Math.random()})`;
ctx.fill(); ctx.fill();
this.radius = 100 * (1 + 0.25 * Math.sin(simulation.cycle * 0.03)) this.radius = 100 * (1 + 0.25 * Math.sin(simulation.cycle * 0.03))
// ctx.fillStyle = "#fff";
// ctx.globalCompositeOperation = "difference";
// ctx.fill();
// ctx.globalCompositeOperation = "source-over"
} }
me.do = function() { //wake up after the player moves me.do = function() { //wake up after the player moves
if (player.speed > 1 && !m.isCloak) { if (player.speed > 1 && !m.isCloak) {

View File

@@ -251,7 +251,8 @@ const tech = {
if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 2 if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 2
if (tech.isSpeedDamage) dmg *= 1 + Math.min(0.66, player.speed * 0.0165) if (tech.isSpeedDamage) dmg *= 1 + Math.min(0.66, player.speed * 0.0165)
if (tech.isDamageAfterKillNoRegen && m.lastKillCycle + 300 > m.cycle) dmg *= 1.6 if (tech.isDamageAfterKillNoRegen && m.lastKillCycle + 300 > m.cycle) dmg *= 1.6
if (m.isSneakAttack && m.cycle > m.lastKillCycle + 240) dmg *= tech.sneakAttackDmg // if (m.isSneakAttack && m.cycle > m.lastKillCycle + 240) dmg *= tech.sneakAttackDmg
if (m.isSneakAttack && m.sneakAttackCycle + Math.min(120, 0.3 * (m.cycle - m.enterCloakCycle)) > m.cycle) dmg *= tech.sneakAttackDmg
if (tech.isAxion && tech.isHarmMACHO) dmg *= 2 - m.harmReduction() if (tech.isAxion && tech.isHarmMACHO) dmg *= 2 - m.harmReduction()
return dmg * tech.slowFire * tech.aimDamage return dmg * tech.slowFire * tech.aimDamage
}, },
@@ -4078,8 +4079,8 @@ const tech = {
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 1,
frequencyDefault: 2, frequencyDefault: 1,
allowed() { allowed() {
return (tech.haveGunCheck("shotgun")) && !tech.isShotgunRecoil return (tech.haveGunCheck("shotgun")) && !tech.isShotgunRecoil
}, },
@@ -5864,42 +5865,44 @@ const tech = {
}, },
{ {
name: "smelting", name: "smelting",
// description: `forge <strong>3</strong> <strong class='color-ammo'>ammo</strong> into a new harpoon<br>fire <strong>+1</strong> <strong>harpoon</strong> with each shot`, descriptionFunction() { return `forge <strong>${this.removeAmmo()}</strong> <strong class='color-ammo'>ammo</strong> into a new harpoon<br>fire <strong>+1</strong> <strong>harpoon</strong> with each shot` },
descriptionFunction() { return `forge <strong>${(tech.isRailGun ? 2 : 1) * (4 + 2 * this.count)}</strong> <strong class='color-ammo'>ammo</strong> into a new harpoon<br>fire <strong>+1</strong> <strong>harpoon</strong> with each shot` },
// descriptionFunction() { return `forge <strong>${tech.isRailGun? 10: 2}</strong> <strong class='color-ammo'>ammo</strong> into a new harpoon<br>fire <strong>+1</strong> <strong>harpoon</strong> with each shot` },
isGunTech: true, isGunTech: true,
maxCount: 9, maxCount: 9,
count: 0, count: 0,
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
ammoRemoved: 0,
removeAmmo() {
return (tech.isRailGun ? 5 : 1) * (2 + 2 * this.count)
},
allowed() { allowed() {
return tech.haveGunCheck("harpoon") && b.returnGunAmmo('harpoon') >= (tech.isRailGun ? 5 : 3) * (1 + this.count) return tech.haveGunCheck("harpoon") && b.returnGunAmmo('harpoon') >= this.removeAmmo()
}, },
requires: "harpoon", requires: "harpoon",
effect() { effect() {
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "harpoon") { if (b.guns[i].name === "harpoon") {
b.guns[i].ammo -= (tech.isRailGun ? 5 : 2) * (1 + this.count) const removeAmmo = this.removeAmmo()
// console.log(3 + this.count * 3) this.ammoRemoved += removeAmmo
b.guns[i].ammo -= removeAmmo
if (b.guns[i].ammo < 0) b.guns[i].ammo = 0 if (b.guns[i].ammo < 0) b.guns[i].ammo = 0
simulation.updateGunHUD(); simulation.updateGunHUD();
tech.extraHarpoons++; tech.extraHarpoons++;
break break
} }
} }
// this.description = `forge <strong>${3+(this.count+1)*3}</strong> <strong class='color-ammo'>ammo</strong> into a new harpoon<br>fire <strong>+1</strong> <strong>harpoon</strong> with each shot`
}, },
remove() { remove() {
if (tech.extraHarpoons) { if (tech.extraHarpoons) {
// this.description = `forge <strong>${2}</strong> <strong class='color-ammo'>ammo</strong> into a new harpoon<br>fire <strong>+1</strong> <strong>harpoon</strong> with each shot`
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "harpoon") { if (b.guns[i].name === "harpoon") {
b.guns[i].ammo += (tech.isRailGun ? 5 : 3) b.guns[i].ammo += this.ammoRemoved
simulation.updateGunHUD(); simulation.updateGunHUD();
break break
} }
} }
} }
this.ammoRemoved = 0
tech.extraHarpoons = 0; tech.extraHarpoons = 0;
} }
}, },
@@ -7113,8 +7116,7 @@ const tech = {
{ {
name: "quantum eraser", name: "quantum eraser",
descriptionFunction() { return `<span style = 'font-size:90%;'>for each mob left <strong>alive</strong> after you exit a <strong>level</strong><br><strong>kill</strong> a mob as they spawn at <strong>+${100-1.6*simulation.difficultyMode**2}%</strong> <strong class='color-dup'>duplication</strong></span>` }, descriptionFunction() { return `<span style = 'font-size:90%;'>for each mob left <strong>alive</strong> after you exit a <strong>level</strong><br><strong>kill</strong> a mob as they spawn at <strong>+${100-1.6*simulation.difficultyMode**2}%</strong> <strong class='color-dup'>duplication</strong></span>` },
// description: `<span style = 'font-size:90%;'>for each mob left <strong>alive</strong> after you exit a <strong>level</strong><br><strong>kill</strong> a mob as they spawn at <strong>100%</strong> <strong class='color-dup'>duplication</strong></span>`,
description: `<span style = 'font-size:90%;'>for each mob left <strong>alive</strong> after you exit a <strong>level</strong><br><strong>kill</strong> a mob as they spawn at <strong>100%</strong> <strong class='color-dup'>duplication</strong></span>`,
isFieldTech: true, isFieldTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -7137,7 +7139,8 @@ const tech = {
}, },
{ {
name: "symbiosis", name: "symbiosis",
description: `after a <strong>boss</strong> <strong>dies</strong> spawn a <strong class='color-m'>tech</strong>, ${powerUps.orb.ammo(1)}, ${powerUps.orb.research(1)}, and ${powerUps.orb.heal(1)}<br>after a <strong>mob</strong> <strong>dies</strong> <strong>0.5</strong> maximum <strong class='color-h'>health</strong>`, descriptionFunction() { return `after a <strong>boss</strong> <strong>dies</strong> spawn a <strong class='color-m'>tech</strong>, ${powerUps.orb.ammo(1)}, ${powerUps.orb.research(1)}, and ${powerUps.orb.heal(1)}<br>after a <strong>mob</strong> <strong>dies</strong> <strong>0.5</strong> maximum ${tech.isEnergyHealth ? "<strong class='color-f'>energy</strong>" : "<strong class='color-h'>health</strong>"}` },
// description: `after a <strong>boss</strong> <strong>dies</strong> spawn a <strong class='color-m'>tech</strong>, ${powerUps.orb.ammo(1)}, ${powerUps.orb.research(1)}, and ${powerUps.orb.heal(1)}<br>after a <strong>mob</strong> <strong>dies</strong> <strong>0.5</strong> maximum <strong class='color-h'>health</strong>`,
isFieldTech: true, isFieldTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -7198,7 +7201,7 @@ const tech = {
}, },
{ {
name: "ambush", name: "ambush",
description: "metamaterial cloaking field <strong class='color-d'>damage</strong> effect<br>is increased from <span style = 'text-decoration: line-through;'>333%</span> to <strong>666%</strong>", description: "metamaterial cloaking field <strong class='color-d'>damage</strong> effect<br>is increased from <span style = 'text-decoration: line-through;'>333%</span> to <strong>555%</strong>",
isFieldTech: true, isFieldTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -7209,10 +7212,10 @@ const tech = {
}, },
requires: "metamaterial cloaking", requires: "metamaterial cloaking",
effect() { effect() {
tech.sneakAttackDmg = 7.66 tech.sneakAttackDmg = 6.55 //555% + 100%
}, },
remove() { remove() {
tech.sneakAttackDmg = 4.33 tech.sneakAttackDmg = 4.33 //333% + 100%
} }
}, },
{ {

View File

@@ -1,35 +1,17 @@
******************************************************** NEXT PATCH ************************************************** ******************************************************** NEXT PATCH **************************************************
finalBoss pushes away things between every phase cloaking +damage occurs for 2 seconds after decloaking
it's much smaller in black hole phase and very hard to hit need to cloak for 4 seconds to get the full 2 seconds of +damage
ambush 666% -> 555% damage
boson composite drains 25% more energy when you move through mobs
timeBoss, shooterBoss, orbitalBoss, laserTargetingBoss have "orbital armor" nail gun gets 20% more ammo
orbitals have less health and move a bit slower harpoons now properly do damage on the frame before they retract
orbitalBoss is slower and has more health smelting removes 10% more ammo to get another harpoon for railgun
blinkBoss does much less collision damage grenade fireworks explosive petals are 25% closer together
laserTargetingBoss does 2.5x damage but it's laser is only on 1/2 the time
URL builds share what mode molecular assembler is on
*********************************************************** TODO ***************************************************** *********************************************************** TODO *****************************************************
make final Boss hidden for the mob spawning phase?
tech for molecular assembler that generates research?
show damage and defense in game?
defense and damage without difficulty included?
update every: 15 cycles?, 30?, 10?
make a m.damage variable that stores the player damage for all slow changing tech
update m.damage variable when:
new tech
flipFlip triggers
duplicationChance changes
add or remove guns
player health changes
research changes
bot count changes
tech ______ effect that last until you get hit tech ______ effect that last until you get hit
field or bots can check your health every cycle and see if it lower field or bots can check your health every cycle and see if it lower
if it's high update the health check value if it's high update the health check value