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

View File

@@ -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)

View File

@@ -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

View File

@@ -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) {

View File

@@ -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(`<span class='color-var'>m</span>.<span class='color-f'>maxEnergy</span> <span class='color-symbol'>=</span> ${(m.maxEnergy.toFixed(2))}`)
},
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",
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",
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"
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: () => {
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);

View File

@@ -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(`<span class='color-var'>m</span>.<span class='color-r'>research</span> <span class='color-symbol'>-=</span> 5<br>${powerUps.research.count}`)
} else {
tech.addJunkTechToPool(49)

View File

@@ -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 <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,
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: "<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,
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 <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,
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 <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,
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 <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,
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 <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,
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 <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,
count: 0,
frequency: 2,
@@ -1000,7 +1001,7 @@
},
{
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,
count: 0,
frequency: 1,
@@ -1018,7 +1019,7 @@
},
{
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,
count: 0,
frequency: 1,
@@ -1257,7 +1258,7 @@
},
{
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,
count: 0,
frequency: 2,
@@ -2129,7 +2130,7 @@
},
{
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,
count: 0,
frequency: 1,
@@ -2354,7 +2355,7 @@
},
{
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,
count: 0,
frequency: 2,
@@ -2852,15 +2853,15 @@
},
{
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,
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: "<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,
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 <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",
description: "fire <strong>1</strong> additional <strong>super ball</strong>",
@@ -4887,7 +4907,30 @@
//************************************************** field
//************************************************** 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",
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;
}
},
{
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",
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;
}
},
{
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",
// 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",
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,
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<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,
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 <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>",
// 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 <strong>1</strong> <strong class='color-r'>research</strong><br>increase your <strong class='color-d'>damage</strong> by <strong>35%</strong>",
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 <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
}
},
{
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",
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,
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
}