diff --git a/js/bullet.js b/js/bullet.js index 7633432..ebe2c71 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -852,7 +852,7 @@ const b = { if (mod.iceEnergy && !who.shield && !who.isShielded && who.dropPowerUp && who.alive) { setTimeout(function() { if (!who.alive) { - mech.energy += mod.iceEnergy * 0.5 * mech.maxEnergy + mech.energy += mod.iceEnergy mech.addHealth(mod.iceEnergy * 0.04) } }, 10); @@ -1255,7 +1255,7 @@ const b = { if (isKeep) mod.boomBotCount++; } }, - nailBot(position = mech.pos) { + nailBot(position = { x: mech.pos.x + 50 * (Math.random() - 0.5), y: mech.pos.y + 50 * (Math.random() - 0.5) }) { const me = bullet.length; const dir = mech.angle; const RADIUS = (12 + 4 * Math.random()) @@ -1286,7 +1286,7 @@ const b = { onEnd() {}, do() { if (this.lastLookCycle < game.cycle && !mech.isCloak) { - this.lastLookCycle = game.cycle + 80 - this.isUpgraded * 65 + this.lastLookCycle = game.cycle + (this.isUpgraded ? 15 : 80) let target for (let i = 0, len = mob.length; i < len; i++) { const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)); @@ -1310,7 +1310,7 @@ const b = { }) World.add(engine.world, bullet[me]); //add bullet to world }, - foamBot(position = mech.pos) { + foamBot(position = { x: mech.pos.x + 50 * (Math.random() - 0.5), y: mech.pos.y + 50 * (Math.random() - 0.5) }) { const me = bullet.length; const dir = mech.angle; const RADIUS = (10 + 5 * Math.random()) @@ -1366,7 +1366,7 @@ const b = { }) World.add(engine.world, bullet[me]); //add bullet to world }, - laserBot(position = mech.pos) { + laserBot(position = { x: mech.pos.x + 50 * (Math.random() - 0.5), y: mech.pos.y + 50 * (Math.random() - 0.5) }) { const me = bullet.length; const dir = mech.angle; const RADIUS = (14 + 6 * Math.random()) @@ -1443,7 +1443,7 @@ const b = { }) World.add(engine.world, bullet[me]); //add bullet to world }, - boomBot(position = mech.pos) { + boomBot(position = { x: mech.pos.x + 50 * (Math.random() - 0.5), y: mech.pos.y + 50 * (Math.random() - 0.5) }) { const me = bullet.length; const dir = mech.angle; const RADIUS = (7 + 2 * Math.random()) @@ -1521,7 +1521,7 @@ const b = { }) World.add(engine.world, bullet[me]); //add bullet to world }, - plasmaBot(position = mech.pos) { + plasmaBot(position = { x: mech.pos.x + 50 * (Math.random() - 0.5), y: mech.pos.y + 50 * (Math.random() - 0.5) }) { const me = bullet.length; const dir = mech.angle; const RADIUS = 21 @@ -2135,8 +2135,8 @@ const b = { name: "flechettes", description: "fire a volley of uranium-235 needles
does radioactive damage over 3 seconds", ammo: 0, - ammoPack: 55, - defaultAmmoPack: 55, + ammoPack: 65, + defaultAmmoPack: 65, have: false, count: 0, //used to track how many shots are in a volley before a big CD lastFireCycle: 0, //use to remember how longs its been since last fire, used to reset count @@ -2163,9 +2163,9 @@ const b = { this.immuneList.push(who.id) who.foundPlayer(); if (mod.isFastDot) { - mobs.statusDoT(who, 4, 30) + mobs.statusDoT(who, 3.78, 30) } else { - mobs.statusDoT(who, 0.66, mod.isSlowDot ? 360 : 180) + mobs.statusDoT(who, 0.63, mod.isSlowDot ? 360 : 180) } game.drawList.push({ //add dmg to draw queue x: this.position.x, @@ -2222,10 +2222,10 @@ const b = { makeFlechette(mech.angle - 0.02 - 0.005 * Math.random()) } - const CD = (mech.crouch) ? 60 : 30 + const CD = (mech.crouch) ? 50 : 20 if (this.lastFireCycle + CD < mech.cycle) this.count = 0 //reset count if it cycles past the CD this.lastFireCycle = mech.cycle - if (this.count > ((mech.crouch) ? 7 : 1)) { + if (this.count > ((mech.crouch) ? 8 : 1)) { this.count = 0 mech.fireCDcycle = mech.cycle + Math.floor(CD * b.fireCD); // cool down const who = bullet[bullet.length - 1] diff --git a/js/level.js b/js/level.js index 169cef8..48cf96a 100644 --- a/js/level.js +++ b/js/level.js @@ -13,7 +13,7 @@ const level = { start() { if (level.levelsCleared === 0) { //this code only runs on the first level // game.enableConstructMode() //used to build maps in testing mode - // level.difficultyIncrease(9) + // level.difficultyIncrease(99) // game.zoomScale = 1000; // game.setZoom(); // mech.setField("wormhole") @@ -2300,7 +2300,7 @@ const level = { //chance to spawn a ring of exploding mobs around this boss if (game.difficulty > 6) spawn.nodeBoss(2850, -80, "spawns", 8, 20, 105); } else { - spawn.randomLevelBoss(2200, -650) + spawn.randomLevelBoss(2200, -450) } } powerUps.addRerollToLevel() //needs to run after mobs are spawned diff --git a/js/mob.js b/js/mob.js index 36cfa67..33c5d8d 100644 --- a/js/mob.js +++ b/js/mob.js @@ -1043,14 +1043,16 @@ const mobs = { for (let i = 0; i < len; i++) { b.spore(this.position) } + } else if (mod.isExplodeMob) { + b.explosion(this.position, Math.min(600, Math.sqrt(this.mass + 2.75) * 55)) + } else if (mod.nailsDeathMob) { + b.targetedNail(this.position, mod.nailsDeathMob, 39 + 6 * Math.random()) } if (Math.random() < mod.isBotSpawner) { b.randomBot(this.position, false) bullet[bullet.length - 1].endCycle = game.cycle + 1000 + Math.floor(400 * Math.random()) this.leaveBody = false; // no body since it turned into the bot } - if (mod.isExplodeMob) b.explosion(this.position, Math.min(550, Math.sqrt(this.mass + 2.5) * 50)) - if (mod.nailsDeathMob) b.targetedNail(this.position, mod.nailsDeathMob, 40 + 7 * Math.random()) } else if (mod.isShieldAmmo && this.shield) { let type = mod.isEnergyNoAmmo ? "heal" : "ammo" if (Math.random() < 0.4) { diff --git a/js/mods.js b/js/mods.js index 8bdb434..d5a8957 100644 --- a/js/mods.js +++ b/js/mods.js @@ -82,7 +82,9 @@ const mod = { }, damageFromMods() { let dmg = mech.fieldDamage - // if (mod.aimDamage>1) + // 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) @@ -100,7 +102,7 @@ const mod = { return dmg * mod.slowFire * mod.aimDamage }, duplicationChance() { - return (mod.isBayesian ? 0.16 : 0) + mod.cancelCount * 0.04 + mod.duplicateChance + mech.duplicateChance + 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 @@ -122,7 +124,7 @@ const mod = { } }, { name: "capacitor", - description: "increase damage by 1%
for every 7% stored energy", + description: "increase damage by 1%
for every 7 stored energy", maxCount: 1, count: 0, allowed() { @@ -153,7 +155,7 @@ const mod = { } }, { - name: "acute stress response", + name: "exothermic process", description: "increase damage by 50%
if a mob dies drain stored energy by 25%", maxCount: 1, count: 0, @@ -168,6 +170,40 @@ const mod = { 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.isTimeAvoidDeath + }, + requires: "heat engine, 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: "heat engine", + effect() { + mod.isLowEnergyDamage = true; + }, + remove() { + mod.isLowEnergyDamage = false; + } + }, { name: "rest frame", description: "increase damage by 25%
when not moving", @@ -202,13 +238,13 @@ const mod = { }, { name: "fluoroantimonic acid", - description: "increase damage by 40%
when your health is above 100%", + description: "increase damage by 40%
when your health is above 100", maxCount: 1, count: 0, allowed() { return mech.maxHealth > 1; }, - requires: "health above 100%", + requires: "health above 100", effect() { mod.isAcidDmg = true; }, @@ -218,13 +254,13 @@ const mod = { }, { name: "negative feedback", - description: "increase damage by 6%
for every 10% missing base health", + 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%", + requires: "health below 60", effect() { mod.isLowHealthDmg = true; //used in mob.damage() }, @@ -283,7 +319,7 @@ const mod = { }, { name: "Ψ(t) collapse", - description: "66% decreased delay after firing
if you have no rerolls", + description: "66% decreased delay after firing
when you have no rerolls", maxCount: 1, count: 0, allowed() { @@ -341,9 +377,9 @@ const mod = { maxCount: 3, count: 0, allowed() { - return true + return mod.nailsDeathMob || mod.sporesOnDeath || mod.isExplodeMob }, - requires: "", + requires: "zoospore vector or impact shear or thermal runaway", effect: () => { mod.mobSpawnWithHealth *= 0.88 @@ -362,9 +398,9 @@ const mod = { maxCount: 9, count: 0, allowed() { - return true + return !mod.nailsDeathMob && !mod.isExplodeMob }, - requires: "", + requires: "not impact shear or thermal runaway", effect() { mod.sporesOnDeath += 0.09; for (let i = 0; i < 8; i++) { @@ -381,9 +417,9 @@ const mod = { maxCount: 9, count: 0, allowed() { - return true + return !mod.sporesOnDeath && !mod.isExplodeMob }, - requires: "", + requires: "not zoospore vector or thermal runaway", effect: () => { mod.nailsDeathMob++ }, @@ -397,9 +433,9 @@ const mod = { maxCount: 1, count: 0, allowed() { - return true + 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 }, - requires: "", + requires: "an explosive damage source, not zoospore vector or impact shear", effect: () => { mod.isExplodeMob = true; }, @@ -490,13 +526,13 @@ const mod = { }, { name: "bot fabrication", - description: "anytime you collect 4 rerolls
use them to build a random bot", + description: "anytime you collect 5 rerolls
use them to build a random bot", maxCount: 1, count: 0, allowed() { - return powerUps.reroll.rerolls > 3 || build.isCustomSelection + return powerUps.reroll.rerolls > 5 || build.isCustomSelection }, - requires: "at least 4 rerolls", + requires: "at least 6 rerolls", effect() { mod.isRerollBots = true; powerUps.reroll.changeRerolls(0) @@ -524,7 +560,7 @@ const mod = { }, { name: "nail-bot upgrade", - description: "300% increased fire rate
applies to all current and future nail-bots", + description: "500% increased fire rate
applies to all current and future nail-bots", maxCount: 1, count: 0, allowed() { @@ -731,7 +767,7 @@ const mod = { maxCount: 1, count: 0, allowed() { - return mod.totalBots() > 6 && !mod.isEnergyHealth + return mod.totalBots() > 6 }, requires: "6 or more bots", effect() { @@ -808,11 +844,12 @@ const mod = { maxCount: 1, count: 0, allowed() { - return true + return mod.duplicationChance() > 0 }, - requires: "", + 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; @@ -1002,13 +1039,13 @@ const mod = { }, { name: "CPT reversal", - description: "rewind 2-4 seconds to avoid harm
drains a minimum of 100% energy", + description: "rewind 1.5 - 5 seconds to avoid harm
drains 66 - 220 energy", maxCount: 1, count: 0, allowed() { - return (mech.fieldUpgrades[mech.fieldMode].name !== "nano-scale manufacturing" || mech.maxEnergy > 1) && mech.fieldUpgrades[mech.fieldMode].name !== "standing wave harmonics" && !mod.isEnergyHealth && !mod.isEnergyLoss && !mod.isPiezo + return mech.maxEnergy > 0.99 && (mech.fieldUpgrades[mech.fieldMode].name !== "nano-scale manufacturing" || mech.maxEnergy > 1) && mech.fieldUpgrades[mech.fieldMode].name !== "standing wave harmonics" && !mod.isEnergyHealth && !mod.isEnergyLoss && !mod.isPiezo }, - requires: "not nano-scale manufacturing, mass-energy equivalence, standing wave harmonics, acute stress response, piezoelectricity", + requires: "not nano-scale, mass-energy, standing wave, acute stress, piezoelectricity", effect() { mod.isTimeAvoidDeath = true; }, @@ -1018,7 +1055,7 @@ const mod = { }, { name: "piezoelectricity", - description: "colliding with mobs overfills energy by 200%
reduce harm by 15%", + description: "colliding with mobs overfills energy by 200
reduce harm by 15%", maxCount: 1, count: 0, allowed() { @@ -1039,9 +1076,9 @@ const mod = { maxCount: 1, count: 0, allowed() { - return mod.isPiezo && mod.energyRegen > 0.001 + return mod.isPiezo && mod.energyRegen !== 0.004 }, - requires: "piezoelectricity", + requires: "piezoelectricity, not time crystals", effect: () => { mod.energyRegen = 0; mech.fieldRegen = mod.energyRegen; @@ -1057,7 +1094,7 @@ const mod = { maxCount: 1, count: 0, allowed() { - return !mod.isPiezo && !mod.isTimeAvoidDeath && !mod.isSpeedHarm && mech.fieldUpgrades[mech.fieldMode].name !== "negative mass field" + return !mod.isEnergyLoss && !mod.isPiezo && !mod.isTimeAvoidDeath && !mod.isSpeedHarm && mech.fieldUpgrades[mech.fieldMode].name !== "negative mass field" }, requires: "not piezoelectricity, acute stress response, 1st law, negative mass field", effect: () => { @@ -1081,7 +1118,7 @@ const mod = { }, { name: "1st ionization energy", - description: "each heal power up you collect
increases your maximum energy by 4%", + description: "each heal power up you collect
increases your maximum energy by 4", maxCount: 1, count: 0, allowed() { @@ -1106,13 +1143,13 @@ const mod = { }, { name: "overcharge", - description: "increase your maximum energy by 50%", + description: "increase your maximum energy by 50", maxCount: 9, count: 0, allowed() { - return true + return mech.maxEnergy > 0.99 }, - requires: "", + requires: "max energy >= 1", effect() { // mech.maxEnergy += 0.5 // mech.energy += 0.5 @@ -1130,9 +1167,9 @@ const mod = { maxCount: 9, count: 0, allowed() { - return true + return mod.damageFromMods() > 1 }, - requires: "", + requires: "some increased damage", effect() { mod.energySiphon += 0.07; }, @@ -1146,9 +1183,9 @@ const mod = { maxCount: 1, count: 0, allowed() { - return true + return mech.maxEnergy > 0.99 }, - requires: "", + requires: "max energy >= 1", effect() { mod.isEnergyRecovery = true; }, @@ -1158,7 +1195,7 @@ const mod = { }, { name: "scrap recycling", - description: "if a mob has died in the last 5 seconds
heal 1% of max health every second", + description: "if a mob has died in the last 5 seconds
regain 1% of max health every second", maxCount: 1, count: 0, allowed() { @@ -1178,9 +1215,9 @@ const mod = { maxCount: 9, count: 0, allowed() { - return !mod.isEnergyHealth + return !mod.isEnergyHealth && mod.damageFromMods() > 1 }, - requires: "not mass-energy equivalence", + requires: "some increased damage, not mass-energy equivalence", effect() { mod.healthDrain += 0.01; }, @@ -1190,7 +1227,7 @@ const mod = { }, { name: "supersaturation", - description: "increase your maximum health by 50%", + description: "increase your maximum health by 50", maxCount: 9, count: 0, allowed() { @@ -1210,7 +1247,7 @@ const mod = { }, { name: "crystallized armor", - description: "increase maximum health by 5% for each
unused power up at the end of a level", + description: "increase maximum health by 5 for each
unused power up at the end of a level", maxCount: 1, count: 0, allowed() { @@ -1228,7 +1265,7 @@ const mod = { }, { name: "negentropy", - description: `at the start of each level
spawn a heal for every 50% missing health`, + description: `at the start of each level
spawn a heal for every 50 missing health`, maxCount: 1, count: 0, allowed() { @@ -1302,7 +1339,7 @@ const mod = { }, { name: "Bayesian statistics", - description: "16% chance to duplicate spawned power ups
after a collision, eject one of your mods", + description: "20% chance to duplicate spawned power ups
after a collision, eject one of your mods", maxCount: 1, count: 0, allowed() { @@ -1342,9 +1379,9 @@ const mod = { maxCount: 1, count: 0, allowed() { - return !mod.isDeterminism + return mod.duplicationChance() > 0 && !mod.isDeterminism }, - requires: "not determinism", + requires: "a chance to duplicate power ups, not determinism", effect() { mod.isCancelDuplication = true mod.cancelCount = 0 @@ -1380,7 +1417,7 @@ const mod = { isNonRefundable: true, isCustomHide: true, allowed() { - return (mod.totalCount > 0) && !mod.isSuperDeterminism && mod.duplicationChance() > 0 + return (mod.totalCount > 3) && !mod.isSuperDeterminism }, requires: "at least 1 mod, a chance to duplicate power ups", effect: () => { @@ -1410,7 +1447,7 @@ const mod = { isNonRefundable: true, isCustomHide: true, allowed() { - return (mod.totalCount > 0) && !mod.isSuperDeterminism && mod.duplicationChance() > 0 + return (mod.totalCount > 3) && !mod.isSuperDeterminism && mod.duplicationChance() > 0 }, requires: "at least 1 mod, a chance to duplicate power ups", effect: () => { @@ -1433,18 +1470,19 @@ const mod = { }, { name: "exchange symmetry", - description: `spawn 1 mod
with double your normal chance for power up duplication`, + description: `use a reroll to spawn 1 mod
with double your duplication chance`, maxCount: 1, count: 0, isNonRefundable: true, isCustomHide: true, allowed() { - return !mod.isSuperDeterminism && mod.duplicationChance() > 0 + return !mod.isSuperDeterminism && mod.duplicationChance() > 0 && powerUps.reroll.rerolls > 1 }, - requires: "at least 1 mod, a chance to duplicate power ups", + requires: "at least 1 mod and 1 reroll, a chance to duplicate power ups", effect: () => { + powerUps.reroll.changeRerolls(-1) const chanceStore = mod.duplicateChance - mod.duplicateChance = (mod.isBayesian ? 0.16 : 0) + mod.cancelCount * 0.04 + mech.duplicateChance + mod.duplicateChance * 2 //increase duplication chance to simulate doubling all 3 sources of duplication chance + mod.duplicateChance = (mod.isBayesian ? 0.2 : 0) + mod.cancelCount * 0.04 + mech.duplicateChance + mod.duplicateChance * 2 //increase duplication chance to simulate doubling all 3 sources of duplication chance powerUps.spawn(mech.pos.x, mech.pos.y, "mod"); mod.duplicateChance = chanceStore }, @@ -1612,7 +1650,7 @@ const mod = { }, { name: "determinism", - description: "spawn 4 mods
mods, fields, and guns have only 1 choice", + description: "spawn 5 mods
mods, fields, and guns have only 1 choice", maxCount: 1, count: 0, isNonRefundable: true, @@ -1622,7 +1660,7 @@ const mod = { requires: "not cardinality, not futures or commodities exchanges", effect: () => { mod.isDeterminism = true; - for (let i = 0; i < 4; i++) { //if you change the six also change it in Born rule + for (let i = 0; i < 5; i++) { //if you change the six also change it in Born rule powerUps.spawn(mech.pos.x, mech.pos.y, "mod"); } }, @@ -1632,7 +1670,7 @@ const mod = { }, { name: "superdeterminism", - description: "spawn 6 mods
rerolls, guns, and fields no longer spawn", + description: "spawn 7 mods
rerolls, guns, and fields no longer spawn", maxCount: 1, count: 0, isNonRefundable: true, @@ -1642,7 +1680,7 @@ const mod = { requires: "determinism", effect: () => { mod.isSuperDeterminism = true; - for (let i = 0; i < 6; i++) { //if you change the six also change it in Born rule + for (let i = 0; i < 7; i++) { //if you change the six also change it in Born rule powerUps.spawn(mech.pos.x, mech.pos.y, "mod"); } }, @@ -1790,7 +1828,7 @@ const mod = { maxCount: 1, count: 0, allowed() { - return !mod.isPerpetualReroll && !mod.isPerpetualHeal && !mod.isPerpetualReroll && !mod.isPerpetualStun + return !mod.isPerpetualReroll && !mod.isPerpetualHeal && !mod.isPerpetualReroll && !mod.isPerpetualStun && !mod.isEnergyNoAmmo }, requires: "only 1 perpetual effect, not exciton lattice", effect() { @@ -2425,7 +2463,7 @@ const mod = { maxCount: 1, count: 0, allowed() { - return mod.haveGunCheck("mine") && !mod.isMineAmmoBack + return (mod.haveGunCheck("mine") && !mod.isMineAmmoBack) || mod.isMineDrop }, requires: "mine, not mine reclamation", effect() { @@ -2441,7 +2479,7 @@ const mod = { maxCount: 1, count: 0, allowed() { - return mod.nailBotCount + mod.grenadeFragments + mod.nailsDeathMob / 2 + (mod.haveGunCheck("mine") + mod.isRailNails + mod.isNailShot + (mod.haveGunCheck("nail gun") && !mod.isIncendiary)) * 2 > 1 + return mod.isMineDrop + mod.nailBotCount + mod.grenadeFragments + mod.nailsDeathMob / 2 + (mod.haveGunCheck("mine") + mod.isRailNails + mod.isNailShot + (mod.haveGunCheck("nail gun") && !mod.isIncendiary)) * 2 > 1 }, requires: "nails", effect() { @@ -2457,7 +2495,7 @@ const mod = { maxCount: 1, count: 0, allowed() { - return mod.nailBotCount + mod.grenadeFragments + mod.nailsDeathMob / 2 + (mod.haveGunCheck("mine") + mod.isRailNails + mod.isNailShot + (mod.haveGunCheck("nail gun") && !mod.isIncendiary)) * 2 > 1 + return mod.isMineDrop + mod.nailBotCount + mod.grenadeFragments + mod.nailsDeathMob / 2 + (mod.haveGunCheck("mine") + mod.isRailNails + mod.isNailShot + (mod.haveGunCheck("nail gun") && !mod.isIncendiary)) * 2 > 1 }, requires: "nails", effect() { @@ -2534,7 +2572,7 @@ const mod = { }, { name: "mutualism", - description: "increase spore damage by 100%
spores borrow 1% health until they die", + description: "increase spore damage by 100%
spores borrow 1 health until they die", maxCount: 1, count: 0, allowed() { @@ -2614,7 +2652,7 @@ const mod = { }, { name: "thermoelectric effect", - description: "killing mobs with ice IX gives 4% health
and overloads energy by 50% of your max", + description: "killing mobs with ice IX gives 4 health
and overloads energy by 100", maxCount: 9, count: 0, allowed() { @@ -3181,7 +3219,7 @@ const mod = { requires: "nano-scale manufacturing", effect: () => { mod.isMassEnergy = true // used in mech.grabPowerUp - if (mech.energy < mech.maxEnergy * 2.5) mech.energy = mech.maxEnergy * 2.5 + mech.energy += mech.maxEnergy * 2.5 }, remove() { mod.isMassEnergy = false; @@ -3193,7 +3231,7 @@ const mod = { maxCount: 1, count: 0, allowed() { - return mech.fieldUpgrades[mech.fieldMode].name === "nano-scale manufacturing" && !(mod.isMissileField || mod.isIceField || mod.isFastDrones || mod.isDroneGrab) + return mech.maxEnergy > 0.99 && mech.fieldUpgrades[mech.fieldMode].name === "nano-scale manufacturing" && !(mod.isMissileField || mod.isIceField || mod.isFastDrones || mod.isDroneGrab) }, requires: "nano-scale manufacturing", effect() { @@ -3209,7 +3247,7 @@ const mod = { maxCount: 1, count: 0, allowed() { - return mech.fieldUpgrades[mech.fieldMode].name === "nano-scale manufacturing" && !(mod.isSporeField || mod.isIceField || mod.isFastDrones || mod.isDroneGrab) + return mech.maxEnergy > 0.99 && mech.fieldUpgrades[mech.fieldMode].name === "nano-scale manufacturing" && !(mod.isSporeField || mod.isIceField || mod.isFastDrones || mod.isDroneGrab) }, requires: "nano-scale manufacturing", effect() { @@ -3319,7 +3357,7 @@ const mod = { }, { name: "Penrose process", - description: "after a block falls into a wormhole
your energy overfills by 50%", + description: "after a block falls into a wormhole
your energy overfills by 50", maxCount: 1, count: 0, allowed() { @@ -3632,4 +3670,6 @@ const mod = { isCancelRerolls: null, isBotDamage: null, isBanish: null, + isMaxEnergyMod: null, + isLowEnergyDamage: null } \ No newline at end of file diff --git a/js/player.js b/js/player.js index 7adb37c..2a5cc64 100644 --- a/js/player.js +++ b/js/player.js @@ -492,8 +492,8 @@ const mech = { return dmg }, damage(dmg) { - if (mod.isTimeAvoidDeath && mech.energy > 0.97) { - const steps = Math.floor(Math.min(240, 120 * mech.energy)) //go back 2 seconds at 100% energy + if (mod.isTimeAvoidDeath && mech.energy > 0.66) { + const steps = Math.floor(Math.min(299, 137 * mech.energy)) //go back 2 seconds at 100% energy let history = mech.history[(mech.cycle - steps) % 300] Matter.Body.setPosition(player, history.position); Matter.Body.setVelocity(player, { x: history.velocity.x, y: history.velocity.y }); @@ -511,8 +511,8 @@ const mech = { } } - mech.energy = Math.max(mech.energy - steps, 0.01) - mech.immuneCycle = mech.cycle + mod.collisionImmuneCycles; //player is immune to collision damage for 30 cycles + mech.energy = Math.max(mech.energy - steps / 136, 0.01) + mech.immuneCycle = mech.cycle + 30; //player is immune to collision damage for 30 cycles let isDrawPlayer = true const shortPause = function() { @@ -541,7 +541,7 @@ const mech = { }; if (mech.defaultFPSCycle < mech.cycle) requestAnimationFrame(shortPause); - game.fpsCap = 4 //1 is shortest pause, 4 is standard + game.fpsCap = 3 //1 is shortest pause, 4 is standard game.fpsInterval = 1000 / game.fpsCap; mech.defaultFPSCycle = mech.cycle return @@ -838,7 +838,7 @@ const mech = { } }, setMaxEnergy() { - mech.maxEnergy = 1 + mod.bonusEnergy + mod.healMaxEnergyBonus + mech.maxEnergy = (mod.isMaxEnergyMod ? 0.5 : 1) + mod.bonusEnergy + mod.healMaxEnergyBonus }, fieldMeterColor: "#0cf", drawFieldMeter(bgColor = "rgba(0, 0, 0, 0.4)", range = 60) { @@ -2253,7 +2253,7 @@ const mech = { ctx.fill(); ctx.globalCompositeOperation = "source-over"; ctx.beginPath(); - ctx.ellipse(mech.fieldPosition.x, mech.fieldPosition.y, 1.2 * mech.fieldRadius * off1, 1.2 * mech.fieldRadius * off2, rotate, 0, mech.energy * 2 * Math.PI); + ctx.ellipse(mech.fieldPosition.x, mech.fieldPosition.y, 1.2 * mech.fieldRadius * off1, 1.2 * mech.fieldRadius * off2, rotate, 0, 2 * Math.PI * mech.energy / mech.maxEnergy); ctx.strokeStyle = "#000"; ctx.lineWidth = 4; ctx.stroke(); @@ -2367,12 +2367,12 @@ const mech = { mech.fieldRange *= 0.8 if (mod.isWormholeEnergy) mech.energy += 0.5 if (mod.isWormSpores) { //pandimensionalspermia - for (let i = 0, len = Math.ceil(2 * Math.random()); i < len; i++) { - b.spore(Vector.add(mech.hole.pos1, Vector.rotate({ - x: mech.fieldRange, + for (let i = 0, len = Math.ceil(3 * Math.random()); i < len; i++) { + b.spore(Vector.add(mech.hole.pos2, Vector.rotate({ + x: mech.fieldRange * 0.4, y: 0 }, 2 * Math.PI * Math.random()))) - Matter.Body.setVelocity(bullet[bullet.length - 1], Vector.mult(Vector.rotate(mech.hole.unit, Math.PI / 2), 15)); + Matter.Body.setVelocity(bullet[bullet.length - 1], Vector.mult(Vector.rotate(mech.hole.unit, Math.PI / 2), -15)); } } break @@ -2393,9 +2393,9 @@ const mech = { // if (mod.isWormholeEnergy && mech.energy < mech.maxEnergy * 2) mech.energy = mech.maxEnergy * 2 if (mod.isWormholeEnergy) mech.energy += 0.5 if (mod.isWormSpores) { //pandimensionalspermia - for (let i = 0, len = Math.ceil(2 * Math.random()); i < len; i++) { + for (let i = 0, len = Math.ceil(3 * Math.random()); i < len; i++) { b.spore(Vector.add(mech.hole.pos1, Vector.rotate({ - x: mech.fieldRange, + x: mech.fieldRange * 0.4, y: 0 }, 2 * Math.PI * Math.random()))) Matter.Body.setVelocity(bullet[bullet.length - 1], Vector.mult(Vector.rotate(mech.hole.unit, Math.PI / 2), 15)); diff --git a/js/powerup.js b/js/powerup.js index c813586..21317de 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -54,14 +54,7 @@ const powerUps = { powerUps.mod.banishLog.push(powerUps.mod.choiceLog[powerUps.mod.choiceLog.length - 1 - i]) } } - if (powerUps.mod.lastTotalChoices - powerUps.mod.banishLog.length < 1) { //check for out of mods to banish - for (let i = 0, len = mod.mods.length; i < len; i++) { - if (mod.mods[i].name === "erase") powerUps.ejectMod(i) - } - game.makeTextLog(`No mods left
erased mods have been recovered`, 300) - } else { - game.makeTextLog(`about ${powerUps.mod.lastTotalChoices - powerUps.mod.banishLog.length} estimated mods left`, 300) - } + game.makeTextLog(`about ${Math.max(0,powerUps.mod.lastTotalChoices - powerUps.mod.banishLog.length)} estimated mods left`, 300) } } if (mod.manyWorlds && powerUps.reroll.rerolls < 1) { @@ -93,7 +86,7 @@ const powerUps = { if (powerUps.reroll.rerolls < 0) powerUps.reroll.rerolls = 0 if (mod.isRerollBots) { - const limit = 4 + const limit = 5 for (; powerUps.reroll.rerolls > limit - 1; powerUps.reroll.rerolls -= limit) { b.randomBot() if (mod.renormalization) { @@ -153,17 +146,7 @@ const powerUps = { powerUps.mod.banishLog.push(powerUps.mod.choiceLog[powerUps.mod.choiceLog.length - 1 - i]) } } - if (powerUps.mod.lastTotalChoices - powerUps.mod.banishLog.length < 1) { - for (let i = 0, len = mod.mods.length; i < len; i++) { - if (mod.mods[i].name === "erase") { - powerUps.ejectMod(i) - } - } - game.makeTextLog(`No mods left
erased mods have been recovered`, 300) - - } else { - game.makeTextLog(`about ${powerUps.mod.lastTotalChoices - powerUps.mod.banishLog.length} estimated mods left`, 300) - } + game.makeTextLog(`about ${Math.max(0,powerUps.mod.lastTotalChoices - powerUps.mod.banishLog.length)} estimated mods left`, 300) } powerUps[type].effect(); }, @@ -312,8 +295,7 @@ const powerUps = { } } } - } else { - //remove repeats from last selection + } else { //remove repeats from last selection const totalChoices = mod.isDeterminism ? 1 : 3 + mod.isExtraChoice * 2 if (powerUps.mod.choiceLog.length > totalChoices || powerUps.mod.choiceLog.length === totalChoices) { //make sure this isn't the first time getting a power up and there are previous choices to remove for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection @@ -365,7 +347,16 @@ const powerUps = { document.getElementById("choose-grid").innerHTML = text powerUps.showDraft(); } else { - powerUps.giveRandomAmmo() + if (mod.isBanish) { + for (let i = 0, len = mod.mods.length; i < len; i++) { + if (mod.mods[i].name === "erase") powerUps.ejectMod(i) + } + game.makeTextLog(`No mods left
erased mods have been recovered`, 300) + powerUps.spawn(mech.pos.x, mech.pos.y, "mod"); + powerUps.endDraft("mod"); + } else { + powerUps.giveRandomAmmo() + } } } } diff --git a/js/spawn.js b/js/spawn.js index f443321..b3b0faa 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -94,7 +94,7 @@ const spawn = { me.frictionAir = 0.01; me.memory = Infinity; me.locatePlayer(); - const density = 0.9 + const density = 0.85 Matter.Body.setDensity(me, density); //extra dense //normal is 0.001 //makes effective life much larger // spawn.shield(me, x, y, 1); me.onDeath = function() { @@ -179,15 +179,17 @@ const spawn = { if (this.mode !== 3) Matter.Body.setAngularVelocity(this, 0.1) //fire a bullet from each vertex let whoSpawn = spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]; - for (let i = 0, len = this.vertices.length; i < len; i++) { + + const step = (this.health > 0.75) ? 2 : 1 + for (let i = 0, len = this.vertices.length; i < len; i += step) { spawn[whoSpawn](this.vertices[i].x, this.vertices[i].y); - //give the bullet a rotational velocity as if they were attached to a vertex - const velocity = Vector.mult(Vector.perp(Vector.normalise(Vector.sub(this.position, this.vertices[i]))), -18) + const velocity = Vector.mult(Vector.perp(Vector.normalise(Vector.sub(this.position, this.vertices[i]))), -18) //give the mob a rotational velocity as if they were attached to a vertex Matter.Body.setVelocity(mob[mob.length - 1], { x: this.velocity.x + velocity.x, y: this.velocity.y + velocity.y }); } + if (game.difficulty > 60) { spawn.randomLevelBoss(3000, -1100) if (game.difficulty > 100) { diff --git a/todo.txt b/todo.txt index 859b169..7ee8521 100644 --- a/todo.txt +++ b/todo.txt @@ -1,5 +1,13 @@ *********** NEXT PATCH *********** +added more requirements to various mods + +CPT reversal is more flexible with energy + 1.5-5 seconds of rewind drains 66% - 220% energy + +mod: exothermic process - renamed acute stress response +mod: heat engine - reduce max energy by 50 increase damage by 40% +mod: Gibbs free energy - gain 5% damage for every 10 energy below 100 ************** BUGS ************** @@ -25,21 +33,33 @@ ************** TODO ************** -extend erase to cancel +mod that gives a bonus for low energy + damage again or something different + requires heat engine + +CPT like mods + delayed rewind: after taking damage, play for 2 seconds, then rewind to just before you took damage + and return lost health + this might need code to run in a field to work + time dilation field? + gain a scrap bot after rewinding + use ammo to rewind instead of energy + explode the area where you were hit before rewinding + +spawn a few power ups on the final boss level mod pilot wave: mini black hole - pull mobs and blocks in with more force also from farther away also do damage? mod pilot wave: antigravity - blocks have no gravity for a few seconds after exiting the field maybe they bounce too? - -make the custom mode not disable mods that don't meet requirements after choosing a new mod + maybe they explode? bullet mechanic - a bullet that swims through the air rotate the velocity vector towards the normalized facing vector use the cross product > 0 to determine which direction to rotate the velocity -lower recoil on nail shot gun +lower recoil on nail shot gun? in custom make a top bar that is fixed use media rules to make the layout look nice @@ -86,17 +106,6 @@ new power up - increase damage and fire speed, for 15 seconds how to indicate effect duration or just give the effect after picking up a reroll -add an ending to the game - maybe the game ending should ask you to open the console and type in some commands like in the end of doki doki - mirror ending (if no cheats) - level after final boss battle is the intro level, but flipped left right, with a fake player - damage the fake player to end the game - message about go outside - no ending (if cheats) - game goes on forever - also game goes on if player attacks, the fake player - game never ends if you have used cheats - Mod: "Solar Power": Energy regeneration is doubled while standing still run in the 1 second check @@ -288,8 +297,6 @@ n-gon outreach ideas to achieve a (technological singularity/positive technological feedback loop) - - game setting: the mind of a new AI in a robot body that is running simulated escape attempts every level is an idealized version of what could be outside @@ -339,4 +346,15 @@ robot AI communication write custom dialogue for field / guns / mods used in last game you'd have to store an array of guns/fields/mod used last game n-gon escape simulation ${random seed} - say something about what mobs types are queued up, and level order \ No newline at end of file + say something about what mobs types are queued up, and level order + +add an ending to the game + maybe the game ending should ask you to open the console and type in some commands like in the end of doki doki + mirror ending (if no cheats) + level after final boss battle is the intro level, but flipped left right, with a fake player + damage the fake player to end the game + message about go outside + no ending (if cheats) + game goes on forever + also game goes on if player attacks, the fake player + game never ends if you have used cheats \ No newline at end of file