From 936741a4e7ef11f1a4176a012e5286eed4462c55 Mon Sep 17 00:00:00 2001 From: landgreen Date: Sun, 1 May 2022 05:56:08 -0700 Subject: [PATCH] time dilation rework time dilation field rework 2x energy regen, but pausing time now uses much more energy you are immune to harm while time is paused but this stops energy regen tech timelike is removed eternalism gives 50% damage instead of ammo also disables the pause button, and other pause effects tech: polyurethane foam - super balls turn into foam after hitting a mob supertemporal renamed autocannon now gives +1 ball, and has a shorter delay between balls harpoon and grapple no longer lose ammo when you run out of energy they just trigger a 2 second fire CD slashBoss doesn't slash as often at higher difficulty levels field descriptions rewritten bug fixes --- .DS_Store | Bin 6148 -> 6148 bytes js/bullet.js | 401 +++++++++++++++++++++++++++----------------------- js/index.js | 2 +- js/level.js | 316 ++++++++++++++++++++------------------- js/player.js | 255 ++++++++++++++++---------------- js/powerup.js | 2 +- js/spawn.js | 2 +- js/tech.js | 146 ++++++++++-------- todo.txt | 45 +++--- 9 files changed, 624 insertions(+), 545 deletions(-) diff --git a/.DS_Store b/.DS_Store index d52b7c36c3d6570acb86287b34398872d26336f0..6e7e76724992c3f3cc6a506419ede150032cb683 100644 GIT binary patch delta 22 dcmZoMXffEJ#mw~h!(<(1UnZ3go2!{SMF3tg2o3-M delta 22 dcmZoMXffEJ#msaiY_blsFO%|x&DG4EA^=pz2Sfk> diff --git a/js/bullet.js b/js/bullet.js index 18e860f..7436b55 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -1437,7 +1437,14 @@ const b = { returnToPlayer() { if (Vector.magnitude(Vector.sub(this.position, m.pos)) < returnRadius) { //near player this.endCycle = 0; - if (m.cycle + 25 * b.fireCDscale < m.fireCDcycle) m.fireCDcycle = m.cycle + 35 * b.fireCDscale //lower cd to 25 if it is above 25 + if (m.energy < 0.05) { + m.fireCDcycle = m.cycle + 120; //fire cooldown + } else if (m.cycle + 25 * b.fireCDscale < m.fireCDcycle) { + m.fireCDcycle = m.cycle + 35 * b.fireCDscale //lower cd to 25 if it is above 25 + } + + if (m.energy < 0.05) this.dropCaughtPowerUp() + //recoil on catching const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (input.down ? 0.00015 : 0.0003)) player.force.x += momentum.x @@ -1488,31 +1495,31 @@ const b = { this.grabPowerUp() if (this.endCycle < simulation.cycle + 1) { //if at end of lifespan, but player is holding down fire, force retraction this.endCycle = simulation.cycle + 60 - m.fireCDcycle = m.cycle + 20 // cool down + m.fireCDcycle = m.cycle + 120 // cool down this.do = this.returnToPlayer Matter.Body.setDensity(this, 0.0005); //reduce density on return if (this.angularSpeed < 0.5) this.torque += this.inertia * 0.001 * (Math.random() - 0.5) //(Math.round(Math.random()) ? 1 : -1) this.collisionFilter.mask = cat.map | cat.mob | cat.mobBullet | cat.mobShield // | cat.body } } else { - //snap rope if not enough energy - if (m.energy < 0.05) { - const returnForce = Vector.mult(Vector.normalise(Vector.sub(this.position, m.pos)), 3 * this.thrustMag * this.mass) - this.force.x -= returnForce.x - this.force.y -= returnForce.y - this.frictionAir = 0.002 - this.do = () => { - if (this.speed < 20) this.force.y += 0.0005 * this.mass; - } - this.dropCaughtPowerUp() - } else { - //return to player - this.do = this.returnToPlayer - this.endCycle = simulation.cycle + 60 - Matter.Body.setDensity(this, 0.0005); //reduce density on return - if (this.angularSpeed < 0.5) this.torque += this.inertia * 0.001 * (Math.random() - 0.5) //(Math.round(Math.random()) ? 1 : -1) - this.collisionFilter.mask = cat.map | cat.mob | cat.mobBullet | cat.mobShield // | cat.body - } + //if not enough energy + if (m.energy < 0.05) this.dropCaughtPowerUp() + // const returnForce = Vector.mult(Vector.normalise(Vector.sub(this.position, m.pos)), 3 * this.thrustMag * this.mass) + // this.force.x -= returnForce.x + // this.force.y -= returnForce.y + // this.frictionAir = 0.002 + // this.do = () => { + // if (this.speed < 20) this.force.y += 0.0005 * this.mass; + // } + + // } else { + //return to player + this.do = this.returnToPlayer + this.endCycle = simulation.cycle + 60 + Matter.Body.setDensity(this, 0.0005); //reduce density on return + if (this.angularSpeed < 0.5) this.torque += this.inertia * 0.001 * (Math.random() - 0.5) //(Math.round(Math.random()) ? 1 : -1) + this.collisionFilter.mask = cat.map | cat.mob | cat.mobBullet | cat.mobShield // | cat.body + // } } //grappling hook if (input.fire && Matter.Query.collides(this, map).length) { @@ -1562,12 +1569,13 @@ const b = { m.immuneCycle = m.cycle + 10; if (m.energy > 0.001) { m.energy -= 0.001 - } else { + } else { //out of energy Matter.Sleeping.set(this, false) this.collisionFilter.category = 0 this.collisionFilter.mask = 0 this.do = this.returnToPlayer this.endCycle = simulation.cycle + 60 + m.fireCDcycle = m.cycle + 120; //fire cooldown } } } else { @@ -1697,7 +1705,12 @@ const b = { returnToPlayer() { if (Vector.magnitude(Vector.sub(this.position, m.pos)) < returnRadius) { //near player this.endCycle = 0; - if (m.cycle + 25 * b.fireCDscale < m.fireCDcycle) m.fireCDcycle = m.cycle + 35 * b.fireCDscale //lower cd to 25 if it is above 25 + + if (m.energy < 0.05) { + m.fireCDcycle = m.cycle + 120; //fire cooldown + } else if (m.cycle + 25 * b.fireCDscale < m.fireCDcycle) { + m.fireCDcycle = m.cycle + 35 * b.fireCDscale //lower cd to 25 if it is above 25 + } //recoil on catching const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (input.down ? 0.00015 : 0.0003)) player.force.x += momentum.x @@ -1749,24 +1762,13 @@ const b = { this.cycle++ if (isReturn || target) { if (isReturn) { - if (this.cycle > totalCycles) { - //snap rope if not enough energy - if (m.energy < 0.05) { - const returnForce = Vector.mult(Vector.normalise(Vector.sub(this.position, m.pos)), 3 * this.thrustMag * this.mass) - this.force.x -= returnForce.x - this.force.y -= returnForce.y - this.frictionAir = 0.002 - this.do = () => { - if (this.speed < 20) this.force.y += 0.0005 * this.mass; - } - this.dropCaughtPowerUp() - } else { - //return to player - this.do = this.returnToPlayer - Matter.Body.setDensity(this, 0.0005); //reduce density on return - if (this.angularSpeed < 0.5) this.torque += this.inertia * 0.001 * (Math.random() - 0.5) //(Math.round(Math.random()) ? 1 : -1) - this.collisionFilter.mask = cat.map | cat.mob | cat.mobBullet | cat.mobShield // | cat.body - } + if (this.cycle > totalCycles || m.energy < 0.05) { //return to player + 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) + Matter.Sleeping.set(this, false) + this.collisionFilter.category = 0 + this.collisionFilter.mask = 0 + this.endCycle = simulation.cycle + 60 } else { this.grabPowerUp() } @@ -5307,6 +5309,9 @@ const b = { have: false, // num: 5, do() {}, + foamBall() { + + }, fireOne() { const SPEED = input.down ? 43 : 36 m.fireCDcycle = m.cycle + Math.floor((input.down ? 23 : 15) * b.fireCDscale); // cool down @@ -5332,6 +5337,15 @@ const b = { b.explosion(this.position, this.mass * 280); //makes bullet do explosive damage at end this.endCycle = 0 } + if (tech.isFoamBall) { + const radius = 5 + 8 * Math.random() + const velocity = { x: Math.max(2, 10 - radius * 0.25), y: 0 } + for (let i = 0, len = 6 * this.mass; i < len; i++) { + b.foam(this.position, Vector.rotate(velocity, 6.28 * Math.random()), radius) + } + this.endCycle = 0 + // this.mass = 0 //prevent damage + } }; }, fireMulti() { @@ -5362,26 +5376,35 @@ const b = { b.explosion(this.position, this.mass * 320 + 70 * Math.random()); //makes bullet do explosive damage at end this.endCycle = 0 } + if (tech.isFoamBall) { + const radius = 5 + 8 * Math.random() + const velocity = { x: Math.max(2, 10 - radius * 0.25), y: 0 } + for (let i = 0, len = 6 * this.mass; i < len; i++) { + b.foam(this.position, Vector.rotate(velocity, 6.28 * Math.random()), radius) + } + this.endCycle = 0 + // this.mass = 0 //prevent damage + } }; dir += SPREAD; } }, fireQueue() { + // const dir = m.angle + // const x = m.pos.x + // const y = m.pos.y const SPEED = input.down ? 43 : 36 - const dir = m.angle - const x = m.pos.x - const y = m.pos.y - const num = 3 + Math.floor(tech.extraSuperBalls * Math.random()) + const num = 1 + 3 + Math.floor(tech.extraSuperBalls * Math.random()) //1 extra const delay = Math.floor((input.down ? 18 : 12) * b.fireCDscale) m.fireCDcycle = m.cycle + delay; // cool down const fireBall = () => { const me = bullet.length; - bullet[me] = Bodies.polygon(x, y, 12, 11 * tech.bulletSize, b.fireAttributes(dir, false)); + bullet[me] = Bodies.polygon(m.pos.x, m.pos.y, 12, 11 * tech.bulletSize, b.fireAttributes(m.angle, false)); Composite.add(engine.world, bullet[me]); //add bullet to world Matter.Body.setVelocity(bullet[me], { - x: SPEED * Math.cos(dir), - y: SPEED * Math.sin(dir) + x: SPEED * Math.cos(m.angle), + y: SPEED * Math.sin(m.angle) }); bullet[me].endCycle = simulation.cycle + Math.floor(330 * tech.isBulletsLastLonger); bullet[me].minDmgSpeed = 0; @@ -5395,16 +5418,28 @@ const b = { b.explosion(this.position, this.mass * 320 + 70 * Math.random()); //makes bullet do explosive damage at end this.endCycle = 0 } + if (tech.isFoamBall) { + const radius = 5 + 8 * Math.random() + const velocity = { x: Math.max(2, 10 - radius * 0.25), y: 0 } + for (let i = 0, len = 6 * this.mass; i < len; i++) { + b.foam(this.position, Vector.rotate(velocity, 6.28 * Math.random()), radius) + } + this.endCycle = 0 + // this.mass = 0 //prevent damage + } }; m.fireCDcycle = m.cycle + delay; // cool down } function cycle() { - if (simulation.paused || m.isBodiesAsleep) { requestAnimationFrame(cycle) } else { - count++ - if (count % 2) fireBall() - if (count < num * 2 && m.alive) requestAnimationFrame(cycle); - } + // if (simulation.paused || m.isBodiesAsleep) { + // requestAnimationFrame(cycle) + // } else { + count++ + // if (count % 2) + fireBall() + if (count < num && m.alive) requestAnimationFrame(cycle); + // } } let count = 0 requestAnimationFrame(cycle); @@ -5449,79 +5484,81 @@ const b = { }, do() {}, do360Longitudinal() { - ctx.strokeStyle = "rgba(0,0,0,0.6)" //"000"; - ctx.lineWidth = 2 * tech.wavePacketDamage - ctx.beginPath(); - const end = 700 * Math.sqrt(tech.isBulletsLastLonger) / Math.sqrt(tech.waveReflections * 0.5) //should equal about 1060 - const damage = 2 * m.dmgScale * tech.wavePacketDamage * tech.waveBeamDamage * (tech.isBulletTeleport ? 1.43 : 1) //damage is lower for large radius mobs, since they feel the waves longer + if (!m.isBodiesAsleep) { + ctx.strokeStyle = "rgba(0,0,0,0.6)" //"000"; + ctx.lineWidth = 2 * tech.wavePacketDamage + ctx.beginPath(); + const end = 700 * Math.sqrt(tech.isBulletsLastLonger) / Math.sqrt(tech.waveReflections * 0.5) //should equal about 1060 + const damage = 2 * m.dmgScale * tech.wavePacketDamage * tech.waveBeamDamage * (tech.isBulletTeleport ? 1.43 : 1) //damage is lower for large radius mobs, since they feel the waves longer - for (let i = this.waves.length - 1; i > -1; i--) { - //draw wave - ctx.moveTo(this.waves[i].position.x + this.waves[i].radius, this.waves[i].position.y) - ctx.arc(this.waves[i].position.x, this.waves[i].position.y, this.waves[i].radius, 0, 2 * Math.PI); - // collisions - if (tech.isBulletTeleport && Math.random() < 0.04) { - const scale = 400 * Math.random() - this.waves[i].position = Vector.add(this.waves[i].position, { x: scale * (Math.random() - 0.5), y: scale * (Math.random() - 0.5) }) - } - for (let j = 0, len = mob.length; j < len; j++) { - const dist = Vector.magnitude(Vector.sub(this.waves[i].position, mob[j].position)) - const r = mob[j].radius + 30 - if (dist + r > this.waves[i].radius && dist - r < this.waves[i].radius) { - //make them shake around - if (!mob[j].isBadTarget) { - mob[j].force.x += 0.01 * (Math.random() - 0.5) * mob[j].mass - mob[j].force.y += 0.01 * (Math.random() - 0.5) * mob[j].mass + for (let i = this.waves.length - 1; i > -1; i--) { + //draw wave + ctx.moveTo(this.waves[i].position.x + this.waves[i].radius, this.waves[i].position.y) + ctx.arc(this.waves[i].position.x, this.waves[i].position.y, this.waves[i].radius, 0, 2 * Math.PI); + // collisions + if (tech.isBulletTeleport && Math.random() < 0.04) { + const scale = 400 * Math.random() + this.waves[i].position = Vector.add(this.waves[i].position, { x: scale * (Math.random() - 0.5), y: scale * (Math.random() - 0.5) }) + } + for (let j = 0, len = mob.length; j < len; j++) { + const dist = Vector.magnitude(Vector.sub(this.waves[i].position, mob[j].position)) + const r = mob[j].radius + 30 + if (dist + r > this.waves[i].radius && dist - r < this.waves[i].radius) { + //make them shake around + if (!mob[j].isBadTarget) { + mob[j].force.x += 0.01 * (Math.random() - 0.5) * mob[j].mass + mob[j].force.y += 0.01 * (Math.random() - 0.5) * mob[j].mass + } + if (!mob[j].isShielded) { + Matter.Body.setVelocity(mob[j], { //friction + x: mob[j].velocity.x * 0.95, + y: mob[j].velocity.y * 0.95 + }); + //draw vibes + let vertices = mob[j].vertices; + const vibe = 50 + mob[j].radius * 0.15 + ctx.moveTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5)); + for (let k = 1; k < vertices.length; k++) { + ctx.lineTo(vertices[k].x + vibe * (Math.random() - 0.5), vertices[k].y + vibe * (Math.random() - 0.5)); + } + ctx.lineTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5)); + //damage + mob[j].locatePlayer(); + mob[j].damage(damage / Math.sqrt(mob[j].radius)); + } } - if (!mob[j].isShielded) { - Matter.Body.setVelocity(mob[j], { //friction - x: mob[j].velocity.x * 0.95, - y: mob[j].velocity.y * 0.95 - }); + } + for (let j = 0, len = body.length; j < len; j++) { + const dist = Vector.magnitude(Vector.sub(this.waves[i].position, body[j].position)) + const r = 20 + if (dist + r > this.waves[i].radius && dist - r < this.waves[i].radius) { + //make them shake around + body[j].force.x += 0.01 * (Math.random() - 0.5) * body[j].mass + body[j].force.y += (0.01 * (Math.random() - 0.5) - simulation.g * 0.25) * body[j].mass //remove force of gravity //draw vibes - let vertices = mob[j].vertices; - const vibe = 50 + mob[j].radius * 0.15 + let vertices = body[j].vertices; + const vibe = 25 ctx.moveTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5)); for (let k = 1; k < vertices.length; k++) { ctx.lineTo(vertices[k].x + vibe * (Math.random() - 0.5), vertices[k].y + vibe * (Math.random() - 0.5)); } ctx.lineTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5)); - //damage - mob[j].locatePlayer(); - mob[j].damage(damage / Math.sqrt(mob[j].radius)); } } - } - for (let j = 0, len = body.length; j < len; j++) { - const dist = Vector.magnitude(Vector.sub(this.waves[i].position, body[j].position)) - const r = 20 - if (dist + r > this.waves[i].radius && dist - r < this.waves[i].radius) { - //make them shake around - body[j].force.x += 0.01 * (Math.random() - 0.5) * body[j].mass - body[j].force.y += (0.01 * (Math.random() - 0.5) - simulation.g * 0.25) * body[j].mass //remove force of gravity - //draw vibes - let vertices = body[j].vertices; - const vibe = 25 - ctx.moveTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5)); - for (let k = 1; k < vertices.length; k++) { - ctx.lineTo(vertices[k].x + vibe * (Math.random() - 0.5), vertices[k].y + vibe * (Math.random() - 0.5)); - } - ctx.lineTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5)); + this.waves[i].radius += tech.waveBeamSpeed * this.waves[i].expanding //expand / move + // if (this.waves[i].radius > end) this.waves.splice(i, 1) //end + if (this.waves[i].radius > end) { + this.waves[i].expanding = -1 + this.waves[i].reflection-- + if (this.waves[i].reflection < 1) this.waves.splice(i, 1) //end + } else if (this.waves[i].radius < 25) { + this.waves[i].expanding = 1 + this.waves[i].reflection-- + if (this.waves[i].reflection < 1) this.waves.splice(i, 1) //end } } - this.waves[i].radius += tech.waveBeamSpeed * this.waves[i].expanding //expand / move - // if (this.waves[i].radius > end) this.waves.splice(i, 1) //end - if (this.waves[i].radius > end) { - this.waves[i].expanding = -1 - this.waves[i].reflection-- - if (this.waves[i].reflection < 1) this.waves.splice(i, 1) //end - } else if (this.waves[i].radius < 25) { - this.waves[i].expanding = 1 - this.waves[i].reflection-- - if (this.waves[i].reflection < 1) this.waves.splice(i, 1) //end - } + ctx.stroke(); } - ctx.stroke(); }, fire360Longitudinal() { m.fireCDcycle = m.cycle + Math.floor((input.down ? 3 : 8) * b.fireCDscale); // cool down @@ -5533,87 +5570,89 @@ const b = { }) }, doLongitudinal() { - ctx.strokeStyle = "rgba(0,0,0,0.6)" //"000"; - ctx.lineWidth = 2 * tech.wavePacketDamage - ctx.beginPath(); - const end = 1100 * tech.isBulletsLastLonger / Math.sqrt(tech.waveReflections * 0.5) //should equal about 1767 - const damage = 2 * m.dmgScale * tech.wavePacketDamage * tech.waveBeamDamage * (tech.isBulletTeleport ? 1.43 : 1) //damage is lower for large radius mobs, since they feel the waves longer + if (!m.isBodiesAsleep) { + ctx.strokeStyle = "rgba(0,0,0,0.6)" //"000"; + ctx.lineWidth = 2 * tech.wavePacketDamage + ctx.beginPath(); + const end = 1100 * tech.isBulletsLastLonger / Math.sqrt(tech.waveReflections * 0.5) //should equal about 1767 + const damage = 2 * m.dmgScale * tech.wavePacketDamage * tech.waveBeamDamage * (tech.isBulletTeleport ? 1.43 : 1) //damage is lower for large radius mobs, since they feel the waves longer - for (let i = this.waves.length - 1; i > -1; i--) { - const v1 = Vector.add(this.waves[i].position, Vector.mult(this.waves[i].unit1, this.waves[i].radius)) - const v2 = Vector.add(this.waves[i].position, Vector.mult(this.waves[i].unit2, this.waves[i].radius)) - //draw wave - ctx.moveTo(v1.x, v1.y) - ctx.arc(this.waves[i].position.x, this.waves[i].position.y, this.waves[i].radius, this.waves[i].angle, this.waves[i].angle + this.waves[i].arc); - // collisions - //using small angle linear approximation of circle arc, this will not work if the arc gets large // https://stackoverflow.com/questions/13652518/efficiently-find-points-inside-a-circle-sector - if (tech.isBulletTeleport && Math.random() < 0.05) { - if (Math.random() < 0.5) { - // const scale = 500 * Math.random() - // this.waves[i].position = Vector.add(this.waves[i].position, { x: scale * (Math.random() - 0.5), y: scale * (Math.random() - 0.5) }) - } else { - this.waves[i].arc *= 1 + 1 * (Math.random() - 0.5) - const halfArc = this.waves[i].arc / 2 - const angle = m.angle + 0.5 * (Math.random() - 0.5) - this.waves[i].angle = angle - halfArc - this.waves[i].unit1 = { x: Math.cos(angle - halfArc), y: Math.sin(angle - halfArc) } - this.waves[i].unit2 = { x: Math.cos(angle + halfArc), y: Math.sin(angle + halfArc) } + for (let i = this.waves.length - 1; i > -1; i--) { + const v1 = Vector.add(this.waves[i].position, Vector.mult(this.waves[i].unit1, this.waves[i].radius)) + const v2 = Vector.add(this.waves[i].position, Vector.mult(this.waves[i].unit2, this.waves[i].radius)) + //draw wave + ctx.moveTo(v1.x, v1.y) + ctx.arc(this.waves[i].position.x, this.waves[i].position.y, this.waves[i].radius, this.waves[i].angle, this.waves[i].angle + this.waves[i].arc); + // collisions + //using small angle linear approximation of circle arc, this will not work if the arc gets large // https://stackoverflow.com/questions/13652518/efficiently-find-points-inside-a-circle-sector + if (tech.isBulletTeleport && Math.random() < 0.05) { + if (Math.random() < 0.5) { + // const scale = 500 * Math.random() + // this.waves[i].position = Vector.add(this.waves[i].position, { x: scale * (Math.random() - 0.5), y: scale * (Math.random() - 0.5) }) + } else { + this.waves[i].arc *= 1 + 1 * (Math.random() - 0.5) + const halfArc = this.waves[i].arc / 2 + const angle = m.angle + 0.5 * (Math.random() - 0.5) + this.waves[i].angle = angle - halfArc + this.waves[i].unit1 = { x: Math.cos(angle - halfArc), y: Math.sin(angle - halfArc) } + this.waves[i].unit2 = { x: Math.cos(angle + halfArc), y: Math.sin(angle + halfArc) } + } } - } - let hits = Matter.Query.ray(mob, v1, v2, 50) //Matter.Query.ray(bodies, startPoint, endPoint, [rayWidth]) - for (let j = 0; j < hits.length; j++) { - const who = hits[j].body - //make them shake around - if (!who.isBadTarget) { + let hits = Matter.Query.ray(mob, v1, v2, 50) //Matter.Query.ray(bodies, startPoint, endPoint, [rayWidth]) + for (let j = 0; j < hits.length; j++) { + const who = hits[j].body + //make them shake around + if (!who.isBadTarget) { + who.force.x += 0.01 * (Math.random() - 0.5) * who.mass + who.force.y += 0.01 * (Math.random() - 0.5) * who.mass + } + if (!who.isShielded) { + Matter.Body.setVelocity(who, { //friction + x: who.velocity.x * 0.95, + y: who.velocity.y * 0.95 + }); + let vertices = who.vertices; + const vibe = 50 + who.radius * 0.15 + ctx.moveTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5)); + for (let j = 1; j < vertices.length; j++) { + ctx.lineTo(vertices[j].x + vibe * (Math.random() - 0.5), vertices[j].y + vibe * (Math.random() - 0.5)); + } + ctx.lineTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5)); + who.locatePlayer(); + who.damage(damage / Math.sqrt(who.radius)); + } + } + + hits = Matter.Query.ray(body, v1, v2, 50) //Matter.Query.ray(bodies, startPoint, endPoint, [rayWidth]) + for (let j = 0; j < hits.length; j++) { + const who = hits[j].body + //make them shake around who.force.x += 0.01 * (Math.random() - 0.5) * who.mass - who.force.y += 0.01 * (Math.random() - 0.5) * who.mass - } - if (!who.isShielded) { - Matter.Body.setVelocity(who, { //friction - x: who.velocity.x * 0.95, - y: who.velocity.y * 0.95 - }); + who.force.y += (0.01 * (Math.random() - 0.5) - simulation.g * 0.25) * who.mass //remove force of gravity + let vertices = who.vertices; - const vibe = 50 + who.radius * 0.15 + const vibe = 25 ctx.moveTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5)); for (let j = 1; j < vertices.length; j++) { ctx.lineTo(vertices[j].x + vibe * (Math.random() - 0.5), vertices[j].y + vibe * (Math.random() - 0.5)); } ctx.lineTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5)); - who.locatePlayer(); - who.damage(damage / Math.sqrt(who.radius)); + } + // ctx.stroke(); //draw vibes + + this.waves[i].radius += tech.waveBeamSpeed * 2 * this.waves[i].expanding //expand / move + if (this.waves[i].radius > end) { + this.waves[i].expanding = -1 + this.waves[i].reflection-- + if (this.waves[i].reflection < 1) this.waves.splice(i, 1) //end + } else if (this.waves[i].radius < 25) { + this.waves[i].expanding = 1 + this.waves[i].reflection-- + if (this.waves[i].reflection < 1) this.waves.splice(i, 1) //end } } - - hits = Matter.Query.ray(body, v1, v2, 50) //Matter.Query.ray(bodies, startPoint, endPoint, [rayWidth]) - for (let j = 0; j < hits.length; j++) { - const who = hits[j].body - //make them shake around - who.force.x += 0.01 * (Math.random() - 0.5) * who.mass - who.force.y += (0.01 * (Math.random() - 0.5) - simulation.g * 0.25) * who.mass //remove force of gravity - - let vertices = who.vertices; - const vibe = 25 - ctx.moveTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5)); - for (let j = 1; j < vertices.length; j++) { - ctx.lineTo(vertices[j].x + vibe * (Math.random() - 0.5), vertices[j].y + vibe * (Math.random() - 0.5)); - } - ctx.lineTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5)); - } - // ctx.stroke(); //draw vibes - - this.waves[i].radius += tech.waveBeamSpeed * 2 * this.waves[i].expanding //expand / move - if (this.waves[i].radius > end) { - this.waves[i].expanding = -1 - this.waves[i].reflection-- - if (this.waves[i].reflection < 1) this.waves.splice(i, 1) //end - } else if (this.waves[i].radius < 25) { - this.waves[i].expanding = 1 - this.waves[i].reflection-- - if (this.waves[i].reflection < 1) this.waves.splice(i, 1) //end - } + ctx.stroke(); } - ctx.stroke(); }, fireLongitudinal() { m.fireCDcycle = m.cycle + Math.floor((input.down ? 3 : 8) * b.fireCDscale); // cool down diff --git a/js/index.js b/js/index.js index f26bfa5..0ee296c 100644 --- a/js/index.js +++ b/js/index.js @@ -904,7 +904,7 @@ window.addEventListener("keydown", function(event) { // level.levelAnnounce(); document.body.style.cursor = "none"; requestAnimationFrame(cycle); - } else { + } else if (!tech.isNoDraftPause) { simulation.paused = true; build.pauseGrid() document.body.style.cursor = "auto"; diff --git a/js/level.js b/js/level.js index 0e05bf3..2edca08 100644 --- a/js/level.js +++ b/js/level.js @@ -16,12 +16,12 @@ const level = { start() { if (level.levelsCleared === 0) { //this code only runs on the first level // simulation.isHorizontalFlipped = true - // m.setField("standing wave") - // b.giveGuns("laser") - // tech.giveTech("scrap-bot manufacturing") + // m.setField("time dilation") + // b.giveGuns("matter wave") + // tech.giveTech("phonon") // tech.giveTech("eternalism") - // tech.giveTech("options exchange") - // tech.giveTech("ICBM") + // tech.giveTech("isotropic radiator") + // tech.giveTech("polyurethane balls") // tech.giveTech("grappling hook") // tech.giveTech("paradigm shift") // for (let i = 0; i < 1; i++) powerUps.directSpawn(450, -50, "tech"); @@ -37,7 +37,7 @@ const level = { // m.immuneCycle = Infinity //you can't take damage // level.difficultyIncrease(15) //30 is near max on hard //60 is near max on why // simulation.enableConstructMode() //used to build maps in testing mode - // level.testChamber(); + // level.labs(); // level.testing(); //not in rotation, used for testing if (simulation.isTraining) { level.walk(); } else { level.intro(); } //normal starting level ************************************************ // powerUps.research.changeRerolls(3000) @@ -972,19 +972,19 @@ const level = { } } //delete any overlapping mobs - const mobsHits = Matter.Query.collides(this, mob) - for (let i = 0; i < mobsHits.length; i++) { - if (mobsHits[i].bodyB !== this && mobsHits[i].bodyB !== m.holdingTarget) { //dont' delete yourself <----- bug here maybe... - Matter.Composite.remove(engine.world, mobsHits[i].bodyB); - mobsHits[i].bodyB.isRemoveMeNow = true - for (let i = 1; i < mob.length; i++) { //find which index in body array it is and remove from array - if (mob[i].isRemoveMeNow) { - mob.splice(i, 1); - break - } - } - } - } + // const mobsHits = Matter.Query.collides(this, mob) + // for (let i = 0; i < mobsHits.length; i++) { + // if (mobsHits[i].bodyB !== this && mobsHits[i].bodyB !== m.holdingTarget) { //dont' delete yourself <----- bug here maybe... + // Matter.Composite.remove(engine.world, mobsHits[i].bodyB); + // mobsHits[i].bodyB.isRemoveMeNow = true + // for (let i = 1; i < mob.length; i++) { //find which index in body array it is and remove from array + // if (mob[i].isRemoveMeNow) { + // mob.splice(i, 1); + // break + // } + // } + // } + // } } } } @@ -1444,15 +1444,15 @@ const level = { spawn.bodyRect(x + 1460, y - 900, 30, 150); //entrance door spawn.mapRect(x + 1600, y - 350, 500, 100); //toggle shelf const toggle = level.toggle(x + 1650, y - 350, true) //(x,y,isOn,isLockOn = true/false) - let hazard + let hazard1 if (Math.random() > 0.5) { spawn.mapRect(x + 550, y - 750, 1500, 50); //entrance shelf - hazard = level.hazard(x + 850, y - 920, 600, 10, 0.4) //laser + hazard1 = level.hazard(x + 850, y - 920, 600, 10, 0.4) //laser spawn.mapRect(x + 860, y - 925, 10, 20); //laser nose spawn.mapRect(x + 660, y - 975, 200, 120); //laser body } else { spawn.mapRect(x + 1350, y - 750, 700, 50); //entrance shelf - hazard = level.hazard(x + 1040, y - 660, 1000, 10, 0.4) //laser + hazard1 = level.hazard(x + 1040, y - 660, 1000, 10, 0.4) //laser spawn.mapRect(x + 1050, y - 665, 10, 20); //laser nose spawn.mapRect(x + 650, y - 705, 400, 100); //laser body } @@ -1476,14 +1476,17 @@ const level = { doCustomTopLayer.push( () => { toggle.query(); - hazard.isOn = toggle.isOn + hazard1.isOn = toggle.isOn hazard2.isOn = toggle.isOn hazard3.isOn = toggle.isOn hazard4.isOn = toggle.isOn - hazard.opticalQuery(); - hazard2.opticalQuery(); - hazard3.opticalQuery(); - hazard4.opticalQuery(); + if ((simulation.cycle % 120) > 60) { + hazard1.opticalQuery(); + hazard2.opticalQuery(); + } else { + hazard3.opticalQuery(); + hazard4.opticalQuery(); + } // if (!isSpawnedMobs && !toggle.isOn) { // isSpawnedMobs = true // spawn.randomMob(x + 150, y + -1100, mobSpawnChance); @@ -2173,89 +2176,102 @@ const level = { // }, (x = offset.x, y = offset.y) => { - const toggle = level.toggle(x + 950, y + 0, false, true) // toggle(x, y, isOn = false, isLockOn = false) { - toggle.isAddedElements = false + // const toggle = level.toggle(x + 950, y + 0, false, true) // toggle(x, y, isOn = false, isLockOn = false) { + // toggle.isAddedElements = false + + const button = level.button(x + 950, y + 0) + button.isUp = true + + spawn.mapVertex(x + 5, y + -1318, "0 0 0 -250 125 -250"); //left ledges spawn.mapVertex(x + 1995, y + -1318, "0 0 0 -250 -125 -250"); // right ledges doCustomTopLayer.push( () => { - toggle.query(); - if (toggle.isOn && !toggle.isAddedElements) { //this code runs once after the toggle is triggered - toggle.isAddedElements = true //only do this once - addMapToLevelInProgress = (who) => { //adds new map elements to the level while the level is already running //don't forget to run simulation.draw.setPaths() after you all the the elements so they show up visually - who.collisionFilter.category = cat.map; - who.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet; - Matter.Body.setStatic(who, true); //make static - Composite.add(engine.world, who); //add to world + button.draw(); + if (button.isUp) { + button.query(); + if (!button.isUp) { + // toggle.isAddedElements = true //only do this once + addMapToLevelInProgress = (who) => { //adds new map elements to the level while the level is already running //don't forget to run simulation.draw.setPaths() after you all the the elements so they show up visually + who.collisionFilter.category = cat.map; + who.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet; + Matter.Body.setStatic(who, true); //make static + Composite.add(engine.world, who); //add to world + } + let r = 150 + let hexagon = `${r} 0 ${r * Math.cos(5.236)} ${r * Math.sin(5.236)} ${r * Math.cos(4.189)} ${r * Math.sin(4.189)} ${-r} 0 ${r * Math.cos(2.0944)} ${r * Math.sin(2.0944)} ${r * Math.cos(1.0472)} ${r * Math.sin(1.0472)} ` + //450 horizontal spread // -130-130-130 = 390 vertical + if (Math.random() < 0.5) { + spawn.mapVertex(x + 775, y + -260, hexagon); + spawn.mapVertex(x + 1225, y + -260, hexagon); + + spawn.mapVertex(x + 550, y + -650, hexagon); + spawn.mapVertex(x + 1000, y + -650, hexagon); + spawn.mapVertex(x + 1450, y + -650, hexagon); + + spawn.mapVertex(x + 325, y + -1040, hexagon); + spawn.mapVertex(x + 775, y + -1040, hexagon); + spawn.mapVertex(x + 1225, y + -1040, hexagon); + spawn.mapVertex(x + 1675, y + -1040, hexagon); + + spawn.mapVertex(x + 550, y + -1430, hexagon); + spawn.mapVertex(x + 1000, y + -1430, hexagon); + spawn.mapVertex(x + 1450, y + -1430, hexagon); + + const numberOfMapElementsAdded = 12 + for (let i = 0; i < numberOfMapElementsAdded; i++) addMapToLevelInProgress(map[map.length - 1 - i]) + spawn.randomMob(x + 225, y + -1775, mobSpawnChance); + spawn.randomMob(x + 700, y + -1750, mobSpawnChance); + spawn.randomMob(x + 1175, y + -1725, mobSpawnChance); + spawn.randomMob(x + 1700, y + -1700, mobSpawnChance); + spawn.randomMob(x + 1750, y + -250, mobSpawnChance); + spawn.randomMob(x + 125, y + -250, mobSpawnChance); + } else { + spawn.mapVertex(x + 775, y + -260, hexagon); + spawn.mapVertex(x + 1225, y + -260, hexagon); + + spawn.mapVertex(x + 550, y + -650, hexagon); + spawn.mapVertex(x + 1000, y + -650, hexagon); + spawn.mapVertex(x + 1450, y + -650, hexagon); + + spawn.mapVertex(x + 775, y + -1040, hexagon); + spawn.mapVertex(x + 1225, y + -1040, hexagon); + + spawn.mapVertex(x + 550, y + -1430, hexagon); + spawn.mapVertex(x + 1000, y + -1430, hexagon); + spawn.mapVertex(x + 1450, y + -1430, hexagon); + + spawn.mapVertex(x + 775, y + -1820, hexagon); + spawn.mapVertex(x + 1225, y + -1820, hexagon); + const numberOfMapElementsAdded = 12 + for (let i = 0; i < numberOfMapElementsAdded; i++) addMapToLevelInProgress(map[map.length - 1 - i]) + + spawn.randomMob(x + 225, y + -1025, mobSpawnChance); + spawn.randomMob(x + 200, y + -675, mobSpawnChance); + spawn.randomMob(x + 225, y + -200, mobSpawnChance); + spawn.randomMob(x + 1750, y + -1075, mobSpawnChance); + spawn.randomMob(x + 1700, y + -650, mobSpawnChance); + spawn.randomMob(x + 1675, y + -175, mobSpawnChance); + } + simulation.draw.setPaths() //update map graphics + spawn.randomGroup(x + 300, y + -2200); + spawn.randomGroup(x + 1625, y + -2200); + spawn.randomLevelBoss(x + 700, y + -2300); + spawn.secondaryBossChance(x + 1250, y + -2300) } - let r = 150 - let hexagon = `${r} 0 ${r * Math.cos(5.236)} ${r * Math.sin(5.236)} ${r * Math.cos(4.189)} ${r * Math.sin(4.189)} ${-r} 0 ${r * Math.cos(2.0944)} ${r * Math.sin(2.0944)} ${r * Math.cos(1.0472)} ${r * Math.sin(1.0472)} ` - //450 horizontal spread // -130-130-130 = 390 vertical - if (Math.random() < 0.5) { - spawn.mapVertex(x + 775, y + -260, hexagon); - spawn.mapVertex(x + 1225, y + -260, hexagon); - - spawn.mapVertex(x + 550, y + -650, hexagon); - spawn.mapVertex(x + 1000, y + -650, hexagon); - spawn.mapVertex(x + 1450, y + -650, hexagon); - - spawn.mapVertex(x + 325, y + -1040, hexagon); - spawn.mapVertex(x + 775, y + -1040, hexagon); - spawn.mapVertex(x + 1225, y + -1040, hexagon); - spawn.mapVertex(x + 1675, y + -1040, hexagon); - - spawn.mapVertex(x + 550, y + -1430, hexagon); - spawn.mapVertex(x + 1000, y + -1430, hexagon); - spawn.mapVertex(x + 1450, y + -1430, hexagon); - - const numberOfMapElementsAdded = 12 - for (let i = 0; i < numberOfMapElementsAdded; i++) addMapToLevelInProgress(map[map.length - 1 - i]) - spawn.randomMob(x + 225, y + -1775, mobSpawnChance); - spawn.randomMob(x + 700, y + -1750, mobSpawnChance); - spawn.randomMob(x + 1175, y + -1725, mobSpawnChance); - spawn.randomMob(x + 1700, y + -1700, mobSpawnChance); - spawn.randomMob(x + 1750, y + -250, mobSpawnChance); - spawn.randomMob(x + 125, y + -250, mobSpawnChance); - } else { - spawn.mapVertex(x + 775, y + -260, hexagon); - spawn.mapVertex(x + 1225, y + -260, hexagon); - - spawn.mapVertex(x + 550, y + -650, hexagon); - spawn.mapVertex(x + 1000, y + -650, hexagon); - spawn.mapVertex(x + 1450, y + -650, hexagon); - - spawn.mapVertex(x + 775, y + -1040, hexagon); - spawn.mapVertex(x + 1225, y + -1040, hexagon); - - spawn.mapVertex(x + 550, y + -1430, hexagon); - spawn.mapVertex(x + 1000, y + -1430, hexagon); - spawn.mapVertex(x + 1450, y + -1430, hexagon); - - spawn.mapVertex(x + 775, y + -1820, hexagon); - spawn.mapVertex(x + 1225, y + -1820, hexagon); - const numberOfMapElementsAdded = 12 - for (let i = 0; i < numberOfMapElementsAdded; i++) addMapToLevelInProgress(map[map.length - 1 - i]) - - spawn.randomMob(x + 225, y + -1025, mobSpawnChance); - spawn.randomMob(x + 200, y + -675, mobSpawnChance); - spawn.randomMob(x + 225, y + -200, mobSpawnChance); - spawn.randomMob(x + 1750, y + -1075, mobSpawnChance); - spawn.randomMob(x + 1700, y + -650, mobSpawnChance); - spawn.randomMob(x + 1675, y + -175, mobSpawnChance); - } - simulation.draw.setPaths() //update map graphics - spawn.randomGroup(x + 300, y + -2200); - spawn.randomGroup(x + 1625, y + -2200); - spawn.randomLevelBoss(x + 700, y + -2300); - spawn.secondaryBossChance(x + 1250, y + -2300) } + // toggle.query(); + // if (toggle.isOn && !toggle.isAddedElements) { //this code runs once after the toggle is triggered + + // } } ) }, (x = offset.x, y = offset.y) => { - const toggle = level.toggle(x + 950, y + 0, false, true) // toggle(x, y, isOn = false, isLockOn = false) { - toggle.isAddedElements = false - + // const toggle = level.toggle(x + 950, y + 0, false, true) // toggle(x, y, isOn = false, isLockOn = false) { + // toggle.isAddedElements = false + const button = level.button(x + 950, y + 0) + button.isUp = true //left ledges spawn.mapVertex(x + 5, y + -1868, "0 0 0 -250 125 -250"); spawn.mapVertex(x + 5, y + -1318, "0 0 0 -250 125 -250"); //door @@ -2267,55 +2283,57 @@ const level = { doCustomTopLayer.push( () => { - toggle.query(); - if (toggle.isOn && !toggle.isAddedElements) { //this code runs once after the toggle is triggered - toggle.isAddedElements = true //only do this once - addMapToLevelInProgress = (who) => { //adds new map elements to the level while the level is already running //don't forget to run simulation.draw.setPaths() after you all the the elements so they show up visually - who.collisionFilter.category = cat.map; - who.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet; - Matter.Body.setStatic(who, true); //make static - Composite.add(engine.world, who); //add to world + button.draw(); + if (button.isUp) { + button.query(); + if (!button.isUp) { + addMapToLevelInProgress = (who) => { //adds new map elements to the level while the level is already running //don't forget to run simulation.draw.setPaths() after you all the the elements so they show up visually + who.collisionFilter.category = cat.map; + who.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet; + Matter.Body.setStatic(who, true); //make static + Composite.add(engine.world, who); //add to world + } + //right side hexagons + let r = 300 + let hexagon = `${r} 0 ${r * Math.cos(5.236)} ${r * Math.sin(5.236)} ${r * Math.cos(4.189)} ${r * Math.sin(4.189)} ${-r} 0 ${r * Math.cos(2.0944)} ${r * Math.sin(2.0944)} ${r * Math.cos(1.0472)} ${r * Math.sin(1.0472)} ` + spawn.mapVertex(x + 1640, y + -365, hexagon); + // r = 275 + // let hexagonHalf = `${r} 0 ${r*Math.cos(5.236)} ${r*Math.sin(5.236)} ${r*Math.cos(4.189)} ${r*Math.sin(4.189)} ${-r} 0 ` + // spawn.mapVertex(x + 2300, y + -75, hexagonHalf); + r = 150 + const hexagon150 = `${r} 0 ${r * Math.cos(5.236)} ${r * Math.sin(5.236)} ${r * Math.cos(4.189)} ${r * Math.sin(4.189)} ${-r} 0 ${r * Math.cos(2.0944)} ${r * Math.sin(2.0944)} ${r * Math.cos(1.0472)} ${r * Math.sin(1.0472)} ` + // spawn.mapVertex(x + 1750, y + -550, hexagon150); + spawn.mapVertex(x + 1750, y + -1100, hexagon150); + spawn.mapVertex(x + 1750, y + -1650, hexagon150); + spawn.mapVertex(x + 1750, y + -2200, hexagon150); + + //left side + r = 350 + let hexagonHalf = `${r} 0 ${r * Math.cos(5.236)} ${r * Math.sin(5.236)} ${r * Math.cos(4.189)} ${r * Math.sin(4.189)} ${-r} 0 ` + spawn.mapVertex(x + 425, y + -90, hexagonHalf); + + spawn.mapVertex(x + 850, y + -500, hexagon150); + spawn.mapVertex(x + 550, y + -850, hexagon150); + spawn.mapVertex(x + 250, y + -1200, hexagon150); + spawn.mapVertex(x + 250, y + -1700, hexagon150); + spawn.mapVertex(x + 725, y + -1950, hexagon150); + spawn.mapVertex(x + 1200, y + -2200, hexagon150); + const numberOfMapElementsAdded = 11 + for (let i = 0; i < numberOfMapElementsAdded; i++) addMapToLevelInProgress(map[map.length - 1 - i]) + + spawn.randomMob(x + 1075, y + -1500, mobSpawnChance); + spawn.randomMob(x + 325, y + -550, mobSpawnChance); + spawn.randomMob(x + 800, y + -925, mobSpawnChance); + spawn.randomMob(x + 1400, y + -1250, mobSpawnChance); + spawn.randomMob(x + 1350, y + -1725, mobSpawnChance); + spawn.randomMob(x + 575, y + -1375, mobSpawnChance); + spawn.randomMob(x + 225, y + -2275, mobSpawnChance); + spawn.randomMob(x + 875, y + -2450, mobSpawnChance); + spawn.randomMob(x + 1550, y + -2525, mobSpawnChance); + spawn.randomLevelBoss(x + 1075, y + -1500); + spawn.secondaryBossChance(x + 1200, y + -1000) + simulation.draw.setPaths() //update map graphics } - //right side hexagons - let r = 300 - let hexagon = `${r} 0 ${r * Math.cos(5.236)} ${r * Math.sin(5.236)} ${r * Math.cos(4.189)} ${r * Math.sin(4.189)} ${-r} 0 ${r * Math.cos(2.0944)} ${r * Math.sin(2.0944)} ${r * Math.cos(1.0472)} ${r * Math.sin(1.0472)} ` - spawn.mapVertex(x + 1640, y + -365, hexagon); - // r = 275 - // let hexagonHalf = `${r} 0 ${r*Math.cos(5.236)} ${r*Math.sin(5.236)} ${r*Math.cos(4.189)} ${r*Math.sin(4.189)} ${-r} 0 ` - // spawn.mapVertex(x + 2300, y + -75, hexagonHalf); - r = 150 - const hexagon150 = `${r} 0 ${r * Math.cos(5.236)} ${r * Math.sin(5.236)} ${r * Math.cos(4.189)} ${r * Math.sin(4.189)} ${-r} 0 ${r * Math.cos(2.0944)} ${r * Math.sin(2.0944)} ${r * Math.cos(1.0472)} ${r * Math.sin(1.0472)} ` - // spawn.mapVertex(x + 1750, y + -550, hexagon150); - spawn.mapVertex(x + 1750, y + -1100, hexagon150); - spawn.mapVertex(x + 1750, y + -1650, hexagon150); - spawn.mapVertex(x + 1750, y + -2200, hexagon150); - - //left side - r = 350 - let hexagonHalf = `${r} 0 ${r * Math.cos(5.236)} ${r * Math.sin(5.236)} ${r * Math.cos(4.189)} ${r * Math.sin(4.189)} ${-r} 0 ` - spawn.mapVertex(x + 425, y + -90, hexagonHalf); - - spawn.mapVertex(x + 850, y + -500, hexagon150); - spawn.mapVertex(x + 550, y + -850, hexagon150); - spawn.mapVertex(x + 250, y + -1200, hexagon150); - spawn.mapVertex(x + 250, y + -1700, hexagon150); - spawn.mapVertex(x + 725, y + -1950, hexagon150); - spawn.mapVertex(x + 1200, y + -2200, hexagon150); - const numberOfMapElementsAdded = 11 - for (let i = 0; i < numberOfMapElementsAdded; i++) addMapToLevelInProgress(map[map.length - 1 - i]) - - spawn.randomMob(x + 1075, y + -1500, mobSpawnChance); - spawn.randomMob(x + 325, y + -550, mobSpawnChance); - spawn.randomMob(x + 800, y + -925, mobSpawnChance); - spawn.randomMob(x + 1400, y + -1250, mobSpawnChance); - spawn.randomMob(x + 1350, y + -1725, mobSpawnChance); - spawn.randomMob(x + 575, y + -1375, mobSpawnChance); - spawn.randomMob(x + 225, y + -2275, mobSpawnChance); - spawn.randomMob(x + 875, y + -2450, mobSpawnChance); - spawn.randomMob(x + 1550, y + -2525, mobSpawnChance); - spawn.randomLevelBoss(x + 1075, y + -1500); - spawn.secondaryBossChance(x + 1200, y + -1000) - simulation.draw.setPaths() //update map graphics } } ) @@ -2654,7 +2672,7 @@ const level = { // spawn.shieldingBoss(1700, -500) // for (let i = 0; i < 10; ++i) spawn.bodyRect(1600 + 5, -500, 30, 40); - for (let i = 0; i < 1; i++) spawn.stabber(1900, -500) + for (let i = 0; i < 4; i++) spawn.starter(1900, -500) // spawn.pulsar(1900, -500) // spawn.shield(mob[mob.length - 1], 1900, -500, 1); // mob[mob.length - 1].isShielded = true diff --git a/js/player.js b/js/player.js index bb2eed4..bf514e0 100644 --- a/js/player.js +++ b/js/player.js @@ -522,7 +522,7 @@ const m = { if (tech.isAddBlockMass && m.isHolding) dmg *= 0.15 if (tech.isSpeedHarm) dmg *= 1 - Math.min(player.speed * 0.0165, 0.66) if (tech.isSlowFPS) dmg *= 0.8 - if (tech.isHarmReduce && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.34 + if (tech.isHarmReduce && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.25 if (tech.isNeutronium && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.1 if (tech.isBotArmor) dmg *= 0.94 ** b.totalBots() if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.33; @@ -1501,8 +1501,9 @@ const m = { }, fieldUpgrades: [{ name: "field emitter", - description: "regen 6 energy per second
use it to deflect mobs and throw blocks
energy regen disabled if immune to harm", - // description: "use energy to deflect mobs,
grab power ups, and throw blocks
regen 6 energy/s, when not immune to harm", + //
energy regen disabled if immune to harm + description: "use energy to deflect mobs
store up to 100 energy
generate 6 energy/second", + // description: "use energy to deflect mobs,
grab power ups, and throw blocks
generate 6 energy/s, when not immune to harm", effect: () => { m.hold = function() { if (m.isHolding) { @@ -1527,7 +1528,8 @@ const m = { }, { name: "standing wave", - description: "3 oscillating shields are permanently active
deflecting protects you in every direction
increase your max energy by 60", //drains energy //deflecting has 50% less recoil + //deflecting protects you in every direction + description: "3 oscillating shields are permanently active
increase your max energy by 60
generate 6 energy/second", //drains energy //deflecting has 50% less recoil drainCD: 0, effect: () => { m.fieldBlockCD = 0; @@ -1540,7 +1542,7 @@ const m = { const fieldRange2 = (0.68 + 0.37 * Math.sin(m.cycle / 37)) * m.fieldRange * m.harmonicRadius const fieldRange3 = (0.7 + 0.35 * Math.sin(m.cycle / 47)) * m.fieldRange * m.harmonicRadius const netfieldRange = Math.max(fieldRange1, fieldRange2, fieldRange3) - ctx.fillStyle = "rgba(110,170,200," + Math.min(0.65, (0.04 + m.energy * (0.11 + 0.13 * Math.random()))) + ")"; + ctx.fillStyle = "rgba(110,170,200," + Math.min(0.6, (0.04 + m.energy * (0.1 + 0.11 * Math.random()))) + ")"; ctx.beginPath(); ctx.arc(m.pos.x, m.pos.y, fieldRange1, 0, 2 * Math.PI); ctx.fill(); @@ -1571,7 +1573,7 @@ const m = { const radius = m.fieldRange * m.harmonicRadius ctx.lineWidth = 1; ctx.strokeStyle = "rgba(110,170,200,0.8)" - ctx.fillStyle = "rgba(110,170,200," + Math.min(0.65, m.energy * (0.13 + 0.1 * Math.random()) * (3 / tech.harmonics)) + ")"; + ctx.fillStyle = "rgba(110,170,200," + Math.min(0.6, m.energy * (0.11 + 0.1 * Math.random()) * (3 / tech.harmonics)) + ")"; // ctx.fillStyle = "rgba(110,170,200," + Math.min(0.7, m.energy * (0.22 - 0.01 * tech.harmonics) * (0.5 + 0.5 * Math.random())) + ")"; for (let i = 0; i < tech.harmonics; i++) { ctx.beginPath(); @@ -1628,7 +1630,8 @@ const m = { }, { name: "perfect diamagnetism", - description: "attract power ups from far away
deflecting does not drain energy
maintains functionality while inactive", + description: "deflecting does not drain energy
maintains functionality while inactive
generate 6 energy/second", + //
attract power ups from far away // description: "attract power ups from far away
deflecting doesn't drain energy
thrown blocks have", // description: "gain energy when blocking
no recoil when blocking", effect: () => { @@ -1810,7 +1813,8 @@ const m = { }, { name: "negative mass", - description: "use energy to nullify  gravity
reduce harm by 55%
hold blocks as if they have a lower mass", + //
hold blocks as if they have a lower mass + description: "use energy to nullify  gravity
reduce harm by 55%
generate 6 energy/second", fieldDrawRadius: 0, effect: () => { m.fieldFire = true; @@ -1960,7 +1964,8 @@ const m = { }, { name: "molecular assembler", - description: "excess energy used to build drones
use energy to deflect mobs
double your default energy regeneration", + description: "excess energy used to build drones
use energy to deflect mobs
generate 12 energy/second", + //double your default energy regeneration effect: () => { // m.fieldMeterColor = "#0c5" // m.eyeFillColor = m.fieldMeterColor @@ -2095,7 +2100,7 @@ const m = { // }, { name: "plasma torch", - description: "use energy to emit short range plasma
damages and pushes mobs away", + description: "use energy to emit short range plasma
damages and pushes mobs away
generate 6 energy/second", set() { b.isExtruderOn = false if (m.plasmaBall) { @@ -2472,7 +2477,7 @@ const m = { { name: "time dilation", // description: "use energy to stop time
while time is stopped you can move and fire
and collisions do 50% less harm", - description: "use energy to stop time
move and fire while time is stopped
but, collisions still do harm", + description: "use energy to stop time
for everything except you
generate 12 energy/second", set() { if (tech.isRewindField) { this.rewindCount = 0 @@ -2488,7 +2493,7 @@ const m = { if (!m.holdingTarget) { this.rewindCount += 6; - const DRAIN = 0.001 + const DRAIN = 0.003 let history = m.history[(m.cycle - this.rewindCount) % 600] if (this.rewindCount > 599 || m.energy < DRAIN) { this.rewindCount = 0; @@ -2538,34 +2543,10 @@ const m = { bullet[bullet.length - 1].endCycle = simulation.cycle + 480 + Math.floor(120 * Math.random()) //8-9 seconds } } - if (tech.isRewindGrenade) { b.grenade(m.pos, this.rewindCount) //Math.PI / 2 const who = bullet[bullet.length - 1] - // Matter.Body.setVelocity(who, { - // x: 0, - // y: 0 - // }); who.endCycle = simulation.cycle + 60 - // if (tech.isVacuumBomb) { - // Matter.Body.setVelocity(who, { - // x: who.velocity.x * 0.5, - // y: who.velocity.y * 0.5 - // }); - // } else if (tech.isRPG) { - // who.endCycle = simulation.cycle + 10 - // } else if (tech.isNeutronBomb) { - // Matter.Body.setVelocity(who, { - // x: who.velocity.x * 0.3, - // y: who.velocity.y * 0.3 - // }); - // } else { - // Matter.Body.setVelocity(who, { - // x: who.velocity.x * 0.5, - // y: who.velocity.y * 0.5 - // }); - // who.endCycle = simulation.cycle + 30 - // } } @@ -2579,74 +2560,13 @@ const m = { m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists) this.rewindCount = 0; } - m.drawFieldMeter() - - - - - // // console.log(this.rewindCount) - // if (input.field && m.fieldCDcycle < m.cycle) { //button has been held down - // if (m.isHolding) { - // m.drawHold(m.holdingTarget); - // m.holding(); - // m.throwBlock(); - // } else { - // m.grabPowerUp(); - // m.lookForPickUp(); - // if (!m.holdingTarget) { - // this.rewindCount += 8; - // const DRAIN = 0.001 - // let history = m.history[(m.cycle - this.rewindCount) % 600] - // if (this.rewindCount > 599 || m.energy < DRAIN) { - // this.rewindCount = 0; - // m.resetHistory(); - // } else { - // // m.grabPowerUp(); //a second grab power up to make the power ups easier to grab, and they more fast which matches the time theme - // m.energy -= DRAIN - // if (m.immuneCycle < m.cycle + 30) m.immuneCycle = m.cycle + 30; //player is immune to damage for 30 cycles - // Matter.Body.setPosition(player, history.position); - // Matter.Body.setVelocity(player, { x: history.velocity.x, y: history.velocity.y }); - // if (m.health < history.health) { - // m.health = history.health - // m.displayHealth(); - // } - // m.yOff = history.yOff - // if (m.yOff < 48) { - // m.doCrouch() - // } else { - // m.undoCrouch() - // } - // //grab power ups - // for (let i = 0, len = powerUp.length; i < len; ++i) { - // if ( - // Vector.magnitudeSquared(Vector.sub(m.pos, powerUp[i].position)) < 100000 && - // !simulation.isChoosing && - // (powerUp[i].name !== "heal" || m.health !== m.maxHealth || tech.isOverHeal) - // ) { - // powerUps.onPickUp(powerUp[i]); - // powerUp[i].effect(); - // Matter.Composite.remove(engine.world, powerUp[i]); - // powerUp.splice(i, 1); - // break; //because the array order is messed up after splice - // } - // } - // } - // } - // } - // } else { //button is held the first time - // this.rewindCount = 0; - // if (m.holdingTarget && m.fieldCDcycle < m.cycle) { - // m.pickUp(); - // } else { - // m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists) - // } - // } - + if (m.energy < m.maxEnergy) m.regenEnergy(); //extra energy regen + m.drawFieldMeter() // this calls m.regenEnergy(); also } } else { m.fieldFire = true; m.isBodiesAsleep = false; - m.drain = 0.0003 + m.drain = 0.003 m.hold = function() { if (m.isHolding) { m.wakeCheck(); @@ -2656,8 +2576,6 @@ const m = { } else if (input.field && m.fieldCDcycle < m.cycle) { m.grabPowerUp(); m.lookForPickUp(); - - m.drain += 0.000002 //also increases inside tech.isTimeSkip if (m.energy > m.drain) { m.energy -= m.drain; if (m.energy < m.drain) { @@ -2665,6 +2583,7 @@ const m = { m.energy = 0; m.wakeCheck(); } + m.immuneCycle = m.cycle + 10; //immune to harm while time is stopped, this also disables regen //draw field everywhere ctx.globalCompositeOperation = "saturation" ctx.fillStyle = "#ccc"; @@ -2687,26 +2606,26 @@ const m = { sleep(bullet); simulation.cycle--; //pause all functions that depend on game cycle increasing - if (tech.isTimeSkip) { - m.immuneCycle = 0; - m.drain += 0.0000025 - m.regenEnergy(); //immunity disables normal regen, so turn off immunity for just this function - m.immuneCycle = m.cycle + 10; - simulation.isTimeSkipping = true; - m.cycle++; - simulation.gravity(); - if (tech.isFireMoveLock && input.fire) { - player.force.x = 0 - player.force.y = 0 - } - Engine.update(engine, simulation.delta); - m.move(); - simulation.checks(); - m.walk_cycle += m.flipLegs * m.Vx; - b.fire(); - b.bulletDo(); - simulation.isTimeSkipping = false; - } + // if (tech.isTimeSkip) { + // m.immuneCycle = 0; + // m.drain += 0.0000025 + // m.regenEnergy(); //immunity disables normal regen, so turn off immunity for just this function + // m.immuneCycle = m.cycle + 10; + // simulation.isTimeSkipping = true; + // m.cycle++; + // simulation.gravity(); + // if (tech.isFireMoveLock && input.fire) { + // player.force.x = 0 + // player.force.y = 0 + // } + // Engine.update(engine, simulation.delta); + // m.move(); + // simulation.checks(); + // m.walk_cycle += m.flipLegs * m.Vx; + // b.fire(); + // b.bulletDo(); + // simulation.isTimeSkipping = false; + // } } else { //holding, but field button is released m.wakeCheck(); } @@ -2714,23 +2633,96 @@ const m = { m.wakeCheck(); m.pickUp(); } else { - if (m.drain > 0.0005) m.drain -= 0.000005 //return drain to base level m.wakeCheck(); m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists) } - // console.log(m.drain.toFixed(6)) + if (m.energy < m.maxEnergy) m.regenEnergy(); //extra energy regen m.drawFieldMeter() } } + // } else { + // m.fieldFire = true; + // m.isBodiesAsleep = false; + // m.isTimeStopped = false; + // m.drain = 0.005 + // let isFieldInputDown = false; + // m.hold = function() { + // if (m.isHolding) { + // m.drawHold(m.holdingTarget); + // m.holding(); + // m.throwBlock(); + // isFieldInputDown = false + // } else if (input.field && m.fieldCDcycle < m.cycle) { //not hold but field button is pressed + // if (!m.holdingTarget) isFieldInputDown = true; + // m.grabPowerUp(); + // m.lookForPickUp(); + // // if (m.energy > 0.05) { //deflecting + // // m.drawField(); + // // m.pushMobsFacing(); + // // } + // } else if (m.holdingTarget && m.fieldCDcycle < m.cycle) { //holding, but field button is released + // m.pickUp(); + // } else { + // m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists) + // } + + // if (isFieldInputDown && !input.field && !m.holdingTarget && !m.isHolding) { + // isFieldInputDown = false; + // m.isTimeStopped = true; + // } + // m.drawFieldMeter() + // if (m.energy < m.maxEnergy) { //extra energy regen + // m.regenEnergy(); + // m.regenEnergy(); + // } + // if (m.isTimeStopped) { + // if (m.energy > m.drain) { + // // if (player.speed > 0.01 || input.fire) + // m.energy -= m.drain; + // m.immuneCycle = m.cycle + 10; //immune to harm while time is stopped, this also disables regen + // simulation.cycle--; //pause all functions that depend on game cycle increasing + // m.isBodiesAsleep = true; + // ctx.globalCompositeOperation = "saturation" //draw field everywhere + // ctx.fillStyle = "#ccc"; + // ctx.fillRect(-100000, -100000, 200000, 200000) + // ctx.globalCompositeOperation = "source-over" + + // function sleep(who) { + // for (let i = 0, len = who.length; i < len; ++i) { + // if (!who[i].isSleeping) { + // who[i].storeVelocity = who[i].velocity + // who[i].storeAngularVelocity = who[i].angularVelocity + // } + // Matter.Sleeping.set(who[i], true) + // } + // } + // sleep(mob); + // sleep(body); + // sleep(bullet); + // } else { //restart time + // m.fieldCDcycle = m.cycle + 60; + // m.energy = 0; + // m.isTimeStopped = false + // m.wakeCheck(); + // } + // if (simulation.isChoosing) { + // // m.fieldCDcycle = m.cycle + 60; + // m.isTimeStopped = false + // m.wakeCheck(); + // } + // } + + // } + // } }, effect() { - // m.fieldMeterColor = "#000" this.set(); } }, { name: "metamaterial cloaking", //"weak photonic coupling" "electromagnetically induced transparency" "optical non-coupling" "slow light field" "electro-optic transparency" - description: "when not firing activate a cloaking effect
+333% damage if a mob hasn't recently died
collisions do 50% less harm when cloaked", + //
collisions do 50% less harm when cloaked + description: "when not firing activate cloaking
+333% damage if no mob has died in 4 seconds
generate 6 energy/second", effect: () => { m.fieldFire = true; m.fieldMeterColor = "#333"; @@ -3028,7 +3020,9 @@ const m = { // }, { name: "pilot wave", - description: "use energy to push blocks with your mouse
blocks can't collide with intangible mobs
field radius decreases out of line of sight", + //
blocks can't collide with intangible mobs + //field radius decreases out of line of sight + description: "use energy to guide blocks
unlock tech from other fields
generate 6 energy/second", effect: () => { m.fieldPhase = 0; m.fieldPosition = { @@ -3223,7 +3217,8 @@ const m = { }, { name: "wormhole", - description: "use energy to tunnel through a wormhole
wormholes attract blocks and power ups
5% chance to duplicate spawned power ups", //
bullets may also traverse wormholes + //wormholes attract blocks and power ups
+ description: "use energy to tunnel through a wormhole
5% chance to duplicate spawned power ups
generate 6 energy/second", //
bullets may also traverse wormholes drain: 0, effect: function() { m.duplicateChance = 0.05 @@ -3641,10 +3636,6 @@ const m = { // } else { // m.hole.isReady = true; // } - - - - m.drawFieldMeter() } }, diff --git a/js/powerup.js b/js/powerup.js index ebe65bd..5e602cc 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -280,7 +280,7 @@ const powerUps = { if (!simulation.paused) { if (tech.isNoDraftPause) { - powerUps.spawn(m.pos.x, m.pos.y, "ammo"); + // powerUps.spawn(m.pos.x, m.pos.y, "ammo"); document.getElementById("choose-grid").style.opacity = "0.7" } else { simulation.paused = true; diff --git a/js/spawn.js b/js/spawn.js index 3fced3f..9688754 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -3929,7 +3929,7 @@ const spawn = { me.lockedOn = null; me.torqueMagnitude = 0.00024 * me.inertia * (Math.random() > 0.5 ? -1 : 1); - me.delay = 120 * simulation.CDScale; + me.delay = 60 + 60 * simulation.CDScale; me.cd = 0; me.swordRadius = 0; me.swordVertex = 1 diff --git a/js/tech.js b/js/tech.js index f9ad2c5..da390e3 100644 --- a/js/tech.js +++ b/js/tech.js @@ -221,6 +221,7 @@ const tech = { }, damageFromTech() { let dmg = 1 //m.fieldDamage + if (tech.isNoDraftPause) dmg *= 1.5 if (tech.isTechDebt) dmg *= Math.max(41 / (tech.totalCount + 21), 4 - 0.15 * tech.totalCount) if (tech.isAxion && tech.isHarmMACHO) dmg *= 1 + 0.75 * (1 - m.harmReduction()) if (tech.OccamDamage) dmg *= tech.OccamDamage @@ -593,25 +594,6 @@ const tech = { tech.isAmmoFromHealth = false; } }, - { - name: "eternalism", - description: `choosing a field, tech, or gun spawns ${powerUps.orb.ammo()}
time doesn't pause while choosing`, //${powerUps.orb.heal()} or - // description: "increase damage by 50%, but time continues
while choosing a field, tech, or gun", - maxCount: 1, - count: 0, - frequency: 1, - frequencyDefault: 1, - allowed() { - return true - }, - requires: "", - effect() { - tech.isNoDraftPause = true - }, - remove() { - tech.isNoDraftPause = false - } - }, { name: "exciton", description: `increase damage by 88%, but
${powerUps.orb.ammo()} will no longer spawn`, @@ -3154,9 +3136,9 @@ const tech = { frequency: 1, frequencyDefault: 1, allowed() { - return !tech.isSuperDeterminism + return !tech.isSuperDeterminism && !tech.isNoDraftPause }, - requires: "not superdeterminism", + requires: "not superdeterminism, eternalism", effect() { tech.isPauseSwitchField = true; for (let i = 0, len = tech.tech.length; i < len; i++) { @@ -3195,8 +3177,10 @@ const tech = { count: 0, frequency: 1, frequencyDefault: 1, - allowed() { return true }, - requires: "", + allowed() { + return !tech.isSuperDeterminism && !tech.isNoDraftPause + }, + requires: "not superdeterminism, eternalism", effect() { tech.isPauseEjectTech = true; }, @@ -3204,6 +3188,25 @@ const tech = { tech.isPauseEjectTech = false; } }, + { + name: "eternalism", + // description: `increase damage by 60%, but time doesn't pause
while choosing a choosing a field, tech, or gun`, //${powerUps.orb.heal()} or + description: "increase damage by 50%, but
time can't be paused (time dilation still works)", + maxCount: 1, + count: 0, + frequency: 1, + frequencyDefault: 1, + allowed() { + return !tech.isPauseSwitchField && !tech.isPauseEjectTech && !tech.isWormHolePause + }, + requires: "not unified field theory, paradigm shift, invariant", + effect() { + tech.isNoDraftPause = true + }, + remove() { + tech.isNoDraftPause = false + } + }, { name: "technical debt", // overengineering // description: `increase damage by 300% minus 10% for tech you have learned(${4 - 0.1 * tech.totalCount})`, @@ -3505,7 +3508,7 @@ const tech = { allowed() { return tech.duplicationChance() > 0.6 }, - requires: "duplication chance above 70%", + requires: "NOT EXPERIMENT MODE, duplication chance above 60%", effect() { tech.is111Duplicate = true; tech.maxDuplicationEvent() @@ -4289,9 +4292,9 @@ const tech = { frequency: 1, frequencyDefault: 1, allowed() { - return (tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIceShot && !tech.isRivets && !tech.isFoamShot && !tech.isSporeWorm && !tech.isNeedles) || tech.haveGunCheck("super balls") || (tech.isRivets && !tech.isNailCrit) || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && !(tech.isDroneTeleport || tech.isDroneRadioactive || tech.isSporeField || tech.isMissileField || tech.isIceField)) || (tech.haveGunCheck("drones") && !tech.isForeverDrones && !tech.isDroneRadioactive && !tech.isDroneTeleport) + return (tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIceShot && !tech.isRivets && !tech.isFoamShot && !tech.isSporeWorm && !tech.isNeedles) || (tech.haveGunCheck("super balls") && !tech.isFoamBall) || (tech.isRivets && !tech.isNailCrit) || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && !(tech.isDroneTeleport || tech.isDroneRadioactive || tech.isSporeField || tech.isMissileField || tech.isIceField)) || (tech.haveGunCheck("drones") && !tech.isForeverDrones && !tech.isDroneRadioactive && !tech.isDroneTeleport) }, - requires: "shotgun, super balls, rivets, drones, not irradiated drones or burst drones", + requires: "shotgun, super balls, rivets, drones, not irradiated drones, burst drones, polyurethane", effect() { tech.isIncendiary = true }, @@ -4300,9 +4303,8 @@ const tech = { } }, { - name: "supertemporal", - link: `supertemporal`, - description: "fire super ball from the same point in space
but separated by 0.1 seconds in time", + name: "autocannon", + description: "fire +1 extra super ball
balls are quickly released in same direction", isGunTech: true, maxCount: 1, count: 0, @@ -4373,6 +4375,26 @@ const tech = { } } }, + { + name: "polyurethane foam", + description: "super balls colliding with mobs catalyzes
a reaction that yields foam bubbles", + isGunTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return tech.haveGunCheck("super balls") + }, + requires: "super balls", + effect() { + tech.isFoamBall = true; + }, + remove() { + tech.isFoamBall = false; + } + }, + // { name: "phase velocity", description: "matter wave propagates faster through solids
increase matter wave damage by 15%", @@ -5218,7 +5240,7 @@ const tech = { frequency: 2, frequencyDefault: 2, allowed() { - return m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || tech.haveGunCheck("spores") || tech.haveGunCheck("drones") || tech.haveGunCheck("missiles") || tech.haveGunCheck("foam") || tech.haveGunCheck("matter wave") || tech.isNeutronBomb || tech.isIceField || tech.isIceShot || tech.relayIce || tech.isNeedleIce || tech.blockingIce > 1 || tech.isSporeWorm || tech.foamBotCount > 1 + return m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || tech.haveGunCheck("spores") || tech.haveGunCheck("drones") || tech.haveGunCheck("missiles") || tech.haveGunCheck("foam") || tech.haveGunCheck("matter wave") || tech.isNeutronBomb || tech.isIceField || tech.isIceShot || tech.relayIce || tech.isNeedleIce || tech.blockingIce > 1 || tech.isSporeWorm || tech.foamBotCount > 1 || tech.isFoamBall }, requires: "drones, spores, missiles, foam, matter wave, neutron bomb, ice IX", effect() { @@ -5489,7 +5511,7 @@ const tech = { frequency: 2, frequencyDefault: 2, allowed() { - return !tech.isBulletTeleport && (tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot) + return !tech.isBulletTeleport && (tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot || tech.isFoamBall) }, requires: "foam, not uncertainty", effect() { @@ -5508,7 +5530,7 @@ const tech = { frequency: 2, frequencyDefault: 2, allowed() { - return (!tech.isFoamAttract && (tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot)) || (tech.haveGunCheck("matter wave") && !tech.isLongitudinal) + return (!tech.isFoamAttract && (tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot || tech.isFoamBall)) || (tech.haveGunCheck("matter wave") && !tech.isLongitudinal) }, requires: "foam, not electrostatic induction, matter wave, not phonon", effect() { @@ -5527,7 +5549,7 @@ const tech = { frequency: 2, frequencyDefault: 2, allowed() { - return tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot || tech.isSporeWorm + return tech.haveGunCheck("foam") || tech.isFoamBall || tech.foamBotCount > 1 || tech.isFoamShot || tech.isSporeWorm }, requires: "foam, worms", effect() { @@ -5546,7 +5568,7 @@ const tech = { frequency: 2, frequencyDefault: 2, allowed() { - return tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot + return tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot || tech.isFoamBall }, requires: "foam", effect() { @@ -6213,9 +6235,9 @@ const tech = { frequency: 3, frequencyDefault: 3, allowed() { - return (m.fieldUpgrades[m.fieldMode].name === "standing wave" || m.fieldUpgrades[m.fieldMode].name === "pilot wave") && (build.isExperimentSelection || powerUps.research.count > 1) + return (m.fieldUpgrades[m.fieldMode].name === "standing wave" || m.fieldUpgrades[m.fieldMode].name === "pilot wave" || m.fieldUpgrades[m.fieldMode].name === "time dilation") && (build.isExperimentSelection || powerUps.research.count > 1) }, - requires: "standing wave or pilot wave", + requires: "standing wave, pilot wave, time dilation", effect() { tech.harmonicEnergy = 1 m.setMaxEnergy() @@ -6747,7 +6769,7 @@ const tech = { // }, { name: "degenerate matter", - description: "reduce harm by 66% while your field is active", + description: "reduce harm by 75% while your field is active", isFieldTech: true, maxCount: 1, count: 0, @@ -6949,25 +6971,25 @@ const tech = { if (this.count) m.fieldUpgrades[m.fieldMode].set() } }, - { - name: "timelike", - description: "time dilation doubles your relative time rate
and makes you immune to harm", - isFieldTech: true, - maxCount: 1, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return m.fieldUpgrades[m.fieldMode].name === "time dilation" && !m.isShipMode && !tech.isRewindField - }, - requires: "time dilation, not retrocausality", - effect() { - tech.isTimeSkip = true; - }, - remove() { - tech.isTimeSkip = false; - } - }, + // { + // name: "timelike", + // description: "time dilation doubles your relative time rate
and makes you immune to harm", + // isFieldTech: true, + // maxCount: 1, + // count: 0, + // frequency: 2, + // frequencyDefault: 2, + // allowed() { + // return m.fieldUpgrades[m.fieldMode].name === "time dilation" && !m.isShipMode && !tech.isRewindField + // }, + // requires: "time dilation, not retrocausality", + // effect() { + // tech.isTimeSkip = true; + // }, + // remove() { + // tech.isTimeSkip = false; + // } + // }, { name: "Lorentz transformation", description: `use ${powerUps.orb.research(3)}to increase your time rate
move, jump, and shoot 50% faster`, @@ -6997,7 +7019,7 @@ const tech = { }, { name: "time crystals", - description: "quadruple your default energy regeneration", + description: "quadruple your base energy regeneration", isFieldTech: true, maxCount: 1, count: 0, @@ -7241,7 +7263,7 @@ const tech = { effect: () => { tech.wimpCount++ spawn.WIMP() - for (let j = 0, len = 1 + 5 * Math.random(); j < len; j++) powerUps.spawn(level.exit.x + 100 * (Math.random() - 0.5), level.exit.y - 100 + 100 * (Math.random() - 0.5), "research", false) + for (let j = 0, len = 5; j < len; j++) powerUps.spawn(level.exit.x + 100 * (Math.random() - 0.5), level.exit.y - 100 + 100 * (Math.random() - 0.5), "research", false) }, remove() { tech.wimpCount = 0 @@ -7368,9 +7390,9 @@ const tech = { frequency: 2, frequencyDefault: 2, allowed() { - return m.fieldUpgrades[m.fieldMode].name === "wormhole" + return m.fieldUpgrades[m.fieldMode].name === "wormhole" && !tech.isNoDraftPause }, - requires: "wormhole", + requires: "wormhole, not eternalism", effect() { tech.isWormHolePause = true }, @@ -7822,7 +7844,7 @@ const tech = { remove() {} }, { - name: "opacity", + name: " ", description: "", maxCount: 1, count: 0, @@ -9895,4 +9917,6 @@ const tech = { coyoteTime: null, missileFireCD: null, isBotField: null, + isFoamBall: null, + isNoDraftPause: null } \ No newline at end of file diff --git a/todo.txt b/todo.txt index 5a7bc11..754db49 100644 --- a/todo.txt +++ b/todo.txt @@ -1,34 +1,45 @@ ******************************************************** NEXT PATCH ************************************************** -tech: eternalism - tech,gun,field gives an ammo but, time doesn't pause while choosing - I might change the ammo to something else, not sure, maybe just damage -JUNK tech: panpsychism - awaken blocks, blocks can drop power ups +time dilation field rework + 2x energy regen, but pausing time now uses much more energy + you are immune to harm while time is paused + but this stops energy regen + tech timelike is removed -cache gives 14->16x ammo -1st ionization energy gives 8->10% max energy on heal +eternalism gives 50% damage instead of ammo + also disables the pause button, and other pause effects -powerUpBossBaby immunity phase is a bit shorter +tech: polyurethane foam - super balls turn into foam after hitting a mob +supertemporal renamed autocannon + now gives +1 ball, and has a shorter delay between balls + +harpoon and grapple no longer lose ammo when you run out of energy + they just trigger a 2 second fire CD +slashBoss doesn't slash as often at higher difficulty levels +field descriptions rewritten bug fixes ******************************************************** TODO ******************************************************** -tech: - don't pause time during draft +tech: eternalism - don't pause time during draft bugs requirements change after draft is generated - disable effects that change requirements - when simulation.isChoosing you can't: eject tech, - check for requirements onclick and give random tech if not met? - -make lasers on labs flash on and off - make switch a button that stays down + check for requirements onclick and give random tech if not met? +tech expansion: should also make other fields do things + perfect diamagnetism moves forward when you hold down the shield + maybe only with crouch? + time dilation drains 1/2 as much energy when paused + grow plasma torch as you hold it down + negative mass effects much more space + needs more benefit + reduces the cloaking vision effect? + needs more benefit nonrefundable tech don't display, this is confusing maybe they can show up but greyed out or something -make your power up list scrollable while in power up selection pause menu - Tech could probably be indexed, something like running tech.index = new Map(); for (let i = 0; i < tech.tech.length; i++) { @@ -45,10 +56,6 @@ if (queriedTech) { guntech fire a bullet that fires nail fragments after 1s in the same direction as the original bullet like overwatch roadhog -make mol fab field do something cool when it blocks - generate energy? - reset lifespan of: drone,spore,worm, iceIX - bring back: the old phase decoherence field make cloak only active on input.field down