From 343486998989d7165c4054187e4d41b4a4537860 Mon Sep 17 00:00:00 2001 From: landgreen Date: Fri, 29 Jul 2022 10:08:10 -0700 Subject: [PATCH] ricochet tech: ricochet - nails bounce off mobs and hit other mobs with extra damage per ricochet tech: dye laser - 20% efficiency and 20% damage laser diode renamed infrared diode 40 -> 50% efficiency but you can't see the laser beam laser-bots acquire new targets much faster iridescence 88 -> 100% damage, a tiny bit harder to hit center of mobs stacks up to 3 -> 9 dynamic equilibrium scales damage with defense goes up to 9x stacks neutronium 25 -> 20% slower movement revolutionBoss laser swords are much slower and shorter but they do more damage --- .DS_Store | Bin 6148 -> 6148 bytes js/bullet.js | 71 +++++++++---- js/level.js | 27 ++--- js/powerup.js | 2 +- js/spawn.js | 26 ++--- js/tech.js | 279 ++++++++++++++++++++++---------------------------- todo.txt | 39 ++++--- 7 files changed, 221 insertions(+), 223 deletions(-) diff --git a/.DS_Store b/.DS_Store index 32b9bd676a56e05e6b5b8fdc81a31b91f77d7bbc..30e823962341dd7aa850bd52acb75046be0dd090 100644 GIT binary patch delta 21 ccmZoMXffEJ#mqFfX|fKpALEA2)y$nD08P{e_5c6? delta 21 ccmZoMXffEJ#muz)&}1EEKSqJg)y$nD08N$#pa1{> diff --git a/js/bullet.js b/js/bullet.js index ae94732..1ad5f6e 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -1964,7 +1964,6 @@ const b = { mob[i].alive && !mob[i].isBadTarget && Matter.Query.ray(map, this.position, mob[i].position).length === 0 && !mob[i].isInvulnerable - // && Matter.Query.ray(body, this.position, mob[i].position).length === 0 ) { const futureDist = Vector.magnitude(Vector.sub(futurePos, mob[i].position)); if (futureDist < closeDist) { @@ -2327,7 +2326,7 @@ const b = { if (best.who.damageReduction) { if ( //iridescence tech.laserCrit && !best.who.shield && - Vector.dot(Vector.normalise(Vector.sub(best.who.position, path[path.length - 1])), Vector.normalise(Vector.sub(path[path.length - 1], path[path.length - 2]))) > 0.995 - 0.6 / best.who.radius + Vector.dot(Vector.normalise(Vector.sub(best.who.position, path[path.length - 1])), Vector.normalise(Vector.sub(path[path.length - 1], path[path.length - 2]))) > 0.997 - 0.6 / best.who.radius ) { damage *= 1 + tech.laserCrit simulation.drawList.push({ //add dmg to draw queue @@ -2449,7 +2448,7 @@ const b = { dmg: 0, // 0.14 //damage done in addition to the damage from momentum minDmgSpeed: 2, lookFrequency: 67 + Math.floor(7 * Math.random()), - drain: 0.7 * tech.isLaserDiode * tech.laserFieldDrain, + drain: 0.7 * tech.laserDrain, isDetonated: false, torqueMagnitude: 0.000003 * (Math.round(Math.random()) ? 1 : -1), range: 1500, @@ -3958,7 +3957,33 @@ const b = { b.explosion(this.position, 150 + 30 * Math.random()); //makes bullet do explosive damage at end } } + this.ricochet(who) }; + bullet[me].ricochet = function(who) { //use for normal nails, and ice crystal nails + if (tech.isRicochet) { + const targets = [] //target nearby mobs + for (let i = 0, len = mob.length; i < len; i++) { + const dist = Vector.magnitude(Vector.sub(this.position, mob[i].position)); + if ( + mob[i] !== who && + dist < 2500 + mob[i].radius && + !mob[i].isBadTarget && //|| mob[i].isMobBullet + !mob[i].isInvulnerable && + Matter.Query.ray(body, this.position, mob[i].position).length === 0 && + Matter.Query.ray(map, this.position, mob[i].position).length === 0 + ) { + targets.push(Vector.add(mob[i].position, Vector.mult(mob[i].velocity, dist / 60))) //predict where the mob will be in a few cycles + } + } + if (targets.length > 0) { // aim near a random target in array + const index = Math.floor(Math.random() * targets.length) + Matter.Body.setVelocity(this, Vector.mult(Vector.normalise(Vector.sub(targets[index], this.position)), 45)); + Matter.Body.setAngle(this, Math.atan2(this.velocity.y, this.velocity.x)) + Matter.Body.setAngularVelocity(this, 0); + } + this.dmg += 2 + } + } bullet[me].do = function() {}; }, needle(angle = m.angle) { @@ -4590,10 +4615,10 @@ const b = { offPlayer: { x: 0, y: 0, }, dmg: 0, //damage done in addition to the damage from momentum minDmgSpeed: 2, - lookFrequency: 40 + Math.floor(7 * Math.random()) - 13 * tech.isLaserBotUpgrade, + lookFrequency: 20 + Math.floor(7 * Math.random()) - 13 * tech.isLaserBotUpgrade, range: (700 + 500 * tech.isLaserBotUpgrade) * (1 + 0.1 * Math.random()), drainThreshold: tech.isEnergyHealth ? 0.6 : 0.4, - drain: (0.5 - 0.44 * tech.isLaserBotUpgrade) * tech.laserFieldDrain * tech.isLaserDiode, + drain: (0.5 - 0.44 * tech.isLaserBotUpgrade) * tech.laserDrain, laserDamage: 0.85 + 0.8 * tech.isLaserBotUpgrade, endCycle: Infinity, classType: "bullet", @@ -5375,6 +5400,7 @@ const b = { b.explosion(this.position, 150 + 30 * Math.random()); //makes bullet do explosive damage at end } } + this.ricochet(who) }; if (m.energy < 0.01) { m.fireCDcycle = m.cycle + 60; // cool down @@ -6950,7 +6976,7 @@ const b = { } ctx.beginPath(); ctx.arc(m.pos.x, m.pos.y, 60, this.angle - this.arcRange, this.angle + this.arcRange); - ctx.strokeStyle = '#fff' //'rgba(255,255,255,0.9)' //'hsl(189, 100%, 95%)' //tech.laserColor + ctx.strokeStyle = '#fff' //'rgba(255,255,255,0.9)' //'hsl(189, 100%, 95%)' ctx.stroke(); // const a = { x: radius * Math.cos(this.angle + this.arcRange), y: radius * Math.sin(this.angle + this.arcRange) } // const b = Vector.add(m.pos, a) @@ -6962,7 +6988,7 @@ const b = { if (tech.isStuckOn) { if (this.isStuckOn) { if (!input.fire) this.fire(); - if (m.energy < tech.laserFieldDrain * tech.isLaserDiode) this.isStuckOn = false + if (m.energy < tech.laserDrain) this.isStuckOn = false } else if (input.fire) { this.isStuckOn = true } @@ -6979,7 +7005,7 @@ const b = { } if (tech.isPulseLaser) { this.fire = () => { - const drain = 0.01 * tech.isLaserDiode * (tech.isCapacitor ? 10 : 1) + const drain = 0.01 * (tech.isCapacitor ? 10 : 1) / b.fireCDscale if (m.energy > drain) { // m.energy -= m.fieldRegen if (this.charge < 50 * m.maxEnergy) { @@ -7003,7 +7029,7 @@ const b = { ctx.moveTo(history.position.x, history.position.y - off); ctx.ellipse(history.position.x, history.position.y - off, mag, mag * 0.65, history.angle, 0, 2 * Math.PI) } - ctx.fillStyle = tech.isLaserDiode === 1 ? `rgba(255,0,0,${0.09 * Math.sqrt(this.charge)})` : `rgba(0,0,255,${0.09 * Math.sqrt(this.charge)})`; + ctx.fillStyle = `rgba(255,0,0,${0.09 * Math.sqrt(this.charge)})`; ctx.fill(); //fire if (!input.fire) { @@ -7027,7 +7053,7 @@ const b = { ctx.beginPath(); ctx.arc(m.pos.x, m.pos.y, 4.2 * Math.sqrt(this.charge), 0, 2 * Math.PI); // ctx.fillStyle = `rgba(255,0,0,${0.09 * Math.sqrt(this.charge)})`; - ctx.fillStyle = tech.isLaserDiode === 1 ? `rgba(255,0,0,${0.09 * Math.sqrt(this.charge)})` : `rgba(0,0,255,${0.09 * Math.sqrt(this.charge)})`; + ctx.fillStyle = `rgba(255,0,0,${0.09 * Math.sqrt(this.charge)})`; ctx.fill(); //fire if (!input.fire) { @@ -7063,11 +7089,12 @@ const b = { // b.photon({ x: m.pos.x + 23 * Math.cos(m.angle), y: m.pos.y + 23 * Math.sin(m.angle) }, m.angle) // }, fireLaser() { - if (m.energy < tech.laserFieldDrain) { + const drain = m.fieldRegen + tech.laserDrain / b.fireCDscale + if (m.energy < drain) { m.fireCDcycle = m.cycle + 100; // cool down if out of energy } else { m.fireCDcycle = m.cycle - m.energy -= m.fieldRegen + tech.laserFieldDrain * tech.isLaserDiode / b.fireCDscale + m.energy -= drain const where = { x: m.pos.x + 20 * Math.cos(m.angle), y: m.pos.y + 20 * Math.sin(m.angle) @@ -7080,11 +7107,12 @@ const b = { }, firePulse() {}, fireSplit() { - if (m.energy < tech.laserFieldDrain) { + const drain = m.fieldRegen + tech.laserDrain / b.fireCDscale + if (m.energy < drain) { m.fireCDcycle = m.cycle + 100; // cool down if out of energy } else { m.fireCDcycle = m.cycle - m.energy -= m.fieldRegen + tech.laserFieldDrain * tech.isLaserDiode / b.fireCDscale + m.energy -= drain // const divergence = input.down ? 0.15 : 0.2 // const scale = Math.pow(0.9, tech.beamSplitter) // const pushScale = scale * scale @@ -7104,11 +7132,12 @@ const b = { } }, fireWideBeam() { - if (m.energy < tech.laserFieldDrain) { + const drain = m.fieldRegen + tech.laserDrain / b.fireCDscale + if (m.energy < drain) { m.fireCDcycle = m.cycle + 100; // cool down if out of energy } else { m.fireCDcycle = m.cycle - m.energy -= m.fieldRegen + tech.laserFieldDrain * tech.isLaserDiode / b.fireCDscale + m.energy -= drain const range = { x: 5000 * Math.cos(m.angle), y: 5000 * Math.sin(m.angle) @@ -7132,9 +7161,6 @@ const b = { ctx.globalAlpha = 0.5; ctx.beginPath(); if (Matter.Query.ray(map, eye, where).length === 0 && Matter.Query.ray(body, eye, where).length === 0) { - // this.isInsideArc(m.angle) ? 8 : 3 - - //where = {x: m.pos.x + 20 * Math.cos(m.angle),y: m.pos.y + 20 * Math.sin(m.angle)}, whereEnd = {x: where.x + 3000 * Math.cos(m.angle),y: where.y + 3000 * Math.sin(m.angle)}, dmg = tech.laserDamage, reflections = tech.laserReflections, isThickBeam = false, push = 1) { b.laser(eye, { x: eye.x + range.x, y: eye.y + range.y @@ -7171,13 +7197,14 @@ const b = { } }, fireHistory() { - if (m.energy < tech.laserFieldDrain) { + drain = m.fieldRegen + tech.laserDrain / b.fireCDscale + if (m.energy < drain) { m.fireCDcycle = m.cycle + 100; // cool down if out of energy } else { m.fireCDcycle = m.cycle - m.energy -= m.fieldRegen + tech.laserFieldDrain * tech.isLaserDiode / b.fireCDscale + m.energy -= drain const dmg = 0.4 * tech.laserDamage / b.fireCDscale * this.lensDamage // 3.5 * 0.55 = 200% more damage - const spacing = Math.ceil(4 - 0.3 * tech.historyLaser) + const spacing = Math.ceil(5 - 0.4 * tech.historyLaser) ctx.beginPath(); b.laser({ x: m.pos.x + 20 * Math.cos(m.angle), diff --git a/js/level.js b/js/level.js index 24611e4..868f44e 100644 --- a/js/level.js +++ b/js/level.js @@ -16,7 +16,7 @@ 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(4 * 4) //30 is near max on hard //60 is near max on why + // level.difficultyIncrease(6 * 4) //30 is near max on hard //60 is near max on why // simulation.isHorizontalFlipped = true // m.maxHealth = m.health = 100 // powerUps.research.changeRerolls(100000) @@ -24,20 +24,21 @@ const level = { // powerUps.research.changeRerolls(100) // tech.tech[297].frequency = 100 // b.guns[0].ammo = 10000 - // m.setField("negative mass") //molecular assembler time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass - // b.giveGuns("nail gun") //0 nail gun 1 shotgun 2 super balls 3 matter wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser - // tech.giveTech("dynamic equilibrium") - // tech.giveTech("quantum eraser"); - // tech.giveTech("patch"); - // tech.giveTech("polyurethane foam") - // for (let i = 0; i < 100; ++i) tech.giveTech("nail-bot") - // for (let i = 0; i < 1; ++i) tech.giveTech("electric generator") - // for (let i = 0; i < 9; i++) tech.giveTech("compound lens") + // m.setField("molecular assembler") //molecular assembler time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass + // b.giveGuns("laser") //0 nail gun 1 shotgun 2 super balls 3 matter wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser + // tech.giveTech("infrared diode"); + // tech.giveTech("active cooling"); + // tech.giveTech("pulse") + // for (let i = 0; i < 1; ++i) tech.giveTech("slow light") + // for (let i = 0; i < 1; ++i) tech.giveTech("free-electron laser") + // m.damage(0.1); + // for (let i = 0; i < 1; i++) tech.giveTech("dynamic equilibrium") // for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "tech"); // for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "research"); - // spawn.starter(1900, -500, 100) - // spawn.snakeBoss(1900, -500) - // for (let i = 0; i < 10; ++i) spawn.grower(1900, -500) + // spawn.starter(1900, -500, 200) + // spawn.starter(1900, -500, 50) + // spawn.revolutionBoss(1900, -500) + // for (let i = 0; i < 10; ++i) spawn.starter(1900 + 300 * Math.random(), -500 + 300 * Math.random()) // level.testing(); //not in rotation, used for testing // for (let i = 0; i < 7; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "research"); // for (let i = 0; i < 4; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "tech"); diff --git a/js/powerup.js b/js/powerup.js index 9ed1b0f..8bf17d4 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -284,7 +284,7 @@ const powerUps = { // } // requestAnimationFrame(cycle); - document.getElementById("choose-grid").style.opacity = "0.8" + document.getElementById("choose-grid").style.opacity = "0.9" } else { simulation.paused = true; document.getElementById("choose-grid").style.opacity = "1" diff --git a/js/spawn.js b/js/spawn.js index 6c63036..10420fb 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -3621,11 +3621,11 @@ const spawn = { mobs.spawn(x, y, sides, radius, "rgb(201,202,225)"); let me = mob[mob.length - 1]; Matter.Body.rotate(me, 2 * Math.PI * Math.random()); - me.accelMag = 0.00038 * Math.sqrt(simulation.accelScale); + me.accelMag = 0.00018 + 0.00018 * Math.sqrt(simulation.accelScale); me.frictionAir = 0.01; - me.swordRadiusMax = 550 + 10 * simulation.difficulty; + me.swordRadiusMax = 400 + 10 * simulation.difficulty; me.laserAngle = 0; - me.swordDamage = 0.0025 * simulation.dmgScale + me.swordDamage = 0.025 * simulation.dmgScale //0.033 * simulation.dmgScale; previous //0.14 * simulation.dmgScale;laserBoss // spawn.shield(me, x, y, 1); Matter.Body.setDensity(me, 0.005); //extra dense //normal is 0.001 //makes effective life much larger @@ -3652,7 +3652,7 @@ const spawn = { if (this.isInvulnerable) { if (this.invulnerabilityCountDown > 0) { this.invulnerabilityCountDown-- - //graphics //draw a super shield? + //draw invulnerability ctx.beginPath(); let vertices = this.vertices; ctx.moveTo(vertices[0].x, vertices[0].y); @@ -3673,7 +3673,7 @@ const spawn = { this.seePlayerByHistory(60); this.attraction(); //traveling laser - this.laserAngle += this.isInvulnerable ? 0.06 : 0.015 + this.laserAngle += this.isInvulnerable ? 0.025 : 0.006 for (let i = 0, len = this.vertices.length; i < len; i++) { // this.laserSword(this.vertices[1], this.angle + laserAngle); const bend = bendFactor * Math.cos(this.laserAngle + 2 * Math.PI * i / len) @@ -3710,15 +3710,15 @@ const spawn = { vertexCollision(where, look, map); if (!m.isCloak) vertexCollision(where, look, [playerBody, playerHead]); if (best.who && (best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) { - // m.immuneCycle = m.cycle + tech.collisionImmuneCycles + 60; //player is immune to damage for an extra second + m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage for an extra second m.damage(this.swordDamage); - // simulation.drawList.push({ //add dmg to draw queue - // x: best.x, - // y: best.y, - // radius: this.swordDamage * 1500, - // color: "rgba(80,0,255,0.5)", - // time: 20 - // }); + simulation.drawList.push({ //add dmg to draw queue + x: best.x, + y: best.y, + radius: this.swordDamage * 1500, + color: "rgba(80,0,255,0.5)", + time: 20 + }); } if (best.dist2 === Infinity) best = look; ctx.beginPath(); //draw beam diff --git a/js/tech.js b/js/tech.js index 81a0312..f84c784 100644 --- a/js/tech.js +++ b/js/tech.js @@ -253,7 +253,7 @@ const tech = { if (m.isSneakAttack && m.sneakAttackCycle + Math.min(120, 0.5 * (m.cycle - m.enterCloakCycle)) > m.cycle) dmg *= tech.sneakAttackDmg if (tech.isAxion && tech.isHarmMACHO) dmg *= 2 - m.harmReduction() if (tech.isHarmDamage && m.lastHarmCycle + 600 > m.cycle) dmg *= 3; - if (tech.isLastHitDamage && m.lastHit) dmg *= 1 + 10 * m.lastHit // if (!simulation.paused) m.lastHit = 0 + if (tech.lastHitDamage && m.lastHit) dmg *= 1 + tech.lastHitDamage * m.lastHit * (2 - m.harmReduction()) // if (!simulation.paused) m.lastHit = 0 return dmg * tech.slowFire * tech.aimDamage }, duplicationChance() { @@ -397,9 +397,6 @@ const tech = { }, { name: "arsenal", - // descriptionFunction() { - // return `increase damage by ${14 * b.inventory.length}%
14% for each gun in your inventory` - // }, description: "for each gun in your inventory
+13% damage", maxCount: 1, count: 0, @@ -439,7 +436,7 @@ const tech = { { name: "integrated armament", link: `integrated armament`, - description: `increase damage by 25%, but new guns
replace your current gun and convert guntech
`, + description: `+25% damage, but new guns
replace your current gun and convert guntech
`, maxCount: 1, count: 0, frequency: 1, @@ -780,7 +777,6 @@ const tech = { { name: "kinetic bombardment", description: "damage is proportional to mob distance
up to +33% damage at 3000 displacement", - // description: "increase damage by up to 33% at a distance
of up to 50 player widths from the target", maxCount: 1, count: 0, frequency: 1, @@ -1022,7 +1018,7 @@ const tech = { }, { name: "anticorrelation", - description: "increase damage by 100%
after not using your gun or field for 2 seconds", + description: "+100% damage
after not using your gun or field for 2 seconds", maxCount: 1, count: 0, frequency: 1, @@ -1161,7 +1157,7 @@ const tech = { { name: "foam-bot upgrade", link: `foam-bot upgrade`, - description: "convert your bots to foam-bots
300% increased foam size and fire rate", + description: "convert your bots to foam-bots
+300% foam size and fire rate", maxCount: 1, count: 0, frequency: 3, @@ -1217,7 +1213,7 @@ const tech = { { name: "boom-bot upgrade", link: `boom-bot upgrade`, - description: "convert your bots to boom-bots
300% increased explosion damage and size", + description: "convert your bots to boom-bots
+300% explosion damage and size", maxCount: 1, count: 0, frequency: 3, @@ -1275,7 +1271,7 @@ const tech = { { name: "laser-bot upgrade", link: `laser-bot upgrade`, - description: "convert your bots to laser-bots
100% improved damage, efficiency, and range", // 400% increased laser-bot laser damage", + description: "convert your bots to laser-bots
+100% damage, efficiency, and range", maxCount: 1, count: 0, frequency: 3, @@ -1331,7 +1327,7 @@ const tech = { { name: "orbital-bot upgrade", link: `orbital-bot upgrade`, - description: "convert your bots to orbital-bots
increase damage by 300% and radius by 50%", + description: "convert your bots to orbital-bots
+300% orbital damage and +50% radius", maxCount: 1, count: 0, frequency: 3, @@ -2229,6 +2225,7 @@ const tech = { name: "1st ionization energy", link: `1st ionization energy`, description: `after you collect ${powerUps.orb.heal()}
+10 maximum energy`, + description: `convert ${powerUps.orb.heal()} into

