field research tech

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
This commit is contained in:
landgreen
2021-07-11 06:21:16 -07:00
parent 8b0acb4c56
commit b5dd456db0
8 changed files with 416 additions and 273 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -225,8 +225,9 @@ const b = {
}, },
fireCDscale: 1, fireCDscale: 1,
setFireCD() { setFireCD() {
b.fireCDscale = tech.fireRate * tech.slowFire * tech.researchHaste * tech.aimDamage / tech.fastTime b.fireCDscale = tech.fireRate * tech.slowFire * tech.researchHaste * tech.aimDamage
if (tech.isFireRateForGuns) b.fireCDscale *= Math.pow(0.86, b.inventory.length) 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 if (tech.isFireMoveLock) b.fireCDscale *= 0.5
}, },
fireAttributes(dir, rotate = true) { fireAttributes(dir, rotate = true) {
@@ -1517,7 +1518,7 @@ const b = {
}); });
if (tech.isLaserPush) { //push mobs away if (tech.isLaserPush) { //push mobs away
const index = path.length - 1 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) Matter.Body.applyForce(best.who, path[index], force)
} }
} }
@@ -3443,7 +3444,7 @@ const b = {
for (let i = 0; i < q.length; i++) { for (let i = 0; i < q.length; i++) {
if (!q[i].isShielded) { if (!q[i].isShielded) {
mobs.statusStun(q[i], 180) 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].damage(dmg);
q[i].foundPlayer(); q[i].foundPlayer();
simulation.drawList.push({ //add dmg to draw queue simulation.drawList.push({ //add dmg to draw queue
@@ -3711,13 +3712,16 @@ const b = {
knock = 0.1 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) m.fireCDcycle -= 0.66 * (45 * b.fireCDscale)
player.force.x -= 2 * knock * Math.cos(m.angle) 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 { } else {
player.force.x -= knock * Math.cos(m.angle) 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); b.muzzleFlash(35);
@@ -3727,7 +3731,7 @@ const b = {
const dir = m.angle + 0.02 * (Math.random() - 0.5) 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)); 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 World.add(engine.world, bullet[me]); //add bullet to world
const SPEED = (m.crouch ? 45 : 35) + Math.random() * 6 const SPEED = (m.crouch ? 45 : 35) + Math.random() * 6
Matter.Body.setVelocity(bullet[me], { Matter.Body.setVelocity(bullet[me], {
@@ -3792,7 +3796,7 @@ const b = {
y: speed * Math.sin(dirOff) y: speed * Math.sin(dirOff)
}); });
bullet[me].onEnd = function() { 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() { bullet[me].beforeDmg = function() {
this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
@@ -3802,6 +3806,7 @@ const b = {
} }
} else if (tech.isNailShot) { } else if (tech.isNailShot) {
spread *= 0.65 spread *= 0.65
const dmg = 1.4 * (tech.isShotgunReversed ? 1.6 : 1)
if (m.crouch) { if (m.crouch) {
for (let i = 0; i < 17; i++) { for (let i = 0; i < 17; i++) {
speed = 38 + 15 * Math.random() speed = 38 + 15 * Math.random()
@@ -3813,7 +3818,7 @@ const b = {
b.nail(pos, { b.nail(pos, {
x: speed * Math.cos(dir), x: speed * Math.cos(dir),
y: speed * Math.sin(dir) y: speed * Math.sin(dir)
}, 1.4) }, dmg)
} }
} else { } else {
for (let i = 0; i < 17; i++) { for (let i = 0; i < 17; i++) {
@@ -3826,7 +3831,7 @@ const b = {
b.nail(pos, { b.nail(pos, {
x: speed * Math.cos(dir), x: speed * Math.cos(dir),
y: speed * Math.sin(dir) y: speed * Math.sin(dir)
}, 1.4) }, dmg)
} }
} }
} else { } else {
@@ -3843,6 +3848,7 @@ const b = {
}); });
bullet[me].endCycle = simulation.cycle + 40 bullet[me].endCycle = simulation.cycle + 40
bullet[me].minDmgSpeed = 15 bullet[me].minDmgSpeed = 15
if (tech.isShotgunReversed) Matter.Body.setDensity(bullet[me], 0.0016)
// bullet[me].restitution = 0.4 // bullet[me].restitution = 0.4
bullet[me].frictionAir = 0.034; bullet[me].frictionAir = 0.034;
bullet[me].do = function() { bullet[me].do = function() {
@@ -3922,38 +3928,45 @@ const b = {
fireQueue() { fireQueue() {
const SPEED = m.crouch ? 43 : 36 const SPEED = m.crouch ? 43 : 36
const dir = m.angle const dir = m.angle
const x = m.pos.x + 30 * Math.cos(m.angle) const x = m.pos.x
const y = m.pos.y + 30 * Math.sin(m.angle) const y = m.pos.y
const delay = Math.floor((m.crouch ? 18 : 12) * b.fireCDscale) const delay = Math.floor((m.crouch ? 18 : 12) * b.fireCDscale)
m.fireCDcycle = m.cycle + delay; // cool down m.fireCDcycle = m.cycle + delay; // cool down
for (let i = 0; i < tech.superBallNumber; i++) { const fireBall = () => {
setTimeout(() => { const me = bullet.length;
if (!simulation.paused) { bullet[me] = Bodies.polygon(x, y, 12, 11 * tech.bulletSize, b.fireAttributes(dir, false));
const me = bullet.length; World.add(engine.world, bullet[me]); //add bullet to world
bullet[me] = Bodies.polygon(x, y, 12, 11 * tech.bulletSize, b.fireAttributes(dir, false)); Matter.Body.setVelocity(bullet[me], {
World.add(engine.world, bullet[me]); //add bullet to world x: SPEED * Math.cos(dir),
Matter.Body.setVelocity(bullet[me], { y: SPEED * Math.sin(dir)
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].endCycle = simulation.cycle + Math.floor(330 * tech.isBulletsLastLonger); bullet[me].restitution = 0.99;
bullet[me].minDmgSpeed = 0; bullet[me].friction = 0;
bullet[me].restitution = 0.99; bullet[me].do = function() {
bullet[me].friction = 0; this.force.y += this.mass * 0.001;
bullet[me].do = function() { };
this.force.y += this.mass * 0.001; bullet[me].beforeDmg = function() {
}; if (tech.isIncendiary) {
bullet[me].beforeDmg = function() { b.explosion(this.position, this.mass * 350 + 60 * Math.random()); //makes bullet do explosive damage at end
if (tech.isIncendiary) { this.endCycle = 0
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
} }
}, 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 chooseFireMethod() { //set in simulation.startGame
if (tech.oneSuperBall) { if (tech.oneSuperBall) {
@@ -4702,7 +4715,7 @@ const b = {
}); });
//knock back //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.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 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; const me = bullet.length;
bullet[me] = Bodies.rectangle(0, 0, 0.015, 0.0015, { bullet[me] = Bodies.rectangle(0, 0, 0.015, 0.0015, {
density: 0.008, //0.001 is normal density: 0.008, //0.001 is normal
//frictionAir: 0.01, //restitution: 0,
// angle: 0,
// friction: 0.5,
restitution: 0, restitution: 0,
frictionAir: 0, frictionAir: 0,
dmg: 0, //damage done in addition to the damage from momentum dmg: 0, //damage done in addition to the damage from momentum
@@ -4738,7 +4748,6 @@ const b = {
x: -0.5 * this.velocity.x, x: -0.5 * this.velocity.x,
y: -0.5 * this.velocity.y y: -0.5 * this.velocity.y
}); });
// Matter.Body.setDensity(this, 0.001);
} }
if (tech.fragments && this.speed > 10) { if (tech.fragments && this.speed > 10) {
b.targetedNail(this.position, tech.fragments * 20) b.targetedNail(this.position, tech.fragments * 20)
@@ -4781,7 +4790,7 @@ const b = {
}); });
//knock back //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.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 player.force.y -= KNOCK * Math.sin(m.angle) * 0.35 //reduce knock back in vertical direction to stop super jumps
pushAway(1200 * this.charge) pushAway(1200 * this.charge)

View File

@@ -15,8 +15,10 @@ const level = {
// level.difficultyIncrease(30) // level.difficultyIncrease(30)
// simulation.isHorizontalFlipped = true // simulation.isHorizontalFlipped = true
// m.setField("wormhole") // m.setField("wormhole")
// b.giveGuns("laser") // b.giveGuns("shotgun")
// tech.giveTech("laser diode") // tech.isShotgunRecoil = true
// tech.isShotgunReversed = true
// tech.giveTech("supertemporal")
// tech.giveTech("free-electron laser") // tech.giveTech("free-electron laser")
// for (let i = 0; i < 9; i++) tech.giveTech("spherical harmonics") // for (let i = 0; i < 9; i++) tech.giveTech("spherical harmonics")
// tech.giveTech("decoherence") // tech.giveTech("decoherence")
@@ -2265,7 +2267,7 @@ const level = {
// spawn.laser(1200, -500) // spawn.laser(1200, -500)
// spawn.shield(mob[mob.length - 1], 1800, -120, 1); // spawn.shield(mob[mob.length - 1], 1800, -120, 1);
spawn.nodeGroup(1200, -500, "grenadier") // spawn.nodeGroup(1200, -500, "grenadier")
// spawn.snakeBoss(1200, -500) // spawn.snakeBoss(1200, -500)
// spawn.suckerBoss(2900, -500) // spawn.suckerBoss(2900, -500)
// spawn.randomMob(1600, -500) // spawn.randomMob(1600, -500)
@@ -2616,10 +2618,9 @@ const level = {
// localSettings.levelsClearedLastGame = 20 // localSettings.levelsClearedLastGame = 20
if (level.levelsCleared === 0) { if (level.levelsCleared === 0) {
// powerUps.spawn(-100, 0, "heal", false); //starting gun powerUps.spawn(2500, -50, "research", false);
powerUps.spawn(1900, -150, "heal", false); //starting gun powerUps.spawn(1900, -50, "heal", false);
powerUps.spawn(2050, -150, "heal", false); //starting gun powerUps.spawn(2050, -50, "heal", false);
// powerUps.spawn(2050, -150, "field", false); //starting gun
if (localSettings.levelsClearedLastGame < 6) { if (localSettings.levelsClearedLastGame < 6) {
if (!simulation.isCheating && !m.isShipMode) { if (!simulation.isCheating && !m.isShipMode) {
spawn.wireFoot(); spawn.wireFoot();
@@ -2632,7 +2633,7 @@ const level = {
simulation.trails() simulation.trails()
} }
} }
powerUps.spawnStartingPowerUps(2300, -150); powerUps.spawnStartingPowerUps(2300, -50);
}, },
testChamber() { testChamber() {
level.setPosToSpawn(0, -50); //lower start level.setPosToSpawn(0, -50); //lower start

View File

@@ -1074,12 +1074,12 @@ const mobs = {
} }
if (tech.isBotSpawnerReset) { if (tech.isBotSpawnerReset) {
for (let i = 0, len = bullet.length; i < len; i++) { 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) { if (Math.random() < tech.botSpawner) {
b.randomBot(this.position, false) 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 this.leaveBody = false; // no body since it turned into the bot
} }
} else if (tech.isShieldAmmo && this.shield && !this.isExtraShield) { } else if (tech.isShieldAmmo && this.shield && !this.isExtraShield) {

View File

@@ -75,8 +75,8 @@ const m = {
Fx: 0.016, //run Force on ground // Fx: 0.016, //run Force on ground //
jumpForce: 0.42, jumpForce: 0.42,
setMovement() { setMovement() {
m.Fx = 0.016 * tech.squirrelFx * tech.fastTime; m.Fx = 0.016 * tech.squirrelFx * (tech.isFastTime ? 1.5 : 1);
m.jumpForce = 0.42 * tech.squirrelJump * tech.fastTimeJump; m.jumpForce = 0.42 * tech.squirrelJump * (tech.isFastTime ? 1.13 : 1)
}, },
FxAir: 0.016, // 0.4/5/5 run Force in Air FxAir: 0.016, // 0.4/5/5 run Force in Air
yOff: 70, yOff: 70,
@@ -490,19 +490,20 @@ const m = {
harmReduction() { harmReduction() {
let dmg = 1 let dmg = 1
dmg *= m.fieldHarmReduction dmg *= m.fieldHarmReduction
if (tech.isFieldHarmReduction) dmg *= 0.5
if (tech.isHarmMACHO) dmg *= 0.33 if (tech.isHarmMACHO) dmg *= 0.33
if (tech.isImmortal) dmg *= 0.66 if (tech.isImmortal) dmg *= 0.66
if (tech.isHarmReduceAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 0.33 : 1.15 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.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.squirrelFx !== 1) dmg *= 1 + (tech.squirrelFx - 1) / 5 //cause more damage
if (tech.isBlockHarm && m.isHolding) dmg *= 0.15 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.isSlowFPS) dmg *= 0.8
// if (tech.isPiezo) dmg *= 0.85 // if (tech.isPiezo) dmg *= 0.85
if (tech.isHarmReduce && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.4 if (tech.isHarmReduce && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.4
if (tech.isBotArmor) dmg *= 0.93 ** b.totalBots() if (tech.isBotArmor) dmg *= 0.93 ** b.totalBots()
if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.33; 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.energyRegen === 0) dmg *= 0.34
if (tech.isTurret && m.crouch) dmg *= 0.55; if (tech.isTurret && m.crouch) dmg *= 0.55;
if (tech.isEntanglement && b.inventory[0] === b.activeGun) { 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))) rewind(steps) { // m.rewind(Math.floor(Math.min(599, 137 * m.energy)))
if (tech.isRewindGrenade) { 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... 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++) { for (let i = 1, len = Math.floor(2 + steps / 40); i < len; i++) {
@@ -605,7 +606,7 @@ const m = {
simulation.fpsInterval = 1000 / simulation.fpsCap; simulation.fpsInterval = 1000 / simulation.fpsCap;
m.defaultFPSCycle = m.cycle m.defaultFPSCycle = m.cycle
if (tech.isRewindBot) { if (tech.isRewindBot) {
const len = steps * 0.052 * tech.isRewindBot const len = steps * 0.07 * tech.isRewindBot
const botStep = Math.floor(steps / len) const botStep = Math.floor(steps / len)
for (let i = 0; i < len; i++) { 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 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() { 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(`<span class='color-var'>m</span>.<span class='color-f'>maxEnergy</span> <span class='color-symbol'>=</span> ${(m.maxEnergy.toFixed(2))}`) simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-f'>maxEnergy</span> <span class='color-symbol'>=</span> ${(m.maxEnergy.toFixed(2))}`)
}, },
fieldMeterColor: "#0cf", fieldMeterColor: "#0cf",
@@ -1655,60 +1656,6 @@ const m = {
} }
} }
}, },
{
name: "nano-scale manufacturing",
description: "excess <strong class='color-f'>energy</strong> used to build <strong>drones</strong><br>use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs<br><strong>double</strong> your default <strong class='color-f'>energy</strong> 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", name: "negative mass field",
description: "use <strong class='color-f'>energy</strong> to nullify &nbsp;<strong style='letter-spacing: 7px;'>gravity</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>55%</strong><br><strong class='color-block'>blocks</strong> held by the field have a lower <strong>mass</strong>", description: "use <strong class='color-f'>energy</strong> to nullify &nbsp;<strong style='letter-spacing: 7px;'>gravity</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>55%</strong><br><strong class='color-block'>blocks</strong> held by the field have a lower <strong>mass</strong>",
@@ -1859,6 +1806,60 @@ const m = {
} }
} }
}, },
{
name: "nano-scale manufacturing",
description: "excess <strong class='color-f'>energy</strong> used to build <strong>drones</strong><br>use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs<br><strong>double</strong> your default <strong class='color-f'>energy</strong> 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", name: "plasma torch",
description: "use <strong class='color-f'>energy</strong> to emit short range <strong class='color-plasma'>plasma</strong><br><strong class='color-d'>damages</strong> and <strong>pushes</strong> mobs away", description: "use <strong class='color-f'>energy</strong> to emit short range <strong class='color-plasma'>plasma</strong><br><strong class='color-d'>damages</strong> and <strong>pushes</strong> 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" name: "metamaterial cloaking", //"weak photonic coupling" "electromagnetically induced transparency" "optical non-coupling" "slow light field" "electro-optic transparency"
description: "when not firing activate a <strong class='color-cloaked'>cloaking</strong> effect<br>if a mob has <strong>not died</strong> in the last <strong>4 seconds</strong><br>increase <strong class='color-d'>damage</strong> by <strong>300%</strong>", description: "when not firing activate a <strong class='color-cloaked'>cloaking</strong> effect<br>if a mob has <strong>not died</strong> in the last <strong>3 seconds</strong><br>increase <strong class='color-d'>damage</strong> by <strong>300%</strong>",
effect: () => { effect: () => {
m.fieldFire = true; m.fieldFire = true;
m.fieldMeterColor = "#333"; m.fieldMeterColor = "#333";
@@ -2031,7 +2032,7 @@ const m = {
// m.fieldDamage = 2.46 // 1 + 146/100 // m.fieldDamage = 2.46 // 1 + 146/100
m.fieldDrawRadius = 0 m.fieldDrawRadius = 0
m.isSneakAttack = true; m.isSneakAttack = true;
const drawRadius = 1000 const drawRadius = 1100
m.hold = function() { m.hold = function() {
if (m.isHolding) { 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) 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.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) { if (!m.isCloak) {
m.isCloak = true //enter cloak m.isCloak = true //enter cloak
if (tech.isIntangible) { if (tech.isIntangible) {
@@ -2161,7 +2162,7 @@ const m = {
} }
//show sneak attack status //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.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.beginPath();
ctx.arc(m.pos.x, m.pos.y, 28, 0, 2 * Math.PI); ctx.arc(m.pos.x, m.pos.y, 28, 0, 2 * Math.PI);

View File

@@ -92,8 +92,8 @@ const spawn = {
if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) { if (tech.isDuplicateBoss && Math.random() < 2 * tech.duplicationChance()) {
spawn.randomLevelBoss(x, y); spawn.randomLevelBoss(x, y);
} else if (tech.isResearchBoss) { } else if (tech.isResearchBoss) {
if (powerUps.research.count > 4) { if (powerUps.research.count > 3) {
powerUps.research.changeRerolls(-5) powerUps.research.changeRerolls(-4)
simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-r'>research</span> <span class='color-symbol'>-=</span> 5<br>${powerUps.research.count}`) simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-r'>research</span> <span class='color-symbol'>-=</span> 5<br>${powerUps.research.count}`)
} else { } else {
tech.addJunkTechToPool(49) tech.addJunkTechToPool(49)

View File

@@ -151,6 +151,7 @@
}, },
damageFromTech() { damageFromTech() {
let dmg = 1 //m.fieldDamage let dmg = 1 //m.fieldDamage
if (tech.isCloakingDamage) dmg *= 1.35
if (tech.isFlipFlopDamage && tech.isFlipFlopOn) dmg *= 1.45 if (tech.isFlipFlopDamage && tech.isFlipFlopOn) dmg *= 1.45
if (tech.isAnthropicDamage && tech.isDeathAvoidedThisLevel) dmg *= 2.3703599 if (tech.isAnthropicDamage && tech.isDeathAvoidedThisLevel) dmg *= 2.3703599
if (tech.isDamageAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 2 : 0.66 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.isLowEnergyDamage) dmg *= 1 + Math.max(0, 1 - m.energy) * 0.5
if (tech.isMaxEnergyTech) dmg *= 1.5 if (tech.isMaxEnergyTech) dmg *= 1.5
if (tech.isEnergyNoAmmo) dmg *= 1.6 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.isLowHealthDmg) dmg *= 1 + 0.5 * Math.max(0, 1 - m.health)
if (tech.isHarmDamage && m.lastHarmCycle + 600 > m.cycle) dmg *= 3; if (tech.isHarmDamage && m.lastHarmCycle + 600 > m.cycle) dmg *= 3;
if (tech.isEnergyLoss) dmg *= 1.55; if (tech.isEnergyLoss) dmg *= 1.55;
if (tech.isAcidDmg && m.health > 1) dmg *= 1.35; if (tech.isAcidDmg && m.health > 1) dmg *= 1.35;
if (tech.restDamage > 1 && player.speed < 1) dmg *= tech.restDamage if (tech.restDamage > 1 && player.speed < 1) dmg *= tech.restDamage
if (tech.isEnergyDamage) dmg *= 1 + m.energy / 9; 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.isRerollDamage) dmg *= 1 + 0.042 * powerUps.research.count
if (tech.isOneGun && b.inventory.length < 2) dmg *= 1.3 if (tech.isOneGun && b.inventory.length < 2) dmg *= 1.3
if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 1.9 if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 2
if (tech.isSpeedDamage) dmg *= 1 + Math.min(0.43, player.speed * 0.015) if (tech.isSpeedDamage) dmg *= 1 + Math.min(0.66, player.speed * 0.022)
if (tech.isBotDamage) dmg *= 1 + 0.06 * b.totalBots() if (tech.isBotDamage) dmg *= 1 + 0.06 * b.totalBots()
return dmg * tech.slowFire * tech.aimDamage return dmg * tech.slowFire * tech.aimDamage
}, },
duplicationChance() { 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() { maxDuplicationEvent() {
if (tech.is100Duplicate && tech.duplicationChance() > 0.99) { if (tech.is100Duplicate && tech.duplicationChance() > 0.99) {
@@ -247,15 +248,15 @@
}, },
{ {
name: "arsenal", name: "arsenal",
description: "increase <strong class='color-d'>damage</strong> by <strong>12%</strong><br>for each <strong class='color-g'>gun</strong> in your inventory", description: "increase <strong class='color-d'>damage</strong> by <strong>13%</strong><br>for each <strong class='color-g'>gun</strong> in your inventory",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return b.inventory.length > 1 return b.inventory.length > 0
}, },
requires: "at least 2 guns", requires: "at least 1 gun",
effect() { effect() {
tech.isDamageForGuns = true; tech.isDamageForGuns = true;
}, },
@@ -265,15 +266,15 @@
}, },
{ {
name: "active cooling", name: "active cooling",
description: "<strong>14%</strong> decreased <strong><em>delay</em></strong> after firing<br>for each <strong class='color-g'>gun</strong> in your inventory", description: "<strong>15%</strong> decreased <strong><em>delay</em></strong> after firing<br>for each <strong class='color-g'>gun</strong> in your inventory",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return b.inventory.length > 1 return b.inventory.length > 0
}, },
requires: "at least 2 guns", requires: "at least 1 gun",
effect() { effect() {
tech.isFireRateForGuns = true; tech.isFireRateForGuns = true;
b.setFireCD(); b.setFireCD();
@@ -517,15 +518,15 @@
}, },
{ {
name: "Newton's 1st law", name: "Newton's 1st law",
description: "moving at high <strong>speeds</strong> reduces <strong class='color-harm'>harm</strong><br>by up to <strong>60%</strong>", description: "moving at high <strong>speeds</strong> reduces <strong class='color-harm'>harm</strong><br>by up to <strong>66%</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 1,
frequencyDefault: 2, frequencyDefault: 1,
allowed() { allowed() {
return m.Fx > 0.016 && !tech.isEnergyHealth return !tech.isEnergyHealth
}, },
requires: "speed increase, not mass-energy equivalence", requires: "not mass-energy equivalence",
effect() { effect() {
tech.isSpeedHarm = true tech.isSpeedHarm = true
}, },
@@ -535,15 +536,15 @@
}, },
{ {
name: "Newton's 2nd law", name: "Newton's 2nd law",
description: "moving at high <strong>speeds</strong> increases <strong class='color-d'>damage</strong><br> by up to <strong>43%</strong>", description: "moving at high <strong>speeds</strong> increases <strong class='color-d'>damage</strong><br> by up to <strong>66%</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 1,
frequencyDefault: 2, frequencyDefault: 1,
allowed() { allowed() {
return m.Fx > 0.016 return true
}, },
requires: "speed increase", requires: "",
effect() { effect() {
tech.isSpeedDamage = true tech.isSpeedDamage = true
}, },
@@ -646,15 +647,15 @@
}, },
{ {
name: "microstates", name: "microstates",
description: "increase <strong class='color-d'>damage</strong> by <strong>4%</strong><br>for every <strong>10</strong> active <strong>bullets</strong>", description: "increase <strong class='color-d'>damage</strong> by <strong>6%</strong><br>for every <strong>10</strong> active <strong>bullets</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return tech.isBulletsLastLonger > 1 return true
}, },
requires: "anti-shear topology", requires: "",
effect() { effect() {
tech.isDamageFromBulletCount = true tech.isDamageFromBulletCount = true
}, },
@@ -964,15 +965,15 @@
}, },
{ {
name: "decorrelation", name: "decorrelation",
description: "reduce <strong class='color-harm'>harm</strong> by <strong>66%</strong> after not <strong>activating</strong><br>your <strong class='color-g'>gun</strong> or <strong class='color-f'>field</strong> for <strong>2</strong> seconds", description: "reduce <strong class='color-harm'>harm</strong> by <strong>70%</strong> after not <strong>activating</strong><br>your <strong class='color-g'>gun</strong> or <strong class='color-f'>field</strong> for <strong>2</strong> seconds",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 1,
frequencyDefault: 2, frequencyDefault: 1,
allowed() { 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() { effect() {
tech.isNoFireDefense = true tech.isNoFireDefense = true
}, },
@@ -982,7 +983,7 @@
}, },
{ {
name: "anticorrelation", name: "anticorrelation",
description: "increase <strong class='color-d'>damage</strong> by <strong>90%</strong><br>after not using your <strong class='color-g'>gun</strong> or <strong class='color-f'>field</strong> for <strong>2</strong> seconds", description: "increase <strong class='color-d'>damage</strong> by <strong>100%</strong><br>after not using your <strong class='color-g'>gun</strong> or <strong class='color-f'>field</strong> for <strong>2</strong> seconds",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 2,
@@ -1000,7 +1001,7 @@
}, },
{ {
name: "scrap bots", name: "scrap bots",
description: "<strong>33%</strong> chance after killing a mob to build<br>a scrap <strong class='color-bot'>bot</strong> that operates for <strong>10</strong> seconds", description: "<strong>33%</strong> chance after killing a mob to build<br>a scrap <strong class='color-bot'>bot</strong> that operates for <strong>14</strong> seconds",
maxCount: 3, maxCount: 3,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -1018,7 +1019,7 @@
}, },
{ {
name: "scrap refit", name: "scrap refit",
description: "killing a mob resets your functional scrap <strong class='color-bot'>bots</strong><br>to <strong>10</strong> seconds of operation", description: "killing a mob resets your functional scrap <strong class='color-bot'>bots</strong><br>to <strong>14</strong> seconds of operation",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -1257,7 +1258,7 @@
}, },
{ {
name: "orbital-bot upgrade", name: "orbital-bot upgrade",
description: "<strong>convert</strong> all your bots to <strong>orbital-bots</strong><br>increase <strong class='color-d'>damage</strong> by <strong>200%</strong> and <strong>radius</strong> by <strong>40%</strong>", description: "<strong>convert</strong> all your bots to <strong>orbital-bots</strong><br>increase <strong class='color-d'>damage</strong> by <strong>250%</strong> and <strong>radius</strong> by <strong>40%</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 2,
@@ -2129,7 +2130,7 @@
}, },
{ {
name: "inductive coupling", name: "inductive coupling",
description: "each unused <strong>power up</strong> at the end of a <strong>level</strong><br>adds 3 <strong>max</strong> <strong class='color-f'>energy</strong>", // <em>(up to 51 health per level)</em>", description: "each unused <strong>power up</strong> at the end of a <strong>level</strong><br>adds 3 <strong>maximum</strong> <strong class='color-f'>energy</strong>", // <em>(up to 51 health per level)</em>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -2354,7 +2355,7 @@
}, },
{ {
name: "dormancy", name: "dormancy",
description: "if a mob has <strong>died</strong> in the last <strong>5 seconds</strong><br><span style = 'font-size:93%;'>increase <strong class='color-d'>damage</strong> by <strong>100%</strong> else decrease it by <strong>33%</strong></span>", description: "if a mob has <strong>died</strong> in the last <strong>5 seconds</strong><br><span style = 'font-size:90%;'>increase <strong class='color-d'>damage</strong> by <strong>99%</strong> else decrease it by <strong>33%</strong></span>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 2,
@@ -2852,15 +2853,15 @@
}, },
{ {
name: "abiogenesis", name: "abiogenesis",
description: "at the start of a level spawn a 2nd <strong>boss</strong> for<br><strong>5</strong> <strong class='color-r'>research</strong> or <strong>+49</strong> <strong class='color-j'>JUNK</strong> to the <strong class='color-m'>tech</strong> pool", description: "at the start of a level spawn a 2nd <strong>boss</strong> for<br><strong>4</strong> <strong class='color-r'>research</strong> or <strong>+49</strong> <strong class='color-j'>JUNK</strong> to the <strong class='color-m'>tech</strong> pool",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 2,
frequencyDefault: 1, frequencyDefault: 2,
allowed() { 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() { effect() {
tech.isResearchBoss = true; //abiogenesis tech.isResearchBoss = true; //abiogenesis
}, },
@@ -3754,16 +3755,16 @@
}, },
{ {
name: "Newton's 3rd law", name: "Newton's 3rd law",
description: "<strong>shotgun</strong> <strong>recoil</strong> is greatly increased<br>and has a <strong>66%</strong> decreased <strong><em>delay</em></strong> after firing", description: "<strong>shotgun</strong> <strong>recoil</strong> is increased<br>decrease <strong>shotgun</strong> <strong><em>delay</em></strong> after firing by <strong>66%</strong>",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return tech.haveGunCheck("shotgun") return tech.haveGunCheck("shotgun") && !tech.isShotgunReversed
}, },
requires: "shotgun", requires: "shotgun, not Noether violation",
effect() { effect() {
tech.isShotgunRecoil = true; tech.isShotgunRecoil = true;
}, },
@@ -3771,6 +3772,25 @@
tech.isShotgunRecoil = false; tech.isShotgunRecoil = false;
} }
}, },
{
name: "Noether violation",
description: "increase <strong>shotgun</strong> and <strong>rail gun</strong> <strong class='color-d'>damage</strong> <strong>60%</strong><br>their <strong>recoil</strong> is increased and <strong>reversed</strong>",
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", name: "super duper",
description: "fire <strong>1</strong> additional <strong>super ball</strong>", description: "fire <strong>1</strong> additional <strong>super ball</strong>",
@@ -4887,7 +4907,30 @@
//************************************************** field //************************************************** field
//************************************************** tech //************************************************** tech
//************************************************** //**************************************************
{
name: "zero point energy",
description: "use <strong>2</strong> <strong class='color-r'>research</strong> to<br>increase your <strong>maximum</strong> <strong class='color-f'>energy</strong> by <strong>74</strong>",
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", name: "spherical harmonics",
description: "<strong>standing wave</strong> oscillates in a 3rd dimension<br>increasing <strong>deflecting</strong> efficiency by <strong>40%</strong>", description: "<strong>standing wave</strong> oscillates in a 3rd dimension<br>increasing <strong>deflecting</strong> efficiency by <strong>40%</strong>",
@@ -5008,6 +5051,104 @@
tech.isPerfectBrake = false; tech.isPerfectBrake = false;
} }
}, },
{
name: "tessellation",
description: "use <strong>4</strong> <strong class='color-r'>research</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>50%</strong>",
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 <strong class='color-harm'>harm</strong> by <strong>60%</strong> while your <strong class='color-f'>field</strong> 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: "<strong>touching</strong> normal mobs <strong>annihilates</strong> them<br>but drains <strong>33%</strong> of your maximum <strong class='color-f'>energy</strong>",
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: "<strong>negative mass field</strong> is larger and <strong>faster</strong><br><strong class='color-block'>blocks</strong> also move <strong>horizontally</strong> 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: "<strong>mobs</strong> inside your <strong class='color-f'>field</strong> are <strong class='color-s'>frozen</strong><br><em style = 'font-size: 100%'>pilot wave, negative mass, time dilation</em>",
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", name: "bot manufacturing",
description: "use <strong>nano-scale manufacturing</strong> and <strong>2</strong> <strong class='color-r'>research</strong><br>to build <strong>3</strong> random <strong class='color-bot'>bots</strong>", description: "use <strong>nano-scale manufacturing</strong> and <strong>2</strong> <strong class='color-r'>research</strong><br>to build <strong>3</strong> random <strong class='color-bot'>bots</strong>",
@@ -5203,82 +5344,6 @@
tech.isMassEnergy = false; tech.isMassEnergy = false;
} }
}, },
{
name: "degenerate matter",
description: "reduce <strong class='color-harm'>harm</strong> by <strong>60%</strong> while your <strong class='color-f'>field</strong> 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: "<strong>touching</strong> normal mobs <strong>annihilates</strong> them<br>but drains <strong>33%</strong> of your maximum <strong class='color-f'>energy</strong>",
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: "<strong>negative mass field</strong> is larger and <strong>faster</strong><br><strong class='color-block'>blocks</strong> also move <strong>horizontally</strong> 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: "<strong>mobs</strong> inside your <strong class='color-f'>field</strong> are <strong class='color-s'>frozen</strong><br><em style = 'font-size: 100%'>pilot wave, negative mass, time dilation</em>",
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", // name: "thermal reservoir",
// description: "increase your <strong class='color-plasma'>plasma</strong> <strong class='color-d'>damage</strong> by <strong>100%</strong><br><strong class='color-plasma'>plasma</strong> temporarily lowers health not <strong class='color-f'>energy</strong>", // description: "increase your <strong class='color-plasma'>plasma</strong> <strong class='color-d'>damage</strong> by <strong>100%</strong><br><strong class='color-plasma'>plasma</strong> temporarily lowers health not <strong class='color-f'>energy</strong>",
@@ -5299,7 +5364,7 @@
// }, // },
{ {
name: "plasma-bot", name: "plasma-bot",
description: "a <strong class='color-bot'>bot</strong> uses <strong class='color-f'>energy</strong> to emit <strong class='color-plasma'>plasma</strong><br>that <strong class='color-d'>damages</strong> and <strong>pushes</strong> mobs", description: "use <strong>1</strong> <strong class='color-r'>research</strong> to build a <strong class='color-bot'>bot</strong><br>that uses <strong class='color-f'>energy</strong> to emit <strong class='color-plasma'>plasma</strong>",
isFieldTech: true, isFieldTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -5307,12 +5372,15 @@
isBot: true, isBot: true,
isBotTech: true, isBotTech: true,
allowed() { 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", requires: "plasma torch",
effect() { effect() {
tech.plasmaBotCount++; tech.plasmaBotCount++;
b.plasmaBot(); b.plasmaBot();
for (let i = 0; i < 1; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
}
}, },
remove() { remove() {
tech.plasmaBotCount = 0; tech.plasmaBotCount = 0;
@@ -5400,25 +5468,26 @@
}, },
{ {
name: "Lorentz transformation", name: "Lorentz transformation",
description: "permanently increase your relative time rate<br><strong>move</strong>, <strong>jump</strong>, and <strong>shoot</strong> <strong>40%</strong> faster", description: "use <strong>3</strong> <strong class='color-r'>research</strong> to increase your time rate<br><strong>move</strong>, <strong>jump</strong>, and <strong>shoot</strong> <strong>50%</strong> faster",
isFieldTech: true, isFieldTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { 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", requires: "time dilation",
effect() { effect() {
tech.fastTime = 1.40; tech.isFastTime = true
tech.fastTimeJump = 1.11;
m.setMovement(); m.setMovement();
b.setFireCD(); b.setFireCD();
for (let i = 0; i < 3; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
}
}, },
remove() { remove() {
tech.fastTime = 1; tech.isFastTime = false
tech.fastTimeJump = 1;
m.setMovement(); m.setMovement();
b.setFireCD(); b.setFireCD();
} }
@@ -5482,24 +5551,28 @@
tech.isCloakStun = false; tech.isCloakStun = false;
} }
}, },
// { {
// name: "combinatorial optimization", name: "dynamical systems",
// description: "increase <strong class='color-d'>damage</strong> by <strong>66%</strong><br>if a mob has <strong>not died</strong> in the last <strong>5 seconds</strong>", description: "use <strong>1</strong> <strong class='color-r'>research</strong><br>increase your <strong class='color-d'>damage</strong> by <strong>35%</strong>",
// isFieldTech: true, isFieldTech: true,
// maxCount: 1, maxCount: 1,
// count: 0, count: 0,
// frequency: 2, frequency: 2,
// allowed() { frequencyDefault: 2,
// return m.fieldUpgrades[m.fieldMode].name === "metamaterial cloaking" 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() { requires: "metamaterial cloaking or pilot wave",
// tech.isSneakAttack = true; effect() {
// }, tech.isCloakingDamage = true
// remove() { for (let i = 0; i < 1; i++) {
// tech.isSneakAttack = false; if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
// } }
// }, },
remove() {
tech.isCloakingDamage = false
}
},
{ {
name: "discrete optimization", name: "discrete optimization",
description: "increase <strong class='color-d'>damage</strong> by <strong>50%</strong><br><strong>50%</strong> increased <strong><em>delay</em></strong> after firing", description: "increase <strong class='color-d'>damage</strong> by <strong>50%</strong><br><strong>50%</strong> increased <strong><em>delay</em></strong> after firing",
@@ -5578,6 +5651,30 @@
tech.isWormholeDamage = false tech.isWormholeDamage = false
} }
}, },
{
name: "virtual particles",
description: "use <strong>3</strong> <strong class='color-r'>research</strong> to exploit your <strong>wormhole</strong> for<br><strong>19%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong>",
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", name: "Penrose process",
description: "after a <strong class='color-block'>block</strong> falls into a <strong class='color-worm'>wormhole</strong><br>you gain <strong>63</strong> <strong class='color-f'>energy</strong>", description: "after a <strong class='color-block'>block</strong> falls into a <strong class='color-worm'>wormhole</strong><br>you gain <strong>63</strong> <strong class='color-f'>energy</strong>",
@@ -7208,7 +7305,6 @@
slowFire: null, slowFire: null,
fastTime: null, fastTime: null,
squirrelJump: null, squirrelJump: null,
fastTimeJump: null,
isFastRadiation: null, isFastRadiation: null,
isExtraMaxEnergy: null, isExtraMaxEnergy: null,
isAmmoForGun: null, isAmmoForGun: null,
@@ -7365,5 +7461,11 @@
junkResearchNumber: null, junkResearchNumber: null,
laserColor: null, laserColor: null,
laserColorAlpha: null, laserColorAlpha: null,
isLongitudinal: null isLongitudinal: null,
isShotgunReversed: null,
wormDuplicate: null,
isCloakingDamage: null,
harmonicEnergy: null,
isFieldHarmReduction: null,
isFastTime: null
} }

View File

@@ -1,8 +1,41 @@
******************************************************** NEXT PATCH ******************************************************** ******************************************************** 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 ******************************************************** ******************************************************** 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 make the player get a buff after using wormhole
while energy lasts: drain energy and give damage buff while energy lasts: drain energy and give damage buff
@@ -321,16 +354,13 @@ possible names for tech
stochastic optimization stochastic optimization
electrostatic discharge electrostatic discharge
Gödel's incompleteness 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) quantum zeno effect (perturbation of a system prevents some systems from evolving because it scrambles coherence) (apply to lasers, fields)
counterfactual - something false counterfactual - something false
axion - maybe a 3rd dark matter type tech axion - maybe a 3rd dark matter type tech
Pigeonhole principle - if there are several things that are matched up Pigeonhole principle - if there are several things that are matched up
regression to the mean 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 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. 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 evolutionary cosmology
eternal inflation eternal inflation