diff --git a/js/bullet.js b/js/bullet.js index 01b1056..1ad262b 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -2177,14 +2177,16 @@ const b = { }, nail(pos, velocity, dmg = 0) { const me = bullet.length; - bullet[me] = Bodies.rectangle(pos.x, pos.y, 25 * tech.biggerNails, 2 * tech.biggerNails, b.fireAttributes(Math.atan2(velocity.y, velocity.x))); + bullet[me] = Bodies.rectangle(pos.x, pos.y, 25, 2, b.fireAttributes(Math.atan2(velocity.y, velocity.x))); Matter.Body.setVelocity(bullet[me], velocity); World.add(engine.world, bullet[me]); //add bullet to world bullet[me].endCycle = simulation.cycle + 60 + 18 * Math.random(); - bullet[me].dmg = dmg + bullet[me].dmg = tech.isNailRadiation ? 0 : dmg bullet[me].beforeDmg = function(who) { //beforeDmg is rewritten with ice crystal tech - if (tech.isNailPoison) mobs.statusDoT(who, dmg * 0.24, 120) // one tick every 30 cycles - if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.99) this.dmg *= 5 //crit if hit near center + if (tech.isNailRadiation) mobs.statusDoT(who, dmg * (tech.isFastRadiation ? 2 : 0.5), tech.isSlowRadiation ? 240 : (tech.isFastRadiation ? 30 : 120)) // one tick every 30 cycles + if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.97) { + b.explosion(this.position, 150 + 30 * Math.random()); //makes bullet do explosive damage at end + } }; bullet[me].do = function() {}; }, @@ -2839,83 +2841,189 @@ const b = { name: "nail gun", description: "use compressed air to fire a stream of nails
delay after firing decreases as you shoot", ammo: 0, - ammoPack: 55, - defaultAmmoPack: 55, + ammoPack: 50, + defaultAmmoPack: 50, recordedAmmo: 0, have: false, nextFireCycle: 0, //use to remember how longs its been since last fire, used to reset count startingHoldCycle: 0, - fire() { - let CD - if (tech.nailFireRate) { //fire delay decreases as you hold fire, down to 3 from 15 - if (tech.nailInstantFireRate) { - CD = 2 - } else { - if (this.nextFireCycle + 1 < mech.cycle) this.startingHoldCycle = mech.cycle //reset if not constantly firing - CD = Math.max(7.5 - 0.06 * (mech.cycle - this.startingHoldCycle), 2) //CD scales with cycles fire is held down - this.nextFireCycle = mech.cycle + CD * b.fireCD //predict next fire cycle if the fire button is held down - } + chooseFireMethod() { //set in simulation.startGame + if (tech.isRivets) { + this.fire = this.fireRivets + } else if (tech.isNeedles) { + this.fire = this.fireNeedles + } else if (tech.nailInstantFireRate) { + this.fire = this.fireNailFireRate + } else if (tech.nailFireRate) { + this.fire = this.fireNailFireRate } else { - if (this.nextFireCycle + 1 < mech.cycle) this.startingHoldCycle = mech.cycle //reset if not constantly firing - CD = Math.max(11 - 0.06 * (mech.cycle - this.startingHoldCycle), 2) //CD scales with cycles fire is held down - this.nextFireCycle = mech.cycle + CD * b.fireCD //predict next fire cycle if the fire button is held down + this.fire = this.fireNormal } - mech.fireCDcycle = mech.cycle + Math.floor(CD * b.fireCD); // cool down - const speed = 30 + 6 * Math.random() + 9 * tech.nailInstantFireRate - const angle = mech.angle + (Math.random() - 0.5) * (Math.random() - 0.5) * (mech.crouch ? 1.35 : 3.2) / CD - if (tech.isIncendiary) { - const me = bullet.length; - bullet[me] = Bodies.rectangle(mech.pos.x + 50 * Math.cos(mech.angle), mech.pos.y + 50 * Math.sin(mech.angle), 25, 2, { - density: 0.0001, //frictionAir: 0.01, //restitution: 0, - angle: angle, - friction: 0.5, - frictionAir: 0, - dmg: 0, //damage done in addition to the damage from momentum - endCycle: Math.floor(mech.crouch ? 28 : 13) + Math.random() * 5 + simulation.cycle, - classType: "bullet", - collisionFilter: { - category: cat.bullet, - mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield - }, - minDmgSpeed: 10, - beforeDmg() { - this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion - }, - onEnd() { - b.explosion(this.position, 72 + (Math.random() - 0.5) * 30); //makes bullet do explosive damage at end - }, - do() {} - }); - Matter.Body.setVelocity(bullet[me], { - x: speed * Math.cos(angle), - y: speed * Math.sin(angle) - }); - World.add(engine.world, bullet[me]); //add bullet to world - } else { - const dmg = 0.9 - b.nail({ - x: mech.pos.x + 30 * Math.cos(mech.angle), - y: mech.pos.y + 30 * Math.sin(mech.angle) - }, { - x: mech.Vx / 2 + speed * Math.cos(angle), - y: mech.Vy / 2 + speed * Math.sin(angle) - }, dmg) //position, velocity, damage - if (tech.isIceCrystals) { - bullet[bullet.length - 1].beforeDmg = function(who) { - mobs.statusSlow(who, 30) - if (tech.isNailPoison) mobs.statusDoT(who, dmg * 0.24, 120) // one tick every 30 cycles - if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.99) this.dmg *= 5 //crit if hit near center - }; + }, + fire() { - if (mech.energy < 0.01) { - mech.fireCDcycle = mech.cycle + 60; // cool down + }, + fireNormal() { + if (this.nextFireCycle + 1 < mech.cycle) this.startingHoldCycle = mech.cycle //reset if not constantly firing + const CD = Math.max(11 - 0.06 * (mech.cycle - this.startingHoldCycle), 2) //CD scales with cycles fire is held down + this.nextFireCycle = mech.cycle + CD * b.fireCD //predict next fire cycle if the fire button is held down + + mech.fireCDcycle = mech.cycle + Math.floor(CD * b.fireCD); // cool down + this.baseFire(mech.angle + (Math.random() - 0.5) * (Math.random() - 0.5) * (mech.crouch ? 1.35 : 3.2) / CD) + }, + fireNeedles() { + mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 40 : 30) * b.fireCD); // cool down + + function makeFlechette(angle = mech.angle) { + const me = bullet.length; + bullet[me] = Bodies.rectangle(mech.pos.x + 40 * Math.cos(mech.angle), mech.pos.y + 40 * Math.sin(mech.angle), 50, 1, b.fireAttributes(angle)); + bullet[me].collisionFilter.mask = cat.mobShield | cat.body + 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 + who = whom[0].bodyA + if (who && who.mob) { + let immune = false + for (let i = 0; i < this.immuneList.length; i++) { + 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.97) { + b.explosion(this.position, 200 + 30 * Math.random()); //makes bullet do explosive damage at end + } + this.immuneList.push(who.id) + who.foundPlayer(); + if (tech.isNailRadiation) { + mobs.statusDoT(who, tech.isFastRadiation ? 10 : 2.5, tech.isSlowRadiation ? 240 : (tech.isFastRadiation ? 30 : 120)) // one tick every 30 cycles + } else { + let dmg = b.dmgScale * 5 + if (tech.isCrit && who.isStunned) dmg *= 4 + who.damage(dmg); + 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 + }); + } + // if (tech.isFastRadiation) { + // mobs.statusDoT(who, 3.78, 30) + // } else { + // mobs.statusDoT(who, 0.63, tech.isSlowRadiation ? 360 : 180) + // } + } + } + } 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() {} + } else if (this.speed < 30) { + this.force.y += this.mass * 0.0007; //no gravity until it slows down to improve aiming + } + }; + const SPEED = 50 + Matter.Body.setVelocity(bullet[me], { + x: mech.Vx / 2 + SPEED * Math.cos(angle), + y: mech.Vy / 2 + SPEED * Math.sin(angle) + }); + Matter.Body.setDensity(bullet[me], 0.00001); + World.add(engine.world, bullet[me]); //add bullet to world + } + const spread = (mech.crouch ? 0.01 : 0.045) + makeFlechette(mech.angle + spread) + makeFlechette() + makeFlechette(mech.angle - spread) + }, + fireRivets() { + mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 25 : 20) * b.fireCD); // cool down + + const me = bullet.length; + const size = tech.rivetSize * 6 + bullet[me] = Bodies.rectangle(mech.pos.x + 35 * Math.cos(mech.angle), mech.pos.y + 35 * Math.sin(mech.angle), 5 * size, size, b.fireAttributes(mech.angle)); + bullet[me].dmg = tech.isNailRadiation ? 0 : 2.75 + Matter.Body.setDensity(bullet[me], 0.002); + World.add(engine.world, bullet[me]); //add bullet to world + const SPEED = mech.crouch ? 55 : 46 + Matter.Body.setVelocity(bullet[me], { + x: SPEED * Math.cos(mech.angle), + y: SPEED * Math.sin(mech.angle) + }); + bullet[me].endCycle = simulation.cycle + 180 + bullet[me].beforeDmg = function(who) { //beforeDmg is rewritten with ice crystal tech + if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.97) { + b.explosion(this.position, 300 + 30 * Math.random()); //makes bullet do explosive damage at end + } + if (tech.isNailRadiation) mobs.statusDoT(who, 7 * (tech.isFastRadiation ? 1 : 0.25), tech.isSlowRadiation ? 240 : (tech.isFastRadiation ? 30 : 120)) // one tick every 30 cycles + }; + + bullet[me].minDmgSpeed = 10 + bullet[me].frictionAir = 0.006; + bullet[me].do = function() { + this.force.y += this.mass * 0.0008 + + //rotates bullet to face current velocity? + if (this.speed > 7) { + const facing = { + x: Math.cos(this.angle), + y: Math.sin(this.angle) + } + const mag = 0.002 * this.mass + if (Vector.cross(Vector.normalise(this.velocity), facing) < 0) { + this.torque += mag } else { - mech.energy -= mech.fieldRegen + 0.01 + this.torque -= mag } } - } + }; + b.muzzleFlash(30); + }, + fireNailFireRate() { + if (this.nextFireCycle + 1 < mech.cycle) this.startingHoldCycle = mech.cycle //reset if not constantly firing + const CD = Math.max(7.5 - 0.06 * (mech.cycle - this.startingHoldCycle), 2) //CD scales with cycles fire is held down + this.nextFireCycle = mech.cycle + CD * b.fireCD //predict next fire cycle if the fire button is held down - } + mech.fireCDcycle = mech.cycle + Math.floor(CD * b.fireCD); // cool down + this.baseFire(mech.angle + (Math.random() - 0.5) * (Math.random() - 0.5) * (mech.crouch ? 1.35 : 3.2) / CD) + }, + fireInstantFireRate() { + mech.fireCDcycle = mech.cycle + Math.floor(2 * b.fireCD); // cool down + this.baseFire(mech.angle + (Math.random() - 0.5) * (Math.random() - 0.5) * (mech.crouch ? 1.35 : 3.2) / 2) + }, + baseFire(angle) { + const speed = 30 + 6 * Math.random() + 9 * tech.nailInstantFireRate + const dmg = 0.9 + b.nail({ + x: mech.pos.x + 30 * Math.cos(mech.angle), + y: mech.pos.y + 30 * Math.sin(mech.angle) + }, { + x: mech.Vx / 2 + speed * Math.cos(angle), + y: mech.Vy / 2 + speed * Math.sin(angle) + }, dmg) //position, velocity, damage + if (tech.isIceCrystals) { + bullet[bullet.length - 1].beforeDmg = function(who) { + mobs.statusSlow(who, 30) + if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.97) { + b.explosion(this.position, 150 + 30 * Math.random()); //makes bullet do explosive damage at end + } + }; + if (mech.energy < 0.01) { + mech.fireCDcycle = mech.cycle + 60; // cool down + } else { + mech.energy -= mech.fieldRegen + 0.01 + } + } + }, }, { name: "shotgun", @@ -2953,7 +3061,7 @@ const b = { const me = bullet.length; const dir = mech.angle + 0.02 * (Math.random() - 0.5) bullet[me] = Bodies.rectangle(mech.pos.x + 35 * Math.cos(mech.angle), mech.pos.y + 35 * Math.sin(mech.angle), 45, 20, b.fireAttributes(dir)); - Matter.Body.setDensity(bullet[me], 0.0022); + Matter.Body.setDensity(bullet[me], 0.003); World.add(engine.world, bullet[me]); //add bullet to world const SPEED = (mech.crouch ? 52 : 43) + Math.random() * 7 Matter.Body.setVelocity(bullet[me], { @@ -3147,109 +3255,6 @@ const b = { } } }, - { - name: "flechettes", - description: "fire a volley of uranium-235 needles
does radioactive damage over 3 seconds", - ammo: 0, - ammoPack: 75, - defaultAmmoPack: 75, - have: false, - count: 0, //used to track how many shots are in a volley before a big CD - lastFireCycle: 0, //use to remember how longs its been since last fire, used to reset count - fire() { - function makeFlechette(angle = mech.angle + 0.02 * (Math.random() - 0.5)) { - const me = bullet.length; - bullet[me] = Bodies.rectangle(mech.pos.x + 40 * Math.cos(mech.angle), mech.pos.y + 40 * Math.sin(mech.angle), 45, 1, b.fireAttributes(angle)); - bullet[me].collisionFilter.mask = tech.pierce ? 0 : cat.body; //cat.mobShield | //cat.map | cat.body | - Matter.Body.setDensity(bullet[me], 0.00001); //0.001 is normal - bullet[me].endCycle = simulation.cycle + 180; - bullet[me].dmg = 0; - bullet[me].immuneList = [] - bullet[me].do = function() { - const whom = Matter.Query.collides(this, mob) - if (whom.length && this.speed > 20) { //if touching a mob - who = whom[0].bodyA - if (who && who.mob) { - if (tech.pierce) { - let immune = false - for (let i = 0; i < this.immuneList.length; i++) { - if (this.immuneList[i] === who.id) immune = true - } - if (!immune) { - this.immuneList.push(who.id) - who.foundPlayer(); - if (tech.isFastDot) { - mobs.statusDoT(who, 3.78, 30) - } else { - mobs.statusDoT(who, 0.63, tech.isSlowDot ? 360 : 180) - } - simulation.drawList.push({ //add dmg to draw queue - x: this.position.x, - y: this.position.y, - radius: 40, - color: "rgba(0,80,80,0.3)", - time: simulation.drawTime - }); - } - } else { - this.endCycle = 0; - if (tech.isFlechetteExplode && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.97) { - this.explodeRad = 300 + 60 * Math.random(); - b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end - } - who.foundPlayer(); - if (tech.isFastDot) { - mobs.statusDoT(who, 4, 30) - } else { - mobs.statusDoT(who, 0.7, tech.isSlowDot ? 360 : 180) - } - simulation.drawList.push({ //add dmg to draw queue - x: this.position.x, - y: this.position.y, - radius: 40, - color: "rgba(0,80,80,0.3)", - 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() {} - } else if (this.speed < 30) { - this.force.y += this.mass * 0.0007; //no gravity until it slows down to improve aiming - } - }; - const SPEED = 50 - Matter.Body.setVelocity(bullet[me], { - x: mech.Vx / 2 + SPEED * Math.cos(angle), - y: mech.Vy / 2 + SPEED * Math.sin(angle) - }); - Matter.Body.setDensity(bullet[me], 0.00001); - World.add(engine.world, bullet[me]); //add bullet to world - } - makeFlechette() - if (tech.isFlechetteMultiShot) { - makeFlechette(mech.angle + 0.02 + 0.005 * Math.random()) - makeFlechette(mech.angle - 0.02 - 0.005 * Math.random()) - } - - const CD = (mech.crouch) ? 40 : 15 - if (this.lastFireCycle + CD < mech.cycle) this.count = 0 //reset count if it cycles past the CD - this.lastFireCycle = mech.cycle - if (this.count > ((mech.crouch) ? 8 : 1)) { - this.count = 0 - mech.fireCDcycle = mech.cycle + Math.floor(CD * b.fireCD); // cool down - } else { - this.count++ - mech.fireCDcycle = mech.cycle + Math.floor(2 * b.fireCD); // cool down - } - } - }, { name: "wave beam", description: "emit a sine wave of oscillating particles
propagates through walls", diff --git a/js/engine.js b/js/engine.js index 8713c40..95b2f52 100644 --- a/js/engine.js +++ b/js/engine.js @@ -108,7 +108,7 @@ function collisionChecks(event) { return } mech.damage(dmg); - if (tech.isPiezo) mech.energy += 2; + if (tech.isPiezo) mech.energy += 4; if (tech.isBayesian) powerUps.ejectTech() if (mob[k].onHit) mob[k].onHit(k); mech.immuneCycle = mech.cycle + tech.collisionImmuneCycles; //player is immune to collision damage for 30 cycles diff --git a/js/level.js b/js/level.js index 28f1ace..06607a5 100644 --- a/js/level.js +++ b/js/level.js @@ -13,13 +13,19 @@ 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(20) + // level.difficultyIncrease(30) // simulation.zoomScale = 1000; // simulation.setZoom(); // mech.setField("plasma torch") - // b.giveGuns("laser") + // b.giveGuns("nail gun") + // tech.giveTech("rivet gun") + // tech.giveTech("needle gun") + // tech.giveTech("supercritical fission") + // tech.giveTech("irradiated nails") + // tech.giveTech("4s half-life") + // tech.giveTech("1/2s half-life") + // tech.isMineSentry = true - // tech.giveTech("diffuse beam") // for (let i = 0; i < 60; i++) tech.giveTech("output coupler") // tech.giveTech("missile-bot") // tech.giveTech("nail-bot") @@ -231,16 +237,16 @@ const level = { spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump // spawn.boost(1500, 0, 900); - // spawn.starter(1900, -500, 200) //big boy + spawn.starter(1900, -500, 200) //big boy // spawn.exploder(2900, -500) // spawn.launcherBoss(1200, -500) // spawn.laserTargetingBoss(1600, -400) // spawn.striker(1600, -500) - spawn.shooter(1700, -120) + // spawn.shooter(1700, -120) // spawn.bomberBoss(1400, -500) // spawn.sniper(1800, -120) // spawn.cellBossCulture(1600, -500) - spawn.streamBoss(1600, -500) + // spawn.streamBoss(1600, -500) // spawn.beamer(1200, -500) // spawn.shield(mob[mob.length - 1], 1800, -120, 1); diff --git a/js/mob.js b/js/mob.js index da8eef1..4cad089 100644 --- a/js/mob.js +++ b/js/mob.js @@ -164,16 +164,16 @@ const mobs = { time: simulation.drawTime }); } - if (true) { - //check for nearby mobs + // if (true) { + // //check for nearby mobs - } + // } }, endEffect() {}, dmg: tickDamage, type: "dot", endCycle: simulation.cycle + cycles, - startCycle: simulation.cycle + startCycle: simulation.cycle + 29 //makes sure it doesn't tick on first application }) } }, diff --git a/js/player.js b/js/player.js index 61484a4..c8af914 100644 --- a/js/player.js +++ b/js/player.js @@ -494,7 +494,7 @@ const mech = { let dmg = 1 dmg *= mech.fieldHarmReduction if (tech.isSpeedHarm) dmg *= 1 - Math.min(player.speed * 0.0185, 0.55) - if (tech.isSlowFPS) dmg *= 0.85 + if (tech.isSlowFPS) dmg *= 0.8 if (tech.isPiezo) dmg *= 0.85 if (tech.isHarmReduce && mech.fieldUpgrades[mech.fieldMode].name === "negative mass field" && mech.isFieldActive) dmg *= 0.6 if (tech.isBotArmor) dmg *= 0.97 ** tech.totalBots() diff --git a/js/simulation.js b/js/simulation.js index ca02be8..8bfd5c5 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -515,6 +515,10 @@ const simulation = { b.removeAllGuns(); simulation.isNoPowerUps = false; tech.setupAllTech(); //sets tech to default values + for (i = 0, len = b.guns.length; i < len; i++) { //find which gun + if (b.guns[i].name === "laser") b.guns[i].chooseFireMethod() + if (b.guns[i].name === "nail gun") b.guns[i].chooseFireMethod() + } tech.laserBotCount = 0; tech.orbitBotCount = 0; tech.nailBotCount = 0; diff --git a/js/spawn.js b/js/spawn.js index 439b304..547f4d6 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -101,24 +101,24 @@ const spawn = { level.exit.x = 5500; level.exit.y = -330; //ramp up damage - // for (let i = 0; i < 2; i++) level.difficultyIncrease(simulation.difficultyMode) + for (let i = 0; i < 3; i++) level.difficultyIncrease(simulation.difficultyMode) //set game to the next highest difficulty level if not on why - if (simulation.difficultyMode < 6) { - if (simulation.difficultyMode === 0) { - simulation.difficultyMode = 1 - } else if (simulation.difficultyMode === 1) { - simulation.difficultyMode = 2 - } else if (simulation.difficultyMode === 2) { - simulation.difficultyMode = 4 - } else { - simulation.difficultyMode = 6 - } - document.getElementById("difficulty-select").value = simulation.difficultyMode - localSettings.difficultyMode = simulation.difficultyMode - localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage - simulation.makeTextLog(`simulation.difficultyMode++`); - } + // if (simulation.difficultyMode < 6) { + // if (simulation.difficultyMode === 0) { + // simulation.difficultyMode = 1 + // } else if (simulation.difficultyMode === 1) { + // simulation.difficultyMode = 2 + // } else if (simulation.difficultyMode === 2) { + // simulation.difficultyMode = 4 + // } else { + // simulation.difficultyMode = 6 + // } + // document.getElementById("difficulty-select").value = simulation.difficultyMode + // localSettings.difficultyMode = simulation.difficultyMode + // localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage + // simulation.makeTextLog(`simulation.difficultyMode++`); + // } //pull in particles for (let i = 0, len = body.length; i < len; ++i) { diff --git a/js/tech.js b/js/tech.js index e7813ff..e1e9688 100644 --- a/js/tech.js +++ b/js/tech.js @@ -109,7 +109,7 @@ const tech = { maxCount: 1, count: 0, allowed() { - return b.inventory.length < 2 + return b.inventory.length < 2 //&& !tech.haveGunCheck("CPT gun") }, requires: "no more than 1 gun", effect() { @@ -364,7 +364,7 @@ const tech = { }, { name: "Higgs mechanism", - description: "movement isn't possible while firing
reduce harm by 60% when firing", + description: "while firing your position is locked
and harm is reduced by 60%", maxCount: 1, count: 0, allowed() { @@ -507,7 +507,7 @@ const tech = { maxCount: 9, count: 0, allowed() { - return tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1 || tech.isFlechetteExplode + return tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1 }, requires: "an explosive damage source", effect: () => { @@ -523,7 +523,7 @@ const tech = { maxCount: 1, count: 0, allowed() { - return tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1 || tech.isFlechetteExplode + return tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1 }, requires: "an explosive damage source", effect: () => { @@ -539,7 +539,7 @@ const tech = { maxCount: 1, count: 0, allowed() { - return tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.isFlechetteExplode + return tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField }, requires: "an explosive damage source", effect: () => { @@ -556,7 +556,7 @@ const tech = { maxCount: 1, count: 0, allowed() { - return tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isMissileField || tech.isExplodeMob || tech.isFlechetteExplode || tech.isPulseLaser + return tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isMissileField || tech.isExplodeMob || tech.isPulseLaser }, requires: "an explosive damage source", effect: () => { @@ -572,7 +572,7 @@ const tech = { maxCount: 1, count: 0, allowed() { - return (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1 || tech.isFlechetteExplode) && !tech.sporesOnDeath && !tech.nailsDeathMob && !tech.isBotSpawner + return (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1) && !tech.sporesOnDeath && !tech.nailsDeathMob && !tech.isBotSpawner }, requires: "an explosive damage source, no other mob death tech", effect: () => { @@ -1136,7 +1136,7 @@ const tech = { }, { name: "clock gating", - description: `slow time by 50% after receiving harm
reduce harm by 15%`, + description: `slow time by 50% after receiving harm
reduce harm by 20%`, maxCount: 1, count: 0, allowed() { @@ -2100,14 +2100,14 @@ const tech = { }, { name: "incendiary ammunition", - description: "some bullets are loaded with explosives
nail gun, shotgun, super balls, drones", + description: "shotgun, super balls, and drones
are loaded with explosives", isGunTech: true, maxCount: 1, count: 0, allowed() { - return ((mech.fieldUpgrades[mech.fieldMode].name === "nano-scale manufacturing" && !(tech.isSporeField || tech.isMissileField || tech.isIceField)) || tech.haveGunCheck("drones") || tech.haveGunCheck("super balls") || tech.haveGunCheck("nail gun") || tech.haveGunCheck("shotgun")) && !tech.isIceCrystals && !tech.isNailCrit && !tech.isNailShot && !tech.isNailPoison + return ((mech.fieldUpgrades[mech.fieldMode].name === "nano-scale manufacturing" && !(tech.isSporeField || tech.isMissileField || tech.isIceField)) || tech.haveGunCheck("drones") || tech.haveGunCheck("super balls") || tech.haveGunCheck("shotgun")) && !tech.isNailShot }, - requires: "drones, super balls, nail gun, shotgun", + requires: "drones, super balls, shotgun", effect() { tech.isIncendiary = true }, @@ -2156,7 +2156,7 @@ const tech = { maxCount: 1, count: 0, allowed() { - return tech.haveGunCheck("flechettes") || tech.isNailPoison || tech.isWormholeDamage || tech.isNeutronBomb + return tech.isNailRadiation || tech.isWormholeDamage || tech.isNeutronBomb }, requires: "radiation damage source", effect() { @@ -2200,6 +2200,91 @@ const tech = { tech.isDamageFromBulletCount = false } }, + { + name: "needle gun", + description: "nail gun slowly fires 3 piercing needles
requires 3 times more ammo", + isGunTech: true, + maxCount: 1, + count: 0, + allowed() { + return tech.haveGunCheck("nail gun") && !tech.nailFireRate && !tech.isIceCrystals + }, + requires: "nail gun, not ice crystal or pneumatic actuator", + effect() { + tech.isNeedles = true + for (i = 0, len = b.guns.length; i < len; i++) { //find which gun + if (b.guns[i].name === "nail gun") { + b.guns[i].ammo = Math.ceil(b.guns[i].ammo / 3); + b.guns[i].ammoPack = Math.ceil(b.guns[i].defaultAmmoPack / 3); + b.guns[i].chooseFireMethod() + simulation.updateGunHUD(); + break + } + } + }, + remove() { + if (tech.isNeedles) { + tech.isNeedles = false + for (i = 0, len = b.guns.length; i < len; i++) { //find which gun + if (b.guns[i].name === "nail gun") { + b.guns[i].chooseFireMethod() + b.guns[i].ammo = Math.ceil(b.guns[i].ammo * 3); + b.guns[i].ammoPack = b.guns[i].defaultAmmoPack; + simulation.updateGunHUD(); + break + } + } + } + } + }, + { + name: "rivet gun", + description: "nail gun slowly fires a heavy rivet", + isGunTech: true, + maxCount: 1, + count: 0, + allowed() { + return tech.haveGunCheck("nail gun") && !tech.nailFireRate && !tech.isIceCrystals + }, + requires: "nail gun, not ice crystal or pneumatic actuator", + effect() { + tech.isRivets = true + for (i = 0, len = b.guns.length; i < len; i++) { //find which gun + if (b.guns[i].name === "nail gun") { + b.guns[i].chooseFireMethod() + break + } + } + }, + remove() { + if (tech.isRivets) { + tech.isRivets = false + for (i = 0, len = b.guns.length; i < len; i++) { //find which gun + if (b.guns[i].name === "nail gun") { + b.guns[i].chooseFireMethod() + break + } + } + } + } + }, + { + name: "rivet diameter", + description: `your rivets are 20% larger
increases mass and physical damage`, + isGunTech: true, + maxCount: 9, + count: 0, + allowed() { + return tech.isRivets + }, + requires: "rivet gun", + effect() { + tech.rivetSize += 0.2 + }, + remove() { + tech.rivetSize = 1; + } + }, { name: "ice crystal nucleation", description: "the nail gun uses energy to condense
unlimited freezing ice shards", @@ -2207,9 +2292,9 @@ const tech = { maxCount: 1, count: 0, allowed() { - return tech.haveGunCheck("nail gun") && !tech.nailInstantFireRate && !tech.isIncendiary + return tech.haveGunCheck("nail gun") && !tech.nailInstantFireRate && !tech.isRivets && !tech.isNeedles && !tech.isNailRadiation && !tech.isNailCrit }, - requires: "nail gun, not incendiary, not powder-actuated", + requires: "nail gun, not powder-actuated, rivets, needles, irradiated, or fission", effect() { tech.isIceCrystals = true; for (i = 0, len = b.guns.length; i < len; i++) { //find which gun @@ -2224,6 +2309,7 @@ const tech = { }, remove() { if (tech.isIceCrystals) { + tech.isIceCrystals = false; for (i = 0, len = b.guns.length; i < len; i++) { //find which gun if (b.guns[i].name === "nail gun") { b.guns[i].ammoPack = b.guns[i].defaultAmmoPack; @@ -2233,24 +2319,6 @@ const tech = { } } } - tech.isIceCrystals = false; - } - }, - { - name: "critical bifurcation", - description: "nail gun nails do 400% more damage
when they strike near the center of a mob", - isGunTech: true, - maxCount: 1, - count: 0, - allowed() { - return tech.haveGunCheck("nail gun") && !tech.isIncendiary - }, - requires: "nail gun, not incendiary", - effect() { - tech.isNailCrit = true - }, - remove() { - tech.isNailCrit = false } }, { @@ -2260,14 +2328,22 @@ const tech = { maxCount: 1, count: 0, allowed() { - return tech.haveGunCheck("nail gun") + return tech.haveGunCheck("nail gun") && !tech.isRivets && !tech.isNeedles }, - requires: "nail gun", + requires: "nail gun, not rivets or needles", effect() { tech.nailFireRate = true + for (i = 0, len = b.guns.length; i < len; i++) { //find which gun + if (b.guns[i].name === "nail gun") b.guns[i].chooseFireMethod() + } }, remove() { - tech.nailFireRate = false + if (tech.nailFireRate) { + tech.nailFireRate = false + for (i = 0, len = b.guns.length; i < len; i++) { //find which gun + if (b.guns[i].name === "nail gun") b.guns[i].chooseFireMethod() + } + } } }, { @@ -2282,9 +2358,85 @@ const tech = { requires: "nail gun and pneumatic actuator", effect() { tech.nailInstantFireRate = true + for (i = 0, len = b.guns.length; i < len; i++) { //find which gun + if (b.guns[i].name === "nail gun") b.guns[i].chooseFireMethod() + } }, remove() { - tech.nailInstantFireRate = false + if (tech.nailInstantFireRate) { + tech.nailInstantFireRate = false + for (i = 0, len = b.guns.length; i < len; i++) { //find which gun + if (b.guns[i].name === "nail gun") b.guns[i].chooseFireMethod() + } + } + } + }, + { + name: "supercritical fission", + description: "nails, needles, and rivets can explode
if they strike mobs near their center", + isGunTech: true, + maxCount: 1, + count: 0, + allowed() { + return tech.haveGunCheck("nail gun") && !tech.isIceCrystals + }, + requires: "nail gun, not ice crystals", + effect() { + tech.isNailCrit = true + }, + remove() { + tech.isNailCrit = false + } + }, + { + name: "irradiated nails", + description: "nails, needles, and rivets are radioactive
about 70% more damage over 2 seconds", + isGunTech: true, + maxCount: 1, + count: 0, + allowed() { + return (tech.isMineDrop + tech.nailBotCount + tech.fragments + tech.nailsDeathMob / 2 + ((tech.haveGunCheck("mine") && !tech.isLaserMine) + tech.isNailShot + tech.haveGunCheck("nail gun")) * 2 > 1) && !tech.isIceCrystals + }, + requires: "nails, not ice crystals", + effect() { + tech.isNailRadiation = true; + }, + remove() { + tech.isNailRadiation = false; + } + }, + { + name: "4s half-life", + description: "nails are made of plutonium-238
increase damage by 100% over 6 seconds", + isGunTech: true, + maxCount: 1, + count: 0, + allowed() { + return tech.isNailRadiation && !tech.isFastRadiation + }, + requires: "irradiated nails", + effect() { + tech.isSlowRadiation = true; + }, + remove() { + tech.isSlowRadiation = false; + } + }, + { + name: "1/2s half-life", + description: "nails are made of lithium-8
flechette damage occurs after 1/2 a second", + isGunTech: true, + maxCount: 1, + count: 0, + allowed() { + return tech.isNailRadiation && !tech.isSlowRadiation + }, + requires: "irradiated nails", + effect() { + tech.isFastRadiation = true; + }, + remove() { + tech.isFastRadiation = false; } }, { @@ -2428,121 +2580,6 @@ const tech = { tech.bulletSize = 1; } }, - { - name: "flechettes cartridges", - description: "flechettes release three needles in each shot
ammo costs are tripled", - isGunTech: true, - maxCount: 1, - count: 0, - allowed() { - return tech.haveGunCheck("flechettes") - }, - requires: "flechettes", - effect() { - tech.isFlechetteMultiShot = true; - //cut current ammo by 1/3 - for (i = 0, len = b.guns.length; i < len; i++) { //find which gun - if (b.guns[i].name === "flechettes") { - b.guns[i].ammo = Math.ceil(b.guns[i].ammo / 3); - break - } - } - //cut ammo packs by 1/3 - for (i = 0, len = b.guns.length; i < len; i++) { //find which gun - if (b.guns[i].name === "flechettes") { - b.guns[i].ammoPack = Math.ceil(b.guns[i].defaultAmmoPack / 3); - break - } - } - simulation.updateGunHUD(); - }, - remove() { - if (tech.isFlechetteMultiShot) { - for (i = 0, len = b.guns.length; i < len; i++) { //find which gun - if (b.guns[i].name === "flechettes") { - b.guns[i].ammo = Math.ceil(b.guns[i].ammo * 3); - break - } - } - for (i = 0, len = b.guns.length; i < len; i++) { //find which gun - if (b.guns[i].name === "flechettes") { - b.guns[i].ammoPack = b.guns[i].defaultAmmoPack; - break - } - simulation.updateGunHUD(); - } - } - tech.isFlechetteMultiShot = false; - } - }, - { - name: "6s half-life", - description: "flechette needles made of plutonium-238
increase damage by 100% over 6 seconds", - isGunTech: true, - maxCount: 1, - count: 0, - allowed() { - return tech.haveGunCheck("flechettes") && !tech.isFastDot - }, - requires: "flechettes", - effect() { - tech.isSlowDot = true; - }, - remove() { - tech.isSlowDot = false; - } - }, - { - name: "1/2s half-life", - description: "flechette needles made of lithium-8
flechette damage occurs after 1/2 a second", - isGunTech: true, - maxCount: 1, - count: 0, - allowed() { - return tech.haveGunCheck("flechettes") && !tech.isSlowDot - }, - requires: "flechettes", - effect() { - tech.isFastDot = true; - }, - remove() { - tech.isFastDot = false; - } - }, - { - name: "supercritical fission", - description: "flechettes can explode
if they strike mobs near their center", - isGunTech: true, - maxCount: 1, - count: 0, - allowed() { - return tech.haveGunCheck("flechettes") && !tech.pierce - }, - requires: "flechettes and not piercing needles", - effect() { - tech.isFlechetteExplode = true - }, - remove() { - tech.isFlechetteExplode = false - } - }, - { - name: "piercing needles", - description: "needles penetrate mobs and blocks
potentially hitting multiple targets", - isGunTech: true, - maxCount: 1, - count: 0, - allowed() { - return tech.haveGunCheck("flechettes") && !tech.isFlechetteExplode - }, - requires: "flechettes and not supercritical fission", - effect() { - tech.pierce = true; - }, - remove() { - tech.pierce = false; - } - }, { name: "wave packet", description: "wave beam emits two oscillating particles
decrease wave damage by 20%", @@ -2550,7 +2587,7 @@ const tech = { maxCount: 1, count: 0, allowed() { - return tech.haveGunCheck("wave beam") && !tech.isExtruder + return tech.haveGunCheck("wave beam") }, requires: "wave beam", effect() { @@ -2567,7 +2604,7 @@ const tech = { maxCount: 1, count: 0, allowed() { - return tech.haveGunCheck("wave beam") && !tech.isWaveReflect && !tech.isExtruder + return tech.haveGunCheck("wave beam") && !tech.isWaveReflect }, requires: "wave beam", effect() { @@ -2586,7 +2623,7 @@ const tech = { maxCount: 1, count: 0, allowed() { - return tech.haveGunCheck("wave beam") && tech.waveSpeedMap !== 3 && !tech.isExtruder + return tech.haveGunCheck("wave beam") && tech.waveSpeedMap !== 3 }, requires: "wave beam", effect() { @@ -2790,40 +2827,6 @@ const tech = { tech.isMineSentry = false; } }, - { - name: "irradiated nails", - description: "nails are made with a cobalt-60 alloy
85% radioactive damage over 2 seconds", - isGunTech: true, - maxCount: 1, - count: 0, - allowed() { - return tech.isMineDrop + tech.nailBotCount + tech.fragments + tech.nailsDeathMob / 2 + ((tech.haveGunCheck("mine") && !tech.isLaserMine) + tech.isNailShot + (tech.haveGunCheck("nail gun") && !tech.isIncendiary)) * 2 > 1 - }, - requires: "nails", - effect() { - tech.isNailPoison = true; - }, - remove() { - tech.isNailPoison = false; - } - }, - { - name: "railroad ties", - description: "nails are 40% larger
increases physical damage by about 20%", - isGunTech: true, - maxCount: 1, - count: 0, - allowed() { - return tech.isMineDrop + tech.nailBotCount + tech.fragments + tech.nailsDeathMob / 2 + ((tech.haveGunCheck("mine") && !tech.isLaserMine) + tech.isNailShot + (tech.haveGunCheck("nail gun") && !tech.isIncendiary)) * 2 > 1 - }, - requires: "nails", - effect() { - tech.biggerNails += 0.33 - }, - remove() { - tech.biggerNails = 1 - } - }, { name: "mycelial fragmentation", description: "sporangium release an extra spore
once a second during their growth phase", @@ -3153,9 +3156,11 @@ const tech = { } }, remove() { - tech.beamSplitter = 0 - for (i = 0, len = b.guns.length; i < len; i++) { //find which gun - if (b.guns[i].name === "laser") b.guns[i].chooseFireMethod() + if (tech.beamSplitter !== 0) { + tech.beamSplitter = 0 + for (i = 0, len = b.guns.length; i < len; i++) { //find which gun + if (b.guns[i].name === "laser") b.guns[i].chooseFireMethod() + } } } }, @@ -3177,10 +3182,12 @@ const tech = { } }, remove() { - tech.wideLaser = 0 - tech.isWideLaser = false; - for (i = 0, len = b.guns.length; i < len; i++) { //find which gun - if (b.guns[i].name === "laser") b.guns[i].chooseFireMethod() + if (tech.isWideLaser) { + tech.wideLaser = 0 + tech.isWideLaser = false; + for (i = 0, len = b.guns.length; i < len; i++) { //find which gun + if (b.guns[i].name === "laser") b.guns[i].chooseFireMethod() + } } } }, @@ -3230,9 +3237,11 @@ const tech = { }, remove() { // this.description = "laser beam is spread into your recent past
increase total beam damage by 300%" - tech.historyLaser = 0 - for (i = 0, len = b.guns.length; i < len; i++) { //find which gun - if (b.guns[i].name === "laser") b.guns[i].chooseFireMethod() + if (tech.historyLaser) { + tech.historyLaser = 0 + for (i = 0, len = b.guns.length; i < len; i++) { //find which gun + if (b.guns[i].name === "laser") b.guns[i].chooseFireMethod() + } } } }, @@ -3253,9 +3262,11 @@ const tech = { } }, remove() { - tech.isPulseLaser = false; - for (i = 0, len = b.guns.length; i < len; i++) { //find which gun - if (b.guns[i].name === "laser") b.guns[i].chooseFireMethod() + if (tech.isPulseLaser) { + tech.isPulseLaser = false; + for (i = 0, len = b.guns.length; i < len; i++) { //find which gun + if (b.guns[i].name === "laser") b.guns[i].chooseFireMethod() + } } } }, @@ -3768,7 +3779,7 @@ const tech = { }, { name: "discrete optimization", - description: "increase damage by 50%
50% increased delay after firing", + description: "increase damage by 66%
50% increased delay after firing", isFieldTech: true, maxCount: 1, count: 0, @@ -3777,7 +3788,7 @@ const tech = { }, requires: "metamaterial cloaking", effect() { - tech.aimDamage = 1.5 + tech.aimDamage = 1.66 b.setFireCD(); }, remove() { @@ -3998,7 +4009,6 @@ const tech = { isSporeField: null, isMissileField: null, isIceField: null, - isFlechetteMultiShot: null, isMineAmmoBack: null, isPlasmaRange: null, isFreezeMobs: null, @@ -4015,7 +4025,7 @@ const tech = { isBotSpawner: null, waveHelix: null, isSporeFollow: null, - isNailPoison: null, + isNailRadiation: null, isEnergyHealth: null, isPulseStun: null, restDamage: null, @@ -4035,7 +4045,7 @@ const tech = { fastTime: null, squirrelJump: null, fastTimeJump: null, - isFastDot: null, + isFastRadiation: null, isArmorFromPowerUps: null, isAmmoForGun: null, isRapidPulse: null, @@ -4134,5 +4144,7 @@ const tech = { isTechDamage: null, isFireNotMove: null, isRestHarm: null, - isFireMoveLock: null + isFireMoveLock: null, + isRivets: null, + isNeedles: null } \ No newline at end of file diff --git a/todo.txt b/todo.txt index 871c13f..d2fc1dd 100644 --- a/todo.txt +++ b/todo.txt @@ -1,12 +1,31 @@ ******************************************************** NEXT PATCH ******************************************************** +damage immunity graphic is more obvious +difficulty mode no longer increases after killing final boss (it was too confusing) + tech: Higgs mechanism - you can't move when firing, reduce harm by 60% when firing removed Galilean group -damage immunity graphic is more obvious +removed gun flechettes +removed critical bifrication +removed railroad ties +removed incendiary (for nail gun) + +nail gun: + needle gun: accurate, piercing mobs, fire 3 at a time + rivet gun: accurate, ballistic arc, doesn't use much ammo + tech: bigger rivets (9x stack) + all nails + radioactive 2s tick (about 70% damage increase) + 0.5s full tick + 4s longer tick + critical hits -> explosion (from flechettes) ******************************************************** BUGS ******************************************************** +Laser+slow light prop+crouch= all but one laser stays in original position + log crouch state and apply that to laser, rewind + CPT check for crouch after rewind (always) make it so that when you are immune to harm you can either jump on mobs or you pass through them @@ -24,12 +43,16 @@ CPT check for crouch after rewind ******************************************************** TODO ******************************************************** -tech: nail gun no longer ramps up in speed, nail gun fires slugs (like the shotgun) +tech: increase maxHealth by 100%, but you can no longer see your health -tech: you are unable to move while firing - float in mid air +modify tech: increase squirrel cage speed, but also increase harm taken by 5-10% -tech: can't fire while moving, get attack speed and damage +tech: explosions are radioactive + +tech: double your rerolls + set your duplication chance to zero + requires 5 rerolls and 20% duplication chance + might want to use a single variable for all duplication bot that follows the players history could have the same shape as the mech circle head