give +10 maximum energy`, maxCount: 1, count: 0, frequency: 2, @@ -3129,8 +3126,8 @@ const tech = { frequencyDefault: 1, isNonRefundable: true, // isJunk: true, - allowed() { return true }, - requires: "", + allowed() { return !tech.isDeterminism }, + requires: "not determinism", effect() { tech.tooManyTechChoices = 1 // for (let i = 0; i < this.bonusResearch; i++) powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false); @@ -3229,7 +3226,6 @@ const tech = { }, { 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: "+34% damage
time can't be paused (time can be dilated)", maxCount: 1, count: 0, @@ -3894,6 +3890,27 @@ const tech = { tech.bulletSize = 1; } }, + { + name: "ricochet", + description: "after nails hit a mob they rebound towards
a new mob with +180% damage per bounce", + isGunTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + // return (tech.haveGunCheck("nail gun") && !tech.isRivets && !tech.isNeedles) || (tech.haveGunCheck("mines")) + return tech.isMineDrop || tech.isNailBotUpgrade || tech.fragments || tech.nailsDeathMob || (tech.haveGunCheck("mine") && !tech.isLaserMine) || (tech.haveGunCheck("nail gun") && !tech.isRivets && !tech.isNeedles) || (tech.haveGunCheck("shotgun") && (tech.isNeedles || tech.isNailShot)) + }, + // + requires: "nail gun, not rotary cannon, rivets, or needles", + effect() { + tech.isRicochet = true + }, + remove() { + tech.isRicochet = false + } + }, { name: "pneumatic actuator", description: "nail gun takes no time to ramp up
to its fastest fire rate", @@ -5026,7 +5043,7 @@ const tech = { }, { name: "vacuum permittivity", - description: "increase radioactive range by 20%
objects in range of the bomb are slowed", + description: "+20% radioactive range
objects in range of the bomb are slowed", isGunTech: true, maxCount: 1, count: 0, @@ -5918,7 +5935,6 @@ const tech = { descriptionFunction() { return `+${(10 * Math.sqrt(b.guns[9].ammo)).toFixed(0)}% harpoon size and damage
(1/10 √ harpoon ammo)` }, - // description: "increase the size of your harpoon
by 10% of √ of harpoon ammo", isGunTech: true, maxCount: 1, count: 0, @@ -5983,7 +5999,6 @@ const tech = { descriptionFunction() { return `+${(b.guns[9].ammo).toFixed(0)}% harpoon rope length
(1/80 of harpoon ammo)` }, - // description: "increase the length of your harpoon's rope
by 1% per harpoon ammo", isGunTech: true, maxCount: 1, count: 0, @@ -6036,7 +6051,7 @@ const tech = { effect() { let techGiven = 0 for (let j = 0; j < 3; j++) { - const names = ["lens", "compound lens", "arc length", "laser diode", "free-electron laser", "relativistic momentum", "specular reflection", "diffraction grating", "diffuse beam", "output coupler", "slow light", "laser-bot", "laser-bot upgrade"] + const names = ["lens", "compound lens", "arc length", "infrared diode", "free-electron laser", "dye laser", "relativistic momentum", "specular reflection", "diffraction grating", "diffuse beam", "output coupler", "slow light", "laser-bot", "laser-bot upgrade"] //convert names into indexes const options = [] for (let i = 0; i < names.length; i++) { @@ -6082,54 +6097,6 @@ const tech = { tech.isStuckOn = false } }, - { - name: "laser diode", - description: "+40% laser energy efficiency", - isGunTech: true, - maxCount: 1, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return (tech.haveGunCheck("laser") || tech.isLaserBotUpgrade || tech.isLaserMine) && tech.laserDamage === 0.18 - }, - requires: "laser, not free-electron", - effect() { - tech.isLaserDiode = 0.6; //100%-40% - tech.laserColor = "rgb(0, 11, 255)" - tech.laserColorAlpha = "rgba(0, 11, 255,0.5)" - }, - remove() { - tech.isLaserDiode = 1; - tech.laserColor = "#f02" - tech.laserColorAlpha = "rgba(255, 0, 0, 0.5)" - } - }, - { - name: "free-electron laser", - description: "+225% laser damage
–250% laser energy efficiency", - isGunTech: true, - maxCount: 1, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return (tech.haveGunCheck("laser") || tech.isLaserMine || tech.isLaserBotUpgrade) && !tech.isPulseLaser && tech.isLaserDiode === 1 - }, - requires: "laser, not pulse, diodes", - effect() { - tech.laserFieldDrain = 0.0063 //base is 0.002 - tech.laserDamage = 0.52; //base is 0.16, 0.16 * (1 + 2.25) - tech.laserColor = "#83f" - tech.laserColorAlpha = "rgba(136, 51, 255,0.5)" - }, - remove() { - tech.laserFieldDrain = 0.0018; - tech.laserDamage = 0.18; //used in check on pulse and diode: tech.laserDamage === 0.18 - tech.laserColor = "#f00" - tech.laserColorAlpha = "rgba(255, 0, 0, 0.5)" - } - }, { name: "relativistic momentum", description: "lasers push mobs and blocks", @@ -6152,9 +6119,9 @@ const tech = { { name: "iridescence", // description: "if a laser hits a mob at a low angle of illumination
+66% laser damage", - description: "if laser beams hit mobs near their center
+88% laser damage", + description: "if laser beams hit mobs near their center
+100% laser damage", isGunTech: true, - maxCount: 3, + maxCount: 9, count: 0, frequency: 2, frequencyDefault: 2, @@ -6163,7 +6130,7 @@ const tech = { }, requires: "laser, not pulse", effect() { - tech.laserCrit += 0.88; + tech.laserCrit += 1; }, remove() { tech.laserCrit = 0; @@ -6215,58 +6182,6 @@ const tech = { b.guns[11].lensDamageOn = 2.5 } }, - // { - // name: "lens", - // // description: "+150% laser gun damage if it passes
through a revolving +90° arc circular lens", //π / 2 - // descriptionFunction() { - // if (this.count) { - // return `+70% lens damage
+20° arc circular lens` - // } else { - // return `+150% laser gun damage if it passes
through a revolving 90° arc circular lens` - // } - // }, - // isGunTech: true, - // maxCount: 3, - // count: 0, - // frequency: 2, - // frequencyDefault: 2, - // allowed() { - // return tech.haveGunCheck("laser") - // }, - // requires: "laser", - // effect() { - // tech.isLaserLens = true - // if (this.count) { - // b.guns[11].lensDamageOn += 0.7 - // b.guns[11].arcRange += 20 * Math.PI / 180 - // } else [ - // b.guns[11].lensDamageOn = 2.5 // 100% + 150% - // ] - // b.guns[11].chooseFireMethod() - // }, - // remove() { - // tech.isLaserLens = false - // b.guns[11].arcRange = 90 * Math.PI / 180 - // b.guns[11].chooseFireMethod() - // } - // }, - // { - // name: "arc length", - // description: "increase the circular arc of your laser lens
by +π / 4", - // isGunTech: true, - // maxCount: 3, - // count: 0, - // frequency: 2, - // frequencyDefault: 2, - // allowed() { - // return tech.isLaserLens && tech.haveGunCheck("laser") - // }, - // requires: "laser gun, lens", - // effect() { - // }, - // remove() { - // } - // }, { name: "specular reflection", description: "+2 laser beam reflections", @@ -6378,13 +6293,85 @@ const tech = { b.guns[11].chooseFireMethod() }, remove() { - // this.description = "laser beam is spread into your recent past
increase total beam damage by 300%" if (tech.historyLaser) { tech.historyLaser = 0 b.guns[11].chooseFireMethod() } } }, + { + name: "infrared diode", + description: "+50% laser energy efficiency
infrared light is outside visual perception", + isGunTech: true, + maxCount: 1, + count: 0, + frequency: 1, + frequencyDefault: 1, + allowed() { + return (tech.haveGunCheck("laser") || tech.isLaserBotUpgrade || tech.isLaserMine) && !tech.isPulseLaser && tech.laserDrain === 0.0018 + }, + requires: "laser, not free-electron", + effect() { + tech.laserDrain *= 0.5; //100%-50% + tech.laserColor = "transparent" //"rgb(255,0,20,0.02)" + // tech.laserColorAlpha = "rgba(255,0,20,0.05)" + }, + remove() { + tech.laserDrain = 0.0018; + tech.laserColor = "#f02" + tech.laserColorAlpha = "rgba(255, 0, 0, 0.5)" + } + }, + { + name: "dye laser", + description: "+20% laser energy efficiency
+20% laser damage", + isGunTech: true, + maxCount: 1, + count: 0, + frequency: 1, + frequencyDefault: 1, + allowed() { + return (tech.haveGunCheck("laser") || tech.isLaserMine || tech.isLaserBotUpgrade) && !tech.isPulseLaser && tech.laserDrain === 0.0018 + }, + requires: "laser, not pulse, infrared diode", + effect() { + tech.laserDrain *= 0.8 + tech.laserDamage *= 1 + 0.2 + tech.laserColor = "rgb(0, 11, 255)" + tech.laserColorAlpha = "rgba(0, 11, 255,0.5)" + }, + remove() { + tech.laserDrain = 0.0018; + tech.laserDamage = 0.18; //used in check on pulse and diode: tech.laserDamage === 0.18 + tech.laserColor = "#f00" + tech.laserColorAlpha = "rgba(255, 0, 0, 0.5)" + } + }, + { + name: "free-electron laser", + description: "–250% laser energy efficiency
+190% laser damage", + isGunTech: true, + maxCount: 1, + count: 0, + frequency: 1, + frequencyDefault: 1, + allowed() { + return (tech.haveGunCheck("laser") || tech.isLaserMine || tech.isLaserBotUpgrade) && !tech.isPulseLaser && tech.laserDrain === 0.0018 + }, + requires: "laser, not pulse, infrared diode", + effect() { + tech.laserDrain *= 1 + 2.5 //250% more drain + tech.laserDamage *= 1 + 1.9 //190% more damage + tech.laserColor = "#83f" + tech.laserColorAlpha = "rgba(136, 51, 255,0.5)" + }, + remove() { + tech.laserDrain = 0.0018; + tech.laserDamage = 0.18; //used in check on pulse and diode: tech.laserDamage === 0.18 + tech.laserColor = "#f00" + tech.laserColorAlpha = "rgba(255, 0, 0, 0.5)" + } + }, { name: "pulse", description: "charge your energy and release it as a
laser pulse that initiates an explosion cluster", @@ -6394,7 +6381,7 @@ const tech = { frequency: 2, frequencyDefault: 2, allowed() { - return tech.haveGunCheck("laser") && tech.laserReflections < 3 && !tech.isWideLaser && tech.laserDamage === 0.18 && !tech.isStuckOn + return tech.haveGunCheck("laser") && tech.laserReflections < 3 && !tech.isWideLaser && tech.laserDrain === 0.0018 && !tech.isStuckOn }, requires: "laser gun, not specular reflection, diffuse, free-electron laser, optical amplifier", effect() { @@ -6661,10 +6648,10 @@ const tech = { }, { name: "dynamic equilibrium", - descriptionFunction() { return `increase damage by 10%
of your last ${tech.isEnergyHealth ? "energy" : "health"} loss` }, - // description: `increase damage by 500%
of your last health loss`, + descriptionFunction() { return `increase damage by your defense times
5% of your last ${tech.isEnergyHealth ? "energy" : "health"} loss   (+${(100*tech.lastHitDamage * m.lastHit * (2 - m.harmReduction())).toFixed(0)}% damage)` }, // = +${10*m.harmReduction()}% + // descriptionFunction() { return `increase damage by your last ${tech.isEnergyHealth ? "energy" : "health"} loss
(${(tech.lastHitDamage).toFixed(0)}%)(${(100*m.lastHit).toFixed(0)} ${tech.isEnergyHealth ? "energy" : "health"})(${2 - m.harmReduction()} defense) = ${(100*tech.lastHitDamage * m.lastHit * (2 - m.harmReduction())).toFixed(0)}% damage ` }, // = +${10*m.harmReduction()}% isFieldTech: true, - maxCount: 1, + maxCount: 9, count: 0, frequency: 2, frequencyDefault: 2, @@ -6673,15 +6660,15 @@ const tech = { }, requires: "negative mass, pilot wave, not patch", effect() { - tech.isLastHitDamage = true; + tech.lastHitDamage += 5; }, remove() { - tech.isLastHitDamage = false; + tech.lastHitDamage = 0; } }, { name: "neutronium", - description: `move and jump 25% slower
if your field is active +90% defense`, + description: `move and jump 20% slower
if your field is active +90% defense`, isFieldTech: true, maxCount: 1, count: 0, @@ -6693,8 +6680,8 @@ const tech = { requires: "negative mass, not mass-energy", effect() { tech.isNeutronium = true - tech.baseFx *= 0.75 - tech.baseJumpForce *= 0.75 + tech.baseFx *= 0.8 + tech.baseJumpForce *= 0.8 m.setMovement() }, //also removed in m.setHoldDefaults() if player switches into a bad field @@ -7066,7 +7053,6 @@ const tech = { name: "plasma jet", link: `plasma jet`, description: `use ${powerUps.orb.research(2)}
+50% plasma torch range`, - // description: "use 1 research to
increase plasma torch's range by 50%", isFieldTech: true, maxCount: 1, count: 0, @@ -7358,7 +7344,7 @@ const tech = { frequency: 2, frequencyDefault: 2, allowed() { - return m.fieldUpgrades[m.fieldMode].name === "metamaterial cloaking" && !tech.isLastHitDamage && !tech.isEnergyHealth + return m.fieldUpgrades[m.fieldMode].name === "metamaterial cloaking" && !tech.lastHitDamage && !tech.isEnergyHealth }, requires: "metamaterial cloaking, not dynamic equilibrium, mass-energy", effect() { @@ -7410,7 +7396,6 @@ const tech = { { name: "dynamical systems", description: `use ${powerUps.orb.research(2)}
+35% damage`, - // description: "use 1 research
increase your damage by 35%", isFieldTech: true, maxCount: 1, count: 0, @@ -7452,25 +7437,6 @@ const tech = { b.setFireCD(); } }, - // { - // name: "potential well", - // description: "the force that pilot wave generates
to trap blocks is greatly increased", - // isFieldTech: true, - // maxCount: 1, - // count: 0, - // frequency: 2, - // frequencyDefault: 2, - // allowed() { - // return m.fieldUpgrades[m.fieldMode].name === "pilot wave" - // }, - // requires: "pilot wave", - // effect() { - // tech.pilotForce = 0.0006 - // }, - // remove() { - // tech.pilotForce = 0.00002 - // } - // }, { name: "WIMPs", description: `at the end of each level spawn ${powerUps.orb.research(5)}
and a harmful particle that slowly chases you`, @@ -7934,7 +7900,6 @@ const tech = { }, requires: "", effect() { - // level.levelsCleared = 0 //increases chance of power ups spawns, so shouldn't reset level.difficultyDecrease(simulation.difficultyMode * 2) level.onLevel = 0 simulation.clearNow = true //end current level @@ -10266,7 +10231,6 @@ const tech = { oneSuperBall: null, laserReflections: null, laserDamage: null, - laserFieldDrain: null, isAmmoFromHealth: null, mobSpawnWithHealth: null, isEnergyRecovery: null, @@ -10303,7 +10267,7 @@ const tech = { isNeutronStun: null, isAnsatz: null, isDamageFromBulletCount: null, - isLaserDiode: null, + laserDrain: null, isNailShot: null, slowFire: null, fastTime: null, @@ -10551,5 +10515,6 @@ const tech = { isSporeColony: null, isExtraBotOption: null, isLastHitDamage: null, - isCloakHealLastHit: null + isCloakHealLastHit: null, + isRicochet: null } \ No newline at end of file diff --git a/todo.txt b/todo.txt index 536ca39..2d0622a 100644 --- a/todo.txt +++ b/todo.txt @@ -1,23 +1,24 @@ ******************************************************** NEXT PATCH ************************************************** -field tech: patch - after cloaking recover 75% of last health lost using that much energy - taking damage now forces decloaking -field tech: dynamic equilibrium - increase damage by 5% the value of your last health loss +tech: ricochet - nails bounce off mobs and hit other mobs with extra damage per ricochet -foam has less velocity after a mob it's stuck to dies -snakeBoss becomes vulnerable if you remove any of the first 3 body segments - body segments have more health +tech: dye laser - 20% efficiency and 20% damage +laser diode renamed infrared diode + 40 -> 50% efficiency but you can't see the laser beam +laser-bots acquire new targets much faster +iridescence 88 -> 100% damage, a tiny bit harder to hit center of mobs + stacks up to 3 -> 9 -bug fix: quantum eraser now removes mobs in a more random order - it used to have a too low chance to remove bosses +dynamic equilibrium scales damage with defense + goes up to 9x stacks +neutronium 25 -> 20% slower movement + +revolutionBoss laser swords are much slower and shorter + but they do more damage *********************************************************** TODO ***************************************************** -labs room: - low gravity zone - a button that toggles it on/off - -boss mechanics +mob mechanics bullets hit player and stay attached for 4-5 seconds, slowing player hopperBullets? black hole sucker effect on tail @@ -25,10 +26,14 @@ boss mechanics draw pair of circles at 2 different locations, like beetle wings flapping draw as ellipse damage player if caught in wings - -tech: ricochet after nails do damage, the nail fires at a different nearby mobs - can reuse some targeted nail code - don't target 'who' you just damaged + vines + attached to map and grows, a series of spheres connected by vines + if node dies it's removed from tree + vine do + keeps track of connection tree + nested object with nesting to show connection + spawns new nodes + draws connections as quad lines tech: You can place an extra perfect diamagnatism field on the map