From 271791703f14af681e6c19a322698e202601bfb4 Mon Sep 17 00:00:00 2001 From: landgreen Date: Sun, 25 Jul 2021 05:53:27 -0700 Subject: [PATCH] worm-shot, ice-shot, needle-shot, foam-shot shotgun techs: (I haven't done enough testing so let me know if these different shotgun modes aren't balanced) worm shot ice-IX shot foam shot needle shot foam lasts much longer on shielded mobs overall foam damage is reduced about 8% attacks that drain energy don't work when the player is immune to harm slime, radiation fields, black holes energy regen that consumes something (ammo, blocks, power ups) now works when immune to harm but passive energy regen is still stopped while you are immune to harm pilot wave field can no longer hit intangible mobs with blocks it was too annoying that you can't use blocks to move around so I reverted it back --- .DS_Store | Bin 6148 -> 6148 bytes js/bullet.js | 256 ++++++++++++++++++++++++--------------------- js/level.js | 35 ++++--- js/mob.js | 6 +- js/player.js | 8 +- js/powerup.js | 2 +- js/simulation.js | 2 +- js/spawn.js | 47 ++++++--- js/tech.js | 266 ++++++++++++++++++++++++++++++----------------- todo.txt | 34 +++--- 10 files changed, 394 insertions(+), 262 deletions(-) diff --git a/.DS_Store b/.DS_Store index 75d098a40cb305cc1dacd1d5fd4b420e99396f0f..4e3bbc2b5cc00bafb6c9728a37fb552b08db3b9b 100644 GIT binary patch delta 21 ccmZoMXffEJ#mp4kJ6VU>kI`XsHFKv307v!)M*si- delta 21 ccmZoMXffEJ#mr=tI9Z3;k1=6$HFKv307YR2A^-pY diff --git a/js/bullet.js b/js/bullet.js index 225f7fb..56bc584 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -329,7 +329,7 @@ const b = { if (Vector.magnitude(Vector.sub(where, player.position)) < radius) { const DRAIN = (tech.isExplosionHarm ? 0.5 : 0.25) * (tech.isRadioactiveResistance ? 0.25 : 1) // * (tech.isImmuneExplosion ? Math.min(1, Math.max(1 - m.energy * 0.7, 0)) : 1) - m.energy -= DRAIN + if (m.immuneCycle < m.cycle) m.energy -= DRAIN if (m.energy < 0) { m.energy = 0 m.damage(0.03 * (tech.isRadioactiveResistance ? 0.25 : 1)); @@ -1036,7 +1036,7 @@ const b = { if (Vector.magnitude(Vector.sub(player.position, this.position)) < this.damageRadius) { const DRAIN = tech.isRadioactiveResistance ? 0.0025 * 0.25 : 0.0025 if (m.energy > DRAIN) { - m.energy -= DRAIN + if (m.immuneCycle < m.cycle) m.energy -= DRAIN } else { m.energy = 0; m.damage(tech.isRadioactiveResistance ? 0.00016 * 0.25 : 0.00016) //0.00015 @@ -1861,7 +1861,7 @@ const b = { }, onEnd() { if (tech.isMutualism && this.isMutualismActive && !tech.isEnergyHealth) { - m.health += 0.005 + m.health += 0.005 + 0.005 * tech.isSporeWorm if (m.health > m.maxHealth) m.health = m.maxHealth; m.displayHealth(); } @@ -1919,7 +1919,7 @@ const b = { }); World.add(engine.world, bullet[bIndex]); //add bullet to world if (tech.isMutualism && m.health > 0.02) { - m.health -= 0.005 + m.health -= 0.005 - 0.005 * tech.isSporeWorm m.displayHealth(); bullet[bIndex].isMutualismActive = true } @@ -1957,7 +1957,7 @@ const b = { }, onEnd() { if (tech.isMutualism && this.isMutualismActive && !tech.isEnergyHealth) { - m.health += 0.005 + m.health += 0.005 + 0.005 * tech.isSporeWorm if (m.health > m.maxHealth) m.health = m.maxHealth; m.displayHealth(); } @@ -2040,7 +2040,7 @@ const b = { World.add(engine.world, bullet[bIndex]); //add bullet to world if (tech.isMutualism && m.health > 0.02) { - m.health -= 0.005 + m.health -= 0.005 - 0.005 * tech.isSporeWorm m.displayHealth(); bullet[bIndex].isMutualismActive = true } @@ -2048,17 +2048,18 @@ const b = { }, iceIX(speed = 0, dir = m.angle + Math.PI * 2 * Math.random(), where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }) { const me = bullet.length; - const THRUST = 0.004 + const THRUST = 0.0006 const RADIUS = 18 + const SCALE = 1 - 0.08 / tech.isBulletsLastLonger bullet[me] = Bodies.polygon(where.x, where.y, 3, RADIUS, { angle: dir - Math.PI, inertia: Infinity, friction: 0, - frictionAir: 0.10, - restitution: 0.3, - dmg: 0.42, //damage done in addition to the damage from momentum + frictionAir: 0.023, + restitution: 0.9, + dmg: 0.5, //damage done in addition to the damage from momentum lookFrequency: 14 + Math.floor(8 * Math.random()), - endCycle: simulation.cycle + 140 * tech.isBulletsLastLonger, + endCycle: simulation.cycle + 150 * tech.isBulletsLastLonger + Math.floor(25 * Math.random()), classType: "bullet", collisionFilter: { category: cat.bullet, @@ -2071,13 +2072,8 @@ const b = { mobs.statusSlow(who, 180) this.endCycle = simulation.cycle // if (tech.isHeavyWater) mobs.statusDoT(who, 0.15, 300) - if (m.immuneCycle < m.cycle && tech.iceEnergy && !who.shield && !who.isShielded && who.isDropPowerUp && who.alive && m.immuneCycle < m.cycle) { - setTimeout(function() { - if (!who.alive) { - m.energy += tech.iceEnergy * 0.8 - // m.addHealth(tech.iceEnergy * 0.04) - } - }, 10); + if (tech.iceEnergy && !who.shield && !who.isShielded && who.isDropPowerUp && who.alive && m.immuneCycle < m.cycle) { + setTimeout(() => { if (!who.alive) m.energy += tech.iceEnergy * 0.8 }, 10); } }, onEnd() {}, @@ -2085,8 +2081,7 @@ const b = { // this.force.y += this.mass * 0.0002; //find mob targets if (!(simulation.cycle % this.lookFrequency)) { - const scale = 1 - 0.08 / tech.isBulletsLastLonger //0.9 * tech.isBulletsLastLonger; - Matter.Body.scale(this, scale, scale); + Matter.Body.scale(this, SCALE, SCALE); this.lockedOn = null; let closeDist = Infinity; for (let i = 0, len = mob.length; i < len; ++i) { @@ -2380,7 +2375,7 @@ const b = { if (Vector.magnitude(Vector.sub(player.position, this.position)) < this.radioRadius) { const DRAIN = tech.isRadioactiveResistance ? 0.0023 * 0.25 : 0.0023 if (m.energy > DRAIN) { - m.energy -= DRAIN + if (m.immuneCycle < m.cycle) m.energy -= DRAIN } else { m.energy = 0; m.damage(tech.isRadioactiveResistance ? 0.00015 * 0.25 : 0.00015) //0.00015 @@ -2543,14 +2538,11 @@ const b = { // radius *= Math.sqrt(tech.bulletSize) const me = bullet.length; bullet[me] = Bodies.polygon(position.x, position.y, 20, radius, { - // angle: 0, density: 0.000001, // 0.001 is normal density inertia: Infinity, frictionAir: 0.003, - // friction: 0.2, - // restitution: 0.2, dmg: 0, //damage on impact - damage: (tech.isFastFoam ? 0.048 : 0.012) * (tech.isFoamTeleport ? 1.66 : 1), //damage done over time + damage: (tech.isFastFoam ? 0.044 : 0.011) * (tech.isFoamTeleport ? 1.66 : 1), //damage done over time scale: 1 - 0.006 / tech.isBulletsLastLonger * (tech.isFastFoam ? 1.6 : 1), classType: "bullet", collisionFilter: { @@ -2610,9 +2602,6 @@ const b = { this.radius *= this.scale; if (this.radius < 8) this.endCycle = 0; } - - - if (this.target && this.target.alive) { //if stuck to a target const rotate = Vector.rotate(this.targetRelativePosition, this.target.angle) //add in the mob's new angle to the relative position vector if (this.target.isVerticesChange) { @@ -2622,12 +2611,10 @@ const b = { } Matter.Body.setVelocity(this.target, Vector.mult(this.target.velocity, 0.9)) Matter.Body.setAngularVelocity(this.target, this.target.angularVelocity * 0.9); - // Matter.Body.setAngularVelocity(this.target, this.target.angularVelocity * 0.9) if (this.target.isShielded) { this.target.damage(b.dmgScale * this.damage, true); //shield damage bypass - //shrink if mob is shielded - const SCALE = 1 - 0.01 / tech.isBulletsLastLonger + const SCALE = 1 - 0.004 / tech.isBulletsLastLonger //shrink if mob is shielded Matter.Body.scale(this, SCALE, SCALE); this.radius *= SCALE; } else { @@ -2641,9 +2628,7 @@ const b = { let targets = [] for (let i = 0, len = mob.length; i < len; i++) { const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)); - if (dist < 1000000) { - targets.push(mob[i]) - } + if (dist < 1000000) targets.push(mob[i]) } const radius = Math.min(this.radius * 0.5, 10) const len = bullet.length < 100 ? 2 : 1 @@ -2682,7 +2667,6 @@ const b = { this.radius *= SCALE; } else { this.force.y += this.mass * tech.foamGravity; //gravity - if (tech.isFoamAttract) { for (let i = 0, len = mob.length; i < len; i++) { if (!mob[i].isBadTarget && Vector.magnitude(Vector.sub(mob[i].position, this.position)) < 375 && mob[i].alive && Matter.Query.ray(map, this.position, mob[i].position).length === 0) { @@ -2768,6 +2752,71 @@ const b = { }; bullet[me].do = function() {}; }, + needle(angle = m.angle) { + const me = bullet.length; + bullet[me] = Bodies.rectangle(m.pos.x + 40 * Math.cos(m.angle), m.pos.y + 40 * Math.sin(m.angle), 75, 0.75, b.fireAttributes(angle)); + bullet[me].collisionFilter.mask = tech.isNeedleShieldPierce ? cat.body : cat.body | cat.mobShield + Matter.Body.setDensity(bullet[me], 0.00001); //0.001 is normal + bullet[me].endCycle = simulation.cycle + 180; + bullet[me].immuneList = [] + bullet[me].do = function() { + const whom = Matter.Query.collides(this, mob) + if (whom.length && this.speed > 20) { //if touching a mob + for (let i = 0, len = whom.length; i < len; i++) { + who = whom[i].bodyA + if (who && who.mob) { + let immune = false + for (let i = 0; i < this.immuneList.length; i++) { //check if this needle has hit this mob already + if (this.immuneList[i] === who.id) { + immune = true + break + } + } + if (!immune) { + if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.975) { + b.explosion(this.position, 220 + 50 * Math.random()); //makes bullet do explosive damage at end + } + this.immuneList.push(who.id) //remember that this needle has hit this mob once already + who.foundPlayer(); + if (tech.isNailRadiation) { + mobs.statusDoT(who, tech.isFastRadiation ? 12 : 3, tech.isSlowRadiation ? 240 : (tech.isFastRadiation ? 30 : 120)) // one tick every 30 cycles + } else { + let dmg = b.dmgScale * 5.5 + if (tech.isCrit && who.isStunned) dmg *= 4 + who.damage(dmg, tech.isNeedleShieldPierce); + simulation.drawList.push({ //add dmg to draw queue + x: this.position.x, + y: this.position.y, + radius: Math.log(2 * dmg + 1.1) * 40, + color: simulation.playerDmgColor, + time: simulation.drawTime + }); + } + } + } + } + } else if (Matter.Query.collides(this, map).length) { //stick in walls + this.collisionFilter.mask = 0; + Matter.Body.setAngularVelocity(this, 0) + Matter.Body.setVelocity(this, { + x: 0, + y: 0 + }); + this.do = function() { + if (!Matter.Query.collides(this, map).length) this.force.y += this.mass * 0.001; + } + } else if (this.speed < 30) { + this.force.y += this.mass * 0.001; //no gravity until it slows down to improve aiming + } + }; + const SPEED = 90 + Matter.Body.setVelocity(bullet[me], { + x: m.Vx / 2 + SPEED * Math.cos(angle), + y: m.Vy / 2 + SPEED * Math.sin(angle) + }); + // Matter.Body.setDensity(bullet[me], 0.00001); + World.add(engine.world, bullet[me]); //add bullet to world + }, // ************************************************************************************************** // ************************************************************************************************** // ******************************** Bots ********************************************* @@ -3629,91 +3678,19 @@ const b = { this.baseFire(m.angle + (Math.random() - 0.5) * (Math.random() - 0.5) * (m.crouch ? 1.35 : 3.2) / CD) }, fireNeedles() { - function makeNeedle(angle = m.angle) { - const me = bullet.length; - bullet[me] = Bodies.rectangle(m.pos.x + 40 * Math.cos(m.angle), m.pos.y + 40 * Math.sin(m.angle), 75, 0.75, b.fireAttributes(angle)); - bullet[me].collisionFilter.mask = tech.isNeedleShieldPierce ? cat.body : cat.body | cat.mobShield - Matter.Body.setDensity(bullet[me], 0.00001); //0.001 is normal - bullet[me].endCycle = simulation.cycle + 180; - bullet[me].immuneList = [] - bullet[me].do = function() { - const whom = Matter.Query.collides(this, mob) - if (whom.length && this.speed > 20) { //if touching a mob - for (let i = 0, len = whom.length; i < len; i++) { - who = whom[i].bodyA - if (who && who.mob) { - let immune = false - for (let i = 0; i < this.immuneList.length; i++) { //check if this needle has hit this mob already - if (this.immuneList[i] === who.id) { - immune = true - break - } - } - if (!immune) { - if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.975) { - b.explosion(this.position, 220 + 50 * Math.random()); //makes bullet do explosive damage at end - } - this.immuneList.push(who.id) //remember that this needle has hit this mob once already - who.foundPlayer(); - if (tech.isNailRadiation) { - mobs.statusDoT(who, tech.isFastRadiation ? 12 : 3, tech.isSlowRadiation ? 240 : (tech.isFastRadiation ? 30 : 120)) // one tick every 30 cycles - } else { - let dmg = b.dmgScale * 5.5 - if (tech.isCrit && who.isStunned) dmg *= 4 - who.damage(dmg, tech.isNeedleShieldPierce); - simulation.drawList.push({ //add dmg to draw queue - x: this.position.x, - y: this.position.y, - radius: Math.log(2 * dmg + 1.1) * 40, - color: simulation.playerDmgColor, - time: simulation.drawTime - }); - } - } - } - } - } else if (Matter.Query.collides(this, map).length) { //stick in walls - this.collisionFilter.mask = 0; - Matter.Body.setAngularVelocity(this, 0) - Matter.Body.setVelocity(this, { - x: 0, - y: 0 - }); - this.do = function() { - if (!Matter.Query.collides(this, map).length) this.force.y += this.mass * 0.001; - } - } else if (this.speed < 30) { - this.force.y += this.mass * 0.001; //no gravity until it slows down to improve aiming - } - }; - const SPEED = 90 - Matter.Body.setVelocity(bullet[me], { - x: m.Vx / 2 + SPEED * Math.cos(angle), - y: m.Vy / 2 + SPEED * Math.sin(angle) - }); - // Matter.Body.setDensity(bullet[me], 0.00001); - World.add(engine.world, bullet[me]); //add bullet to world - } - if (m.crouch) { m.fireCDcycle = m.cycle + 45 * b.fireCDscale; // cool down - makeNeedle() + b.needle() for (let i = 1; i < 4; i++) { //4 total needles - setTimeout(() => { if (!simulation.paused) makeNeedle() }, 60 * i); + setTimeout(() => { if (!simulation.paused) b.needle() }, 60 * i); } } else { m.fireCDcycle = m.cycle + 25 * b.fireCDscale; // cool down - makeNeedle() + b.needle() for (let i = 1; i < 3; i++) { //3 total needles - setTimeout(() => { if (!simulation.paused) makeNeedle() }, 60 * i); + setTimeout(() => { if (!simulation.paused) b.needle() }, 60 * i); } } - - - // const spread = (m.crouch ? 0.013 : 0.06) - // makeNeedle(m.angle + spread) - // makeNeedle() - // makeNeedle(m.angle - spread) }, fireRivets() { m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 25 : 17) * b.fireCDscale); // cool down @@ -3806,11 +3783,11 @@ const b = { let knock, spread if (m.crouch) { spread = 0.65 - m.fireCDcycle = m.cycle + Math.floor(55 * b.fireCDscale); // cool down + m.fireCDcycle = m.cycle + Math.floor(55 * b.fireCDscale) // cool down if (tech.isShotgunImmune && m.immuneCycle < m.cycle + Math.floor(58 * b.fireCDscale)) m.immuneCycle = m.cycle + Math.floor(58 * b.fireCDscale); //player is immune to damage for 30 cycles knock = 0.01 } else { - m.fireCDcycle = m.cycle + Math.floor(45 * b.fireCDscale); // cool down + m.fireCDcycle = m.cycle + Math.floor(45 * b.fireCDscale) // cool down if (tech.isShotgunImmune && m.immuneCycle < m.cycle + Math.floor(47 * b.fireCDscale)) m.immuneCycle = m.cycle + Math.floor(47 * b.fireCDscale); //player is immune to damage for 30 cycles spread = 1.3 knock = 0.1 @@ -3900,7 +3877,7 @@ const b = { y: speed * Math.sin(dirOff) }); bullet[me].onEnd = function() { - b.explosion(this.position, 150 * (tech.isShotgunReversed ? 1.6 : 1) + (Math.random() - 0.5) * 40); //makes bullet do explosive damage at end + b.explosion(this.position, 160 * (tech.isShotgunReversed ? 1.6 : 1) + (Math.random() - 0.5) * 40); //makes bullet do explosive damage at end } bullet[me].beforeDmg = function() { this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion @@ -3910,7 +3887,7 @@ const b = { } } else if (tech.isNailShot) { spread *= 0.65 - const dmg = 1.4 * (tech.isShotgunReversed ? 1.6 : 1) + const dmg = 2 * (tech.isShotgunReversed ? 1.6 : 1) if (m.crouch) { for (let i = 0; i < 17; i++) { speed = 38 + 15 * Math.random() @@ -3938,6 +3915,49 @@ const b = { }, dmg) } } + } else if (tech.isWormShot) { + const unit = { + x: Math.cos(m.angle), + y: Math.sin(m.angle) + } + const where = { + x: m.pos.x + 35 * unit.x, + y: m.pos.y + 35 * unit.y + } + for (let i = 0, len = 3 * (tech.isShotgunReversed ? 1.6 : 1) + Math.random(); i < len; i++) { + b.worm(where) + const SPEED = 14 + 6 * Math.random() + 20 * m.crouch; + Matter.Body.setVelocity(bullet[bullet.length - 1], { + x: SPEED * unit.x, + y: SPEED * unit.y + }); + } + } else if (tech.isIceShot) { + const spread = (m.crouch ? 0.6 : 1.6) + for (let i = 0, len = 16 * (tech.isShotgunReversed ? 1.6 : 1); i < len; i++) { + // iceIX(speed = 0, dir = m.angle + Math.PI * 2 * Math.random(), where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }) { + b.iceIX(14 + 30 * Math.random(), m.angle + spread * (Math.random() - 0.5)) + } + } else if (tech.isFoamShot) { + const spread = (m.crouch ? 0.35 : 0.7) + const where = { + x: m.pos.x + 25 * Math.cos(m.angle), + y: m.pos.y + 25 * Math.sin(m.angle) + } + const number = 14 * (tech.isShotgunReversed ? 1.6 : 1) + for (let i = 0; i < number; i++) { + const SPEED = 25 + 12 * Math.random(); + const angle = m.angle + spread * (Math.random() - 0.5) + b.foam(where, { x: SPEED * Math.cos(angle), y: SPEED * Math.sin(angle) }, 5 + 8 * Math.random()) + } + } else if (tech.isNeedleShot) { + const number = 12 * (tech.isShotgunReversed ? 1.6 : 1) + const spread = (m.crouch ? 0.04 : 0.08) + let angle = m.angle - (number - 1) * spread * 0.5 + for (let i = 0; i < number; i++) { + b.needle(angle) + angle += spread + } } else { const side = 22 for (let i = 0; i < 17; i++) { @@ -4843,7 +4863,7 @@ const b = { if (tech.isCapacitor) { if ((m.energy > 0.16 || tech.isRailEnergyGain)) { //&& m.immuneCycle < m.cycle - if (m.immuneCycle < m.cycle) m.energy += 0.16 * (tech.isRailEnergyGain ? 6 : -1) + m.energy += 0.16 * (tech.isRailEnergyGain ? 4.5 : -1) m.fireCDcycle = m.cycle + Math.floor(30 * b.fireCDscale); const me = bullet.length; bullet[me] = Bodies.rectangle(m.pos.x + 50 * Math.cos(m.angle), m.pos.y + 50 * Math.sin(m.angle), 60, 14, { @@ -4970,7 +4990,7 @@ const b = { bullet[me].charge = 0; bullet[me].do = function() { if (m.energy < 0.005 && !tech.isRailEnergyGain) { - if (m.immuneCycle < m.cycle) m.energy += 0.05 + this.charge * 0.3 + m.energy += 0.05 + this.charge * 0.2 m.fireCDcycle = m.cycle + 120; // cool down if out of energy this.endCycle = 0; return @@ -5019,7 +5039,7 @@ const b = { let smoothRate = 0.98 * (m.crouch ? 0.99 : 1) * (0.98 + 0.02 * b.fireCDscale) //small b.fireCDscale = faster shots, b.fireCDscale=1 = normal shot, big b.fireCDscale = slower chot this.charge = this.charge * smoothRate + 1 * (1 - smoothRate) if (tech.isRailEnergyGain) { - if (m.immuneCycle < m.cycle) m.energy += (this.charge - previousCharge) * 2 //energy drain is proportional to charge gained, but doesn't stop normal m.fieldRegen + m.energy += (this.charge - previousCharge) * 1.5 //energy drain is proportional to charge gained, but doesn't stop normal m.fieldRegen } else { m.energy -= (this.charge - previousCharge) * 0.33 //energy drain is proportional to charge gained, but doesn't stop normal m.fieldRegen } diff --git a/js/level.js b/js/level.js index 7c7aaf2..0e63a6a 100644 --- a/js/level.js +++ b/js/level.js @@ -12,10 +12,15 @@ const level = { start() { if (level.levelsCleared === 0) { //this code only runs on the first level // simulation.enableConstructMode() //used to build maps in testing mode - // level.difficultyIncrease(60) //30 is near max on hard //60 is near max on why + // level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why // simulation.isHorizontalFlipped = true // m.setField("wormhole") - // b.giveGuns("spores") + // b.giveGuns("shotgun") + // b.giveGuns("foam") + // tech.isNeedleShot = true + // tech.isIceShot = true + // tech.isFoamShot = true + // tech.isWormShot = true // tech.giveTech("CPT reversal") // tech.giveTech("causality bombs") // b.giveGuns("wave beam") @@ -966,12 +971,14 @@ const level = { ctx.fillRect(this.min.x, this.min.y + offset, this.width, this.height - offset) if (this.height > 0 && Matter.Query.region([player], this).length) { - const DRAIN = 0.002 * (tech.isRadioactiveResistance ? 0.25 : 1) + m.fieldRegen - if (m.energy > DRAIN) { - m.energy -= DRAIN - m.damage(damage * (tech.isRadioactiveResistance ? 0.25 : 1) * 0.03) //still take 2% damage while you have energy - } else { - m.damage(damage * (tech.isRadioactiveResistance ? 0.25 : 1)) + if (m.immuneCycle < m.cycle) { + const DRAIN = 0.002 * (tech.isRadioactiveResistance ? 0.25 : 1) + m.fieldRegen + if (m.energy > DRAIN) { + m.energy -= DRAIN + m.damage(damage * (tech.isRadioactiveResistance ? 0.25 : 1) * 0.03) //still take 2% damage while you have energy + } else { + m.damage(damage * (tech.isRadioactiveResistance ? 0.25 : 1)) + } } //float if (player.velocity.y > 5) player.force.y -= 0.95 * player.mass * simulation.g @@ -1621,8 +1628,10 @@ const level = { ctx.lineWidth = 2; if (Vector.magnitudeSquared(Vector.sub(m.pos, powerUp1.position)) < 90000) { //zone radius is 300 //damage player and drain energy - if (m.immuneCycle < m.cycle) m.damage(0.01); - if (m.energy > 0.1) m.energy -= 0.02 + if (m.immuneCycle < m.cycle) { + m.damage(0.01); + if (m.energy > 0.1) m.energy -= 0.02 + } //draw electricity going towards player const unit = Vector.normalise(Vector.sub(m.pos, powerUp1.position)) let xElec = powerUp1.position.x + 40 * unit.x; @@ -2256,10 +2265,10 @@ const level = { spawn.mapRect(6700, -1800, 800, 2600); //right wall spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump - // spawn.starter(1900, -500, 200) //big boy - spawn.growBossCulture(1900, -500) + spawn.starter(1900, -500, 200) //big boy + // spawn.growBossCulture(1900, -500) - // spawn.pulsarBoss(1900, -500) + // spawn.snakeBoss(1900, -500) // spawn.shieldingBoss(1900, -500) // spawn.grenadierBoss(1900, -500) diff --git a/js/mob.js b/js/mob.js index 6b1dd09..9fd8d6c 100644 --- a/js/mob.js +++ b/js/mob.js @@ -417,8 +417,10 @@ const mobs = { ctx.setLineDash([125 * Math.random(), 125 * Math.random()]); // ctx.lineDashOffset = 6*(simulation.cycle % 215); if (this.distanceToPlayer() < this.laserRange) { - if (m.immuneCycle < m.cycle) m.damage(0.0003 * simulation.dmgScale); - if (m.energy > 0.1) m.energy -= 0.003 + if (m.immuneCycle < m.cycle) { + m.damage(0.0003 * simulation.dmgScale); + if (m.energy > 0.1) m.energy -= 0.003 + } ctx.beginPath(); ctx.moveTo(this.position.x, this.position.y); ctx.lineTo(m.pos.x, m.pos.y); diff --git a/js/player.js b/js/player.js index 635b536..b4fdae7 100644 --- a/js/player.js +++ b/js/player.js @@ -635,7 +635,7 @@ const m = { } if (tech.isEnergyHealth) { - m.energy -= dmg * 1.15; + m.energy -= dmg * 1.1; if (m.energy < 0 || isNaN(m.energy)) { //taking deadly damage if (tech.isDeathAvoid && powerUps.research.count && !tech.isDeathAvoidedThisLevel) { tech.isDeathAvoidedThisLevel = true @@ -2443,7 +2443,9 @@ const m = { const unit = Vector.mult(Vector.normalise(sub), body[i].mass * tech.pilotForce * Vector.magnitude(sub)) body[i].force.x += unit.x body[i].force.y += unit.y - body[i].mass * simulation.g //remove gravity effects - if (body[i].collisionFilter.category !== cat.bullet) body[i].collisionFilter.category = cat.bullet; + // if (body[i].collisionFilter.category !== cat.bullet) { + // body[i].collisionFilter.category = cat.bullet; + // } } else { m.fieldCDcycle = m.cycle + 120; m.fieldOn = false @@ -2602,7 +2604,7 @@ const m = { Matter.World.remove(engine.world, body[i]); body.splice(i, 1); m.fieldRange *= 0.8 - if (tech.isWormholeEnergy && m.immuneCycle < m.cycle) m.energy += 0.63 + if (tech.isWormholeEnergy) m.energy += 0.63 if (tech.isWormSpores) { //pandimensionalspermia for (let i = 0, len = Math.ceil(3 * (tech.isSporeWorm ? 0.5 : 1) * Math.random()); i < len; i++) { if (tech.isSporeWorm) { diff --git a/js/powerup.js b/js/powerup.js index 650b303..7dd5e6f 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -676,7 +676,7 @@ const powerUps = { onPickUp(who) { powerUps.research.currentRerollCount = 0 if (tech.isTechDamage && who.name === "tech") m.damage(0.11) - if (tech.isMassEnergy && m.immuneCycle < m.cycle) m.energy += 2; + if (tech.isMassEnergy) m.energy += 2; if (tech.isMineDrop) { if (tech.isLaserMine) { b.laserMine(who.position) diff --git a/js/simulation.js b/js/simulation.js index 33681f5..3cc9f70 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -696,7 +696,7 @@ const simulation = { if (tech.isMutualism && !tech.isEnergyHealth) { for (let i = 0; i < bullet.length; i++) { if (bullet[i].isMutualismActive) { - m.health += 0.005 + m.health += 0.005 + 0.005 * tech.isSporeWorm if (m.health > m.maxHealth) m.health = m.maxHealth; m.displayHealth(); } diff --git a/js/spawn.js b/js/spawn.js index 74ff1df..a984af9 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -188,7 +188,7 @@ const spawn = { if (m.immuneCycle < m.cycle && Vector.magnitude(Vector.sub(player.position, this.position)) < this.radius) { const DRAIN = tech.isRadioactiveResistance ? 0.07 * 0.25 : 0.07 if (m.energy > DRAIN) { - m.energy -= DRAIN + if (m.immuneCycle < m.cycle) m.energy -= DRAIN } else { m.energy = 0; m.damage((tech.isRadioactiveResistance ? 0.007 * 0.25 : 0.007) * simulation.dmgScale) @@ -504,9 +504,9 @@ const spawn = { ctx.fill(); //when player is inside event horizon if (Vector.magnitude(Vector.sub(this.position, player.position)) < eventHorizon) { - if (m.energy > 0) m.energy -= 0.01 - if (m.energy < 0.15 && m.immuneCycle < m.cycle) { - m.damage(0.0004 * simulation.dmgScale); + if (m.immuneCycle < m.cycle) { + if (m.energy > 0) m.energy -= 0.01 + if (m.energy < 0.15 && m.immuneCycle < m.cycle) m.damage(0.0004 * simulation.dmgScale); } const angle = Math.atan2(player.position.y - this.position.y, player.position.x - this.position.x); player.force.x -= 0.0017 * Math.cos(angle) * player.mass * (m.onGround ? 1.7 : 1); @@ -704,7 +704,7 @@ const spawn = { let me = mob[mob.length - 1]; // console.log(`mass=${me.mass}, radius = ${radius}`) me.accelMag = 0.0002 - me.repulsionRange = 100000; //squared + me.repulsionRange = 100000 + radius * radius; //squared // me.memory = 120; me.seeAtDistance2 = 2000000 //1400 vision range Matter.Body.setDensity(me, 0.0005) // normal density is 0.001 // this reduces life by half and decreases knockback @@ -1338,9 +1338,9 @@ const spawn = { //when player is inside event horizon if (Vector.magnitude(Vector.sub(this.position, player.position)) < eventHorizon) { - if (m.energy > 0) m.energy -= 0.004 - if (m.energy < 0.1 && m.immuneCycle < m.cycle) { - m.damage(0.00015 * simulation.dmgScale); + if (m.immuneCycle < m.cycle) { + if (m.energy > 0) m.energy -= 0.004 + if (m.energy < 0.1) m.damage(0.00015 * simulation.dmgScale); } const angle = Math.atan2(player.position.y - this.position.y, player.position.x - this.position.x); player.force.x -= 0.00125 * player.mass * Math.cos(angle) * (m.onGround ? 1.8 : 1); @@ -1447,9 +1447,9 @@ const spawn = { ctx.fill(); //when player is inside event horizon if (Vector.magnitude(Vector.sub(this.position, player.position)) < eventHorizon) { - if (m.energy > 0) m.energy -= 0.006 - if (m.energy < 0.1 && m.immuneCycle < m.cycle) { - m.damage(0.0002 * simulation.dmgScale); + if (m.immuneCycle < m.cycle) { + if (m.energy > 0) m.energy -= 0.006 + if (m.energy < 0.1) m.damage(0.0002 * simulation.dmgScale); } const angle = Math.atan2(player.position.y - this.position.y, player.position.x - this.position.x); player.force.x -= 0.0013 * Math.cos(angle) * player.mass * (m.onGround ? 1.7 : 1); @@ -1703,10 +1703,12 @@ const spawn = { ctx.setLineDash([125 * Math.random(), 125 * Math.random()]); //the dashed effect is not set back to normal, because it looks neat for how the player is drawn // ctx.lineDashOffset = 6*(simulation.cycle % 215); if (this.distanceToPlayer() < this.laserRange) { - if (m.energy > 0.002) { - m.energy -= 0.0035 - } else if (m.immuneCycle < m.cycle) { - m.damage(0.0003 * simulation.dmgScale) + if (m.immuneCycle < m.cycle) { + if (m.energy > 0.002) { + m.energy -= 0.0035 + } else { + m.damage(0.0003 * simulation.dmgScale) + } } ctx.beginPath(); ctx.moveTo(eye.x, eye.y); @@ -3551,7 +3553,8 @@ const spawn = { }; }, snakeBoss(x, y, radius = 75) { //snake boss with a laser head - mobs.spawn(x, y, 8, radius, "rgb(55,170,170)"); + const color1 = "#f27" + mobs.spawn(x, y, 8, radius, color1); //"rgb(55,170,170)" let me = mob[mob.length - 1]; me.isBoss = true; me.damageReduction = 0.25; @@ -3579,6 +3582,14 @@ const spawn = { //snake tail const nodes = Math.min(8 + Math.ceil(0.5 * simulation.difficulty), 40) spawn.lineGroup(x + 105, y, "snakeBody", nodes); + + for (let i = mob.length - 1, len = i - nodes; i > len; i--) { //set alternating colors + if (i % 2) { + mob[i].fill = "#333" + } else { + mob[i].fill = color1 + } + } //constraint with first 3 mobs in line consBB[consBB.length] = Constraint.create({ bodyA: mob[mob.length - nodes], @@ -3598,7 +3609,7 @@ const spawn = { stiffness: 0.05 }); World.add(engine.world, consBB[consBB.length - 1]); - spawn.shield(me, x, y, 1); + // spawn.shield(me, x, y, 1); }, snakeBody(x, y, radius = 10) { mobs.spawn(x, y, 8, radius, "rgba(0,180,180,0.4)"); @@ -3610,6 +3621,8 @@ const spawn = { me.collisionFilter.mask = cat.bullet | cat.player | cat.mob //| cat.body me.accelMag = 0.0004 * simulation.accelScale; me.leaveBody = false; + me.showHealthBar = false; + // Matter.Body.setDensity(me, 0.00004); //normal is 0.001 me.frictionAir = 0.02; me.isSnakeTail = true; me.stroke = "transparent" diff --git a/js/tech.js b/js/tech.js index a01f7ff..af3b062 100644 --- a/js/tech.js +++ b/js/tech.js @@ -682,7 +682,7 @@ frequency: 2, frequencyDefault: 2, allowed() { - return m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" || tech.haveGunCheck("spores") || tech.haveGunCheck("drones") || tech.haveGunCheck("missiles") || tech.haveGunCheck("foam") || tech.haveGunCheck("wave beam") || tech.isNeutronBomb || tech.isIceField || tech.relayIce || tech.blockingIce > 1 + return m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" || tech.haveGunCheck("spores") || tech.haveGunCheck("drones") || tech.haveGunCheck("missiles") || tech.haveGunCheck("foam") || tech.haveGunCheck("wave beam") || tech.isNeutronBomb || tech.isIceField || tech.isIceShot || tech.relayIce || tech.blockingIce > 1 }, requires: "drones, spores, missiles, foam, wave beam, neutron bomb, ice IX", effect() { @@ -865,9 +865,9 @@ frequency: 1, frequencyDefault: 1, allowed() { - return ((m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isDroneRadioactive || tech.isSporeField || tech.isMissileField || tech.isIceField)) || (tech.haveGunCheck("drones") && !tech.isDroneRadioactive) || tech.haveGunCheck("super balls") || tech.haveGunCheck("shotgun")) && !tech.isNailShot + return ((m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isDroneRadioactive || tech.isSporeField || tech.isMissileField || tech.isIceField)) || (tech.haveGunCheck("drones") && !tech.isDroneRadioactive) || tech.haveGunCheck("super balls") || tech.haveGunCheck("shotgun")) && !tech.isNailShot && !tech.isIceShot && !tech.isFoamShot && !tech.isWormShot }, - requires: "super balls, shotgun, drones, not irradiated drones", + requires: "super balls, basic or slug shotgun, drones, not irradiated drones", effect() { tech.isIncendiary = true }, @@ -1812,7 +1812,7 @@ frequency: 2, frequencyDefault: 2, allowed() { - return (tech.isIceCrystals || tech.isSporeFreeze || tech.isIceField || tech.relayIce || tech.blockingIce > 1) && !tech.sporesOnDeath && !tech.isExplodeMob && !tech.botSpawner && !tech.isMobBlockFling && !tech.nailsDeathMob + return (tech.isIceCrystals || tech.isSporeFreeze || tech.isIceField || tech.isIceShot || tech.relayIce || tech.blockingIce > 1) && !tech.sporesOnDeath && !tech.isExplodeMob && !tech.botSpawner && !tech.isMobBlockFling && !tech.nailsDeathMob }, requires: "a localized freeze effect, no other mob death tech", effect() { @@ -1830,7 +1830,7 @@ frequency: 2, frequencyDefault: 2, allowed() { - return tech.isIceField || tech.relayIce || tech.blockingIce || tech.iceIXOnDeath + return tech.isIceField || tech.relayIce || tech.blockingIce || tech.iceIXOnDeath || tech.isIceShot }, requires: "ice IX", effect() { @@ -1848,7 +1848,7 @@ frequency: 2, frequencyDefault: 2, allowed() { - return tech.isIceCrystals || tech.isSporeFreeze || tech.isIceField || tech.relayIce || tech.blockingIce > 1 || tech.iceIXOnDeath + return tech.isIceCrystals || tech.isSporeFreeze || tech.isIceField || tech.relayIce || tech.blockingIce > 1 || tech.iceIXOnDeath || tech.isIceShot }, requires: "a localized freeze effect", effect() { @@ -1866,7 +1866,7 @@ frequency: 2, frequencyDefault: 2, allowed() { - return tech.isStunField || tech.isExplosionStun || tech.oneSuperBall || tech.isHarmFreeze || tech.isIceField || tech.relayIce || tech.isIceCrystals || tech.isSporeFreeze || tech.isAoESlow || tech.isFreezeMobs || tech.isCloakStun || tech.orbitBotCount > 1 || tech.isWormholeDamage || tech.blockingIce > 1 || tech.iceIXOnDeath + return tech.isStunField || tech.isExplosionStun || tech.oneSuperBall || tech.isHarmFreeze || tech.isIceField || tech.relayIce || tech.isIceCrystals || tech.isSporeFreeze || tech.isAoESlow || tech.isFreezeMobs || tech.isCloakStun || tech.orbitBotCount > 1 || tech.isWormholeDamage || tech.blockingIce > 1 || tech.iceIXOnDeath || tech.isIceShot }, requires: "a freezing or stunning effect", effect() { @@ -3461,9 +3461,9 @@ frequency: 2, frequencyDefault: 2, allowed() { - return tech.isNeedles && !tech.isNailRadiation + return (tech.isNeedles || tech.isNeedleShot) && !tech.isNailRadiation }, - requires: "needle gun, not irradiated nails", + requires: "needle gun, needle-shot, not irradiated nails", effect() { tech.isNeedleShieldPierce = true }, @@ -3729,44 +3729,6 @@ } } }, - { - name: "nailshot", - description: "the shotgun fires a burst of nails", - isGunTech: true, - maxCount: 1, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return tech.haveGunCheck("shotgun") && !tech.isIncendiary && !tech.isSlugShot - }, - requires: "shotgun, not slug, incendiary", - effect() { - tech.isNailShot = true; - }, - remove() { - tech.isNailShot = false; - } - }, - { - name: "shotgun slug", - description: "the shotgun fires 1 large bullet", - isGunTech: true, - maxCount: 1, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return tech.haveGunCheck("shotgun") && !tech.isNailShot - }, - requires: "shotgun, not nailshot", - effect() { - tech.isSlugShot = true; - }, - remove() { - tech.isSlugShot = false; - } - }, { name: "Newton's 3rd law", description: "shotgun recoil is increased
decrease shotgun delay after firing by 66%", @@ -3805,6 +3767,120 @@ tech.isShotgunReversed = false; } }, + { + name: "shotgun slug", + description: "the shotgun fires a huge dense bullet", + isGunTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIncendiary && !tech.isIceShot && !tech.isFoamShot && !tech.isWormShot && !tech.isNeedleShot + }, + requires: "shotgun, not nail-shot, foam-shot, worm-shot, ice-shot", + effect() { + tech.isSlugShot = true; + }, + remove() { + tech.isSlugShot = false; + } + }, + { + name: "nail-shot", + description: "the shotgun fires a burst of nails", + isGunTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return tech.haveGunCheck("shotgun") && !tech.isIncendiary && !tech.isSlugShot && !tech.isIceShot && !tech.isFoamShot && !tech.isWormShot && !tech.isNeedleShot + }, + requires: "shotgun, not incendiary, slug, foam-shot, worm-shot, ice-shot", + effect() { + tech.isNailShot = true; + }, + remove() { + tech.isNailShot = false; + } + }, + { + name: "worm-shot", + description: "the shotgun fires 3-4 worms", //
worms seek out nearby mobs + isGunTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIncendiary && !tech.isSlugShot && !tech.isIceShot && !tech.isFoamShot && !tech.isNeedleShot + }, + requires: "shotgun, not incendiary, nail-shot, slug, foam-shot, ice-shot", + effect() { + tech.isWormShot = true; + }, + remove() { + tech.isWormShot = false; + } + }, + { + name: "foam-shot", + description: "the shotgun fires 14 foam bubbles", + isGunTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIncendiary && !tech.isSlugShot && !tech.isIceShot && !tech.isWormShot && !tech.isNeedleShot + }, + requires: "shotgun, not incendiary, nail-shot, slug, worm-shot, ice-shot", + effect() { + tech.isFoamShot = true; + }, + remove() { + tech.isFoamShot = false; + } + }, + { + name: "ice-shot", + description: "the shotgun fires 16 ice IX crystals", + isGunTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIncendiary && !tech.isSlugShot && !tech.isFoamShot && !tech.isWormShot && !tech.isNeedleShot + }, + requires: "shotgun, not incendiary, nail-shot, slug, foam-shot, worm-shot", + effect() { + tech.isIceShot = true; + }, + remove() { + tech.isIceShot = false; + } + }, + { + name: "needle-shot", + description: "the shotgun fires 12 mob piercing needles", + isGunTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIncendiary && !tech.isSlugShot && !tech.isFoamShot && !tech.isWormShot && !tech.isIceShot + }, + requires: "shotgun, not incendiary, nail-shot, slug, foam-shot, worm-shot, ice-shot", + effect() { + tech.isNeedleShot = true; + }, + remove() { + tech.isNeedleShot = false; + } + }, { name: "super duper", description: "fire 1 additional super ball", @@ -4318,9 +4394,9 @@ frequency: 2, frequencyDefault: 2, allowed() { - return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField + return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField || tech.isWormShot }, - requires: "spores", + requires: "spores or worms", effect() { tech.isSporeFreeze = true }, @@ -4337,9 +4413,9 @@ frequency: 2, frequencyDefault: 2, allowed() { - return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField + return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField || tech.isWormShot }, - requires: "spores", + requires: "spores or worms", effect() { tech.isSporeFollow = true }, @@ -4347,6 +4423,25 @@ tech.isSporeFollow = false } }, + { + name: "mutualism", + description: "increase spore damage by 150%
spores borrow 0.5 health until they die", + isGunTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return (tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField) && !tech.isEnergyHealth || tech.isWormShot + }, + requires: "spores, worms, not mass-energy", + effect() { + tech.isMutualism = true + }, + remove() { + tech.isMutualism = false + } + }, { name: "nematodes", description: "spores develop into 1/2 as many worms
worms do 200% more damage", @@ -4366,25 +4461,6 @@ tech.isSporeWorm = false } }, - { - name: "mutualism", - description: "increase spore damage by 150%
spores borrow 0.5 health until they die", - isGunTech: true, - maxCount: 1, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return (tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField) && !tech.isEnergyHealth - }, - requires: "spores, not mass-energy", - effect() { - tech.isMutualism = true - }, - remove() { - tech.isMutualism = false - } - }, { name: "reduced tolerances", description: "increase drone ammo/efficiency by 66%
reduce the average drone lifetime by 40%", @@ -4543,6 +4619,25 @@ tech.droneRadioDamage = 1 } }, + { + name: "electrostatic induction", + description: "foam bubbles are electrically charged
causing attraction to nearby mobs", + isGunTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return !tech.isFoamTeleport && (tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot) + }, + requires: "foam, not uncertainty", + effect() { + tech.isFoamAttract = true + }, + remove() { + tech.isFoamAttract = false + } + }, { name: "uncertainty principle", description: "foam bubbles randomly change position
increase foam damage per second by 66%", @@ -4552,7 +4647,7 @@ frequency: 2, frequencyDefault: 2, allowed() { - return !tech.isFoamAttract && (tech.haveGunCheck("foam") || tech.foamBotCount > 1) + return !tech.isFoamAttract && (tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot) }, requires: "foam, not electrostatic induction", effect() { @@ -4571,7 +4666,7 @@ frequency: 2, frequencyDefault: 2, allowed() { - return tech.haveGunCheck("foam") || tech.foamBotCount > 1 + return tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot }, requires: "foam", effect() { @@ -4590,7 +4685,7 @@ frequency: 2, frequencyDefault: 2, allowed() { - return tech.haveGunCheck("foam") || tech.foamBotCount > 1 + return tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot }, requires: "foam", effect() { @@ -4640,25 +4735,6 @@ tech.isAmmoFoamSize = false; } }, - { - name: "electrostatic induction", - description: "foam bubbles are electrically charged
causing attraction to nearby mobs", - isGunTech: true, - maxCount: 1, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return !tech.isFoamTeleport && (tech.haveGunCheck("foam") || tech.foamBotCount > 1) - }, - requires: "foam, not uncertainty", - effect() { - tech.isFoamAttract = true - }, - remove() { - tech.isFoamAttract = false - } - }, { name: "half-wave rectifier", description: "charging the rail gun gives you energy
instead of draining it", @@ -7553,6 +7629,10 @@ isFieldHarmReduction: null, isFastTime: null, isDroneTeleport: null, + isAnthropicTech: null, isSporeWorm: null, - isAnthropicTech: null + isWormShot: null, + isFoamShot: null, + isIceShot: null, + isNeedleShot: null } \ No newline at end of file diff --git a/todo.txt b/todo.txt index 27fb786..b70fc8b 100644 --- a/todo.txt +++ b/todo.txt @@ -1,25 +1,31 @@ ******************************************************** NEXT PATCH ******************************************************** -tech: weak anthropic principle - after anthropic principle prevents your death, gain 50% duplication for that level -anthropic principle now correctly gives 6 seconds of harm immunity after preventing your death -almost all energy regen is disabled while immune to harm - you aren't immune very often so you may not notice, but it will limit some builds that let you get almost constant immunity - Pauli exclusion gives 1 s of harm immunity (was .75 s) - CPT reversal requires 10% less energy (min energy is 60% to activate) - CPT grenades gives many more bombs - CPT bots gives many more bots +shotgun techs: + (I haven't done enough testing so let me know if these different shotgun modes aren't balanced) + worm shot + ice-IX shot + foam shot + needle shot -growBoss balance: a bit smaller and slower, and a extra high chance to drop a random power up when you kill one -sneaker mobs are a bit slower, and have much lower health -starter mobs are no longer aggressive +foam lasts much longer on shielded mobs + overall foam damage is reduced about 8% -gun tech will now only show up for your active gun -set CSS max width of the update element to match other elements +attacks that drain energy don't work when the player is immune to harm + slime, radiation fields, black holes +energy regen that consumes something (ammo, blocks, power ups) now works when immune to harm + but passive energy regen is still stopped while you are immune to harm + +pilot wave field can no longer hit intangible mobs with blocks + it was too annoying that you can't use blocks to move around so I reverted it back ******************************************************** TODO ******************************************************** +snake boss tail should shrink in size -CPT reversal should drain less energy? +mob that grows or gets a shield when player is near + and charges when player is near + charge triggers an escape mode + mob wonders and drops eggs that hatch into seekers if no player around pink seeker boss is cool as heck, make an alt version of it