engine mods

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
This commit is contained in:
landgreen
2020-12-05 15:37:26 -08:00
parent 257a9db297
commit 15f2c00fe8
8 changed files with 196 additions and 143 deletions

View File

@@ -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 <strong class='color-p'>uranium-235</strong> <strong>needles</strong><br>does <strong class='color-p'>radioactive</strong> <strong class='color-d'>damage</strong> over <strong>3</strong> 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]

View File

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

View File

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

View File

@@ -83,6 +83,8 @@ const mod = {
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)
@@ -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 <strong class='color-d'>damage</strong> by <strong>1%</strong><br>for every <strong>7%</strong> stored <strong class='color-f'>energy</strong>",
description: "increase <strong class='color-d'>damage</strong> by <strong>1%</strong><br>for every <strong>7</strong> stored <strong class='color-f'>energy</strong>",
maxCount: 1,
count: 0,
allowed() {
@@ -153,7 +155,7 @@ const mod = {
}
},
{
name: "acute stress response",
name: "exothermic process",
description: "increase <strong class='color-d'>damage</strong> by <strong>50%</strong><br>if a mob <strong>dies</strong> drain stored <strong class='color-f'>energy</strong> by <strong>25%</strong>",
maxCount: 1,
count: 0,
@@ -168,6 +170,40 @@ const mod = {
mod.isEnergyLoss = false;
}
},
{
name: "heat engine",
description: `increase <strong class='color-d'>damage</strong> by <strong>40%</strong>, but<br>reduce maximum <strong class='color-f'>energy</strong> by <strong>50</strong>`,
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 <strong class='color-d'>damage</strong> by <strong>5%</strong><br>for every <strong>10</strong> <strong class='color-f'>energy</strong> below <strong>100</strong>`,
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 <strong class='color-d'>damage</strong> by <strong>25%</strong><br>when not <strong>moving</strong>",
@@ -202,13 +238,13 @@ const mod = {
},
{
name: "fluoroantimonic acid",
description: "increase <strong class='color-d'>damage</strong> by <strong>40%</strong><br>when your <strong>health</strong> is above <strong>100%</strong>",
description: "increase <strong class='color-d'>damage</strong> by <strong>40%</strong><br>when your <strong>health</strong> is above <strong>100</strong>",
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 <strong class='color-d'>damage</strong> by <strong>6%</strong><br>for every <strong>10%</strong> missing base <strong>health</strong>",
description: "increase <strong class='color-d'>damage</strong> by <strong>6%</strong><br>for every <strong>10</strong> missing base <strong>health</strong>",
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: "<strong>66%</strong> decreased <strong><em>delay</em></strong> after firing<br>if you have no <strong class='color-r'>rerolls</strong>",
description: "<strong>66%</strong> decreased <strong><em>delay</em></strong> after firing<br>when you have no <strong class='color-r'>rerolls</strong>",
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 <strong>4</strong> <strong class='color-r'>rerolls</strong><br>use them to build a <strong>random bot</strong>",
description: "anytime you collect <strong>5</strong> <strong class='color-r'>rerolls</strong><br>use them to build a <strong>random bot</strong>",
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: "<strong>300%</strong> increased <strong> fire rate</strong><br><em>applies to all current and future nail-bots</em>",
description: "<strong>500%</strong> increased <strong> fire rate</strong><br><em>applies to all current and future nail-bots</em>",
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: "<strong>rewind 2-4</strong> seconds to avoid <strong class='color-harm'>harm</strong><br>drains a minimum of <strong>100%</strong> <strong class='color-f'>energy</strong>",
description: "<strong>rewind 1.5 - 5</strong> seconds to avoid <strong class='color-harm'>harm</strong><br>drains <strong>66 - 220</strong> <strong class='color-f'>energy</strong>",
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: "<strong>colliding</strong> with mobs overfills <strong class='color-f'>energy</strong> by <strong>200%</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>15%</strong>",
description: "<strong>colliding</strong> with mobs overfills <strong class='color-f'>energy</strong> by <strong>200</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>15%</strong>",
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 <strong class='color-h'>heal</strong> <strong>power up</strong> you collect<br>increases your <strong>maximum</strong> <strong class='color-f'>energy</strong> by <strong>4%</strong>",
description: "each <strong class='color-h'>heal</strong> <strong>power up</strong> you collect<br>increases your <strong>maximum</strong> <strong class='color-f'>energy</strong> by <strong>4</strong>",
maxCount: 1,
count: 0,
allowed() {
@@ -1106,13 +1143,13 @@ const mod = {
},
{
name: "overcharge",
description: "increase your <strong>maximum</strong> <strong class='color-f'>energy</strong> by <strong>50%</strong>",
description: "increase your <strong>maximum</strong> <strong class='color-f'>energy</strong> by <strong>50</strong>",
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 <strong>died</strong> in the last <strong>5 seconds</strong><br><strong class='color-h'>heal</strong> <strong>1%</strong> of max health every second",
description: "if a mob has <strong>died</strong> in the last <strong>5 seconds</strong><br>regain <strong>1%</strong> of max <strong class='color-h'>health</strong> 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 <strong>maximum</strong> <strong class='color-h'>health</strong> by <strong>50%</strong>",
description: "increase your <strong>maximum</strong> <strong class='color-h'>health</strong> by <strong>50</strong>",
maxCount: 9,
count: 0,
allowed() {
@@ -1210,7 +1247,7 @@ const mod = {
},
{
name: "crystallized armor",
description: "increase <strong>maximum</strong> <strong class='color-h'>health</strong> by <strong>5%</strong> for each<br>unused <strong>power up</strong> at the end of a <strong>level</strong>",
description: "increase <strong>maximum</strong> <strong class='color-h'>health</strong> by <strong>5</strong> for each<br>unused <strong>power up</strong> at the end of a <strong>level</strong>",
maxCount: 1,
count: 0,
allowed() {
@@ -1228,7 +1265,7 @@ const mod = {
},
{
name: "negentropy",
description: `at the start of each <strong>level</strong><br>spawn a <strong class='color-h'>heal</strong> for every <strong>50%</strong> missing health`,
description: `at the start of each <strong>level</strong><br>spawn a <strong class='color-h'>heal</strong> for every <strong>50</strong> missing health`,
maxCount: 1,
count: 0,
allowed() {
@@ -1302,7 +1339,7 @@ const mod = {
},
{
name: "Bayesian statistics",
description: "<strong>16%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>after a <strong>collision</strong>, <strong>eject</strong> one of your <strong class='color-m'>mods</strong>",
description: "<strong>20%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>after a <strong>collision</strong>, <strong>eject</strong> one of your <strong class='color-m'>mods</strong>",
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 <strong>1</strong> <strong class='color-m'>mod</strong><br>with <strong>double</strong> your normal chance for power up <strong class='color-dup'>duplication</strong>`,
description: `use a <strong class='color-r'>reroll</strong> to spawn <strong>1</strong> <strong class='color-m'>mod</strong><br>with <strong>double</strong> your <strong class='color-dup'>duplication</strong> 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 <strong>4</strong> <strong class='color-m'>mods</strong><br><strong class='color-m'>mods</strong>, <strong class='color-f'>fields</strong>, and <strong class='color-g'>guns</strong> have only <strong>1 choice</strong>",
description: "spawn <strong>5</strong> <strong class='color-m'>mods</strong><br><strong class='color-m'>mods</strong>, <strong class='color-f'>fields</strong>, and <strong class='color-g'>guns</strong> have only <strong>1 choice</strong>",
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 <strong>6</strong> <strong class='color-m'>mods</strong><br><strong class='color-r'>rerolls</strong>, <strong class='color-g'>guns</strong>, and <strong class='color-f'>fields</strong> no longer <strong>spawn</strong>",
description: "spawn <strong>7</strong> <strong class='color-m'>mods</strong><br><strong class='color-r'>rerolls</strong>, <strong class='color-g'>guns</strong>, and <strong class='color-f'>fields</strong> no longer <strong>spawn</strong>",
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 <strong class='color-p' style='letter-spacing: 2px;'>spore</strong> <strong class='color-d'>damage</strong> by <strong>100%</strong><br><strong class='color-p' style='letter-spacing: 2px;'>spores</strong> borrow <strong>1%</strong> <strong>health</strong> until they <strong>die</strong>",
description: "increase <strong class='color-p' style='letter-spacing: 2px;'>spore</strong> <strong class='color-d'>damage</strong> by <strong>100%</strong><br><strong class='color-p' style='letter-spacing: 2px;'>spores</strong> borrow <strong>1</strong> <strong>health</strong> until they <strong>die</strong>",
maxCount: 1,
count: 0,
allowed() {
@@ -2614,7 +2652,7 @@ const mod = {
},
{
name: "thermoelectric effect",
description: "<strong>killing</strong> mobs with <strong>ice IX</strong> gives <strong>4%</strong> <strong class='color-h'>health</strong><br>and overloads <strong class='color-f'>energy</strong> by <strong>50%</strong> of your max",
description: "<strong>killing</strong> mobs with <strong>ice IX</strong> gives <strong>4</strong> <strong class='color-h'>health</strong><br>and overloads <strong class='color-f'>energy</strong> by <strong>100</strong>",
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 <strong>block</strong> falls into a <strong class='color-worm'>wormhole</strong><br>your <strong class='color-f'>energy</strong> overfills by <strong>50%</strong>",
description: "after a <strong>block</strong> falls into a <strong class='color-worm'>wormhole</strong><br>your <strong class='color-f'>energy</strong> overfills by <strong>50</strong>",
maxCount: 1,
count: 0,
allowed() {
@@ -3632,4 +3670,6 @@ const mod = {
isCancelRerolls: null,
isBotDamage: null,
isBanish: null,
isMaxEnergyMod: null,
isLowEnergyDamage: null
}

View File

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

View File

@@ -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 <strong class='color-m'>mods</strong> left<br>erased <strong class='color-m'>mods</strong> have been recovered`, 300)
} else {
game.makeTextLog(`about ${powerUps.mod.lastTotalChoices - powerUps.mod.banishLog.length} estimated <strong class='color-m'>mods</strong> left`, 300)
}
game.makeTextLog(`about ${Math.max(0,powerUps.mod.lastTotalChoices - powerUps.mod.banishLog.length)} estimated <strong class='color-m'>mods</strong> 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 <strong class='color-m'>mods</strong> left<br>erased <strong class='color-m'>mods</strong> have been recovered`, 300)
} else {
game.makeTextLog(`about ${powerUps.mod.lastTotalChoices - powerUps.mod.banishLog.length} estimated <strong class='color-m'>mods</strong> left`, 300)
}
game.makeTextLog(`about ${Math.max(0,powerUps.mod.lastTotalChoices - powerUps.mod.banishLog.length)} estimated <strong class='color-m'>mods</strong> 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 <strong class='color-m'>mods</strong> left<br>erased <strong class='color-m'>mods</strong> have been recovered`, 300)
powerUps.spawn(mech.pos.x, mech.pos.y, "mod");
powerUps.endDraft("mod");
} else {
powerUps.giveRandomAmmo()
}
}
}
}

View File

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

View File

@@ -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
@@ -340,3 +347,14 @@ robot AI communication
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
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