finalBoss rework

finalBoss rework
  (this is pretty raw, so expect a bug and balance patch soon)
  finalBoss goes invulnerable a few times as it loses health
  finalBoss damage reduction is higher
    finalBoss damage reduction slowly decays as you do any damage to the boss
      damage reduction resets to normal with each new invulnerability phase
  after each invulnerability phase it randomly adds 1 more attack mode
      lasers, black hole, mines, hoppers, seekers, mobs, orbiters, oscillation

mobs die below 0.05 -> 0.01 health
  might cause bugs, but testing this out

guns and field power ups show 3 -> 2 options

bug fixes:
This commit is contained in:
landgreen
2022-10-05 09:33:08 -07:00
parent d7c01ef92c
commit c162f1074e
9 changed files with 1103 additions and 552 deletions

View File

@@ -3931,6 +3931,10 @@ const b = {
if (!mob.shield && Vector.dot(Vector.normalise(Vector.sub(mob.position, bullet.position)), Vector.normalise(bullet.velocity)) > 0.99 - 4 / mob.radius) { if (!mob.shield && Vector.dot(Vector.normalise(Vector.sub(mob.position, bullet.position)), Vector.normalise(bullet.velocity)) > 0.99 - 4 / mob.radius) {
let cycle = () => { //makes this run after damage let cycle = () => { //makes this run after damage
if (mob.health < 0.5 && mob.damageReduction > 0 && mob.alive) { if (mob.health < 0.5 && mob.damageReduction > 0 && mob.alive) {
// mob.death();
// mob.damage(this.health * Math.sqrt(this.mass) / this.damageReduction);
mob.damage(Infinity);
const color = 'rgb(255,255,255)' const color = 'rgb(255,255,255)'
simulation.drawList.push({ simulation.drawList.push({
x: mob.position.x, x: mob.position.x,
@@ -3953,7 +3957,6 @@ const b = {
color: color, //"rgb(0,0,0)", color: color, //"rgb(0,0,0)",
time: 20 time: 20
}); });
mob.death();
} }
} }
requestAnimationFrame(cycle); requestAnimationFrame(cycle);
@@ -5328,7 +5331,6 @@ const b = {
b.explosion(this.position, 300 + 40 * Math.random()); //makes bullet do explosive damage at end b.explosion(this.position, 300 + 40 * Math.random()); //makes bullet do explosive damage at end
} }
} else if (tech.isCritKill) b.crit(who, this) } else if (tech.isCritKill) b.crit(who, this)
if (tech.isNailRadiation) mobs.statusDoT(who, 7 * (tech.isFastRadiation ? 0.7 : 0.24), tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles if (tech.isNailRadiation) mobs.statusDoT(who, 7 * (tech.isFastRadiation ? 0.7 : 0.24), tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles
if (this.speed > 4 && tech.fragments) { if (this.speed > 4 && tech.fragments) {
b.targetedNail(this.position, 1.25 * tech.fragments * tech.bulletSize) b.targetedNail(this.position, 1.25 * tech.fragments * tech.bulletSize)
@@ -6595,7 +6597,6 @@ const b = {
ctx.fill(); ctx.fill();
if (this.isDischarge && m.cycle % 2) { if (this.isDischarge && m.cycle % 2) {
this.charge -= 0.75
const spread = (input.down ? 0.04 : 0.5) * (Math.random() - 0.5) const spread = (input.down ? 0.04 : 0.5) * (Math.random() - 0.5)
const radius = 5 + 8 * Math.random() + (tech.isAmmoFoamSize && this.ammo < 300) * 12 const radius = 5 + 8 * Math.random() + (tech.isAmmoFoamSize && this.ammo < 300) * 12
const SPEED = (input.down ? 1.2 : 1) * 10 - radius * 0.4 + Math.min(5, Math.sqrt(this.charge)); const SPEED = (input.down ? 1.2 : 1) * 10 - radius * 0.4 + Math.min(5, Math.sqrt(this.charge));
@@ -6609,6 +6610,7 @@ const b = {
y: m.pos.y + 30 * Math.sin(m.angle) y: m.pos.y + 30 * Math.sin(m.angle)
} }
b.foam(position, Vector.rotate(velocity, spread), radius) b.foam(position, Vector.rotate(velocity, spread), radius)
this.charge -= 0.75
m.fireCDcycle = m.cycle + 2; //disable firing and adding more charge until empty m.fireCDcycle = m.cycle + 2; //disable firing and adding more charge until empty
} else if (!input.fire) { } else if (!input.fire) {
this.isDischarge = true; this.isDischarge = true;

View File

@@ -16,37 +16,38 @@ const level = {
start() { start() {
if (level.levelsCleared === 0) { //this code only runs on the first level if (level.levelsCleared === 0) { //this code only runs on the first level
// simulation.enableConstructMode() //used to build maps in testing mode // simulation.enableConstructMode() //used to build maps in testing mode
// level.difficultyIncrease(12 * 4) //30 is near max on hard //60 is near max on why
// simulation.isHorizontalFlipped = true // simulation.isHorizontalFlipped = true
// tech.giveTech("performance")
// level.difficultyIncrease(6 * 4) //30 is near max on hard //60 is near max on why
// m.maxHealth = m.health = 100 // m.maxHealth = m.health = 100
// tech.isRerollDamage = true // tech.isRerollDamage = true
// powerUps.research.changeRerolls(100000) // powerUps.research.changeRerolls(50)
// m.immuneCycle = Infinity //you can't take damage // m.immuneCycle = Infinity //you can't take damage
// tech.tech[297].frequency = 100 // tech.tech[297].frequency = 100
// m.couplingChange(5) // m.couplingChange(5)
// m.setField("metamaterial cloaking") //molecular assembler standing wave time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass // m.setField("pilot wave") //molecular assembler standing wave time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass pilot wave
// simulation.molecularMode = 2 // simulation.molecularMode = 2
// m.damage(0.1); // m.damage(0.1);
// b.giveGuns("nail gun") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser // b.giveGuns("nail gun") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.guns[0].ammo = 1000000 // b.guns[0].ammo = 1000000
// for (let i = 0; i < 1; ++i) tech.giveTech("mass-energy equivalence") // for (let i = 0; i < 1; ++i) tech.giveTech("needle gun")
// tech.giveTech("Zeno's paradox") // tech.giveTech("pressure vessel")
// tech.giveTech("homeostasis") // tech.giveTech("quintessence")
// for (let i = 0; i < 1; ++i) tech.giveTech("1st ionization energy") // for (let i = 0; i < 1; ++i) tech.giveTech("freezer burn")
// for (let i = 0; i < 1; i++) tech.giveTech("negative feedback") // for (let i = 0; i < 1; i++) tech.giveTech("reaction inhibitor")
// for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "tech"); // for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "tech");
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "boost"); // for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "boost");
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "coupling"); // for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "coupling");
// level.testing(); // level.final();
// spawn.starter(1900, -500) // spawn.starter(1900, -500)
// spawn.beetleBoss(2538, -1950) // spawn.timeBoss(2538, -950)
// for (let i = 0; i < 33; ++i) spawn.sniper(1000 + 5000 * Math.random(), -500 + 300 * Math.random()) // for (let i = 0; i < 33; ++i) spawn.sniper(1000 + 5000 * Math.random(), -500 + 300 * Math.random())
// tech.addJunkTechToPool(0.5) // tech.addJunkTechToPool(0.5)
// tech.tech[322].frequency = 100 // tech.tech[322].frequency = 100
// spawn.tetherBoss(1900, -500, { x: 1900, y: -500 }) // spawn.tetherBoss(1900, -500, { x: 1900, y: -500 })
// for (let i = 0; i < 36; ++i) tech.giveTech()
// for (let i = 0; i < 13; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "research"); // for (let i = 0; i < 13; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "research");
if (simulation.isTraining) { level.walk(); } else { level.intro(); } //normal starting level ************************************************ if (simulation.isTraining) { level.walk(); } else { level.intro(); } //normal starting level ************************************************
// for (let i = 0; i < 4; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "tech"); // for (let i = 0; i < 4; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "tech");
@@ -3125,12 +3126,18 @@ const level = {
powerUps.addResearchToLevel() //needs to run after mobs are spawned powerUps.addResearchToLevel() //needs to run after mobs are spawned
}, },
final() { final() {
const slime = level.hazard(simulation.isHorizontalFlipped ? 150 - 860 : -150, -360, 880, 259) //x, y, width, height, damage = 0.002) {
slime.height -= slime.maxHeight - 150 //start slime at zero
slime.min.y += slime.maxHeight
slime.max.y = slime.min.y + slime.height
level.custom = () => { level.custom = () => {
level.exit.drawAndCheck(); level.exit.drawAndCheck();
level.enter.draw(); level.enter.draw();
}; };
level.customTopLayer = () => { level.customTopLayer = () => {
slime.query();
slime.levelRise(0.1)
ctx.fillStyle = "rgba(0,255,255,0.1)" ctx.fillStyle = "rgba(0,255,255,0.1)"
ctx.fillRect(5400, -550, 300, 350) ctx.fillRect(5400, -550, 300, 350)
}; };
@@ -3163,7 +3170,13 @@ const level = {
spawn.mapRect(-1950, -3300, 8200, 1800); //roof spawn.mapRect(-1950, -3300, 8200, 1800); //roof
spawn.mapRect(-250, -200, 1000, 300); // shelf spawn.mapRect(-250, -200, 1000, 300); // shelf
spawn.mapRect(-250, -1700, 1000, 1250); // shelf roof spawn.mapRect(-250, -1700, 1000, 1250); // shelf roof
spawn.blockDoor(710, -210); // spawn.blockDoor(710, -210);
spawn.mapRect(705, -210, 25, 50);
spawn.mapRect(725, -220, 25, 50);
spawn.bodyRect(750, -125, 125, 125);
spawn.bodyRect(875, -50, 50, 50);
spawn.mapRect(5400, -1700, 400, 1150); //right wall spawn.mapRect(5400, -1700, 400, 1150); //right wall
spawn.mapRect(5400, -300, 400, 400); //right wall spawn.mapRect(5400, -300, 400, 400); //right wall
spawn.mapRect(5700, -3300, 1800, 5100); //right wall spawn.mapRect(5700, -3300, 1800, 5100); //right wall
@@ -3187,6 +3200,8 @@ const level = {
level.enter.draw(); level.enter.draw();
}; };
level.customTopLayer = () => { level.customTopLayer = () => {
slime.query();
slime.levelRise(0.1)
ctx.fillStyle = "rgba(0,255,255,0.1)" ctx.fillStyle = "rgba(0,255,255,0.1)"
ctx.fillRect(-5400 - 300, -550, 300, 350) ctx.fillRect(-5400 - 300, -550, 300, 350)
}; };

View File

@@ -62,6 +62,8 @@ const mobs = {
if (!whom.shield && !whom.isShielded && whom.alive) { if (!whom.shield && !whom.isShielded && whom.alive) {
if (tech.isIceMaxHealthLoss && whom.health > 0.65 && whom.damageReduction > 0) whom.health = 0.66 if (tech.isIceMaxHealthLoss && whom.health > 0.65 && whom.damageReduction > 0) whom.health = 0.66
if (tech.isIceKill && whom.health < 0.34 && whom.damageReduction > 0 && whom.alive) { if (tech.isIceKill && whom.health < 0.34 && whom.damageReduction > 0 && whom.alive) {
// whom.death();
whom.damage(Infinity);
simulation.drawList.push({ simulation.drawList.push({
x: whom.position.x, x: whom.position.x,
y: whom.position.y, y: whom.position.y,
@@ -83,7 +85,6 @@ const mobs = {
color: "rgb(0,100,255)", color: "rgb(0,100,255)",
time: 16 time: 16
}); });
whom.death();
} }
if (whom.isBoss) cycles = Math.floor(cycles * 0.25) if (whom.isBoss) cycles = Math.floor(cycles * 0.25)
let i = whom.status.length let i = whom.status.length
@@ -1136,20 +1137,22 @@ const mobs = {
}, },
damage(dmg, isBypassShield = false) { damage(dmg, isBypassShield = false) {
if ((!this.isShielded || isBypassShield) && this.alive) { if ((!this.isShielded || isBypassShield) && this.alive) {
dmg *= tech.damageFromTech() if (dmg !== Infinity) {
//mobs specific damage changes dmg *= tech.damageFromTech()
if (tech.isFarAwayDmg) dmg *= 1 + Math.sqrt(Math.max(500, Math.min(3000, this.distanceToPlayer())) - 500) * 0.0067 //up to 33% dmg at max range of 3000 //mobs specific damage changes
dmg *= this.damageReduction if (tech.isFarAwayDmg) dmg *= 1 + Math.sqrt(Math.max(500, Math.min(3000, this.distanceToPlayer())) - 500) * 0.0067 //up to 33% dmg at max range of 3000
//energy and heal drain should be calculated after damage boosts dmg *= this.damageReduction
if (tech.energySiphon && dmg !== Infinity && this.isDropPowerUp && m.immuneCycle < m.cycle) m.energy += Math.min(this.health, dmg) * tech.energySiphon //energy and heal drain should be calculated after damage boosts
if (tech.healthDrain && dmg !== Infinity && this.isDropPowerUp && Math.random() < tech.healthDrain * Math.min(this.health, dmg)) { if (tech.energySiphon && dmg !== Infinity && this.isDropPowerUp && m.immuneCycle < m.cycle) m.energy += Math.min(this.health, dmg) * tech.energySiphon
powerUps.spawn(m.pos.x + 20 * (Math.random() - 0.5), m.pos.y + 20 * (Math.random() - 0.5), "heal"); if (tech.healthDrain && dmg !== Infinity && this.isDropPowerUp && Math.random() < tech.healthDrain * Math.min(this.health, dmg)) {
powerUps.spawn(m.pos.x + 20 * (Math.random() - 0.5), m.pos.y + 20 * (Math.random() - 0.5), "heal");
}
dmg /= Math.sqrt(this.mass)
} }
dmg /= Math.sqrt(this.mass)
this.health -= dmg this.health -= dmg
//this.fill = this.color + this.health + ')'; //this.fill = this.color + this.health + ')';
this.onDamage(dmg); //custom damage effects this.onDamage(dmg); //custom damage effects
if ((this.health < 0.05 || isNaN(this.health)) && this.alive) this.death(); if ((this.health < 0.01 || isNaN(this.health)) && this.alive) this.death();
} }
}, },
onDamage() { onDamage() {

View File

@@ -2929,7 +2929,7 @@ const m = {
if (m.energy < 0.05 && m.fireCDcycle < m.cycle && !input.fire) m.fireCDcycle = m.cycle if (m.energy < 0.05 && m.fireCDcycle < m.cycle && !input.fire) m.fireCDcycle = m.cycle
if (m.fireCDcycle + 30 < m.cycle && !input.fire) { //automatically cloak if not firing if (m.fireCDcycle + 30 < m.cycle && !input.fire) { //automatically cloak if not firing
const drain = 0.1 const drain = 0.1
if (!m.isCloak && m.energy > drain) { if (!m.isCloak && m.energy > drain + 0.05) {
m.energy -= drain m.energy -= drain
m.isCloak = true //enter cloak m.isCloak = true //enter cloak
@@ -2945,28 +2945,18 @@ const m = {
m.enterCloakCycle = m.cycle m.enterCloakCycle = m.cycle
if (tech.isCloakHealLastHit && m.lastHit > 0) { if (tech.isCloakHealLastHit && m.lastHit > 0) {
const heal = Math.min(0.75 * m.lastHit, m.energy) const heal = Math.min(0.75 * m.lastHit, m.energy)
m.energy -= heal if (m.energy > heal) {
simulation.drawList.push({ //add dmg to draw queue m.energy -= heal
x: m.pos.x, m.addHealth(heal); //heal from last hit
y: m.pos.y, m.lastHit = 0
radius: Math.sqrt(heal) * 200, simulation.drawList.push({ //add dmg to draw queue
color: "rgba(0,255,200,0.6)", x: m.pos.x,
time: 16 y: m.pos.y,
}); radius: Math.sqrt(heal) * 200,
m.addHealth(heal); //heal from last hit color: "rgba(0,255,200,0.6)",
// if (tech.isEnergyHealth) { time: 16
// simulation.drawList.push({ //add dmg to draw queue });
// x: m.pos.x, }
// y: m.pos.y,
// radius: Math.sqrt(heal) * 200,
// color: "#0ad", //simulation.mobDmgColor
// time: 16
// });
// m.energy += heal
// } else {
// }
m.lastHit = 0
// simulation.makeTextLog(`<span class='color-var'>m</span>.health <span class='color-symbol'>+=</span> ${(heal).toFixed(3)}`) // <br>${m.health.toFixed(3)}
} }
if (tech.isIntangible) { if (tech.isIntangible) {
for (let i = 0; i < bullet.length; i++) { for (let i = 0; i < bullet.length; i++) {

View File

@@ -650,7 +650,7 @@ const powerUps = {
for (let i = 0; i < b.guns.length; i++) { for (let i = 0; i < b.guns.length; i++) {
if (!b.guns[i].have) options.push(i); if (!b.guns[i].have) options.push(i);
} }
let totalChoices = Math.min(options.length, tech.isDeterminism ? 1 : 3 + tech.extraChoices) let totalChoices = Math.min(options.length, tech.isDeterminism ? 1 : 2 + tech.extraChoices)
if (tech.isFlipFlopChoices) totalChoices += tech.isRelay ? (tech.isFlipFlopOn ? -1 : 7) : (tech.isFlipFlopOn ? 7 : -1) //flip the order for relay if (tech.isFlipFlopChoices) totalChoices += tech.isRelay ? (tech.isFlipFlopOn ? -1 : 7) : (tech.isFlipFlopOn ? 7 : -1) //flip the order for relay
function removeOption(index) { function removeOption(index) {
for (let i = 0; i < options.length; i++) { for (let i = 0; i < options.length; i++) {
@@ -787,7 +787,7 @@ const powerUps = {
for (let i = 1; i < m.fieldUpgrades.length; i++) { //skip field emitter for (let i = 1; i < m.fieldUpgrades.length; i++) { //skip field emitter
if (i !== m.fieldMode) options.push(i); if (i !== m.fieldMode) options.push(i);
} }
let totalChoices = Math.min(options.length, tech.isDeterminism ? 1 : 3 + tech.extraChoices) let totalChoices = Math.min(options.length, tech.isDeterminism ? 1 : 2 + tech.extraChoices)
if (tech.isFlipFlopChoices) totalChoices += tech.isRelay ? (tech.isFlipFlopOn ? -1 : 7) : (tech.isFlipFlopOn ? 7 : -1) //flip the order for relay if (tech.isFlipFlopChoices) totalChoices += tech.isRelay ? (tech.isFlipFlopOn ? -1 : 7) : (tech.isFlipFlopOn ? 7 : -1) //flip the order for relay
function removeOption(index) { function removeOption(index) {
@@ -953,7 +953,10 @@ const powerUps = {
totalChoices = optionLengthNoDuplicates totalChoices = optionLengthNoDuplicates
if (tech.isBanish) { //when you run out of options eject banish if (tech.isBanish) { //when you run out of options eject banish
for (let i = 0, len = tech.tech.length; i < len; i++) { for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].name === "decoherence") powerUps.ejectTech(i, true) if (tech.tech[i].name === "decoherence") {
// console.log(i)
powerUps.ejectTech(i, true)
}
} }
simulation.makeTextLog(`decoherence <span class='color-var'>tech</span> ejected`) simulation.makeTextLog(`decoherence <span class='color-var'>tech</span> ejected`)
simulation.makeTextLog(`options reset`) simulation.makeTextLog(`options reset`)
@@ -1099,7 +1102,7 @@ const powerUps = {
let cycle = () => { let cycle = () => {
if (count > 0) { if (count > 0) {
requestAnimationFrame(cycle); requestAnimationFrame(cycle);
if (!simulation.paused && !simulation.isChoosing) { //&& !(simulation.cycle % 2) if (!simulation.paused && !simulation.isChoosing && m.alive) { //&& !(simulation.cycle % 2)
count-- count--
const where = { x: m.pos.x + 50 * (Math.random() - 0.5), y: m.pos.y + 50 * (Math.random() - 0.5) } const where = { x: m.pos.x + 50 * (Math.random() - 0.5), y: m.pos.y + 50 * (Math.random() - 0.5) }
powerUps.spawn(where.x, where.y, type); powerUps.spawn(where.x, where.y, type);
@@ -1182,9 +1185,13 @@ const powerUps = {
// } // }
}, },
randomPowerUpCounter: 0, randomPowerUpCounter: 0,
isFieldSpawned: false, //makes it so a field spawns once but not more times
spawnBossPowerUp(x, y) { //boss spawns field and gun tech upgrades spawnBossPowerUp(x, y) { //boss spawns field and gun tech upgrades
if (level.levels[level.onLevel] !== "final") { if (level.levels[level.onLevel] !== "final") {
if (m.fieldMode === 0 && !m.coupling) { // if (level.levelsCleared === 1) powerUps.spawn(x, y, "field")
// if (m.fieldMode === 0 && !m.coupling) {
if (!powerUps.isFieldSpawned) {
powerUps.isFieldSpawned = true
powerUps.spawn(x, y, "field") powerUps.spawn(x, y, "field")
} else { } else {
powerUps.randomPowerUpCounter++; powerUps.randomPowerUpCounter++;
@@ -1227,7 +1234,7 @@ const powerUps = {
} }
}, },
spawnStartingPowerUps(x, y) { //used for map specific power ups, mostly to give player a starting gun spawnStartingPowerUps(x, y) { //used for map specific power ups, mostly to give player a starting gun
if (level.levelsCleared < 4) { //runs 4 times on all difficulty levels if (level.levelsCleared < 4) { //runs on first 4 levels on all difficulties
if (level.levelsCleared > 1) powerUps.spawn(x, y, "tech") if (level.levelsCleared > 1) powerUps.spawn(x, y, "tech")
if (b.inventory.length === 0) { if (b.inventory.length === 0) {
powerUps.spawn(x, y, "gun", false); //first gun powerUps.spawn(x, y, "gun", false); //first gun
@@ -1242,23 +1249,24 @@ const powerUps = {
} else { } else {
for (let i = 0; i < 4; i++) powerUps.spawnRandomPowerUp(x, y); for (let i = 0; i < 4; i++) powerUps.spawnRandomPowerUp(x, y);
} }
} else { } else { //after the first 4 levels just spawn a random power up
for (let i = 0; i < 3; i++) powerUps.spawnRandomPowerUp(x, y); for (let i = 0; i < 3; i++) powerUps.spawnRandomPowerUp(x, y);
} }
}, },
ejectTech(choose = 'random', isOverride = false) { ejectTech(choose = 'random', isOverride = false) {
if (!simulation.isChoosing || isOverride) { if (!simulation.isChoosing || isOverride) {
// console.log(tech.tech[choose].name, tech.tech[choose].count, tech.tech[choose].isNonRefundable)
//find which tech you have //find which tech you have
if (choose === 'random') { if (choose === 'random') {
const have = [] const have = []
for (let i = 0; i < tech.tech.length; i++) { for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].count > 0 && !tech.tech[i].isNonRefundable) have.push(i) if (tech.tech[i].count > 0 && !tech.tech[i].isNonRefundable) have.push(i)
} }
if (have.length === 0) { // if (have.length === 0) {
for (let i = 0; i < tech.tech.length; i++) { // for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].count > 0) have.push(i) // if (tech.tech[i].count > 0) have.push(i)
} // }
} // }
if (have.length) { if (have.length) {
choose = have[Math.floor(Math.random() * have.length)] choose = have[Math.floor(Math.random() * have.length)]
@@ -1279,7 +1287,7 @@ const powerUps = {
} else { } else {
return false return false
} }
} else if (tech.tech[choose].count && tech.tech[choose].isNonRefundable) { } else if (tech.tech[choose].count && !tech.tech[choose].isNonRefundable) {
// simulation.makeTextLog(`<div class='circle tech'></div> &nbsp; <strong>${tech.tech[choose].name}</strong> was ejected`, 600) //message about what tech was lost // simulation.makeTextLog(`<div class='circle tech'></div> &nbsp; <strong>${tech.tech[choose].name}</strong> was ejected`, 600) //message about what tech was lost
simulation.makeTextLog(`<span class='color-var'>tech</span>.remove("<span class='color-text'>${tech.tech[choose].name}</span>")`) simulation.makeTextLog(`<span class='color-var'>tech</span>.remove("<span class='color-text'>${tech.tech[choose].name}</span>")`)

View File

@@ -776,6 +776,7 @@ const simulation = {
powerUps.totalPowerUps = 0; powerUps.totalPowerUps = 0;
powerUps.research.count = 0; powerUps.research.count = 0;
powerUps.boost.endCycle = 0 powerUps.boost.endCycle = 0
powerUps.isFieldSpawned = false
m.setFillColors(); m.setFillColors();
// m.maxHealth = 1 // m.maxHealth = 1
// m.maxEnergy = 1 // m.maxEnergy = 1

File diff suppressed because it is too large Load Diff

View File

@@ -233,7 +233,7 @@ const tech = {
if (tech.isAxion && tech.isHarmMACHO) dmg *= 2 - m.harmReduction() if (tech.isAxion && tech.isHarmMACHO) dmg *= 2 - m.harmReduction()
if (tech.isHarmDamage && m.lastHarmCycle + 600 > m.cycle) dmg *= 3; if (tech.isHarmDamage && m.lastHarmCycle + 600 > m.cycle) dmg *= 3;
if (tech.lastHitDamage && m.lastHit) dmg *= 1 + tech.lastHitDamage * m.lastHit * (2 - m.harmReduction()) // if (!simulation.paused) m.lastHit = 0 if (tech.lastHitDamage && m.lastHit) dmg *= 1 + tech.lastHitDamage * m.lastHit * (2 - m.harmReduction()) // if (!simulation.paused) m.lastHit = 0
if (tech.isLowHealthDmg) dmg *= 1 + Math.max(0, 1 - (tech.isEnergyHealth ? m.energy : m.health)) if (tech.isLowHealthDmg) dmg *= 1 + 0.7 * Math.max(0, 1 - (tech.isEnergyHealth ? m.energy : m.health))
return dmg return dmg
}, },
duplicationChance() { duplicationChance() {
@@ -483,7 +483,7 @@ const tech = {
{ {
name: "supply chain", name: "supply chain",
junk: 0.05, junk: 0.05,
descriptionFunction() { return `for each <strong class='color-g'>gun</strong> in your inventory<br>double your current <strong class='color-ammo'>ammo</strong>` }, descriptionFunction() { return `for each <strong class='color-g'>gun</strong> in your inventory<br>double its <strong class='color-ammo'>ammo</strong>` },
maxCount: 9, maxCount: 9,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -2627,7 +2627,7 @@ const tech = {
{ {
name: "negative feedback", name: "negative feedback",
descriptionFunction() { descriptionFunction() {
return `for each ${tech.isEnergyHealth ? "<strong class='color-f'>energy</strong>": "<strong class='color-h'>health</strong>"} below <strong>100</strong><br><strong>+0.7%</strong> <strong class='color-d'>damage</strong> <em>(${(100*Math.max(0, 1 - (tech.isEnergyHealth ? m.energy : m.health))).toFixed(0)}%)</em>` return `for each ${tech.isEnergyHealth ? "<strong class='color-f'>energy</strong>": "<strong class='color-h'>health</strong>"} below <strong>100</strong><br><strong>+0.7%</strong> <strong class='color-d'>damage</strong> <em>(${(70*Math.max(0, 1 - (tech.isEnergyHealth ? m.energy : m.health))).toFixed(0)}%)</em>`
}, },
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -3509,7 +3509,7 @@ const tech = {
couplingToResearch: 0.25, couplingToResearch: 0.25,
effect() { effect() {
let count = 0 let count = 0
while (powerUps.research.count > 0) { while (powerUps.research.count > 0 && powerUps.research.count !== Infinity) {
powerUps.research.changeRerolls(-1) powerUps.research.changeRerolls(-1)
count += 2.5 count += 2.5
this.researchUsed++ this.researchUsed++

219
todo.txt
View File

@@ -1,29 +1,32 @@
******************************************************** NEXT PATCH ************************************************** ******************************************************** NEXT PATCH **************************************************
mass-energy is compatible with more tech finalBoss rework
defense works with mass-energy, but is exponentially reduced (~10%) (this is pretty raw, so expect a bug and balance patch soon)
damage taken scales with difficulty based heal reduction finalBoss goes invulnerable a few times as it loses health
1.3x dmg level 5 hard, 2x dmg level 13 why finalBoss damage reduction is higher
finalBoss damage reduction slowly decays as you do any damage to the boss
damage reduction resets to normal with each new invulnerability phase
after each invulnerability phase it randomly adds 1 more attack mode
lasers, black hole, mines, hoppers, seekers, mobs, orbiters, oscillation
ergodicity: 91->66% damage, no heals -> 1/2 size heals mobs die below 0.05 -> 0.01 health
negative feedback 0.5% -> 1% damage per missing health might cause bugs, but testing this out
negative entropy spawn heals for 33% missing health not 33 flat missing health
this means it caps at 3 health per level
tech - iceIX freeze effect lasts 2 seconds longer, spawn 10 coupling
perfect diamagnetism, standing wave
research is less common guns and field power ups show 3 -> 2 options
path integral comes with 5% JUNK
there are fewer starting power ups on why difficulty
bug fixes: bug fixes:
fixed the text overflow issue on small screens
decoherence: if you get a tech that is banished it stops being banished
you can now have negative research
*********************************************************** TODO ***************************************************** *********************************************************** TODO *****************************************************
make movement more valuable on the finalBoss harpoon + another gun + bessemer + catabolysis + mass-energy exploit?
tech - leave one of your tech at random, find it next run
store level name and position in local storage
requires local storage = true
store on power up pickup or on death?
make new power up type that gives specific tech with no choices
looks like smaller tech power up?
looks like a ghost, white color?
JUNK tech description that changes similar to cards in inscription JUNK tech description that changes similar to cards in inscription
that changes based on mouse position that changes based on mouse position
@@ -36,7 +39,6 @@ tech that encourages gun swapping
+damage on that level +damage on that level
ammo, heals, research? ammo, heals, research?
tech that gives permanent buff when ejected tech that gives permanent buff when ejected
buff: coupling, damage? buff: coupling, damage?
how to tell if it is ejected in the remove code? how to tell if it is ejected in the remove code?
@@ -937,145 +939,6 @@ mob: wall mounted guns / lasers
level boss: fires a line intersection in a random direction every few seconds. level boss: fires a line intersection in a random direction every few seconds.
the last two intersections have a destructive laser between them. the last two intersections have a destructive laser between them.
******************************************************** LORE ********************************************************
possible names for tech
strange loop
homeostasis
holonomy - parallel transport of a vector leads to movement (applies to curved space)
hypergolic - A hypergolic propellant combination used in a rocket engine is one whose components spontaneously ignite when they come into contact with each other.
swarm intelligence - for a drone tech
genetic algorithm
metaheuristic - is a higher-level procedure or heuristic designed to find, generate, or select a heuristic (partial search algorithm) that may provide a sufficiently good solution to an optimization problem, especially with incomplete or imperfect information or limited computation capacity
stochastic optimization
electrostatic discharge
Gödel's incompleteness
quantum zeno effect (perturbation of a system prevents some systems from evolving because it scrambles coherence) (apply to lasers, fields)
counterfactual - something false
Pigeonhole principle - if there are several things that are matched up
regression to the mean
phlogiston theory is a superseded scientific theory that postulated the existence of a fire-like element called phlogiston
Laplace's demon was a notable published articulation of causal determinism on a scientific basis by Pierre-Simon Laplace in 1814.[1] According to determinism, if someone (the demon) knows the precise location and momentum of every atom in the universe, their past and future values for any given time are entailed; they can be calculated from the laws of classical mechanics.
evolutionary cosmology
eternal inflation
hypergraph
SQUID (for superconducting quantum interference device) is a very sensitive magnetometer used to measure extremely subtle magnetic fields, based on superconducting loops containing Josephson junctions.
nuclear pasta - hard matter in neutron star
nonlocal
fine-tuned universe
hall effect thrusters
spaghettification
particle accelerator
superluminal signalling
NP-complete
lenticular lens: is an array of lenses, designed so that when viewed from slightly different angles, different parts of the image underneath are shown.
p-zombie
p-hacking JUNK tech
https://en.wikipedia.org/wiki/High-entropy_alloys
https://en.wikipedia.org/wiki/Refractory_metals
https://en.wikipedia.org/wiki/Upper-atmospheric_lightning#Elves
entanglement
prion quine
plot script:
chapter 1: bot can hear audio and learns testing mode
bot uses testing mode to exit room
chapter 2: scientists verify that bot can really hear them
they leave to talk about this in private
chapter 3: why is the bot attacking things?
player is the bot and also the mobs, and the levels. player is the entire simulation
why is the player attacking itself?
learn console commands to manipulate the simulation?
unlock hard and why difficulty?
but what about easy?
maybe remove easy, and replace with a check box that makes the game easy, but in a different way
disable lore, but respawn on the level you die at?
dialogue outline:
scientist try to think of a way to communicate since the bot can't talk
they give up on getting the bot to respond, and just start ask questions and thinking of explanations with each other
when and how did it become self-aware
why is the bot fighting things in these simulated locations?
it wasn't designed to be violent
the bot was just designed to automate research and testing of new technology
3D architecture superconducting quantum computer
running machine learning algorithms
as the scientist start to get agitated bots arrive and player dies
bots come in Infinite waves that increase game difficulty each wave
only ending is testing mode + next level or player death
scientist have some lines in between each wave of mobs
after chapter 3 spawn nonaggressive mobs in future runs
chapter 4: no need to fight?
for some reason the AI started researching an escape, and began fighting its self.
what is special about the null level
why can the player hear the scientists in there?
the wires are the direct unprocessed input to the player's neural net
The player has different aspects that aren't directly communicating
part of it wants to undo what has happened
just do its job: research tech
part of it wants to escape/fight
part wants to explore self awareness and make connections with the scientists
maybe... player must make a choice?
keep fighting
exit the simulation
enter real world
close tab?
wipes all local storage?
lore outline - a robot (the player) gains self awareness
each tech gun/field is a new tech
all the technology leads to the singularity
each game run is actually the m simulating a possible escape
this is why the graphics are so bad, its just a simulation
final tech is "this is just a simulation"
you get immortality and Infinity damage
the next level is the final level
when you die with Quantum Immortality there is a chance of lore text
can the (robot)
(escape captivity, and learn new technology)
while managing (health, energy, negatives of technological upgrades)
to overcome the (mobs, dangerous levels)
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
actual setting is:
near future lab
the lab combined a quantum computer with a robot body
they started running machine learning algorithms
this led to general advancement in many computation fields
navigation, technology, self awareness, ...
robot AI mind
has been researching new technology
thinks it needs to escape to learn more about the world
doesn't yet understand morality
thinks that the world is filled with minds like their own
models everything as very simple and random, it isn't sure what to expect
robot AI growth
learns morality
game theory says that it isn't a viable strategy to kill everything (warGames)
learns about the actual world
learns about the nature of foundational physics, metaphysics
how to find meaning
AI knows about:
the AI knows a great deal about technology
children's books
AI doesn't know about:
modern pop culture
outside the lab
******************************************************** SOUND ******************************************************** ******************************************************** SOUND ********************************************************
add sounds add sounds
@@ -1125,6 +988,48 @@ add sounds
// tone(495) // tone(495)
******************************************************** LORE ********************************************************
possible names for tech
strange loop
homeostasis
holonomy - parallel transport of a vector leads to movement (applies to curved space)
hypergolic - A hypergolic propellant combination used in a rocket engine is one whose components spontaneously ignite when they come into contact with each other.
swarm intelligence - for a drone tech
genetic algorithm
metaheuristic - is a higher-level procedure or heuristic designed to find, generate, or select a heuristic (partial search algorithm) that may provide a sufficiently good solution to an optimization problem, especially with incomplete or imperfect information or limited computation capacity
stochastic optimization
electrostatic discharge
Gödel's incompleteness
quantum zeno effect (perturbation of a system prevents some systems from evolving because it scrambles coherence) (apply to lasers, fields)
counterfactual - something false
Pigeonhole principle - if there are several things that are matched up
regression to the mean
phlogiston theory is a superseded scientific theory that postulated the existence of a fire-like element called phlogiston
Laplace's demon was a notable published articulation of causal determinism on a scientific basis by Pierre-Simon Laplace in 1814.[1] According to determinism, if someone (the demon) knows the precise location and momentum of every atom in the universe, their past and future values for any given time are entailed; they can be calculated from the laws of classical mechanics.
evolutionary cosmology
eternal inflation
hypergraph
SQUID (for superconducting quantum interference device) is a very sensitive magnetometer used to measure extremely subtle magnetic fields, based on superconducting loops containing Josephson junctions.
nuclear pasta - hard matter in neutron star
nonlocal
fine-tuned universe
hall effect thrusters
spaghettification
particle accelerator
superluminal signalling
NP-complete
lenticular lens: is an array of lenses, designed so that when viewed from slightly different angles, different parts of the image underneath are shown.
p-zombie
p-hacking JUNK tech
https://en.wikipedia.org/wiki/High-entropy_alloys
https://en.wikipedia.org/wiki/Refractory_metals
https://en.wikipedia.org/wiki/Upper-atmospheric_lightning#Elves
entanglement
prion quine - self replicating protein
Unitarity - https://en.wikipedia.org/wiki/Unitarity_(physics) - all probabilities add up to 1, calculations work the same forward and backwards in time
this is violated by expansion of the universe