const mod = {
totalCount: null,
setupAllMods() {
for (let i = 0, len = mod.mods.length; i < len; i++) {
mod.mods[i].remove();
mod.mods[i].isLost = false
mod.mods[i].count = 0
}
// mod.nailBotCount = 0;
// mod.foamBotCount = 0;
// mod.boomBotCount = 0;
// mod.laserBotCount = 0;
// mod.orbitalBotCount = 0;
// mod.plasmaBotCount = 0;
mod.armorFromPowerUps = 0;
mod.totalCount = 0;
game.updateModHUD();
},
removeMod(index) {
mod.mods[index].remove();
mod.mods[index].count = 0;
game.updateModHUD();
},
giveMod(index = 'random') {
if (index === 'random') {
let options = [];
for (let i = 0; i < mod.mods.length; i++) {
if (mod.mods[i].count < mod.mods[i].maxCount && mod.mods[i].allowed())
options.push(i);
}
// give a random mod from the mods I don't have
if (options.length > 0) {
let newMod = options[Math.floor(Math.random() * options.length)]
mod.giveMod(newMod)
}
} else {
if (isNaN(index)) { //find index by name
let found = false;
for (let i = 0; i < mod.mods.length; i++) {
if (index === mod.mods[i].name) {
index = i;
found = true;
break;
}
}
if (!found) return //if name not found don't give any mod
}
if (mod.mods[index].isLost) mod.mods[index].isLost = false; //give specific mod
mod.mods[index].effect(); //give specific mod
mod.mods[index].count++
mod.totalCount++ //used in power up randomization
game.updateModHUD();
}
},
setModToNonRefundable(name) {
for (let i = 0; i < mod.mods.length; i++) {
if (mod.mods.name === name) {
mod.mods[i].isNonRefundable = true;
return
}
}
},
// giveBasicMod(index = 'random') {
// // if (isNaN(index)) { //find index by name
// // let found = false;
// // for (let i = 0; i < mod.mods.length; i++) {
// // if (index === mod.mods[i].name) {
// // index = i;
// // found = true;
// // break;
// // }
// // }
// // if (!found) return //if name not found don't give any mod
// // }
// mod.basicMods[index].effect(); //give specific mod
// mod.mods[index].count++
// mod.totalCount++ //used in power up randomization
// game.updateModHUD();
// },
haveGunCheck(name) {
if (
!build.isCustomSelection &&
b.inventory.length > 2 &&
name !== b.guns[b.activeGun].name &&
Math.random() > 2 / (b.inventory.length + mod.isGunCycle * 3) //lower chance of mods specific to a gun if you have lots of guns
) {
return false
}
for (i = 0, len = b.inventory.length; i < len; i++) {
if (b.guns[b.inventory[i]].name === name) return true
}
return false
},
damageFromMods() {
let dmg = mech.fieldDamage
// if (mod.aimDamage>1)
if (mod.isLowEnergyDamage) dmg *= 1 + Math.max(0, 1 - mech.energy) * 0.5
if (mod.isMaxEnergyMod) dmg *= 1.4
if (mod.isEnergyNoAmmo) dmg *= 1.5
if (mod.isDamageForGuns) dmg *= 1 + 0.07 * b.inventory.length
if (mod.isLowHealthDmg) dmg *= 1 + 0.6 * Math.max(0, 1 - mech.health)
if (mod.isHarmDamage && mech.lastHarmCycle + 600 > mech.cycle) dmg *= 2;
if (mod.isEnergyLoss) dmg *= 1.5;
if (mod.isAcidDmg && mech.health > 1) dmg *= 1.4;
if (mod.restDamage > 1 && player.speed < 1) dmg *= mod.restDamage
if (mod.isEnergyDamage) dmg *= 1 + mech.energy / 8;
if (mod.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.0038
if (mod.isRerollDamage) dmg *= 1 + 0.04 * powerUps.reroll.rerolls
if (mod.isOneGun && b.inventory.length < 2) dmg *= 1.25
if (mod.isNoFireDamage && mech.cycle > mech.fireCDcycle + 120) dmg *= 1.5
if (mod.isSpeedDamage) dmg *= 1 + Math.min(0.33, player.speed * 0.011)
if (mod.isBotDamage) dmg *= 1 + 0.02 * mod.totalBots()
return dmg * mod.slowFire * mod.aimDamage
},
duplicationChance() {
return (mod.isBayesian ? 0.2 : 0) + mod.cancelCount * 0.04 + mod.duplicateChance + mech.duplicateChance
},
totalBots() {
return mod.foamBotCount + mod.nailBotCount + mod.laserBotCount + mod.boomBotCount + mod.plasmaBotCount + mod.orbitBotCount
},
mods: [{
name: "capacitor",
description: "increase damage by 1%
for every 8 stored energy",
maxCount: 1,
count: 0,
allowed() {
return mech.maxEnergy > 1 || mod.isEnergyRecovery || mod.isPiezo || mod.energySiphon > 0
},
requires: "increased energy regen or max energy",
effect: () => {
mod.isEnergyDamage = true
},
remove() {
mod.isEnergyDamage = false;
}
},
{
name: "exciton-lattice",
description: `increase damage by 50%, but
ammo will no longer spawn`,
maxCount: 1,
count: 0,
allowed() {
return (mod.haveGunCheck("nail gun") && mod.isIceCrystals) || mod.haveGunCheck("laser") || mech.fieldUpgrades[mech.fieldMode].name === "plasma torch" || mech.fieldUpgrades[mech.fieldMode].name === "nano-scale manufacturing" || mech.fieldUpgrades[mech.fieldMode].name === "pilot wave"
},
requires: "energy based damage",
effect() {
mod.isEnergyNoAmmo = true;
},
remove() {
mod.isEnergyNoAmmo = false;
}
},
{
name: "exothermic process",
description: "increase damage by 50%
if a mob dies drain stored energy by 25%",
maxCount: 1,
count: 0,
allowed() {
return !mod.isEnergyHealth
},
requires: "not mass-energy equivalence",
effect() {
mod.isEnergyLoss = true;
},
remove() {
mod.isEnergyLoss = false;
}
},
{
name: "heat engine",
description: `increase damage by 40%, but
reduce maximum energy by 50`,
maxCount: 1,
count: 0,
allowed() {
return mod.isEnergyLoss && mech.maxEnergy === 1 && !mod.isMissileField && !mod.isSporeField && !mod.isRewindAvoidDeath
},
requires: "exothermic process, not max energy increase, CPT, missile or spore nano-scale",
effect() {
mod.isMaxEnergyMod = true;
mech.setMaxEnergy()
},
remove() {
mod.isMaxEnergyMod = false;
mech.setMaxEnergy()
}
},
{
name: "Gibbs free energy",
description: `increase damage by 5%
for every 10 energy below 100`,
maxCount: 1,
count: 0,
allowed() {
return mod.isEnergyLoss && mech.maxEnergy < 1.1
},
requires: "exothermic process",
effect() {
mod.isLowEnergyDamage = true;
},
remove() {
mod.isLowEnergyDamage = false;
}
},
{
name: "rest frame",
description: "increase damage by 25%
when not moving",
maxCount: 6,
count: 0,
allowed() {
return mech.Fx === 0.016
},
requires: "base movement speed",
effect: () => {
mod.restDamage += 0.25
},
remove() {
mod.restDamage = 1;
}
},
{
name: "kinetic bombardment",
description: "increase damage by up to 33%
at a distance of 40 steps from the target",
maxCount: 1,
count: 0,
allowed() {
return true
},
requires: "",
effect() {
mod.isFarAwayDmg = true; //used in mob.damage()
},
remove() {
mod.isFarAwayDmg = false;
}
},
{
name: "fluoroantimonic acid",
description: "increase damage by 40%
when your health is above 100",
maxCount: 1,
count: 0,
allowed() {
return mech.maxHealth > 1;
},
requires: "health above 100",
effect() {
mod.isAcidDmg = true;
},
remove() {
mod.isAcidDmg = false;
}
},
{
name: "integrated armament",
description: "increase damage by 25%
your inventory can only hold 1 gun",
maxCount: 1,
count: 0,
allowed() {
return b.inventory.length < 2
},
requires: "no more than 1 gun",
effect() {
mod.isOneGun = true;
},
remove() {
mod.isOneGun = false;
}
},
{
name: "negative feedback",
description: "increase damage by 6%
for every 10 missing base health",
maxCount: 1,
count: 0,
allowed() {
return mech.health < 0.6 || build.isCustomSelection
},
requires: "health below 60",
effect() {
mod.isLowHealthDmg = true; //used in mob.damage()
},
remove() {
mod.isLowHealthDmg = false;
}
},
{
name: "radiative equilibrium",
description: "for 10 seconds after receiving harm
increase damage by 100%",
maxCount: 1,
count: 0,
allowed() {
return mech.harmReduction() < 1
},
requires: "some harm reduction",
effect() {
mod.isHarmDamage = true;
},
remove() {
mod.isHarmDamage = false;
}
},
{
name: "perturbation theory",
description: "increase damage by 4%
for each of your rerolls",
maxCount: 1,
count: 0,
allowed() {
return powerUps.reroll.rerolls > 3 || build.isCustomSelection
},
requires: "at least 4 rerolls",
effect() {
mod.isRerollDamage = true;
},
remove() {
mod.isRerollDamage = false;
}
},
{
name: "electrostatic discharge",
description: "increase damage by 20%
20% increased delay after firing",
maxCount: 1,
count: 0,
allowed() {
return true
},
effect() {
mod.slowFire = 1.2
b.setFireCD();
},
remove() {
mod.slowFire = 1;
b.setFireCD();
}
},
{
name: "Ψ(t) collapse",
description: "66% decreased delay after firing
when you have no rerolls",
maxCount: 1,
count: 0,
allowed() {
return powerUps.reroll.rerolls === 0 && !mod.manyWorlds
},
requires: "no rerolls",
effect() {
mod.isRerollHaste = true;
mod.rerollHaste = 0.33;
b.setFireCD();
},
remove() {
mod.isRerollHaste = false;
mod.rerollHaste = 1;
b.setFireCD();
}
},
{
name: "auto-loading heuristics",
description: "30% decreased delay after firing",
maxCount: 9,
count: 0,
allowed() {
return true
},
requires: "",
effect() {
mod.fireRate *= 0.7
b.setFireCD();
},
remove() {
mod.fireRate = 1;
b.setFireCD();
}
},
{
name: "mass driver",
description: "increase block collision damage by 100%
charge throws more quickly for less energy",
maxCount: 1,
count: 0,
allowed() {
return mech.fieldUpgrades[mech.fieldMode].name !== "wormhole"
},
requires: "not wormhole",
effect() {
mod.throwChargeRate = 2
},
remove() {
mod.throwChargeRate = 1
}
},
{
name: "fragmentation",
description: "detonation or collisions with mobs eject nails
blocks, rail gun, grenades, shotgun slugs",
maxCount: 9,
count: 0,
allowed() {
return (mod.haveGunCheck("grenades") && !mod.isNeutronBomb) || mod.haveGunCheck("rail gun") || (mod.haveGunCheck("shotgun") && mod.isSlugShot) || mod.throwChargeRate > 1
},
requires: "grenades, rail gun, shotgun slugs, or mass driver",
effect() {
mod.fragments++
},
remove() {
mod.fragments = 0
}
},
{
name: "ammonium nitrate",
description: "increase explosive damage by 20%
increase explosive radius by 20%",
maxCount: 9,
count: 0,
allowed() {
return mod.haveGunCheck("missiles") || mod.isIncendiary || (mod.haveGunCheck("grenades") && !mod.isNeutronBomb) || mod.haveGunCheck("vacuum bomb") || mod.isPulseLaser || mod.isMissileField || mod.boomBotCount > 1 || mod.isFlechetteExplode
},
requires: "an explosive damage source",
effect: () => {
mod.explosiveRadius += 0.2;
},
remove() {
mod.explosiveRadius = 1;
}
},
{
name: "nitroglycerin",
description: "increase explosive damage by 60%
decrease explosive radius by 20%",
maxCount: 1,
count: 0,
allowed() {
return mod.haveGunCheck("missiles") || mod.isIncendiary || (mod.haveGunCheck("grenades") && !mod.isNeutronBomb) || mod.haveGunCheck("vacuum bomb") || mod.isPulseLaser || mod.isMissileField || mod.boomBotCount > 1 || mod.isFlechetteExplode
},
requires: "an explosive damage source",
effect: () => {
mod.isSmallExplosion = true;
},
remove() {
mod.isSmallExplosion = false;
}
},
{
name: "acetone peroxide",
description: "increase explosive radius by 80%, but
you take 400% more harm from explosions",
maxCount: 1,
count: 0,
allowed() {
return mod.haveGunCheck("missiles") || mod.isIncendiary || (mod.haveGunCheck("grenades") && !mod.isNeutronBomb) || mod.haveGunCheck("vacuum bomb") || mod.isPulseLaser || mod.isMissileField || mod.isFlechetteExplode
},
requires: "an explosive damage source",
effect: () => {
mod.isExplosionHarm = true;
},
remove() {
mod.isExplosionHarm = false;
}
},
{
name: "electric reactive armor",
// description: "explosions do no harm
while your energy is above 98%",
description: "harm from explosions is passively reduced
by 7% for every 10 stored energy",
maxCount: 1,
count: 0,
allowed() {
return mod.haveGunCheck("missiles") || mod.isIncendiary || (mod.haveGunCheck("grenades") && !mod.isNeutronBomb) || mod.haveGunCheck("vacuum bomb") || mod.isMissileField || mod.isExplodeMob || mod.isFlechetteExplode || mod.isPulseLaser
},
requires: "an explosive damage source",
effect: () => {
mod.isImmuneExplosion = true;
},
remove() {
mod.isImmuneExplosion = false;
}
},
{
name: "thermal runaway",
description: "mobs explode when they die
be careful",
maxCount: 1,
count: 0,
allowed() {
return (mod.haveGunCheck("missiles") || mod.isIncendiary || (mod.haveGunCheck("grenades") && !mod.isNeutronBomb) || mod.haveGunCheck("vacuum bomb") || mod.isPulseLaser || mod.isMissileField || mod.boomBotCount > 1 || mod.isFlechetteExplode) && !mod.sporesOnDeath && !mod.nailsDeathMob && !mod.isBotSpawner
},
requires: "an explosive damage source, no other mob death mods",
effect: () => {
mod.isExplodeMob = true;
},
remove() {
mod.isExplodeMob = false;
}
},
{
name: "reaction inhibitor",
description: "mobs spawn with 12% less health",
maxCount: 3,
count: 0,
allowed() {
return mod.nailsDeathMob || mod.sporesOnDeath || mod.isExplodeMob || mod.isBotSpawner
},
requires: "any mob death mod",
effect: () => {
mod.mobSpawnWithHealth *= 0.88
//set all mobs at full health to 0.85
for (let i = 0; i < mob.length; i++) {
if (mob.health > mod.mobSpawnWithHealth) mob.health = mod.mobSpawnWithHealth
}
},
remove() {
mod.mobSpawnWithHealth = 1;
}
},
{
name: "zoospore vector",
description: "mobs produce spores when they die
9% chance",
maxCount: 9,
count: 0,
allowed() {
return !mod.nailsDeathMob && !mod.isExplodeMob && !mod.isBotSpawner
},
requires: "no other mob death mods",
effect() {
mod.sporesOnDeath += 0.09;
for (let i = 0; i < 8; i++) {
b.spore(mech.pos)
}
},
remove() {
mod.sporesOnDeath = 0;
}
},
{
name: "impact shear",
description: "mobs release a nail when they die
nails target nearby mobs",
maxCount: 9,
count: 0,
allowed() {
return !mod.sporesOnDeath && !mod.isExplodeMob && !mod.isBotSpawner
},
requires: "no other mob death mods",
effect: () => {
mod.nailsDeathMob++
},
remove() {
mod.nailsDeathMob = 0;
}
},
{
name: "scrap bots",
description: "20% chance to build a bot after killing a mob
the bot lasts for about 20 seconds",
maxCount: 3,
count: 0,
allowed() {
return mod.totalBots() > 0 && !mod.sporesOnDeath && !mod.nailsDeathMob && !mod.isExplodeMob
},
requires: "a bot and no other mob death mods",
effect() {
mod.isBotSpawner += 0.20;
},
remove() {
mod.isBotSpawner = 0;
}
},
{
name: "nail-bot",
description: "a bot fires nails at targets in line of sight",
maxCount: 9,
count: 0,
allowed() {
return true
},
requires: "",
effect() {
mod.nailBotCount++;
b.nailBot();
},
remove() {
mod.nailBotCount = 0;
}
},
{
name: "nail-bot upgrade",
description: "500% increased fire rate
applies to all current and future nail-bots",
maxCount: 1,
count: 0,
allowed() {
return mod.nailBotCount > 1
},
requires: "2 or more nail bots",
effect() {
mod.isNailBotUpgrade = true
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType === 'nail') bullet[i].isUpgraded = true
}
},
remove() {
mod.isNailBotUpgrade = false
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType === 'nail') bullet[i].isUpgraded = false
}
}
},
{
name: "foam-bot",
description: "a bot fires foam at targets in line of sight",
maxCount: 9,
count: 0,
allowed() {
return true
},
requires: "",
effect() {
mod.foamBotCount++;
b.foamBot();
},
remove() {
mod.foamBotCount = 0;
}
},
{
name: "foam-bot upgrade",
description: "200% increased foam size and fire rate
applies to all current and future foam-bots",
maxCount: 1,
count: 0,
allowed() {
return mod.foamBotCount > 1
},
requires: "2 or more foam bots",
effect() {
mod.isFoamBotUpgrade = true
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType === 'foam') bullet[i].isUpgraded = true
}
},
remove() {
mod.isFoamBotUpgrade = false
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType === 'foam') bullet[i].isUpgraded = false
}
}
},
{
name: "boom-bot",
description: "a bot defends the space around you
ignites an explosion after hitting a mob",
maxCount: 9,
count: 0,
allowed() {
return true
},
requires: "",
effect() {
mod.boomBotCount++;
b.boomBot();
},
remove() {
mod.boomBotCount = 0;
}
},
{
name: "boom-bot upgrade",
description: "250% increased explosion damage and size
applies to all current and future boom-bots",
maxCount: 1,
count: 0,
allowed() {
return mod.boomBotCount > 1
},
requires: "2 or more boom bots",
effect() {
mod.isBoomBotUpgrade = true
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType === 'boom') bullet[i].isUpgraded = true
}
},
remove() {
mod.isBoomBotUpgrade = false
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType === 'boom') bullet[i].isUpgraded = false
}
}
},
{
name: "laser-bot",
description: "a bot uses energy to emit a laser
targeting nearby mobs",
maxCount: 9,
count: 0,
allowed() {
return mech.maxEnergy > 0.5
},
requires: "maximum energy above 50%",
effect() {
mod.laserBotCount++;
b.laserBot();
},
remove() {
mod.laserBotCount = 0;
}
},
{
name: "laser-bot upgrade",
description: "350% increased laser damage
applies to all current and future laser-bots",
maxCount: 1,
count: 0,
allowed() {
return mod.laserBotCount > 1
},
requires: "2 or more laser bots",
effect() {
mod.isLaserBotUpgrade = true
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType === 'laser') bullet[i].isUpgraded = true
}
},
remove() {
mod.isLaserBotUpgrade = false
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType === 'laser') bullet[i].isUpgraded = false
}
}
},
{
name: "orbital-bot",
description: "a bot is locked in orbit around you
stuns and damages mobs on contact",
maxCount: 9,
count: 0,
allowed() {
return true
},
requires: "",
effect() {
b.orbitBot();
mod.orbitBotCount++;
},
remove() {
mod.orbitBotCount = 0;
}
},
{
name: "orbital-bot upgrade",
description: "increase damage by 150% and radius by 30%
applies to all current and future orbit-bots",
maxCount: 1,
count: 0,
allowed() {
return mod.orbitBotCount > 1
},
requires: "2 or more orbital bots",
effect() {
mod.isOrbitBotUpgrade = true
const range = 190 + 60 * mod.isOrbitBotUpgrade
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType === 'orbit') {
bullet[i].isUpgraded = true
bullet[i].range = range
bullet[i].orbitalSpeed = Math.sqrt(0.25 / range)
}
}
},
remove() {
mod.isOrbitBotUpgrade = false
const range = 190 + 60 * mod.isOrbitBotUpgrade
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType === 'orbit') {
bullet[i].range = range
bullet[i].orbitalSpeed = Math.sqrt(0.25 / range)
}
}
}
},
{
name: "bot fabrication",
description: "anytime you collect 5 rerolls
use them to build a random bot",
maxCount: 1,
count: 0,
allowed() {
return powerUps.reroll.rerolls > 5 || build.isCustomSelection
},
requires: "at least 6 rerolls",
effect() {
mod.isRerollBots = true;
powerUps.reroll.changeRerolls(0)
},
remove() {
mod.isRerollBots = false;
}
},
{
name: "perimeter defense",
description: "reduce harm by 3%
for each of your permanent bots",
maxCount: 1,
count: 0,
allowed() {
return mod.totalBots() > 5 && !mod.isEnergyHealth
},
requires: "5 or more bots",
effect() {
mod.isBotArmor = true
},
remove() {
mod.isBotArmor = false
}
}, {
name: "network effect",
description: "increase damage by 2%
for each of your permanent bots",
maxCount: 1,
count: 0,
allowed() {
return mod.totalBots() > 6
},
requires: "6 or more bots",
effect() {
mod.isBotDamage = true
},
remove() {
mod.isBotDamage = false
}
},
{
name: "bot replication",
description: "duplicate your permanent bots
remove all of your guns",
maxCount: 1,
count: 0,
// isNonRefundable: true,
isCustomHide: true,
allowed() {
return mod.totalBots() > 3
},
requires: "at least 3 bots",
effect() {
b.removeAllGuns();
game.makeGunHUD();
//double bots
for (let i = 0; i < mod.nailBotCount; i++) {
b.nailBot();
}
mod.nailBotCount *= 2
for (let i = 0; i < mod.laserBotCount; i++) {
b.laserBot();
}
mod.laserBotCount *= 2
for (let i = 0; i < mod.foamBotCount; i++) {
b.foamBot();
}
mod.foamBotCount *= 2
for (let i = 0; i < mod.boomBotCount; i++) {
b.boomBot();
}
mod.boomBotCount *= 2
for (let i = 0; i < mod.plasmaBotCount; i++) {
b.plasmaBot();
}
mod.plasmaBotCount *= 2
for (let i = 0; i < mod.orbitBotCount; i++) {
b.orbitBot();
}
mod.orbitBotCount *= 2
},
remove() {}
},
{
name: "ablative drones",
description: "rebuild your broken parts as drones
chance to occur after receiving harm",
maxCount: 1,
count: 0,
allowed() {
return mech.harmReduction() < 1
},
requires: "some harm reduction",
effect() {
mod.isDroneOnDamage = true;
for (let i = 0; i < 4; i++) {
b.drone() //spawn drone
}
},
remove() {
mod.isDroneOnDamage = false;
}
},
{
name: "mine synthesis",
description: "drop a mine after picking up a power up",
maxCount: 1,
count: 0,
allowed() {
return mod.duplicationChance() > 0
},
requires: "some power up duplication",
effect() {
mod.isMineDrop = true;
if (mod.isMineDrop) b.mine(mech.pos, { x: 0, y: 0 }, 0, mod.isMineAmmoBack)
},
remove() {
mod.isMineDrop = false;
}
},
{
name: "squirrel-cage rotor",
description: "move and jump about 25% faster",
maxCount: 9,
count: 0,
allowed() {
return true
},
requires: "",
effect() { // good with melee builds, content skipping builds
mod.squirrelFx += 0.2;
mod.squirrelJump += 0.09;
mech.setMovement()
},
remove() {
mod.squirrelFx = 1;
mod.squirrelJump = 1;
mech.setMovement()
}
},
{
name: "Newton's 1st law",
description: "moving at high speeds reduces harm
by up to 50%",
maxCount: 1,
count: 0,
allowed() {
return mech.Fx > 0.016 && !mod.isEnergyHealth
},
requires: "speed increase, not mass-energy equivalence",
effect() {
mod.isSpeedHarm = true
},
remove() {
mod.isSpeedHarm = false
}
},
{
name: "Newton's 2nd law",
description: "moving at high speeds increases damage
by up to 33%",
maxCount: 1,
count: 0,
allowed() {
return mech.Fx > 0.016
},
requires: "speed increase",
effect() {
mod.isSpeedDamage = true
},
remove() {
mod.isSpeedDamage = false
}
},
{
name: "Pauli exclusion",
description: `immune to harm for 0.5 seconds longer
after receiving harm from a collision`,
maxCount: 9,
count: 0,
allowed() {
return true
},
requires: "",
effect() {
mod.collisionImmuneCycles += 30;
mech.immuneCycle = mech.cycle + mod.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
},
remove() {
mod.collisionImmuneCycles = 25;
}
},
{
name: "decorrelation",
description: "reduce harm by 40%
after not using your gun or field for 2 seconds",
maxCount: 1,
count: 0,
allowed() {
return (mod.totalBots() > 1 || mod.haveGunCheck("drone") || mod.haveGunCheck("mine") || mod.haveGunCheck("spores") || mech.fieldUpgrades[mech.fieldMode].name === "nano-scale manufacturing") && !mod.isEnergyHealth
},
requires: "drones, spores, mines, or bots",
effect() {
mod.isNoFireDefense = true
},
remove() {
mod.isNoFireDefense = false
}
},
{
name: "anticorrelation",
description: "increase damage by 50%
after not using your gun or field for 2 seconds",
maxCount: 1,
count: 0,
allowed() {
return mod.isNoFireDefense
},
requires: "decorrelation",
effect() {
mod.isNoFireDamage = true
},
remove() {
mod.isNoFireDamage = false
}
},
{
name: "non-Newtonian armor",
description: "for 10 seconds after receiving harm
reduce harm by 50%",
maxCount: 1,
count: 0,
allowed() {
return !mod.isEnergyHealth && mech.harmReduction() < 1
},
requires: "some harm reduction",
effect() {
mod.isHarmArmor = true;
},
remove() {
mod.isHarmArmor = false;
}
},
{
name: "clock gating",
description: `slow time by 50% after receiving harm
reduce harm by 15%`,
maxCount: 1,
count: 0,
allowed() {
return game.fpsCapDefault > 45 && !mod.isRailTimeSlow
},
requires: "FPS above 45",
effect() {
mod.isSlowFPS = true;
},
remove() {
mod.isSlowFPS = false;
}
},
{
name: "liquid cooling",
description: `freeze all mobs for 4 seconds
after receiving harm`,
maxCount: 1,
count: 0,
allowed() {
return mod.isSlowFPS
},
requires: "clock gating",
effect() {
mod.isHarmFreeze = true;
},
remove() {
mod.isHarmFreeze = false;
}
},
{
name: "osmoprotectant",
description: `collisions with stunned or frozen mobs
cause you no harm`,
maxCount: 1,
count: 0,
allowed() {
return mod.isStunField || mod.isPulseStun || mod.oneSuperBall || mod.isHarmFreeze || mod.isIceField || mod.isIceCrystals || mod.isSporeFreeze || mod.isAoESlow || mod.isFreezeMobs || mod.haveGunCheck("ice IX") || mod.isCloakStun || mod.orbitBotCount > 1 || mod.isWormholeDamage
},
requires: "a freezing or stunning effect",
effect() {
mod.isFreezeHarmImmune = true;
},
remove() {
mod.isFreezeHarmImmune = false;
}
},
{
name: "supercapacitor",
description: "energy above your max decays 66% slower",
maxCount: 1,
count: 0,
allowed() {
return mod.isEnergyRecovery || mod.isPiezo || mod.energySiphon > 0 || mod.isRailEnergyGain || mod.isWormholeEnergy || mod.iceEnergy > 0
},
requires: "a source of overfilled energy",
effect() {
mod.overfillDrain = 0.933
},
remove() {
mod.overfillDrain = 0.8
}
},
{
name: "CPT reversal",
description: "rewind 1.5 - 5 seconds to avoid harm
drains 66 - 220 energy",
maxCount: 1,
count: 0,
allowed() { //&& (mech.fieldUpgrades[mech.fieldMode].name !== "nano-scale manufacturing" || mech.maxEnergy > 1)
return mech.maxEnergy > 0.99 && mech.fieldUpgrades[mech.fieldMode].name !== "standing wave harmonics" && !mod.isEnergyHealth
},
requires: "standing wave, mass-energy, piezoelectricity, max energy reduction",
effect() {
mod.isRewindAvoidDeath = true;
},
remove() {
mod.isRewindAvoidDeath = false;
}
},
{
name: "causality bots",
description: "when you rewind, build some bots
that protect you for about 7 seconds",
maxCount: 3,
count: 0,
allowed() {
return mod.isRewindAvoidDeath || mod.isRewindEnergy
},
requires: "CPT",
effect() {
mod.isRewindBot++;
},
remove() {
mod.isRewindBot = 0;
}
},
{
name: "causality bombs",
description: "before you rewind drop some grenades",
maxCount: 1,
count: 0,
allowed() {
return mod.isRewindAvoidDeath
},
requires: "CPT",
effect() {
mod.isRewindGrenade = true;
},
remove() {
mod.isRewindGrenade = false;
}
},
{
name: "piezoelectricity",
description: "colliding with mobs overfills energy by 200
reduce harm by 15%",
maxCount: 1,
count: 0,
allowed() {
return !mod.isEnergyHealth
},
requires: "not mass-energy equivalence",
effect() {
mod.isPiezo = true;
mech.energy += 2;
},
remove() {
mod.isPiezo = false;
}
},
{
name: "ground state",
description: "reduce harm by 60%
you no longer passively regenerate energy",
maxCount: 1,
count: 0,
allowed() {
return mod.isPiezo && mod.energyRegen !== 0.004
},
requires: "piezoelectricity, not time crystals",
effect: () => {
mod.energyRegen = 0;
mech.fieldRegen = mod.energyRegen;
},
remove() {
mod.energyRegen = 0.001;
mech.fieldRegen = mod.energyRegen;
}
},
{
name: "mass-energy equivalence",
description: "energy protects you instead of health
harm reduction effects provide no benefit",
maxCount: 1,
count: 0,
allowed() {
return !mod.isEnergyLoss && !mod.isPiezo && !mod.isRewindAvoidDeath && !mod.isSpeedHarm && mech.fieldUpgrades[mech.fieldMode].name !== "negative mass field"
},
requires: "not exothermic process, piezoelectricity, CPT, 1st law, negative mass field",
effect: () => {
mech.health = 0
// mech.displayHealth();
document.getElementById("health").style.display = "none"
document.getElementById("health-bg").style.display = "none"
document.getElementById("dmg").style.backgroundColor = "#0cf";
mod.isEnergyHealth = true;
mech.displayHealth();
},
remove() {
mod.isEnergyHealth = false;
document.getElementById("health").style.display = "inline"
document.getElementById("health-bg").style.display = "inline"
document.getElementById("dmg").style.backgroundColor = "#f67";
mech.health = Math.min(mech.maxHealth, mech.energy);
mech.displayHealth();
}
},
{
name: "1st ionization energy",
description: "each heal power up you collect
increases your maximum energy by 4",
maxCount: 1,
count: 0,
allowed() {
return mod.isEnergyHealth
},
requires: "mass-energy equivalence",
effect() {
mod.healGiveMaxEnergy = true; //mod.healMaxEnergyBonus given from heal power up
powerUps.heal.color = "#0ae"
for (let i = 0; i < powerUp.length; i++) { //find active heal power ups and adjust color live
if (powerUp[i].name === "heal") powerUp[i].color = powerUps.heal.color
}
},
remove() {
mod.healGiveMaxEnergy = false;
mod.healMaxEnergyBonus = 0
powerUps.heal.color = "#0eb"
for (let i = 0; i < powerUp.length; i++) { //find active heal power ups and adjust color live
if (powerUp[i].name === "heal") powerUp[i].color = powerUps.heal.color
}
}
},
{
name: "overcharge",
description: "increase your maximum energy by 50",
maxCount: 9,
count: 0,
allowed() {
return mech.maxEnergy > 0.99
},
requires: "max energy >= 1",
effect() {
// mech.maxEnergy += 0.5
// mech.energy += 0.5
mod.bonusEnergy += 0.5
mech.setMaxEnergy()
},
remove() {
mod.bonusEnergy = 0;
mech.setMaxEnergy()
}
},
{
name: "energy conservation",
description: "6% of damage done recovered as energy",
maxCount: 9,
count: 0,
allowed() {
return mod.damageFromMods() > 1
},
requires: "some increased damage",
effect() {
mod.energySiphon += 0.06;
},
remove() {
mod.energySiphon = 0;
}
},
{
name: "waste energy recovery",
description: "if a mob has died in the last 5 seconds
regen 5% of max energy every second",
maxCount: 1,
count: 0,
allowed() {
return mech.maxEnergy > 0.99
},
requires: "max energy >= 1",
effect() {
mod.isEnergyRecovery = true;
},
remove() {
mod.isEnergyRecovery = false;
}
},
{
name: "scrap recycling",
description: "if a mob has died in the last 5 seconds
regain 1% of max health every second",
maxCount: 1,
count: 0,
allowed() {
return !mod.isEnergyHealth
},
requires: "not mass-energy equivalence",
effect() {
mod.isHealthRecovery = true;
},
remove() {
mod.isHealthRecovery = false;
}
},
{
name: "entropy exchange",
description: "heal for 1% of damage done",
maxCount: 9,
count: 0,
allowed() {
return !mod.isEnergyHealth && mod.damageFromMods() > 1
},
requires: "some increased damage, not mass-energy equivalence",
effect() {
mod.healthDrain += 0.01;
},
remove() {
mod.healthDrain = 0;
}
},
{
name: "supersaturation",
description: "increase your maximum health by 50",
maxCount: 9,
count: 0,
allowed() {
return !mod.isEnergyHealth
},
requires: "not mass-energy equivalence",
effect() {
mod.bonusHealth += 0.5
mech.addHealth(0.50)
mech.setMaxHealth();
},
remove() {
mod.bonusHealth = 0
mech.setMaxHealth();
}
},
{
name: "crystallized armor",
description: "increase maximum health by 5 for each
unused power up at the end of a level",
maxCount: 1,
count: 0,
allowed() {
return !mod.isEnergyHealth
},
requires: "not mass-energy equivalence",
effect() {
mod.isArmorFromPowerUps = true; //tracked by mod.armorFromPowerUps
},
remove() {
mod.isArmorFromPowerUps = false;
// mod.armorFromPowerUps = 0; //this is now reset in mod.setupAllMods();
mech.setMaxHealth();
}
},
{
name: "negentropy",
description: `at the start of each level
spawn a heal for every 50 missing health`,
maxCount: 1,
count: 0,
allowed() {
return mech.maxHealth > 1 || mod.isArmorFromPowerUps
},
requires: "increased max health",
effect() {
mod.isHealLowHealth = true;
},
remove() {
mod.isHealLowHealth = false;
}
},
{
name: "adiabatic healing",
description: "heal power ups are 100% more effective",
maxCount: 3,
count: 0,
allowed() {
return (mech.health < 0.7 || build.isCustomSelection) && !mod.isEnergyHealth
},
requires: "not mass-energy equivalence",
effect() {
mod.largerHeals++;
},
remove() {
mod.largerHeals = 1;
}
},
{
name: "anthropic principle",
nameInfo: "",
addNameInfo() {
setTimeout(function() {
powerUps.reroll.changeRerolls(0)
}, 1000);
},
description: "consume a reroll to avoid dying once a level
and spawn 6 heal power ups",
maxCount: 1,
count: 0,
allowed() {
return powerUps.reroll.rerolls > 0 || build.isCustomSelection
},
requires: "at least 1 reroll",
effect() {
mod.isDeathAvoid = true;
mod.isDeathAvoidedThisLevel = false;
setTimeout(function() {
powerUps.reroll.changeRerolls(0)
}, 1000);
},
remove() {
mod.isDeathAvoid = false;
}
},
{
name: "bubble fusion",
description: "after destroying a mob's shield
spawn 1-2 heals, ammo, or rerolls",
maxCount: 1,
count: 0,
allowed() {
return true
},
requires: "",
effect() {
mod.isShieldAmmo = true;
},
remove() {
mod.isShieldAmmo = false;
}
},
{
name: "Bayesian statistics",
description: "20% chance to duplicate spawned power ups
after a collision, eject one of your mods",
maxCount: 1,
count: 0,
allowed() {
return true
},
requires: "",
effect: () => {
mod.isBayesian = true
game.draw.powerUp = game.draw.powerUpBonus //change power up draw
},
remove() {
mod.isBayesian = false
if (mod.duplicationChance() === 0) game.draw.powerUp = game.draw.powerUpNormal
}
},
{
name: "stimulated emission",
description: "7% chance to duplicate spawned power ups",
maxCount: 9,
count: 0,
allowed() {
return true
},
requires: "",
effect() {
mod.duplicateChance += 0.07
game.draw.powerUp = game.draw.powerUpBonus //change power up draw
},
remove() {
mod.duplicateChance = 0
if (mod.duplicationChance() === 0) game.draw.powerUp = game.draw.powerUpNormal
}
},
{
name: "futures exchange",
description: "clicking × to cancel a mod, field, or gun
increases power up duplication chance by 4%",
maxCount: 1,
count: 0,
allowed() {
return !mod.isDeterminism
},
requires: "not determinism",
effect() {
mod.isCancelDuplication = true
mod.cancelCount = 0
game.draw.powerUp = game.draw.powerUpBonus //change power up draw
},
remove() {
mod.isCancelDuplication = false
mod.cancelCount = 0
if (mod.duplicationChance() === 0) game.draw.powerUp = game.draw.powerUpNormal
}
},
{
name: "commodities exchange",
description: "clicking × to cancel a mod, field, or gun
spawns 6 heals, ammo, or rerolls",
maxCount: 1,
count: 0,
allowed() {
return mod.duplicationChance() > 0 && !mod.isDeterminism
},
requires: "a chance to duplicate power ups, not determinism",
effect() {
mod.isCancelRerolls = true
},
remove() {
mod.isCancelRerolls = false
}
},
{
name: "reallocation",
description: "convert 1 random mod into 3 new guns
recursive mods lose all stacks",
maxCount: 1,
count: 0,
isNonRefundable: true,
isCustomHide: true,
allowed() {
return (mod.totalCount > 3) && !mod.isSuperDeterminism
},
requires: "at least 1 mod, a chance to duplicate power ups",
effect: () => {
const have = [] //find which mods you have
for (let i = 0; i < mod.mods.length; i++) {
if (mod.mods[i].count > 0) have.push(i)
}
const choose = have[Math.floor(Math.random() * have.length)]
game.makeTextLog(`