diff --git a/.DS_Store b/.DS_Store index d52b7c3..6e7e767 100644 Binary files a/.DS_Store and b/.DS_Store differ 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