complex spinstatistics

tech: active cooling - 15% faster fire rate for each gun in your inventory
tech: specialist - spawn a random power up for each gun in your inventory
  (not available in custom, requires tech: generalist)
tech: complex spin-statistics - become immune to harm for 1s every 7s
  requires Pauli exclusion

even less difficulty ramp after killing final boss
This commit is contained in:
landgreen
2021-01-07 12:24:40 -08:00
parent 736f1d12e7
commit cd0e47df30
9 changed files with 211 additions and 155 deletions

View File

@@ -36,6 +36,68 @@ const b = {
if (mech.holdingTarget) mech.drop(); if (mech.holdingTarget) mech.drop();
} }
}, },
giveGuns(gun = "random", ammoPacks = 10) {
if (tech.isOneGun) b.removeAllGuns();
if (gun === "random") {
//find what guns player doesn't have
options = []
for (let i = 0, len = b.guns.length; i < len; i++) {
if (!b.guns[i].have) options.push(i)
}
if (options.length === 0) return
//randomly pick from list of possible guns
gun = options[Math.floor(Math.random() * options.length)]
}
if (gun === "all") {
b.activeGun = 0;
b.inventoryGun = 0;
for (let i = 0; i < b.guns.length; i++) {
b.inventory[i] = i;
b.guns[i].have = true;
b.guns[i].ammo = Math.floor(b.guns[i].ammoPack * ammoPacks);
}
} else {
if (isNaN(gun)) { //find gun by name
let found = false;
for (let i = 0; i < b.guns.length; i++) {
if (gun === b.guns[i].name) {
gun = i
found = true;
break
}
}
if (!found) return //if no gun found don't give a gun
}
if (!b.guns[gun].have) b.inventory.push(gun);
b.guns[gun].have = true;
b.guns[gun].ammo = Math.floor(b.guns[gun].ammoPack * ammoPacks);
if (b.activeGun === null) b.activeGun = gun //if no active gun switch to new gun
}
simulation.makeGunHUD();
b.setFireCD();
},
removeGun(gun, isRemoveSelection = false) {
for (let i = 0; i < b.guns.length; i++) {
if (b.guns[i].name === gun) {
b.guns[i].have = false
for (let j = 0; j < b.inventory.length; j++) {
if (b.inventory[j] === i) {
b.inventory.splice(j, 1)
break
}
}
if (b.inventory.length) {
b.activeGun = b.inventory[0];
} else {
b.activeGun = null;
}
simulation.makeGunHUD();
if (isRemoveSelection) b.guns.splice(i, 1) //also remove gun from gun pool array
break
}
}
b.setFireCD();
},
removeAllGuns() { removeAllGuns() {
b.inventory = []; //removes guns and ammo b.inventory = []; //removes guns and ammo
for (let i = 0, len = b.guns.length; i < len; ++i) { for (let i = 0, len = b.guns.length; i < len; ++i) {
@@ -89,6 +151,7 @@ const b = {
fireCD: 1, fireCD: 1,
setFireCD() { setFireCD() {
b.fireCD = tech.fireRate * tech.slowFire * tech.researchHaste * tech.aimDamage / tech.fastTime b.fireCD = tech.fireRate * tech.slowFire * tech.researchHaste * tech.aimDamage / tech.fastTime
if (tech.isFireRateForGuns) b.fireCD *= Math.pow(0.85, b.inventory.length)
}, },
fireAttributes(dir, rotate = true) { fireAttributes(dir, rotate = true) {
if (rotate) { if (rotate) {
@@ -1213,12 +1276,12 @@ const b = {
}); });
if (tech.isLaserPush) { //push mobs away if (tech.isLaserPush) { //push mobs away
console.log(-0.003 * Math.min(4, best.who.mass), dmg) // console.log(-0.003 * Math.min(4, best.who.mass), dmg)
const index = path.length - 1 const index = path.length - 1
// const force = Vector.mult(Vector.normalise(Vector.sub(path[Math.max(0, index - 1)], path[index])), -0.003 * Math.min(4, best.who.mass)) // const force = Vector.mult(Vector.normalise(Vector.sub(path[Math.max(0, index - 1)], path[index])), -0.003 * Math.min(4, best.who.mass))
// const push = -0.004 / (1 + tech.beamSplitter + tech.wideLaser + tech.historyLaser) // const push = -0.004 / (1 + tech.beamSplitter + tech.wideLaser + tech.historyLaser)
// console.log(push) // console.log(push)
const force = Vector.mult(Vector.normalise(Vector.sub(path[index], path[Math.max(0, index - 1)])), 0.004 * push * Math.min(4, best.who.mass)) const force = Vector.mult(Vector.normalise(Vector.sub(path[index], path[Math.max(0, index - 1)])), 0.003 * push * Math.min(6, best.who.mass))
Matter.Body.applyForce(best.who, path[index], force) Matter.Body.applyForce(best.who, path[index], force)
// Matter.Body.setVelocity(best.who, { //friction // Matter.Body.setVelocity(best.who, { //friction
// x: best.who.velocity.x * 0.7, // x: best.who.velocity.x * 0.7,
@@ -1975,13 +2038,13 @@ const b = {
// ************************************************************************************************** // **************************************************************************************************
// ************************************************************************************************** // **************************************************************************************************
respawnBots() { respawnBots() {
for (let i = 0; i < tech.laserBotCount; i++) b.laserBot() for (let i = 0; i < tech.laserBotCount; i++) b.laserBot({ x: mech.pos.x + 50 * (Math.random() - 0.5), y: mech.pos.y + 50 * (Math.random() - 0.5) }, false)
for (let i = 0; i < tech.nailBotCount; i++) b.nailBot() for (let i = 0; i < tech.nailBotCount; i++) b.nailBot({ x: mech.pos.x + 50 * (Math.random() - 0.5), y: mech.pos.y + 50 * (Math.random() - 0.5) }, false)
for (let i = 0; i < tech.foamBotCount; i++) b.foamBot() for (let i = 0; i < tech.foamBotCount; i++) b.foamBot({ x: mech.pos.x + 50 * (Math.random() - 0.5), y: mech.pos.y + 50 * (Math.random() - 0.5) }, false)
for (let i = 0; i < tech.boomBotCount; i++) b.boomBot() for (let i = 0; i < tech.boomBotCount; i++) b.boomBot({ x: mech.pos.x + 50 * (Math.random() - 0.5), y: mech.pos.y + 50 * (Math.random() - 0.5) }, false)
for (let i = 0; i < tech.orbitBotCount; i++) b.orbitBot() for (let i = 0; i < tech.orbitBotCount; i++) b.orbitBot({ x: mech.pos.x + 50 * (Math.random() - 0.5), y: mech.pos.y + 50 * (Math.random() - 0.5) }, false)
for (let i = 0; i < tech.plasmaBotCount; i++) b.plasmaBot() for (let i = 0; i < tech.plasmaBotCount; i++) b.plasmaBot({ x: mech.pos.x + 50 * (Math.random() - 0.5), y: mech.pos.y + 50 * (Math.random() - 0.5) }, false)
for (let i = 0; i < tech.missileBotCount; i++) b.missileBot() for (let i = 0; i < tech.missileBotCount; i++) b.missileBot({ x: mech.pos.x + 50 * (Math.random() - 0.5), y: mech.pos.y + 50 * (Math.random() - 0.5) }, false)
if (tech.isIntangible && mech.isCloak) { if (tech.isIntangible && mech.isCloak) {
for (let i = 0; i < bullet.length; i++) { for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType) bullet[i].collisionFilter.mask = cat.map | cat.bullet | cat.mobBullet | cat.mobShield if (bullet[i].botType) bullet[i].collisionFilter.mask = cat.map | cat.bullet | cat.mobBullet | cat.mobShield
@@ -1993,7 +2056,7 @@ const b = {
b.laserBot(where) b.laserBot(where)
if (isKeep) tech.laserBotCount++; if (isKeep) tech.laserBotCount++;
} else if (Math.random() < 0.25 && isAll) { } else if (Math.random() < 0.25 && isAll) {
b.orbitBot(); b.orbitBot(where);
if (isKeep) tech.orbitBotCount++; if (isKeep) tech.orbitBotCount++;
} else if (Math.random() < 0.33) { } else if (Math.random() < 0.33) {
b.nailBot(where) b.nailBot(where)
@@ -2006,8 +2069,8 @@ const b = {
if (isKeep) tech.boomBotCount++; if (isKeep) tech.boomBotCount++;
} }
}, },
nailBot(position = { x: mech.pos.x + 50 * (Math.random() - 0.5), y: mech.pos.y + 50 * (Math.random() - 0.5) }) { nailBot(position = { x: mech.pos.x + 50 * (Math.random() - 0.5), y: mech.pos.y + 50 * (Math.random() - 0.5) }, isConsole = true) {
simulation.makeTextLog(`<span class='color-var'>b</span>.nailBot()`); if (isConsole) simulation.makeTextLog(`<span class='color-var'>b</span>.nailBot()`);
const me = bullet.length; const me = bullet.length;
const dir = mech.angle; const dir = mech.angle;
const RADIUS = (12 + 4 * Math.random()) const RADIUS = (12 + 4 * Math.random())
@@ -2062,8 +2125,8 @@ const b = {
}) })
World.add(engine.world, bullet[me]); //add bullet to world World.add(engine.world, bullet[me]); //add bullet to world
}, },
missileBot(position = { x: mech.pos.x + 50 * (Math.random() - 0.5), y: mech.pos.y + 50 * (Math.random() - 0.5) }) { missileBot(position = { x: mech.pos.x + 50 * (Math.random() - 0.5), y: mech.pos.y + 50 * (Math.random() - 0.5) }, isConsole = true) {
simulation.makeTextLog(`<span class='color-var'>b</span>.missileBot()`); if (isConsole) simulation.makeTextLog(`<span class='color-var'>b</span>.missileBot()`);
const me = bullet.length; const me = bullet.length;
bullet[me] = Bodies.rectangle(position.x, position.y, 28, 11, { bullet[me] = Bodies.rectangle(position.x, position.y, 28, 11, {
botType: "foam", botType: "foam",
@@ -2112,8 +2175,8 @@ const b = {
}) })
World.add(engine.world, bullet[me]); //add bullet to world World.add(engine.world, bullet[me]); //add bullet to world
}, },
foamBot(position = { x: mech.pos.x + 50 * (Math.random() - 0.5), y: mech.pos.y + 50 * (Math.random() - 0.5) }) { foamBot(position = { x: mech.pos.x + 50 * (Math.random() - 0.5), y: mech.pos.y + 50 * (Math.random() - 0.5) }, isConsole = true) {
simulation.makeTextLog(`<span class='color-var'>b</span>.foamBot()`); if (isConsole) simulation.makeTextLog(`<span class='color-var'>b</span>.foamBot()`);
const me = bullet.length; const me = bullet.length;
const dir = mech.angle; const dir = mech.angle;
const RADIUS = (10 + 5 * Math.random()) const RADIUS = (10 + 5 * Math.random())
@@ -2167,8 +2230,8 @@ const b = {
}) })
World.add(engine.world, bullet[me]); //add bullet to world World.add(engine.world, bullet[me]); //add bullet to world
}, },
laserBot(position = { x: mech.pos.x + 50 * (Math.random() - 0.5), y: mech.pos.y + 50 * (Math.random() - 0.5) }) { laserBot(position = { x: mech.pos.x + 50 * (Math.random() - 0.5), y: mech.pos.y + 50 * (Math.random() - 0.5) }, isConsole = true) {
simulation.makeTextLog(`<span class='color-var'>b</span>.laserBot()`); if (isConsole) simulation.makeTextLog(`<span class='color-var'>b</span>.laserBot()`);
const me = bullet.length; const me = bullet.length;
const dir = mech.angle; const dir = mech.angle;
const RADIUS = (14 + 6 * Math.random()) const RADIUS = (14 + 6 * Math.random())
@@ -2252,8 +2315,8 @@ const b = {
}) })
World.add(engine.world, bullet[me]); //add bullet to world World.add(engine.world, bullet[me]); //add bullet to world
}, },
boomBot(position = { x: mech.pos.x + 50 * (Math.random() - 0.5), y: mech.pos.y + 50 * (Math.random() - 0.5) }) { boomBot(position = { x: mech.pos.x + 50 * (Math.random() - 0.5), y: mech.pos.y + 50 * (Math.random() - 0.5) }, isConsole = true) {
simulation.makeTextLog(`<span class='color-var'>b</span>.boomBot()`); if (isConsole) simulation.makeTextLog(`<span class='color-var'>b</span>.boomBot()`);
const me = bullet.length; const me = bullet.length;
const dir = mech.angle; const dir = mech.angle;
const RADIUS = (7 + 2 * Math.random()) const RADIUS = (7 + 2 * Math.random())
@@ -2331,8 +2394,8 @@ const b = {
}) })
World.add(engine.world, bullet[me]); //add bullet to world World.add(engine.world, bullet[me]); //add bullet to world
}, },
plasmaBot(position = { x: mech.pos.x + 50 * (Math.random() - 0.5), y: mech.pos.y + 50 * (Math.random() - 0.5) }) { plasmaBot(position = { x: mech.pos.x + 50 * (Math.random() - 0.5), y: mech.pos.y + 50 * (Math.random() - 0.5) }, isConsole = true) {
simulation.makeTextLog(`<span class='color-var'>b</span>.plasmaBot()`); if (isConsole) simulation.makeTextLog(`<span class='color-var'>b</span>.plasmaBot()`);
const me = bullet.length; const me = bullet.length;
const dir = mech.angle; const dir = mech.angle;
const RADIUS = 21 const RADIUS = 21
@@ -2516,8 +2579,8 @@ const b = {
}) })
World.add(engine.world, bullet[me]); //add bullet to world World.add(engine.world, bullet[me]); //add bullet to world
}, },
orbitBot(position = mech.pos) { orbitBot(position = mech.pos, isConsole = true) {
simulation.makeTextLog(`<span class='color-var'>b</span>.orbitBot()`); if (isConsole) simulation.makeTextLog(`<span class='color-var'>b</span>.orbitBot()`);
const me = bullet.length; const me = bullet.length;
bullet[me] = Bodies.polygon(position.x, position.y, 9, 12, { bullet[me] = Bodies.polygon(position.x, position.y, 9, 12, {
isUpgraded: tech.isOrbitBotUpgrade, isUpgraded: tech.isOrbitBotUpgrade,
@@ -2616,66 +2679,6 @@ const b = {
// ******************************** Guns ********************************************* // ******************************** Guns *********************************************
// ************************************************************************************************** // **************************************************************************************************
// ************************************************************************************************** // **************************************************************************************************
giveGuns(gun = "random", ammoPacks = 10) {
if (tech.isOneGun) b.removeAllGuns();
if (gun === "random") {
//find what guns player doesn't have
options = []
for (let i = 0, len = b.guns.length; i < len; i++) {
if (!b.guns[i].have) options.push(i)
}
if (options.length === 0) return
//randomly pick from list of possible guns
gun = options[Math.floor(Math.random() * options.length)]
}
if (gun === "all") {
b.activeGun = 0;
b.inventoryGun = 0;
for (let i = 0; i < b.guns.length; i++) {
b.inventory[i] = i;
b.guns[i].have = true;
b.guns[i].ammo = Math.floor(b.guns[i].ammoPack * ammoPacks);
}
} else {
if (isNaN(gun)) { //find gun by name
let found = false;
for (let i = 0; i < b.guns.length; i++) {
if (gun === b.guns[i].name) {
gun = i
found = true;
break
}
}
if (!found) return //if no gun found don't give a gun
}
if (!b.guns[gun].have) b.inventory.push(gun);
b.guns[gun].have = true;
b.guns[gun].ammo = Math.floor(b.guns[gun].ammoPack * ammoPacks);
if (b.activeGun === null) b.activeGun = gun //if no active gun switch to new gun
}
simulation.makeGunHUD();
},
removeGun(gun, isRemoveSelection = false) {
for (let i = 0; i < b.guns.length; i++) {
if (b.guns[i].name === gun) {
b.guns[i].have = false
for (let j = 0; j < b.inventory.length; j++) {
if (b.inventory[j] === i) {
b.inventory.splice(j, 1)
break
}
}
if (b.inventory.length) {
b.activeGun = b.inventory[0];
} else {
b.activeGun = null;
}
simulation.makeGunHUD();
if (isRemoveSelection) b.guns.splice(i, 1) //also remove gun from gun pool array
break
}
}
},
guns: [{ guns: [{
name: "nail gun", name: "nail gun",
description: "use compressed air to fire a stream of <strong>nails</strong><br><strong>delay</strong> after firing <strong>decreases</strong> as you shoot", description: "use compressed air to fire a stream of <strong>nails</strong><br><strong>delay</strong> after firing <strong>decreases</strong> as you shoot",
@@ -4017,7 +4020,7 @@ const b = {
b.laser(where, { b.laser(where, {
x: where.x + 3000 * Math.cos(angle), x: where.x + 3000 * Math.cos(angle),
y: where.y + 3000 * Math.sin(angle) y: where.y + 3000 * Math.sin(angle)
}, dmg, 0, true, 0.4) }, dmg, 0, true, 0.3)
for (let i = 1; i < tech.wideLaser; i++) { for (let i = 1; i < tech.wideLaser; i++) {
let whereOff = Vector.add(where, { let whereOff = Vector.add(where, {
x: i * off * Math.cos(angle + Math.PI / 2), x: i * off * Math.cos(angle + Math.PI / 2),
@@ -4026,7 +4029,7 @@ const b = {
b.laser(whereOff, { b.laser(whereOff, {
x: whereOff.x + 3000 * Math.cos(angle), x: whereOff.x + 3000 * Math.cos(angle),
y: whereOff.y + 3000 * Math.sin(angle) y: whereOff.y + 3000 * Math.sin(angle)
}, dmg, 0, true, 0.4) }, dmg, 0, true, 0.3)
whereOff = Vector.add(where, { whereOff = Vector.add(where, {
x: i * off * Math.cos(angle - Math.PI / 2), x: i * off * Math.cos(angle - Math.PI / 2),
y: i * off * Math.sin(angle - Math.PI / 2) y: i * off * Math.sin(angle - Math.PI / 2)
@@ -4034,7 +4037,7 @@ const b = {
b.laser(whereOff, { b.laser(whereOff, {
x: whereOff.x + 3000 * Math.cos(angle), x: whereOff.x + 3000 * Math.cos(angle),
y: whereOff.y + 3000 * Math.sin(angle) y: whereOff.y + 3000 * Math.sin(angle)
}, dmg, 0, true, 0.4) }, dmg, 0, true, 0.3)
} }
ctx.stroke(); ctx.stroke();
ctx.globalAlpha = 1; ctx.globalAlpha = 1;
@@ -4071,7 +4074,7 @@ const b = {
}, { }, {
x: mech.pos.x + 3000 * Math.cos(mech.angle), x: mech.pos.x + 3000 * Math.cos(mech.angle),
y: mech.pos.y + 3000 * Math.sin(mech.angle) y: mech.pos.y + 3000 * Math.sin(mech.angle)
}, dmg, 0, true, 0.3); }, dmg, 0, true, 0.2);
for (let i = 1; i < len; i++) { for (let i = 1; i < len; i++) {
const history = mech.history[(mech.cycle - i * spacing) % 600] const history = mech.history[(mech.cycle - i * spacing) % 600]
b.laser({ b.laser({
@@ -4080,7 +4083,7 @@ const b = {
}, { }, {
x: history.position.x + 3000 * Math.cos(history.angle), x: history.position.x + 3000 * Math.cos(history.angle),
y: history.position.y + 3000 * Math.sin(history.angle) - mech.yPosDifference y: history.position.y + 3000 * Math.sin(history.angle) - mech.yPosDifference
}, dmg, 0, true, 0.3); }, dmg, 0, true, 0.2);
} }
ctx.stroke(); ctx.stroke();
} }

View File

@@ -201,8 +201,7 @@ const build = {
<text x="5" y="18">copy build url</text> <text x="5" y="18">copy build url</text>
</g> </g>
</svg> </svg>
</div>`;
</div>`;
for (let i = 0, len = b.inventory.length; i < len; i++) { for (let i = 0, len = b.inventory.length; i < len; i++) {
text += `<div class="pause-grid-module"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[b.inventory[i]].name} - <span style="font-size:100%;font-weight: 100;">${b.guns[b.inventory[i]].ammo}</span></div> ${b.guns[b.inventory[i]].description}</div>` text += `<div class="pause-grid-module"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[b.inventory[i]].name} - <span style="font-size:100%;font-weight: 100;">${b.guns[b.inventory[i]].ammo}</span></div> ${b.guns[b.inventory[i]].description}</div>`
} }
@@ -744,6 +743,7 @@ window.addEventListener("keydown", function(event) {
break break
} }
if (simulation.testing) { if (simulation.testing) {
if (event.key === "X") mech.death(); //only uppercase
switch (event.key.toLowerCase()) { switch (event.key.toLowerCase()) {
case "o": case "o":
simulation.isAutoZoom = false; simulation.isAutoZoom = false;
@@ -826,9 +826,6 @@ window.addEventListener("keydown", function(event) {
case "u": case "u":
level.nextLevel(); level.nextLevel();
break break
case "X": //capital X to make it hard to die
mech.death();
break
} }
} }
}); });

View File

@@ -61,7 +61,7 @@ const level = {
b.respawnBots(); b.respawnBots();
mech.resetHistory(); mech.resetHistory();
if (tech.isArmorFromPowerUps) { if (tech.isArmorFromPowerUps) {
const gain = Math.min(0.04 * powerUps.totalPowerUps, 0.40) const gain = Math.min(0.03 * powerUps.totalPowerUps, 0.42)
tech.armorFromPowerUps += gain tech.armorFromPowerUps += gain
mech.setMaxHealth(); mech.setMaxHealth();
// if (powerUps.totalPowerUps) simulation.makeTextLog("<span style='font-size:115%;'> max health increased by " + (gain * 100).toFixed(0) + "%</span>", 300) // if (powerUps.totalPowerUps) simulation.makeTextLog("<span style='font-size:115%;'> max health increased by " + (gain * 100).toFixed(0) + "%</span>", 300)

View File

@@ -429,7 +429,6 @@ const mech = {
} }
simulation.isTextLogOpen = true; simulation.isTextLogOpen = true;
simulation.makeTextLog("simulation.amplitude <span class='color-symbol'>=</span> null"); simulation.makeTextLog("simulation.amplitude <span class='color-symbol'>=</span> null");
}, 6 * swapPeriod); }, 6 * swapPeriod);
} else if (mech.alive) { //normal death code here } else if (mech.alive) { //normal death code here
@@ -482,8 +481,10 @@ const mech = {
}, },
baseHealth: 1, baseHealth: 1,
setMaxHealth() { setMaxHealth() {
mech.maxHealth = mech.baseHealth + tech.bonusHealth + tech.armorFromPowerUps const set = mech.baseHealth + tech.bonusHealth + tech.armorFromPowerUps
if (mech.health > mech.maxHealth) mech.health = mech.maxHealth; simulation.makeTextLog(`<span class='color-var'>mech</span>.maxHealth <span class='color-symbol'>=</span> ${set}`)
mech.maxHealth = set
if(mech.health > mech.maxHealth) mech.health = mech.maxHealth;
mech.displayHealth(); mech.displayHealth();
}, },
@@ -604,7 +605,9 @@ const mech = {
}, },
damage(dmg) { damage(dmg) {
if (tech.isRewindAvoidDeath && mech.energy > 0.66) { if (tech.isRewindAvoidDeath && mech.energy > 0.66) {
mech.rewind(Math.floor(Math.min(299, 137 * mech.energy))) const steps = Math.floor(Math.min(299, 137 * mech.energy))
simulation.makeTextLog(`<span class='color-var'>mech</span>.rewind(${steps})`)
mech.rewind(steps)
return return
} }
mech.lastHarmCycle = mech.cycle mech.lastHarmCycle = mech.cycle
@@ -621,8 +624,7 @@ const mech = {
if (tech.isDeathAvoid && powerUps.research.research && !tech.isDeathAvoidedThisLevel) { if (tech.isDeathAvoid && powerUps.research.research && !tech.isDeathAvoidedThisLevel) {
tech.isDeathAvoidedThisLevel = true tech.isDeathAvoidedThisLevel = true
powerUps.research.changeRerolls(-1) powerUps.research.changeRerolls(-1)
simulation.makeTextLog(`<span class='color-var'>mech</span>.<span class='color-r'>research</span><span class='color-symbol'>--</span> simulation.makeTextLog(`<span class='color-var'>mech</span>.<span class='color-r'>research</span><span class='color-symbol'>--</span><br>${powerUps.research.research}`)
<br>${powerUps.research.research}`)
for (let i = 0; i < 6; i++) { for (let i = 0; i < 6; i++) {
powerUps.spawn(mech.pos.x, mech.pos.y, "heal", false); powerUps.spawn(mech.pos.x, mech.pos.y, "heal", false);
} }
@@ -655,9 +657,7 @@ const mech = {
powerUps.research.changeRerolls(-1) powerUps.research.changeRerolls(-1)
simulation.makeTextLog(`<span class='color-var'>mech</span>.<span class='color-r'>research</span><span class='color-symbol'>--</span> simulation.makeTextLog(`<span class='color-var'>mech</span>.<span class='color-r'>research</span><span class='color-symbol'>--</span>
<br>${powerUps.research.research}`) <br>${powerUps.research.research}`)
for (let i = 0; i < 6; i++) { for (let i = 0; i < 6; i++) powerUps.spawn(mech.pos.x + 10 * Math.random(), mech.pos.y + 10 * Math.random(), "heal", false);
powerUps.spawn(mech.pos.x, mech.pos.y, "heal", false);
}
mech.immuneCycle = mech.cycle + 360 //disable this.immuneCycle bonus seconds mech.immuneCycle = mech.cycle + 360 //disable this.immuneCycle bonus seconds
simulation.wipe = function() { //set wipe to have trails simulation.wipe = function() { //set wipe to have trails
ctx.fillStyle = "rgba(255,255,255,0.03)"; ctx.fillStyle = "rgba(255,255,255,0.03)";
@@ -900,6 +900,7 @@ const mech = {
}, },
setMaxEnergy() { setMaxEnergy() {
mech.maxEnergy = (tech.isMaxEnergyTech ? 0.5 : 1) + tech.bonusEnergy + tech.healMaxEnergyBonus mech.maxEnergy = (tech.isMaxEnergyTech ? 0.5 : 1) + tech.bonusEnergy + tech.healMaxEnergyBonus
simulation.makeTextLog(`<span class='color-var'>mech</span>.maxEnergy <span class='color-symbol'>=</span> ${mech.maxEnergy}`)
}, },
fieldMeterColor: "#0cf", fieldMeterColor: "#0cf",
drawFieldMeter(bgColor = "rgba(0, 0, 0, 0.4)", range = 60) { drawFieldMeter(bgColor = "rgba(0, 0, 0, 0.4)", range = 60) {

View File

@@ -6,10 +6,10 @@ const powerUps = {
if (type === "gun") { if (type === "gun") {
b.giveGuns(index) b.giveGuns(index)
let text = `b.giveGuns("<span class='color-text'>${b.guns[index].name}</span>")` let text = `b.giveGuns("<span class='color-text'>${b.guns[index].name}</span>")`
if (b.inventory.length === 1) text += `<br>input.key.gun <span class='color-symbol'>=</span> ["<span class='color-text'>MouseLeft</span>"]` if (b.inventory.length === 1) text += `<br>input.key.gun<span class='color-symbol'>:</span> ["<span class='color-text'>MouseLeft</span>"]`
if (b.inventory.length === 2) text += ` if (b.inventory.length === 2) text += `
<br>input.key.nextGun <span class='color-symbol'>=</span> ["<span class='color-text'>${input.key.nextGun}</span>","<span class='color-text'>MouseWheel</span>"] <br>input.key.nextGun<span class='color-symbol'>:</span> ["<span class='color-text'>${input.key.nextGun}</span>","<span class='color-text'>MouseWheel</span>"]
<br>input.key.previousGun <span class='color-symbol'>=</span> ["<span class='color-text'>${input.key.previousGun}</span>","<span class='color-text'>MouseWheel</span>"]` <br>input.key.previousGun<span class='color-symbol'>:</span> ["<span class='color-text'>${input.key.previousGun}</span>","<span class='color-text'>MouseWheel</span>"]`
simulation.makeTextLog(text); simulation.makeTextLog(text);
} else if (type === "field") { } else if (type === "field") {
mech.setField(index) mech.setField(index)
@@ -489,7 +489,7 @@ const powerUps = {
powerUps.spawn(x, y, "ammo"); powerUps.spawn(x, y, "ammo");
return; return;
} }
if (Math.random() < 0.0015 * (3 - b.inventory.length)) { //a new gun has a low chance for each not acquired gun up to 3 if (Math.random() < 0.001 * (3 - b.inventory.length)) { //a new gun has a low chance for each not acquired gun up to 3
powerUps.spawn(x, y, "gun"); powerUps.spawn(x, y, "gun");
return; return;
} }
@@ -520,7 +520,7 @@ const powerUps = {
function powerUpChance(chanceToFail) { function powerUpChance(chanceToFail) {
if (Math.random() * chanceToFail < powerUps.randomPowerUpCounter) { if (Math.random() * chanceToFail < powerUps.randomPowerUpCounter) {
powerUps.randomPowerUpCounter = 0; powerUps.randomPowerUpCounter = 0;
if (Math.random() < 0.95) { if (Math.random() < 0.97) {
powerUps.spawn(x, y, "tech") powerUps.spawn(x, y, "tech")
} else { } else {
powerUps.spawn(x, y, "gun") powerUps.spawn(x, y, "gun")
@@ -565,25 +565,17 @@ const powerUps = {
powerUps.spawn(x, y, "gun", false); //first gun powerUps.spawn(x, y, "gun", false); //first gun
} else if (tech.totalCount === 0) { //first tech } else if (tech.totalCount === 0) { //first tech
powerUps.spawn(x, y, "tech", false); powerUps.spawn(x, y, "tech", false);
} else if (b.inventory.length < 2) { //second gun or extra ammo } else if (b.inventory.length === 1) { //second gun or extra ammo
if (Math.random() < 0.5) { if (Math.random() < 0.4) {
powerUps.spawn(x, y, "gun", false); powerUps.spawn(x, y, "gun", false);
} else { } else {
powerUps.spawn(x, y, "ammo", false); for (let i = 0; i < 5; i++) powerUps.spawn(x, y, "ammo", false);
powerUps.spawn(x, y, "ammo", false);
powerUps.spawn(x, y, "ammo", false);
powerUps.spawn(x, y, "ammo", false);
} }
} else { } else {
powerUps.spawnRandomPowerUp(x, y); for (let i = 0; i < 4; i++) powerUps.spawnRandomPowerUp(x, y);
powerUps.spawnRandomPowerUp(x, y);
powerUps.spawnRandomPowerUp(x, y);
powerUps.spawnRandomPowerUp(x, y);
} }
} else { } else {
powerUps.spawnRandomPowerUp(x, y); for (let i = 0; i < 3; i++) powerUps.spawnRandomPowerUp(x, y);
powerUps.spawnRandomPowerUp(x, y);
powerUps.spawnRandomPowerUp(x, y);
} }
}, },
ejectTech(choose = 'random') { ejectTech(choose = 'random') {

View File

@@ -576,19 +576,19 @@ const simulation = {
let delay = 500 let delay = 500
const step = 150 const step = 150
setTimeout(function() { setTimeout(function() {
simulation.makeTextLog(`input.key.up <span class='color-symbol'>=</span> ["<span class='color-text'>${input.key.up}</span>", "<span class='color-text'>ArrowUp</span>"]`); simulation.makeTextLog(`input.key.up<span class='color-symbol'>:</span> ["<span class='color-text'>${input.key.up}</span>", "<span class='color-text'>ArrowUp</span>"]`);
}, delay); }, delay);
delay += step delay += step
setTimeout(function() { setTimeout(function() {
simulation.makeTextLog(`input.key.left <span class='color-symbol'>=</span> ["<span class='color-text'>${input.key.left}</span>", "<span class='color-text'>ArrowLeft</span>"]`); simulation.makeTextLog(`input.key.left<span class='color-symbol'>:</span> ["<span class='color-text'>${input.key.left}</span>", "<span class='color-text'>ArrowLeft</span>"]`);
}, delay); }, delay);
delay += step delay += step
setTimeout(function() { setTimeout(function() {
simulation.makeTextLog(`input.key.down <span class='color-symbol'>=</span> ["<span class='color-text'>${input.key.down}</span>", "<span class='color-text'>ArrowDown</span>"]`); simulation.makeTextLog(`input.key.down<span class='color-symbol'>:</span> ["<span class='color-text'>${input.key.down}</span>", "<span class='color-text'>ArrowDown</span>"]`);
}, delay); }, delay);
delay += step delay += step
setTimeout(function() { setTimeout(function() {
simulation.makeTextLog(`input.key.right <span class='color-symbol'>=</span> ["<span class='color-text'>${input.key.right}</span>", "<span class='color-text'>ArrowRight</span>"]`); simulation.makeTextLog(`input.key.right<span class='color-symbol'>:</span> ["<span class='color-text'>${input.key.right}</span>", "<span class='color-text'>ArrowRight</span>"]`);
}, delay); }, delay);
delay += 1000 delay += 1000
setTimeout(function() { setTimeout(function() {
@@ -596,7 +596,7 @@ const simulation = {
}, delay); }, delay);
delay += step delay += step
setTimeout(function() { setTimeout(function() {
simulation.makeTextLog(`input.key.field <span class='color-symbol'>=</span> ["<span class='color-text'>${input.key.field}</span>", "<span class='color-text'>MouseRight</span>"]`); simulation.makeTextLog(`input.key.field<span class='color-symbol'>:</span> ["<span class='color-text'>${input.key.field}</span>", "<span class='color-text'>MouseRight</span>"]`);
}, delay); }, delay);
// delay += step // delay += step
// setTimeout(function() { // setTimeout(function() {
@@ -790,6 +790,9 @@ const simulation = {
} }
if (!(simulation.cycle % 420)) { //once every 7 seconds if (!(simulation.cycle % 420)) { //once every 7 seconds
if (tech.cyclicImmunity && mech.immuneCycle < mech.cycle + tech.cyclicImmunity) mech.immuneCycle = mech.cycle + tech.cyclicImmunity; //player is immune to collision damage for 60 cycles
fallCheck = function(who, save = false) { fallCheck = function(who, save = false) {
let i = who.length; let i = who.length;
while (i--) { while (i--) {

View File

@@ -101,7 +101,7 @@ const spawn = {
level.exit.x = 5500; level.exit.x = 5500;
level.exit.y = -330; level.exit.y = -330;
//ramp up damage //ramp up damage
for (let i = 0; i < 2; i++) level.difficultyIncrease(simulation.difficultyMode) // for (let i = 0; i < 2; i++) level.difficultyIncrease(simulation.difficultyMode)
//set game to the next highest difficulty level if not on why //set game to the next highest difficulty level if not on why
if (simulation.difficultyMode < 6) { if (simulation.difficultyMode < 6) {

View File

@@ -81,7 +81,7 @@ const tech = {
if (tech.isLowEnergyDamage) dmg *= 1 + Math.max(0, 1 - mech.energy) * 0.5 if (tech.isLowEnergyDamage) dmg *= 1 + Math.max(0, 1 - mech.energy) * 0.5
if (tech.isMaxEnergyTech) dmg *= 1.4 if (tech.isMaxEnergyTech) dmg *= 1.4
if (tech.isEnergyNoAmmo) dmg *= 1.5 if (tech.isEnergyNoAmmo) dmg *= 1.5
if (tech.isDamageForGuns) dmg *= 1 + 0.1 * b.inventory.length if (tech.isDamageForGuns) dmg *= 1 + 0.13 * b.inventory.length
if (tech.isLowHealthDmg) dmg *= 1 + 0.6 * Math.max(0, 1 - mech.health) if (tech.isLowHealthDmg) dmg *= 1 + 0.6 * Math.max(0, 1 - mech.health)
if (tech.isHarmDamage && mech.lastHarmCycle + 600 > mech.cycle) dmg *= 3; if (tech.isHarmDamage && mech.lastHarmCycle + 600 > mech.cycle) dmg *= 3;
if (tech.isEnergyLoss) dmg *= 1.5; if (tech.isEnergyLoss) dmg *= 1.5;
@@ -146,7 +146,7 @@ const tech = {
}, },
{ {
name: "arsenal", name: "arsenal",
description: "increase <strong class='color-d'>damage</strong> by <strong>10%</strong><br>for each <strong class='color-g'>gun</strong> in your inventory", description: "increase <strong class='color-d'>damage</strong> by <strong>13%</strong><br>for each <strong class='color-g'>gun</strong> in your inventory",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
@@ -160,26 +160,71 @@ const tech = {
tech.isDamageForGuns = false; tech.isDamageForGuns = false;
} }
}, },
{
name: "active cooling",
description: "<strong>15%</strong> decreased <strong><em>delay</em></strong> after firing<br>for each <strong class='color-g'>gun</strong> in your inventory",
maxCount: 1,
count: 0,
allowed() {
return b.inventory.length > 1
},
requires: "at least 2 guns",
effect() {
tech.isFireRateForGuns = true;
b.setFireCD();
},
remove() {
tech.isFireRateForGuns = false;
b.setFireCD();
}
},
{ {
name: "generalist", name: "generalist",
description: "<strong>spawn</strong> 6 <strong class='color-g'>guns</strong>, but you can't <strong>switch</strong> <strong class='color-g'>guns</strong><br><strong class='color-g'>guns</strong> cycle automatically with each new level", description: "spawn <strong>6</strong> <strong class='color-g'>guns</strong>, but you can't <strong>switch</strong> <strong class='color-g'>guns</strong><br><strong class='color-g'>guns</strong> cycle automatically with each new level",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
isNonRefundable: true, isNonRefundable: true,
allowed() { allowed() {
return tech.isDamageForGuns return tech.isDamageForGuns || tech.isFireRateForGuns
}, },
requires: "arsenal", requires: "arsenal or cyclic rate boost",
effect() { effect() {
tech.isGunCycle = true; tech.isGunCycle = true;
for (let i = 0; i < 6; i++) { for (let i = 0; i < 6; i++) powerUps.spawn(mech.pos.x + 10 * Math.random(), mech.pos.y + 10 * Math.random(), "gun");
powerUps.spawn(mech.pos.x, mech.pos.y, "gun");
}
}, },
remove() { remove() {
tech.isGunCycle = false; tech.isGunCycle = false;
} }
}, },
{
name: "specialist",
description: "for every <strong class='color-g'>gun</strong> in your inventory spawn a<br><strong class='color-h'>heal</strong>, <strong class='color-r'>research</strong>, <strong class='color-f'>field</strong>, <strong class='color-g'>ammo</strong>, or <strong class='color-m'>tech</strong>",
maxCount: 1, //random power up
count: 0,
isNonRefundable: true,
isCustomHide: true,
allowed() {
return tech.isGunCycle
},
requires: "generalist",
effect() {
for (let i = 0; i < b.inventory.length; i++) {
if (Math.random() < 0.2) {
powerUps.spawn(mech.pos.x + 10 * Math.random(), mech.pos.y + 10 * Math.random(), "tech");
} else if (Math.random() < 0.25) {
powerUps.spawn(mech.pos.x + 10 * Math.random(), mech.pos.y + 10 * Math.random(), "field");
} else if (Math.random() < 0.33) {
powerUps.spawn(mech.pos.x + 10 * Math.random(), mech.pos.y + 10 * Math.random(), "heal");
} else if (Math.random() < 0.5) {
powerUps.spawn(mech.pos.x + 10 * Math.random(), mech.pos.y + 10 * Math.random(), "ammo");
} else {
powerUps.spawn(mech.pos.x + 10 * Math.random(), mech.pos.y + 10 * Math.random(), "research");
}
}
},
remove() {}
},
{ {
name: "logistics", name: "logistics",
description: "<strong class='color-g'>ammo</strong> power ups give <strong>200%</strong> <strong class='color-g'>ammo</strong><br>but <strong class='color-g'>ammo</strong> is only added to your <strong>current gun</strong>", description: "<strong class='color-g'>ammo</strong> power ups give <strong>200%</strong> <strong class='color-g'>ammo</strong><br>but <strong class='color-g'>ammo</strong> is only added to your <strong>current gun</strong>",
@@ -617,7 +662,7 @@ const tech = {
}, },
{ {
name: "laser-bot", name: "laser-bot",
description: "a bot uses <strong class='color-f'>energy</strong> to emit a <strong class='color-laser'>laser</strong><br>targeting nearby mobs", description: "a bot uses <strong class='color-f'>energy</strong> to emit a <strong class='color-laser'>laser</strong> beam<br>that targets nearby mobs",
maxCount: 9, maxCount: 9,
count: 0, count: 0,
allowed() { allowed() {
@@ -932,7 +977,7 @@ const tech = {
}, },
{ {
name: "Pauli exclusion", name: "Pauli exclusion",
description: `<strong>immune</strong> to <strong class='color-harm'>harm</strong> for an extra <strong>0.75</strong> seconds<br>after receiving <strong class='color-harm'>harm</strong> from a <strong>collision</strong>`, description: `after receiving <strong class='color-harm'>harm</strong> from a <strong>collision</strong> become<br><strong>immune</strong> to <strong class='color-harm'>harm</strong> for an extra <strong>0.75</strong> seconds`,
maxCount: 9, maxCount: 9,
count: 0, count: 0,
allowed() { allowed() {
@@ -947,6 +992,22 @@ const tech = {
tech.collisionImmuneCycles = 25; tech.collisionImmuneCycles = 25;
} }
}, },
{
name: "complex spin-statistics",
description: `become <strong>immune</strong> to <strong class='color-harm'>harm</strong> for <strong>+1</strong> second<br>once every <strong>7</strong> seconds`,
maxCount: 3,
count: 0,
allowed() {
return true //tech.collisionImmuneCycles > 30
},
requires: "",
effect() {
tech.cyclicImmunity += 60 - this.count * 6;
},
remove() {
tech.cyclicImmunity = 0;
}
},
{ {
name: "ablative drones", name: "ablative drones",
description: "rebuild your broken parts as <strong>drones</strong><br>chance to occur after receiving <strong class='color-harm'>harm</strong>", description: "rebuild your broken parts as <strong>drones</strong><br>chance to occur after receiving <strong class='color-harm'>harm</strong>",
@@ -1102,7 +1163,7 @@ const tech = {
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
return (tech.iceEnergy || tech.isWormholeEnergy || tech.isPiezo || tech.isRailEnergyGain) && tech.energyRegen !== 0.004 return (tech.iceEnergy || tech.isWormholeEnergy || tech.isPiezo || tech.isRailEnergyGain) && tech.energyRegen !== 0.004 && !tech.isEnergyHealth
}, },
requires: "piezoelectricity, Penrose, half-wave, or thermoelectric, but not time crystals", requires: "piezoelectricity, Penrose, half-wave, or thermoelectric, but not time crystals",
effect: () => { effect: () => {
@@ -1403,7 +1464,7 @@ const tech = {
}, },
{ {
name: "inductive coupling", name: "inductive coupling",
description: "for each unused <strong>power up</strong> at the end of a <strong>level</strong><br>add 4 <strong>max</strong> <strong class='color-h'>health</strong> <em>(up to 40 health per level)</em>", description: "for each unused <strong>power up</strong> at the end of a <strong>level</strong><br>add 3 <strong>max</strong> <strong class='color-h'>health</strong> <em>(up to 42 health per level)</em>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
@@ -1520,9 +1581,7 @@ const tech = {
requires: "at least 2 research", requires: "at least 2 research",
effect() { effect() {
tech.isImmortal = true; tech.isImmortal = true;
for (let i = 0; i < 4; i++) { for (let i = 0; i < 4; i++) powerUps.spawn(mech.pos.x + Math.random() * 10, mech.pos.y + Math.random() * 10, "research", false);
powerUps.spawn(mech.pos.x, mech.pos.y, "research", false);
}
}, },
remove() { remove() {
tech.isImmortal = false; tech.isImmortal = false;
@@ -3996,5 +4055,7 @@ const tech = {
isLaserMine: null, isLaserMine: null,
isAmmoFoamSize: null, isAmmoFoamSize: null,
isIceIX: null, isIceIX: null,
isDupDamage: null isDupDamage: null,
isFireRateForGuns: null,
cyclicImmunity: null
} }

View File

@@ -1,6 +1,12 @@
******************************************************** NEXT PATCH ******************************************************** ******************************************************** NEXT PATCH ********************************************************
tech: relativistic momentum - laser beams push mobs away tech: active cooling - 15% faster fire rate for each gun in your inventory
tech: specialist - spawn a random power up for each gun in your inventory
(not available in custom, requires tech: generalist)
tech: complex spin-statistics - become immune to harm for 1s every 7s
requires Pauli exclusion
even less difficulty ramp after killing final boss
******************************************************** BUGS ******************************************************** ******************************************************** BUGS ********************************************************
@@ -21,6 +27,9 @@ CPT check for crouch after rewind
******************************************************** TODO ******************************************************** ******************************************************** TODO ********************************************************
tech "Circadian Rhythm": Become immune to harm for 1 second every 10 seconds while playing.
bot that follows the players history bot that follows the players history
could have the same shape as the mech circle head could have the same shape as the mech circle head
1st bot is at 5s, 2nd is at 4.5s, ... 1st bot is at 5s, 2nd is at 4.5s, ...
@@ -46,11 +55,6 @@ in game console
set highlighting rules set highlighting rules
mech, tech, level are all highlighted mech, tech, level are all highlighted
maybe the first term in each variable should get a highlight maybe the first term in each variable should get a highlight
make all commands actually work
input.key commands don't work
rewrite to not be a console command?
add commands
death, max health, max energy, rewind
mechanic: use gun swap as an active ability mechanic: use gun swap as an active ability
this effect is spammable, so it needs a cost or a cooldown this effect is spammable, so it needs a cost or a cooldown
@@ -63,14 +67,10 @@ tech: time dilation - when you exit time dilation rewind to the state you entere
position, velocity, and health position, velocity, and health
no energy cost no energy cost
CPT gun seems a bit weak right now. How to buff the gun?
mob ability bombs/bullets that suck in player mob ability bombs/bullets that suck in player
tech where you can't stop firing, how to code? tech where you can't stop firing, how to code?
tech: translational invariance - laser beams push like plasma torch pushes with directional force
mechanic: technological dead end - add tech to the tech pool with a dumb effect mechanic: technological dead end - add tech to the tech pool with a dumb effect
don't show up in custom? don't show up in custom?
negative effect (one time effects are better to avoid code clutter) negative effect (one time effects are better to avoid code clutter)
@@ -92,7 +92,6 @@ mechanic: technological dead end - add tech to the tech pool with a dumb effect
tech "Expansion Formula": Permanently increase the size of Negative Mass field by 16%(Max 96%) tech "Expansion Formula": Permanently increase the size of Negative Mass field by 16%(Max 96%)
tech "Circadian Rhythm": Become immune to harm for 1 second every 10 seconds while playing.
tech "High Risk": Spawn two bosses per level. tech "High Risk": Spawn two bosses per level.
maybe limit to just the power up boss and spawn it at the exit every time to keep it simple maybe limit to just the power up boss and spawn it at the exit every time to keep it simple