diff --git a/.DS_Store b/.DS_Store index 1f2ebdb..af8396e 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/js/bullet.js b/js/bullet.js index 6ff8f8b..0c568e9 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -225,8 +225,9 @@ const b = { }, fireCDscale: 1, setFireCD() { - b.fireCDscale = tech.fireRate * tech.slowFire * tech.researchHaste * tech.aimDamage / tech.fastTime - if (tech.isFireRateForGuns) b.fireCDscale *= Math.pow(0.86, b.inventory.length) + b.fireCDscale = tech.fireRate * tech.slowFire * tech.researchHaste * tech.aimDamage + if (tech.isFastTime) b.fireCDscale *= 0.5 + if (tech.isFireRateForGuns) b.fireCDscale *= Math.pow(0.85, b.inventory.length) if (tech.isFireMoveLock) b.fireCDscale *= 0.5 }, fireAttributes(dir, rotate = true) { @@ -1517,7 +1518,7 @@ const b = { }); if (tech.isLaserPush) { //push mobs away const index = path.length - 1 - const force = Vector.mult(Vector.normalise(Vector.sub(path[index], path[Math.max(0, index - 1)])), 0.003 * push * Math.min(6, best.who.mass)) + const force = Vector.mult(Vector.normalise(Vector.sub(path[index], path[Math.max(0, index - 1)])), 0.0035 * push * Math.min(6, best.who.mass)) Matter.Body.applyForce(best.who, path[index], force) } } @@ -3443,7 +3444,7 @@ const b = { for (let i = 0; i < q.length; i++) { if (!q[i].isShielded) { mobs.statusStun(q[i], 180) - const dmg = 0.5 * b.dmgScale * (this.isUpgraded ? 3 : 1) * (tech.isCrit ? 4 : 1) + const dmg = 0.5 * b.dmgScale * (this.isUpgraded ? 3.5 : 1) * (tech.isCrit ? 4 : 1) q[i].damage(dmg); q[i].foundPlayer(); simulation.drawList.push({ //add dmg to draw queue @@ -3711,13 +3712,16 @@ const b = { knock = 0.1 } - if (tech.isShotgunRecoil) { + if (tech.isShotgunReversed) { + player.force.x += 2 * knock * Math.cos(m.angle) + player.force.y += 2 * knock * Math.sin(m.angle) - 6 * player.mass * simulation.g + } else if (tech.isShotgunRecoil) { m.fireCDcycle -= 0.66 * (45 * b.fireCDscale) player.force.x -= 2 * knock * Math.cos(m.angle) - player.force.y -= 2 * knock * Math.sin(m.angle) //reduce knock back in vertical direction to stop super jumps + player.force.y -= 2 * knock * Math.sin(m.angle) } else { player.force.x -= knock * Math.cos(m.angle) - player.force.y -= knock * Math.sin(m.angle) * 0.3 //reduce knock back in vertical direction to stop super jumps + player.force.y -= knock * Math.sin(m.angle) * 0.5 //reduce knock back in vertical direction to stop super jumps } b.muzzleFlash(35); @@ -3727,7 +3731,7 @@ const b = { const dir = m.angle + 0.02 * (Math.random() - 0.5) bullet[me] = Bodies.rectangle(m.pos.x + 35 * Math.cos(m.angle), m.pos.y + 35 * Math.sin(m.angle), 60, 27, b.fireAttributes(dir)); - Matter.Body.setDensity(bullet[me], 0.007); + Matter.Body.setDensity(bullet[me], 0.007 * (tech.isShotgunReversed ? 1.6 : 1)); World.add(engine.world, bullet[me]); //add bullet to world const SPEED = (m.crouch ? 45 : 35) + Math.random() * 6 Matter.Body.setVelocity(bullet[me], { @@ -3792,7 +3796,7 @@ const b = { y: speed * Math.sin(dirOff) }); bullet[me].onEnd = function() { - b.explosion(this.position, 135 + (Math.random() - 0.5) * 40); //makes bullet do explosive damage at end + b.explosion(this.position, 135 * (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 @@ -3802,6 +3806,7 @@ const b = { } } else if (tech.isNailShot) { spread *= 0.65 + const dmg = 1.4 * (tech.isShotgunReversed ? 1.6 : 1) if (m.crouch) { for (let i = 0; i < 17; i++) { speed = 38 + 15 * Math.random() @@ -3813,7 +3818,7 @@ const b = { b.nail(pos, { x: speed * Math.cos(dir), y: speed * Math.sin(dir) - }, 1.4) + }, dmg) } } else { for (let i = 0; i < 17; i++) { @@ -3826,7 +3831,7 @@ const b = { b.nail(pos, { x: speed * Math.cos(dir), y: speed * Math.sin(dir) - }, 1.4) + }, dmg) } } } else { @@ -3843,6 +3848,7 @@ const b = { }); bullet[me].endCycle = simulation.cycle + 40 bullet[me].minDmgSpeed = 15 + if (tech.isShotgunReversed) Matter.Body.setDensity(bullet[me], 0.0016) // bullet[me].restitution = 0.4 bullet[me].frictionAir = 0.034; bullet[me].do = function() { @@ -3922,38 +3928,45 @@ const b = { fireQueue() { const SPEED = m.crouch ? 43 : 36 const dir = m.angle - const x = m.pos.x + 30 * Math.cos(m.angle) - const y = m.pos.y + 30 * Math.sin(m.angle) + const x = m.pos.x + const y = m.pos.y const delay = Math.floor((m.crouch ? 18 : 12) * b.fireCDscale) m.fireCDcycle = m.cycle + delay; // cool down - for (let i = 0; i < tech.superBallNumber; i++) { - setTimeout(() => { - if (!simulation.paused) { - const me = bullet.length; - bullet[me] = Bodies.polygon(x, y, 12, 11 * tech.bulletSize, b.fireAttributes(dir, false)); - World.add(engine.world, bullet[me]); //add bullet to world - Matter.Body.setVelocity(bullet[me], { - x: SPEED * Math.cos(dir), - y: SPEED * Math.sin(dir) - }); - bullet[me].endCycle = simulation.cycle + Math.floor(330 * tech.isBulletsLastLonger); - bullet[me].minDmgSpeed = 0; - bullet[me].restitution = 0.99; - bullet[me].friction = 0; - bullet[me].do = function() { - this.force.y += this.mass * 0.001; - }; - bullet[me].beforeDmg = function() { - if (tech.isIncendiary) { - b.explosion(this.position, this.mass * 350 + 60 * Math.random()); //makes bullet do explosive damage at end - this.endCycle = 0 - } - }; - m.fireCDcycle = m.cycle + delay; // cool down + const fireBall = () => { + const me = bullet.length; + bullet[me] = Bodies.polygon(x, y, 12, 11 * tech.bulletSize, b.fireAttributes(dir, false)); + World.add(engine.world, bullet[me]); //add bullet to world + Matter.Body.setVelocity(bullet[me], { + x: SPEED * Math.cos(dir), + y: SPEED * Math.sin(dir) + }); + bullet[me].endCycle = simulation.cycle + Math.floor(330 * tech.isBulletsLastLonger); + bullet[me].minDmgSpeed = 0; + bullet[me].restitution = 0.99; + bullet[me].friction = 0; + bullet[me].do = function() { + this.force.y += this.mass * 0.001; + }; + bullet[me].beforeDmg = function() { + if (tech.isIncendiary) { + b.explosion(this.position, this.mass * 350 + 60 * Math.random()); //makes bullet do explosive damage at end + this.endCycle = 0 } - }, 50 * i + 100); + }; + m.fireCDcycle = m.cycle + delay; // cool down } + + function cycle() { + if (simulation.paused || m.isBodiesAsleep) { requestAnimationFrame(cycle) } else { + count++ + if (count % 2) fireBall() + if (count < tech.superBallNumber * 2 && m.alive) requestAnimationFrame(cycle); + } + } + let count = 0 + requestAnimationFrame(cycle); + // fireBall(); }, chooseFireMethod() { //set in simulation.startGame if (tech.oneSuperBall) { @@ -4702,7 +4715,7 @@ const b = { }); //knock back - const KNOCK = m.crouch ? 0.08 : 0.34 + const KNOCK = (m.crouch ? 0.08 : 0.34) * (tech.isShotgunReversed ? -2 : 1) player.force.x -= KNOCK * Math.cos(m.angle) player.force.y -= KNOCK * Math.sin(m.angle) * 0.35 //reduce knock back in vertical direction to stop super jumps @@ -4714,9 +4727,6 @@ const b = { const me = bullet.length; bullet[me] = Bodies.rectangle(0, 0, 0.015, 0.0015, { density: 0.008, //0.001 is normal - //frictionAir: 0.01, //restitution: 0, - // angle: 0, - // friction: 0.5, restitution: 0, frictionAir: 0, dmg: 0, //damage done in addition to the damage from momentum @@ -4738,7 +4748,6 @@ const b = { x: -0.5 * this.velocity.x, y: -0.5 * this.velocity.y }); - // Matter.Body.setDensity(this, 0.001); } if (tech.fragments && this.speed > 10) { b.targetedNail(this.position, tech.fragments * 20) @@ -4781,7 +4790,7 @@ const b = { }); //knock back - const KNOCK = ((m.crouch) ? 0.1 : 0.5) * this.charge * this.charge + const KNOCK = ((m.crouch) ? 0.1 : 0.5) * this.charge * this.charge * (tech.isShotgunReversed ? -2 : 1) player.force.x -= KNOCK * Math.cos(m.angle) player.force.y -= KNOCK * Math.sin(m.angle) * 0.35 //reduce knock back in vertical direction to stop super jumps pushAway(1200 * this.charge) diff --git a/js/level.js b/js/level.js index 22e8661..813aaaa 100644 --- a/js/level.js +++ b/js/level.js @@ -15,8 +15,10 @@ const level = { // level.difficultyIncrease(30) // simulation.isHorizontalFlipped = true // m.setField("wormhole") - // b.giveGuns("laser") - // tech.giveTech("laser diode") + // b.giveGuns("shotgun") + // tech.isShotgunRecoil = true + // tech.isShotgunReversed = true + // tech.giveTech("supertemporal") // tech.giveTech("free-electron laser") // for (let i = 0; i < 9; i++) tech.giveTech("spherical harmonics") // tech.giveTech("decoherence") @@ -2265,7 +2267,7 @@ const level = { // spawn.laser(1200, -500) // spawn.shield(mob[mob.length - 1], 1800, -120, 1); - spawn.nodeGroup(1200, -500, "grenadier") + // spawn.nodeGroup(1200, -500, "grenadier") // spawn.snakeBoss(1200, -500) // spawn.suckerBoss(2900, -500) // spawn.randomMob(1600, -500) @@ -2616,10 +2618,9 @@ const level = { // localSettings.levelsClearedLastGame = 20 if (level.levelsCleared === 0) { - // powerUps.spawn(-100, 0, "heal", false); //starting gun - powerUps.spawn(1900, -150, "heal", false); //starting gun - powerUps.spawn(2050, -150, "heal", false); //starting gun - // powerUps.spawn(2050, -150, "field", false); //starting gun + powerUps.spawn(2500, -50, "research", false); + powerUps.spawn(1900, -50, "heal", false); + powerUps.spawn(2050, -50, "heal", false); if (localSettings.levelsClearedLastGame < 6) { if (!simulation.isCheating && !m.isShipMode) { spawn.wireFoot(); @@ -2632,7 +2633,7 @@ const level = { simulation.trails() } } - powerUps.spawnStartingPowerUps(2300, -150); + powerUps.spawnStartingPowerUps(2300, -50); }, testChamber() { level.setPosToSpawn(0, -50); //lower start diff --git a/js/mob.js b/js/mob.js index 7d4d598..58acfa0 100644 --- a/js/mob.js +++ b/js/mob.js @@ -1074,12 +1074,12 @@ const mobs = { } if (tech.isBotSpawnerReset) { for (let i = 0, len = bullet.length; i < len; i++) { - if (bullet[i].botType && bullet[i].endCycle !== Infinity) bullet[i].endCycle = simulation.cycle + 660 //10 seconds and 1 extra second for fun + if (bullet[i].botType && bullet[i].endCycle !== Infinity) bullet[i].endCycle = simulation.cycle + 840 //14 seconds } } if (Math.random() < tech.botSpawner) { b.randomBot(this.position, false) - bullet[bullet.length - 1].endCycle = simulation.cycle + 660 //10 seconds and 1 extra second for fun + bullet[bullet.length - 1].endCycle = simulation.cycle + 840 //14 seconds this.leaveBody = false; // no body since it turned into the bot } } else if (tech.isShieldAmmo && this.shield && !this.isExtraShield) { diff --git a/js/player.js b/js/player.js index 9a84530..df0d6a7 100644 --- a/js/player.js +++ b/js/player.js @@ -75,8 +75,8 @@ const m = { Fx: 0.016, //run Force on ground // jumpForce: 0.42, setMovement() { - m.Fx = 0.016 * tech.squirrelFx * tech.fastTime; - m.jumpForce = 0.42 * tech.squirrelJump * tech.fastTimeJump; + m.Fx = 0.016 * tech.squirrelFx * (tech.isFastTime ? 1.5 : 1); + m.jumpForce = 0.42 * tech.squirrelJump * (tech.isFastTime ? 1.13 : 1) }, FxAir: 0.016, // 0.4/5/5 run Force in Air yOff: 70, @@ -490,19 +490,20 @@ const m = { harmReduction() { let dmg = 1 dmg *= m.fieldHarmReduction + if (tech.isFieldHarmReduction) dmg *= 0.5 if (tech.isHarmMACHO) dmg *= 0.33 if (tech.isImmortal) dmg *= 0.66 if (tech.isHarmReduceAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 0.33 : 1.15 if (tech.healthDrain) dmg *= 1 + 2.667 * tech.healthDrain //tech.healthDrain = 0.03 at one stack //cause more damage if (tech.squirrelFx !== 1) dmg *= 1 + (tech.squirrelFx - 1) / 5 //cause more damage if (tech.isBlockHarm && m.isHolding) dmg *= 0.15 - if (tech.isSpeedHarm) dmg *= 1 - Math.min(player.speed * 0.019, 0.60) + if (tech.isSpeedHarm) dmg *= 1 - Math.min(player.speed * 0.022, 0.66) if (tech.isSlowFPS) dmg *= 0.8 // if (tech.isPiezo) dmg *= 0.85 if (tech.isHarmReduce && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.4 if (tech.isBotArmor) dmg *= 0.93 ** b.totalBots() if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.33; - if (tech.isNoFireDefense && m.cycle > m.fireCDcycle + 120) dmg *= 0.34 + if (tech.isNoFireDefense && m.cycle > m.fireCDcycle + 120) dmg *= 0.3 if (tech.energyRegen === 0) dmg *= 0.34 if (tech.isTurret && m.crouch) dmg *= 0.55; if (tech.isEntanglement && b.inventory[0] === b.activeGun) { @@ -512,7 +513,7 @@ const m = { }, rewind(steps) { // m.rewind(Math.floor(Math.min(599, 137 * m.energy))) if (tech.isRewindGrenade) { - const immunityCycle = m.cycle + 60 + const immunityCycle = m.cycle + 90 if (m.immuneCycle < immunityCycle) m.immuneCycle = immunityCycle; //player is immune to damage until after grenades might explode... for (let i = 1, len = Math.floor(2 + steps / 40); i < len; i++) { @@ -605,7 +606,7 @@ const m = { simulation.fpsInterval = 1000 / simulation.fpsCap; m.defaultFPSCycle = m.cycle if (tech.isRewindBot) { - const len = steps * 0.052 * tech.isRewindBot + const len = steps * 0.07 * tech.isRewindBot const botStep = Math.floor(steps / len) for (let i = 0; i < len; i++) { const where = m.history[Math.abs(m.cycle - i * botStep) % 600].position //spread out spawn locations along past history @@ -975,7 +976,7 @@ const m = { } }, setMaxEnergy() { - m.maxEnergy = (tech.isMaxEnergyTech ? 0.5 : 1) + tech.bonusEnergy + tech.healMaxEnergyBonus + m.maxEnergy = (tech.isMaxEnergyTech ? 0.5 : 1) + tech.bonusEnergy + tech.healMaxEnergyBonus + tech.harmonicEnergy simulation.makeTextLog(`m.maxEnergy = ${(m.maxEnergy.toFixed(2))}`) }, fieldMeterColor: "#0cf", @@ -1655,60 +1656,6 @@ const m = { } } }, - { - name: "nano-scale manufacturing", - description: "excess energy used to build drones
use energy to deflect mobs
double your default energy regeneration", - effect: () => { - // m.fieldMeterColor = "#0c5" - // m.eyeFillColor = m.fieldMeterColor - m.hold = function() { - if (m.energy > m.maxEnergy - 0.02 && m.fieldCDcycle < m.cycle && !input.field && bullet.length < 150 && (m.cycle % 2)) { - if (tech.isSporeField) { - for (let i = 0, len = Math.random() * 20; i < len; i++) { - m.energy -= 0.08 - if (m.energy > 0) { - b.spore(m.pos) - } else { - m.energy = 0.001 - break; - } - } - } else if (tech.isMissileField) { - m.energy -= 0.3; - b.missile({ x: m.pos.x, y: m.pos.y - 40 }, -Math.PI / 2 + 0.5 * (Math.random() - 0.5), 0, 1) - } else if (tech.isIceField) { - m.energy -= 0.04; - b.iceIX(1) - } else if (tech.isDroneRadioactive) { - m.energy -= 1.5; //almost 5x drain of normal drones - b.droneRadioactive({ x: m.pos.x + 30 * Math.cos(m.angle) + 10 * (Math.random() - 0.5), y: m.pos.y + 30 * Math.sin(m.angle) + 10 * (Math.random() - 0.5) }, 25) - } else { - m.energy -= 0.45 * tech.droneEnergyReduction; - b.drone() - } - } - - if (m.isHolding) { - m.drawHold(m.holdingTarget); - m.holding(); - m.throwBlock(); - } else if ((input.field && m.fieldCDcycle < m.cycle)) { //not hold but field button is pressed - m.grabPowerUp(); - m.lookForPickUp(); - if (m.energy > 0.05) { - m.drawField(); - m.pushMobsFacing(); - } - } else if (m.holdingTarget && m.fieldCDcycle < m.cycle) { //holding, but field button is released - m.pickUp(); - } else { - m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists) - } - m.energy += m.fieldRegen; - m.drawFieldMeter() - } - } - }, { name: "negative mass field", description: "use energy to nullify  gravity
reduce harm by 55%
blocks held by the field have a lower mass", @@ -1859,6 +1806,60 @@ const m = { } } }, + { + name: "nano-scale manufacturing", + description: "excess energy used to build drones
use energy to deflect mobs
double your default energy regeneration", + effect: () => { + // m.fieldMeterColor = "#0c5" + // m.eyeFillColor = m.fieldMeterColor + m.hold = function() { + if (m.energy > m.maxEnergy - 0.02 && m.fieldCDcycle < m.cycle && !input.field && bullet.length < 150 && (m.cycle % 2)) { + if (tech.isSporeField) { + for (let i = 0, len = Math.random() * 20; i < len; i++) { + m.energy -= 0.08 + if (m.energy > 0) { + b.spore(m.pos) + } else { + m.energy = 0.001 + break; + } + } + } else if (tech.isMissileField) { + m.energy -= 0.3; + b.missile({ x: m.pos.x, y: m.pos.y - 40 }, -Math.PI / 2 + 0.5 * (Math.random() - 0.5), 0, 1) + } else if (tech.isIceField) { + m.energy -= 0.04; + b.iceIX(1) + } else if (tech.isDroneRadioactive) { + m.energy -= 1.5; //almost 5x drain of normal drones + b.droneRadioactive({ x: m.pos.x + 30 * Math.cos(m.angle) + 10 * (Math.random() - 0.5), y: m.pos.y + 30 * Math.sin(m.angle) + 10 * (Math.random() - 0.5) }, 25) + } else { + m.energy -= 0.45 * tech.droneEnergyReduction; + b.drone() + } + } + + if (m.isHolding) { + m.drawHold(m.holdingTarget); + m.holding(); + m.throwBlock(); + } else if ((input.field && m.fieldCDcycle < m.cycle)) { //not hold but field button is pressed + m.grabPowerUp(); + m.lookForPickUp(); + if (m.energy > 0.05) { + m.drawField(); + m.pushMobsFacing(); + } + } else if (m.holdingTarget && m.fieldCDcycle < m.cycle) { //holding, but field button is released + m.pickUp(); + } else { + m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists) + } + m.energy += m.fieldRegen; + m.drawFieldMeter() + } + } + }, { name: "plasma torch", description: "use energy to emit short range plasma
damages and pushes mobs away", @@ -2020,7 +2021,7 @@ const m = { }, { name: "metamaterial cloaking", //"weak photonic coupling" "electromagnetically induced transparency" "optical non-coupling" "slow light field" "electro-optic transparency" - description: "when not firing activate a cloaking effect
if a mob has not died in the last 4 seconds
increase damage by 300%", + description: "when not firing activate a cloaking effect
if a mob has not died in the last 3 seconds
increase damage by 300%", effect: () => { m.fieldFire = true; m.fieldMeterColor = "#333"; @@ -2031,7 +2032,7 @@ const m = { // m.fieldDamage = 2.46 // 1 + 146/100 m.fieldDrawRadius = 0 m.isSneakAttack = true; - const drawRadius = 1000 + const drawRadius = 1100 m.hold = function() { if (m.isHolding) { @@ -2047,9 +2048,9 @@ const m = { m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists) } - //120 cycles after shooting (or using field) enable cloak + //shooting (or using field) enable cloak if (m.energy < 0.05 && m.fireCDcycle < m.cycle && !input.fire) m.fireCDcycle = m.cycle - if (m.fireCDcycle + 50 < m.cycle && !input.fire) { //automatically cloak if not firing + if (m.fireCDcycle + 30 < m.cycle && !input.fire) { //automatically cloak if not firing if (!m.isCloak) { m.isCloak = true //enter cloak if (tech.isIntangible) { @@ -2161,7 +2162,7 @@ const m = { } //show sneak attack status - if (m.cycle > m.lastKillCycle + 300) { + if (m.cycle > m.lastKillCycle + 240) { ctx.strokeStyle = "rgba(0,0,0,0.4)" //m.fieldMeterColor; //"rgba(255,255,0,0.2)" //ctx.strokeStyle = `rgba(0,0,255,${0.5+0.5*Math.random()})` ctx.beginPath(); ctx.arc(m.pos.x, m.pos.y, 28, 0, 2 * Math.PI); diff --git a/js/spawn.js b/js/spawn.js index c3412de..0ab5db1 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -92,8 +92,8 @@ const spawn = { if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) { spawn.randomLevelBoss(x, y); } else if (tech.isResearchBoss) { - if (powerUps.research.count > 4) { - powerUps.research.changeRerolls(-5) + if (powerUps.research.count > 3) { + powerUps.research.changeRerolls(-4) simulation.makeTextLog(`m.research -= 5
${powerUps.research.count}`) } else { tech.addJunkTechToPool(49) diff --git a/js/tech.js b/js/tech.js index e0fe69f..ccf0d07 100644 --- a/js/tech.js +++ b/js/tech.js @@ -151,6 +151,7 @@ }, damageFromTech() { let dmg = 1 //m.fieldDamage + if (tech.isCloakingDamage) dmg *= 1.35 if (tech.isFlipFlopDamage && tech.isFlipFlopOn) dmg *= 1.45 if (tech.isAnthropicDamage && tech.isDeathAvoidedThisLevel) dmg *= 2.3703599 if (tech.isDamageAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 2 : 0.66 @@ -160,23 +161,23 @@ if (tech.isLowEnergyDamage) dmg *= 1 + Math.max(0, 1 - m.energy) * 0.5 if (tech.isMaxEnergyTech) dmg *= 1.5 if (tech.isEnergyNoAmmo) dmg *= 1.6 - if (tech.isDamageForGuns) dmg *= 1 + 0.12 * b.inventory.length + if (tech.isDamageForGuns) dmg *= 1 + 0.13 * b.inventory.length if (tech.isLowHealthDmg) dmg *= 1 + 0.5 * Math.max(0, 1 - m.health) if (tech.isHarmDamage && m.lastHarmCycle + 600 > m.cycle) dmg *= 3; if (tech.isEnergyLoss) dmg *= 1.55; if (tech.isAcidDmg && m.health > 1) dmg *= 1.35; if (tech.restDamage > 1 && player.speed < 1) dmg *= tech.restDamage if (tech.isEnergyDamage) dmg *= 1 + m.energy / 9; - if (tech.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.0038 + if (tech.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.005 if (tech.isRerollDamage) dmg *= 1 + 0.042 * powerUps.research.count if (tech.isOneGun && b.inventory.length < 2) dmg *= 1.3 - if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 1.9 - if (tech.isSpeedDamage) dmg *= 1 + Math.min(0.43, player.speed * 0.015) + if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 2 + if (tech.isSpeedDamage) dmg *= 1 + Math.min(0.66, player.speed * 0.022) if (tech.isBotDamage) dmg *= 1 + 0.06 * b.totalBots() return dmg * tech.slowFire * tech.aimDamage }, duplicationChance() { - return (tech.isPowerUpsVanish ? 0.2 : 0) + (tech.isStimulatedEmission ? 0.22 : 0) + tech.cancelCount * 0.05 + tech.duplicateChance + m.duplicateChance + return (tech.isPowerUpsVanish ? 0.2 : 0) + (tech.isStimulatedEmission ? 0.22 : 0) + tech.cancelCount * 0.05 + tech.duplicateChance + m.duplicateChance + tech.wormDuplicate }, maxDuplicationEvent() { if (tech.is100Duplicate && tech.duplicationChance() > 0.99) { @@ -247,15 +248,15 @@ }, { name: "arsenal", - description: "increase damage by 12%
for each gun in your inventory", + description: "increase damage by 13%
for each gun in your inventory", maxCount: 1, count: 0, frequency: 2, frequencyDefault: 2, allowed() { - return b.inventory.length > 1 + return b.inventory.length > 0 }, - requires: "at least 2 guns", + requires: "at least 1 gun", effect() { tech.isDamageForGuns = true; }, @@ -265,15 +266,15 @@ }, { name: "active cooling", - description: "14% decreased delay after firing
for each gun in your inventory", + description: "15% decreased delay after firing
for each gun in your inventory", maxCount: 1, count: 0, frequency: 2, frequencyDefault: 2, allowed() { - return b.inventory.length > 1 + return b.inventory.length > 0 }, - requires: "at least 2 guns", + requires: "at least 1 gun", effect() { tech.isFireRateForGuns = true; b.setFireCD(); @@ -517,15 +518,15 @@ }, { name: "Newton's 1st law", - description: "moving at high speeds reduces harm
by up to 60%", + description: "moving at high speeds reduces harm
by up to 66%", maxCount: 1, count: 0, - frequency: 2, - frequencyDefault: 2, + frequency: 1, + frequencyDefault: 1, allowed() { - return m.Fx > 0.016 && !tech.isEnergyHealth + return !tech.isEnergyHealth }, - requires: "speed increase, not mass-energy equivalence", + requires: "not mass-energy equivalence", effect() { tech.isSpeedHarm = true }, @@ -535,15 +536,15 @@ }, { name: "Newton's 2nd law", - description: "moving at high speeds increases damage
by up to 43%", + description: "moving at high speeds increases damage
by up to 66%", maxCount: 1, count: 0, - frequency: 2, - frequencyDefault: 2, + frequency: 1, + frequencyDefault: 1, allowed() { - return m.Fx > 0.016 + return true }, - requires: "speed increase", + requires: "", effect() { tech.isSpeedDamage = true }, @@ -646,15 +647,15 @@ }, { name: "microstates", - description: "increase damage by 4%
for every 10 active bullets", + description: "increase damage by 6%
for every 10 active bullets", maxCount: 1, count: 0, frequency: 2, frequencyDefault: 2, allowed() { - return tech.isBulletsLastLonger > 1 + return true }, - requires: "anti-shear topology", + requires: "", effect() { tech.isDamageFromBulletCount = true }, @@ -964,15 +965,15 @@ }, { name: "decorrelation", - description: "reduce harm by 66% after not activating
your gun or field for 2 seconds", + description: "reduce harm by 70% after not activating
your gun or field for 2 seconds", maxCount: 1, count: 0, - frequency: 2, - frequencyDefault: 2, + frequency: 1, + frequencyDefault: 1, allowed() { - return ((m.fieldUpgrades[m.fieldMode].name === "standing wave harmonics" && (tech.blockingIce !== 0 || tech.blockDmg !== 0)) || b.totalBots() > 1 || tech.haveGunCheck("mine") || tech.haveGunCheck("spores") || m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing") && !tech.isEnergyHealth + return !tech.isEnergyHealth //((m.fieldUpgrades[m.fieldMode].name === "standing wave harmonics" && (tech.blockingIce !== 0 || tech.blockDmg !== 0)) || b.totalBots() > 1 || tech.haveGunCheck("mine") || tech.haveGunCheck("spores") || m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing") && }, - requires: "drones, spores, mines, or bots, ", + requires: "not mass-energy", effect() { tech.isNoFireDefense = true }, @@ -982,7 +983,7 @@ }, { name: "anticorrelation", - description: "increase damage by 90%
after not using your gun or field for 2 seconds", + description: "increase damage by 100%
after not using your gun or field for 2 seconds", maxCount: 1, count: 0, frequency: 2, @@ -1000,7 +1001,7 @@ }, { name: "scrap bots", - description: "33% chance after killing a mob to build
a scrap bot that operates for 10 seconds", + description: "33% chance after killing a mob to build
a scrap bot that operates for 14 seconds", maxCount: 3, count: 0, frequency: 1, @@ -1018,7 +1019,7 @@ }, { name: "scrap refit", - description: "killing a mob resets your functional scrap bots
to 10 seconds of operation", + description: "killing a mob resets your functional scrap bots
to 14 seconds of operation", maxCount: 1, count: 0, frequency: 1, @@ -1257,7 +1258,7 @@ }, { name: "orbital-bot upgrade", - description: "convert all your bots to orbital-bots
increase damage by 200% and radius by 40%", + description: "convert all your bots to orbital-bots
increase damage by 250% and radius by 40%", maxCount: 1, count: 0, frequency: 2, @@ -2129,7 +2130,7 @@ }, { name: "inductive coupling", - description: "each unused power up at the end of a level
adds 3 max energy", // (up to 51 health per level)", + description: "each unused power up at the end of a level
adds 3 maximum energy", // (up to 51 health per level)", maxCount: 1, count: 0, frequency: 1, @@ -2354,7 +2355,7 @@ }, { name: "dormancy", - description: "if a mob has died in the last 5 seconds
increase damage by 100% else decrease it by 33%", + description: "if a mob has died in the last 5 seconds
increase damage by 99% else decrease it by 33%", maxCount: 1, count: 0, frequency: 2, @@ -2852,15 +2853,15 @@ }, { name: "abiogenesis", - description: "at the start of a level spawn a 2nd boss for
5 research or +49 JUNK to the tech pool", + description: "at the start of a level spawn a 2nd boss for
4 research or +49 JUNK to the tech pool", maxCount: 1, count: 0, - frequency: 1, - frequencyDefault: 1, + frequency: 2, + frequencyDefault: 2, allowed() { - return (build.isExperimentSelection || powerUps.research.count > 4) && !tech.isDuplicateBoss + return (build.isExperimentSelection || powerUps.research.count > 3) && !tech.isDuplicateBoss }, - requires: "at least 5 research and not parthenogenesis", + requires: "at least 4 research and not parthenogenesis", effect() { tech.isResearchBoss = true; //abiogenesis }, @@ -3754,16 +3755,16 @@ }, { name: "Newton's 3rd law", - description: "shotgun recoil is greatly increased
and has a 66% decreased delay after firing", + description: "shotgun recoil is increased
decrease shotgun delay after firing by 66%", isGunTech: true, maxCount: 1, count: 0, frequency: 2, frequencyDefault: 2, allowed() { - return tech.haveGunCheck("shotgun") + return tech.haveGunCheck("shotgun") && !tech.isShotgunReversed }, - requires: "shotgun", + requires: "shotgun, not Noether violation", effect() { tech.isShotgunRecoil = true; }, @@ -3771,6 +3772,25 @@ tech.isShotgunRecoil = false; } }, + { + name: "Noether violation", + description: "increase shotgun and rail gun damage 60%
their recoil is increased and reversed", + isGunTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return (tech.haveGunCheck("shotgun") || tech.haveGunCheck("rail gun")) && !tech.isShotgunRecoil + }, + requires: "shotgun or rail gun, not Newton's 3rd law", + effect() { + tech.isShotgunReversed = true; + }, + remove() { + tech.isShotgunReversed = false; + } + }, { name: "super duper", description: "fire 1 additional super ball", @@ -4887,7 +4907,30 @@ //************************************************** field //************************************************** tech //************************************************** - + { + name: "zero point energy", + description: "use 2 research to
increase your maximum energy by 74", + isFieldTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return (m.fieldUpgrades[m.fieldMode].name === "standing wave harmonics" || m.fieldUpgrades[m.fieldMode].name === "pilot wave") && (build.isExperimentSelection || powerUps.research.count > 1) + }, + requires: "standing wave harmonics or pilot wave", + effect() { + tech.harmonicEnergy = 0.74 + m.setMaxEnergy() + for (let i = 0; i < 2; i++) { + if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) + } + }, + remove() { + tech.harmonicEnergy = 0; + m.setMaxEnergy() + } + }, { name: "spherical harmonics", description: "standing wave oscillates in a 3rd dimension
increasing deflecting efficiency by 40%", @@ -5008,6 +5051,104 @@ tech.isPerfectBrake = false; } }, + { + name: "tessellation", + description: "use 4 research
reduce harm by 50%", + isFieldTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return (m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism" || m.fieldUpgrades[m.fieldMode].name === "negative mass field") && (build.isExperimentSelection || powerUps.research.count > 3) + }, + requires: "perfect diamagnetism or negative mass field", + effect() { + tech.isFieldHarmReduction = true + for (let i = 0; i < 4; i++) { + if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) + } + }, + remove() { + tech.isFieldHarmReduction = false + } + }, + { + name: "degenerate matter", + description: "reduce harm by 60% while your field is active", + isFieldTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return (m.fieldUpgrades[m.fieldMode].name === "plasma torch" || m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism" || m.fieldUpgrades[m.fieldMode].name === "pilot wave" || m.fieldUpgrades[m.fieldMode].name === "negative mass field") && !tech.isEnergyHealth + }, + requires: "field: perfect, negative mass, pilot wave, plasma, not mass-energy", + effect() { + tech.isHarmReduce = true + }, + remove() { + tech.isHarmReduce = false; + } + }, + { + name: "annihilation", + description: "touching normal mobs annihilates them
but drains 33% of your maximum energy", + isFieldTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return m.fieldUpgrades[m.fieldMode].name === "negative mass field" + }, + requires: "negative mass field", + effect() { + tech.isAnnihilation = true + }, + remove() { + tech.isAnnihilation = false; + } + }, + { + name: "inertial mass", + description: "negative mass field is larger and faster
blocks also move horizontally with the field", + isFieldTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return m.fieldUpgrades[m.fieldMode].name === "negative mass field" + }, + requires: "negative mass field", + effect() { + tech.isFlyFaster = true + }, + remove() { + tech.isFlyFaster = false; + } + }, + { + name: "Bose Einstein condensate", + description: "mobs inside your field are frozen
pilot wave, negative mass, time dilation", + isFieldTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return m.fieldUpgrades[m.fieldMode].name === "pilot wave" || m.fieldUpgrades[m.fieldMode].name === "negative mass field" || m.fieldUpgrades[m.fieldMode].name === "time dilation" + }, + requires: "pilot wave, negative mass field, time dilation", + effect() { + tech.isFreezeMobs = true + }, + remove() { + tech.isFreezeMobs = false + } + }, { name: "bot manufacturing", description: "use nano-scale manufacturing and 2 research
to build 3 random bots", @@ -5203,82 +5344,6 @@ tech.isMassEnergy = false; } }, - { - name: "degenerate matter", - description: "reduce harm by 60% while your field is active", - isFieldTech: true, - maxCount: 1, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return (m.fieldUpgrades[m.fieldMode].name === "plasma torch" || m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism" || m.fieldUpgrades[m.fieldMode].name === "pilot wave" || m.fieldUpgrades[m.fieldMode].name === "negative mass field") && !tech.isEnergyHealth - }, - requires: "field: perfect, negative mass, pilot wave, plasma, not mass-energy", - effect() { - tech.isHarmReduce = true - }, - remove() { - tech.isHarmReduce = false; - } - }, - { - name: "annihilation", - description: "touching normal mobs annihilates them
but drains 33% of your maximum energy", - isFieldTech: true, - maxCount: 1, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return m.fieldUpgrades[m.fieldMode].name === "negative mass field" - }, - requires: "negative mass field", - effect() { - tech.isAnnihilation = true - }, - remove() { - tech.isAnnihilation = false; - } - }, - { - name: "inertial mass", - description: "negative mass field is larger and faster
blocks also move horizontally with the field", - isFieldTech: true, - maxCount: 1, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return m.fieldUpgrades[m.fieldMode].name === "negative mass field" - }, - requires: "negative mass field", - effect() { - tech.isFlyFaster = true - }, - remove() { - tech.isFlyFaster = false; - } - }, - { - name: "Bose Einstein condensate", - description: "mobs inside your field are frozen
pilot wave, negative mass, time dilation", - isFieldTech: true, - maxCount: 1, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return m.fieldUpgrades[m.fieldMode].name === "pilot wave" || m.fieldUpgrades[m.fieldMode].name === "negative mass field" || m.fieldUpgrades[m.fieldMode].name === "time dilation" - }, - requires: "pilot wave, negative mass field, time dilation", - effect() { - tech.isFreezeMobs = true - }, - remove() { - tech.isFreezeMobs = false - } - }, // { // name: "thermal reservoir", // description: "increase your plasma damage by 100%
plasma temporarily lowers health not energy", @@ -5299,7 +5364,7 @@ // }, { name: "plasma-bot", - description: "a bot uses energy to emit plasma
that damages and pushes mobs", + description: "use 1 research to build a bot
that uses energy to emit plasma", isFieldTech: true, maxCount: 1, count: 0, @@ -5307,12 +5372,15 @@ isBot: true, isBotTech: true, allowed() { - return m.fieldUpgrades[m.fieldMode].name === "plasma torch" + return m.fieldUpgrades[m.fieldMode].name === "plasma torch" && (build.isExperimentSelection || powerUps.research.count > 0) }, requires: "plasma torch", effect() { tech.plasmaBotCount++; b.plasmaBot(); + for (let i = 0; i < 1; i++) { + if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) + } }, remove() { tech.plasmaBotCount = 0; @@ -5400,25 +5468,26 @@ }, { name: "Lorentz transformation", - description: "permanently increase your relative time rate
move, jump, and shoot 40% faster", + description: "use 3 research to increase your time rate
move, jump, and shoot 50% faster", isFieldTech: true, maxCount: 1, count: 0, frequency: 2, frequencyDefault: 2, allowed() { - return m.fieldUpgrades[m.fieldMode].name === "time dilation" + return m.fieldUpgrades[m.fieldMode].name === "time dilation" && (build.isExperimentSelection || powerUps.research.count > 2) }, requires: "time dilation", effect() { - tech.fastTime = 1.40; - tech.fastTimeJump = 1.11; + tech.isFastTime = true m.setMovement(); b.setFireCD(); + for (let i = 0; i < 3; i++) { + if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) + } }, remove() { - tech.fastTime = 1; - tech.fastTimeJump = 1; + tech.isFastTime = false m.setMovement(); b.setFireCD(); } @@ -5482,24 +5551,28 @@ tech.isCloakStun = false; } }, - // { - // name: "combinatorial optimization", - // description: "increase damage by 66%
if a mob has not died in the last 5 seconds", - // isFieldTech: true, - // maxCount: 1, - // count: 0, - // frequency: 2, - // allowed() { - // return m.fieldUpgrades[m.fieldMode].name === "metamaterial cloaking" - // }, - // requires: "metamaterial cloaking or pilot wave", - // effect() { - // tech.isSneakAttack = true; - // }, - // remove() { - // tech.isSneakAttack = false; - // } - // }, + { + name: "dynamical systems", + description: "use 1 research
increase your damage by 35%", + isFieldTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return (m.fieldUpgrades[m.fieldMode].name === "metamaterial cloaking" || m.fieldUpgrades[m.fieldMode].name === "pilot wave") && (build.isExperimentSelection || powerUps.research.count > 0) + }, + requires: "metamaterial cloaking or pilot wave", + effect() { + tech.isCloakingDamage = true + for (let i = 0; i < 1; i++) { + if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) + } + }, + remove() { + tech.isCloakingDamage = false + } + }, { name: "discrete optimization", description: "increase damage by 50%
50% increased delay after firing", @@ -5578,6 +5651,30 @@ tech.isWormholeDamage = false } }, + { + name: "virtual particles", + description: "use 3 research to exploit your wormhole for
19% chance to duplicate spawned power ups", + isFieldTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return m.fieldUpgrades[m.fieldMode].name === "wormhole" && (build.isExperimentSelection || powerUps.research.count > 2) + }, + requires: "wormhole", + effect() { + tech.wormDuplicate = 0.19 + powerUps.setDo(); //needed after adjusting duplication chance + for (let i = 0; i < 3; i++) { + if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) + } + }, + remove() { + tech.wormDuplicate = 0 + powerUps.setDo(); //needed after adjusting duplication chance + } + }, { name: "Penrose process", description: "after a block falls into a wormhole
you gain 63 energy", @@ -7208,7 +7305,6 @@ slowFire: null, fastTime: null, squirrelJump: null, - fastTimeJump: null, isFastRadiation: null, isExtraMaxEnergy: null, isAmmoForGun: null, @@ -7365,5 +7461,11 @@ junkResearchNumber: null, laserColor: null, laserColorAlpha: null, - isLongitudinal: null + isLongitudinal: null, + isShotgunReversed: null, + wormDuplicate: null, + isCloakingDamage: null, + harmonicEnergy: null, + isFieldHarmReduction: null, + isFastTime: null } \ No newline at end of file diff --git a/todo.txt b/todo.txt index d30c193..3a83850 100644 --- a/todo.txt +++ b/todo.txt @@ -1,8 +1,41 @@ ******************************************************** NEXT PATCH ******************************************************** +tech: Noether violation - shotgun and railgun recoil is increased and it's direction is reversed, +60% damage for shot/rail gun + +each field now has a tech that uses research to give a simple bonus + wormhole: virtual particles - 3 research for 19% duplication chance + cloaking field, pilot wave: dynamical systems - 2 research for 35% damage + standing wave harmonics, pilot wave: zero point energy - 2 research for 74% max energy + perfect diamagnetism or negative mass field: tessellation - 50% harm reduction for 4 research cost + time dilation field - Lorentz transformation now uses 4 research for a 50% speed increase (was 40% for no research) + plasma-bot - now also requires 1 research + nano-scale already has several research deals + +added a research to the intro level +Newton's 1st law reduces harm by up to 66% (was 60%) when moving at up to 30 +Newton's 2nd law increases damage by up to 66% (was 43%) when moving at up to 30 + also they both have no requirements anymore +super ball tech supertemporal now fires with much less delay + and it syncs with frame rate much cleaner +metamaterial cloaking + now gets the damage buff after 3 seconds of no kills (was 4s) + recloaks 1/2 second faster + cloaked vision has a 10% larger radius +6 situational tech can now show up in situations where they are only "OK", but not "great" choices ******************************************************** TODO ******************************************************** +undo the research lost when you refund researched tech??? + this only really matters for many worlds type runs, would yield an general research drain? + +consider executables: + press F to do things + ideas: + +at the start of the null level use speech API to say something short, + if the on end event runs set the lore.isVoiceWorking flag to be true + if lore.isVoiceWorking is false, skip voice and just move through each sentence with a short delay + make the player get a buff after using wormhole while energy lasts: drain energy and give damage buff @@ -321,16 +354,13 @@ possible names for tech stochastic optimization electrostatic discharge Gödel's incompleteness - dynamical systems quantum zeno effect (perturbation of a system prevents some systems from evolving because it scrambles coherence) (apply to lasers, fields) counterfactual - something false axion - maybe a 3rd dark matter type tech Pigeonhole principle - if there are several things that are matched up regression to the mean - tessellation = tiling of a flat surface is the covering of a plane using one or more geometric shapes, called tiles, with no overlaps and no gaps. phlogiston theory is a superseded scientific theory that postulated the existence of a fire-like element called phlogiston Laplace's demon was a notable published articulation of causal determinism on a scientific basis by Pierre-Simon Laplace in 1814.[1] According to determinism, if someone (the demon) knows the precise location and momentum of every atom in the universe, their past and future values for any given time are entailed; they can be calculated from the laws of classical mechanics. - Degenerate matter is a highly dense state of fermionic matter in which the Pauli exclusion principle exerts significant pressure in addition to, or in lieu of thermal pressure. evolutionary cosmology eternal inflation