endless experimental mode

"labs" is now in the normal map rotation
experimental mode is now endless  (no gauntlet, finalBoss, ...)
fixed a bug that was giving experimental mode full life at the start

perfect diamagnetism field has a 10% larger radius and arc
the 1/15 second cooldown after blocking with perfect diamagnetism no longer stops you from blocking
  it still disables field damage effects and player recoil after blocking  (for 1/15 of a second)

mass-energy now works with catabolism by removing max energy to make ammo
ergodicity - now reduces difficulty by 2 levels and prevent healing from heal power ups (was all healing)
Noether violation gives even more forward recoil
blinkBoss has more health, but it's much slower at easy difficulty
This commit is contained in:
landgreen
2021-08-01 06:33:53 -07:00
parent 1a5071cf06
commit 7e6fc208a9
10 changed files with 239 additions and 214 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -96,17 +96,20 @@ const b = {
outOfAmmo() { //triggers after firing when you have NO ammo outOfAmmo() { //triggers after firing when you have NO ammo
simulation.makeTextLog(`${b.guns[b.activeGun].name}.<span class='color-gun'>ammo</span><span class='color-symbol'>:</span> 0`); simulation.makeTextLog(`${b.guns[b.activeGun].name}.<span class='color-gun'>ammo</span><span class='color-symbol'>:</span> 0`);
m.fireCDcycle = m.cycle + 30; //fire cooldown m.fireCDcycle = m.cycle + 30; //fire cooldown
if (tech.isAmmoFromHealth && m.maxHealth > 0.01) { if (tech.isAmmoFromHealth) {
tech.extraMaxHealth -= 0.01 //decrease max health if (tech.isEnergyHealth) {
m.setMaxHealth(); tech.healMaxEnergyBonus -= 0.01
m.setMaxEnergy();
} else if (m.maxHealth > 0.01) {
tech.extraMaxHealth -= 0.01 //decrease max health
m.setMaxHealth();
}
for (let i = 0; i < 4; i++) powerUps.spawn(m.pos.x + 50 * (Math.random() - 0.5), m.pos.y + 50 * (Math.random() - 0.5), "ammo"); for (let i = 0; i < 4; i++) powerUps.spawn(m.pos.x + 50 * (Math.random() - 0.5), m.pos.y + 50 * (Math.random() - 0.5), "ammo");
// if (m.health > 0.03) {
// m.damage(0.03 / m.harmReduction()); // /m.harmReduction() undoes damage increase from difficulty
// if (!(tech.isRewindAvoidDeath && m.energy > 0.66)) { //don't give ammo if CPT triggered
//
// }
// }
} }
// if (tech.isAmmoFromHealth && m.maxHealth > 0.01) {
// tech.extraMaxHealth -= 0.01 //decrease max health
// m.setMaxHealth();
// }
}, },
giveGuns(gun = "random", ammoPacks = 10) { giveGuns(gun = "random", ammoPacks = 10) {
if (tech.isOneGun) b.removeAllGuns(); if (tech.isOneGun) b.removeAllGuns();
@@ -3794,8 +3797,8 @@ const b = {
} }
if (tech.isShotgunReversed) { if (tech.isShotgunReversed) {
player.force.x += 2 * knock * Math.cos(m.angle) player.force.x += 4 * knock * Math.cos(m.angle)
player.force.y += 2 * knock * Math.sin(m.angle) - 6 * player.mass * simulation.g player.force.y += 4 * knock * Math.sin(m.angle) - 6 * player.mass * simulation.g
} else if (tech.isShotgunRecoil) { } else if (tech.isShotgunRecoil) {
m.fireCDcycle -= 0.66 * (45 * b.fireCDscale) m.fireCDcycle -= 0.66 * (45 * b.fireCDscale)
player.force.x -= 2 * knock * Math.cos(m.angle) player.force.x -= 2 * knock * Math.cos(m.angle)

View File

@@ -106,7 +106,7 @@ window.addEventListener('load', () => {
simulation.difficultyMode = Number(set[property]) simulation.difficultyMode = Number(set[property])
document.getElementById("difficulty-select-experiment").value = Number(set[property]) document.getElementById("difficulty-select-experiment").value = Number(set[property])
} }
if (property === "level") document.getElementById("starting-level").value = Number(set[property]) if (property === "level") document.getElementById("starting-level").value = Math.max(Number(set[property]) - 1, 0)
if (property === "noPower") document.getElementById("no-power-ups").checked = Number(set[property]) if (property === "noPower") document.getElementById("no-power-ups").checked = Number(set[property])
} }
} }
@@ -275,7 +275,7 @@ const build = {
document.getElementById("pause-grid-right").style.display = "none" document.getElementById("pause-grid-right").style.display = "none"
window.scrollTo(0, 0); window.scrollTo(0, 0);
}, },
isExperimentSelection: true, isExperimentSelection: false,
choosePowerUp(who, index, type, isAllowed = false) { choosePowerUp(who, index, type, isAllowed = false) {
if (type === "gun") { if (type === "gun") {
let isDeselect = false let isDeselect = false
@@ -413,7 +413,7 @@ const build = {
</svg> </svg>
</div> </div>
<div style="align-items: center; text-align:center; font-size: 1.00em; line-height: 190%;background-color:var(--build-bg-color);"> <div style="align-items: center; text-align:center; font-size: 1.00em; line-height: 190%;background-color:var(--build-bg-color);">
<div>starting level: <input id='starting-level' type="number" step="1" value="0" min="0" max="99"></div> <div>starting level: <input id='starting-level' type="number" step="1" value="1" min="0" max="99"></div>
<div> <div>
<label for="difficulty-select" title="effects: number of mobs, damage done by mobs, damage done to mobs, mob speed, heal effects">difficulty:</label> <label for="difficulty-select" title="effects: number of mobs, damage done by mobs, damage done to mobs, mob speed, heal effects">difficulty:</label>
<select name="difficulty-select" id="difficulty-select-experiment"> <select name="difficulty-select" id="difficulty-select-experiment">
@@ -466,7 +466,7 @@ const build = {
}, },
reset() { reset() {
simulation.startGame(true); //starts game, but pauses it simulation.startGame(true); //starts game, but pauses it
build.isExperimentSelection = true; build.isExperimentSelection = false;
simulation.paused = true; simulation.paused = true;
m.setField(0) m.setField(0)
b.inventory = []; //removes guns and ammo b.inventory = []; //removes guns and ammo
@@ -537,7 +537,7 @@ const build = {
} }
for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]); for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]);
bullet = []; //remove any bullets that might have spawned from tech bullet = []; //remove any bullets that might have spawned from tech
const levelsCleared = Math.abs(Number(document.getElementById("starting-level").value)) const levelsCleared = Math.abs(Number(document.getElementById("starting-level").value) - 1)
level.difficultyIncrease(Math.min(99, levelsCleared * simulation.difficultyMode)) //increase difficulty based on modes level.difficultyIncrease(Math.min(99, levelsCleared * simulation.difficultyMode)) //increase difficulty based on modes
level.levelsCleared += levelsCleared; level.levelsCleared += levelsCleared;
simulation.isNoPowerUps = document.getElementById("no-power-ups").checked simulation.isNoPowerUps = document.getElementById("no-power-ups").checked
@@ -573,6 +573,7 @@ function openExperimentMenu() {
document.body.style.overflowY = "scroll"; document.body.style.overflowY = "scroll";
document.body.style.overflowX = "hidden"; document.body.style.overflowX = "hidden";
document.getElementById("info").style.display = 'none' document.getElementById("info").style.display = 'none'
build.isExperimentSelection = true
build.reset(); build.reset();
} }

View File

@@ -7,7 +7,7 @@ const level = {
defaultZoom: 1400, defaultZoom: 1400,
onLevel: -1, onLevel: -1,
levelsCleared: 0, levelsCleared: 0,
playableLevels: ["skyscrapers", "rooftops", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber"], playableLevels: ["skyscrapers", "rooftops", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber", "labs"],
levels: [], levels: [],
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
@@ -17,16 +17,9 @@ const level = {
// tech.isFieldFree = true // tech.isFieldFree = true
// m.setField("perfect diamagnetism") // m.setField("perfect diamagnetism")
// b.giveGuns("shotgun") // b.giveGuns("shotgun")
// tech.isNeedleShot = true // tech.giveTech("Noether violation")
// tech.isIceShot = true
// tech.isFoamShot = true
// tech.isWormShot = true
// tech.giveTech("CPT reversal")
// tech.giveTech("causality bombs")
// b.giveGuns("wave beam") // b.giveGuns("wave beam")
// tech.giveTech("phonon") // tech.giveTech("Lenz's law")
// tech.giveTech("cardinality")
// tech.giveTech("isotropic radiator")
// for (let i = 0; i < 3; i++) tech.giveTech("packet length") // for (let i = 0; i < 3; i++) tech.giveTech("packet length")
// for (let i = 0; i < 4; i++) tech.giveTech() // for (let i = 0; i < 4; i++) tech.giveTech()
@@ -233,6 +226,9 @@ const level = {
player.force.y = 0; player.force.y = 0;
Matter.Body.setPosition(player, m.spawnPos); Matter.Body.setPosition(player, m.spawnPos);
Matter.Body.setVelocity(player, m.spawnVel); Matter.Body.setVelocity(player, m.spawnVel);
//makes perfect diamagnetism tech: Lenz's law show up in the right spot at the start of a level
m.fieldPosition = { x: m.pos.x, y: m.pos.y }
m.fieldAngle = m.angle
}, },
enter: { enter: {
x: 0, x: 0,
@@ -1082,6 +1078,7 @@ const level = {
doCustom = [] doCustom = []
doCustomTopLayer = [] doCustomTopLayer = []
offset = { x: 0, y: 0 } offset = { x: 0, y: 0 }
const mobSpawnChance = 0 // Math.random() < chance + 0.07 * simulation.difficulty
enterOptions = [ enterOptions = [
(x = offset.x, y = offset.y) => { //lasers (x = offset.x, y = offset.y) => { //lasers
level.setPosToSpawn(x + 1750, y - 800); level.setPosToSpawn(x + 1750, y - 800);
@@ -1127,12 +1124,12 @@ const level = {
hazard4.opticalQuery(); hazard4.opticalQuery();
if (!isSpawnedMobs && !toggle.isOn) { if (!isSpawnedMobs && !toggle.isOn) {
isSpawnedMobs = true isSpawnedMobs = true
spawn.randomMob(x + 150, y + -1100, Infinity); spawn.randomMob(x + 150, y + -1100, mobSpawnChance);
spawn.randomMob(x + 175, y + -775, Infinity); spawn.randomMob(x + 175, y + -775, mobSpawnChance);
spawn.randomMob(x + 150, y + -350, Infinity); spawn.randomMob(x + 150, y + -350, mobSpawnChance);
spawn.randomMob(x + 150, y + -75, Infinity); spawn.randomMob(x + 150, y + -75, mobSpawnChance);
spawn.randomMob(x + 650, y + -125, Infinity); spawn.randomMob(x + 650, y + -125, mobSpawnChance);
spawn.randomMob(x + 1200, y + -75, Infinity); spawn.randomMob(x + 1200, y + -75, mobSpawnChance);
} }
} }
) )
@@ -1168,11 +1165,11 @@ const level = {
() => { () => {
if (!isInRoom && m.pos.x > x - 100 && m.pos.x < x + 2700 && m.pos.y > y - 1300 && m.pos.y < y) { //check if player is in this room and run code once if (!isInRoom && m.pos.x > x - 100 && m.pos.x < x + 2700 && m.pos.y > y - 1300 && m.pos.y < y) { //check if player is in this room and run code once
isInRoom = true isInRoom = true
spawn.randomMob(x + 1175, y - 725, Infinity); spawn.randomMob(x + 1175, y - 725, mobSpawnChance);
spawn.randomMob(x + 1450, y - 725, Infinity); spawn.randomMob(x + 1450, y - 725, mobSpawnChance);
spawn.randomMob(x + 425, y - 100, Infinity); spawn.randomMob(x + 425, y - 100, mobSpawnChance);
spawn.randomMob(x + 1200, y - 125, Infinity); spawn.randomMob(x + 1200, y - 125, mobSpawnChance);
spawn.randomMob(x + 1300, y - 375, Infinity); spawn.randomMob(x + 1300, y - 375, mobSpawnChance);
} }
ctx.fillStyle = "#d4f4f4" ctx.fillStyle = "#d4f4f4"
ctx.fillRect(x + 1550, y - 1300, 450, 350) ctx.fillRect(x + 1550, y - 1300, 450, 350)
@@ -1237,11 +1234,11 @@ const level = {
() => { () => {
if (!isInRoom && m.pos.x > x - 100 && m.pos.x < x + 2700 && m.pos.y > y - 1300 && m.pos.y < y) { //check if player is in this room and run code once if (!isInRoom && m.pos.x > x - 100 && m.pos.x < x + 2700 && m.pos.y > y - 1300 && m.pos.y < y) { //check if player is in this room and run code once
isInRoom = true isInRoom = true
spawn.randomMob(x + 1175, y - 725, Infinity); spawn.randomMob(x + 1175, y - 725, mobSpawnChance);
spawn.randomMob(x + 1450, y - 725, Infinity); spawn.randomMob(x + 1450, y - 725, mobSpawnChance);
spawn.randomMob(x + 425, y - 100, Infinity); spawn.randomMob(x + 425, y - 100, mobSpawnChance);
spawn.randomMob(x + 1200, y - 125, Infinity); spawn.randomMob(x + 1200, y - 125, mobSpawnChance);
spawn.randomMob(x + 1300, y - 375, Infinity); spawn.randomMob(x + 1300, y - 375, mobSpawnChance);
} }
ctx.fillStyle = "#d4f4f4" ctx.fillStyle = "#d4f4f4"
ctx.fillRect(x + 1600, y - 1300, 400, 350) ctx.fillRect(x + 1600, y - 1300, 400, 350)
@@ -1290,11 +1287,11 @@ const level = {
} }
} }
) )
spawn.randomMob(x + 2000 - 1600, y + -425, Infinity); spawn.randomMob(x + 2000 - 1600, y + -425, mobSpawnChance);
spawn.randomMob(x + 2000 - 1725, y + -1250, Infinity); spawn.randomMob(x + 2000 - 1725, y + -1250, mobSpawnChance);
spawn.randomMob(x + 2000 - 1250, y + -1200, Infinity); spawn.randomMob(x + 2000 - 1250, y + -1200, mobSpawnChance);
spawn.randomMob(x + 2000 - 300, y + -1200, Infinity); spawn.randomMob(x + 2000 - 300, y + -1200, mobSpawnChance);
spawn.randomMob(x + 2000 - 800, y + -125, Infinity); spawn.randomMob(x + 2000 - 800, y + -125, mobSpawnChance);
let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)]; let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
spawn[pick](x + 2000 - 1275, y + -150, 90 + Math.random() * 40); //one extra large mob spawn[pick](x + 2000 - 1275, y + -150, 90 + Math.random() * 40); //one extra large mob
spawn.secondaryBossChance(x + 2000 - 650, y + -875) spawn.secondaryBossChance(x + 2000 - 650, y + -875)
@@ -1322,11 +1319,11 @@ const level = {
} }
} }
) )
spawn.randomMob(x + 1600, y + -425, Infinity); spawn.randomMob(x + 1600, y + -425, mobSpawnChance);
spawn.randomMob(x + 1725, y + -1250, Infinity); spawn.randomMob(x + 1725, y + -1250, mobSpawnChance);
spawn.randomMob(x + 1250, y + -1200, Infinity); spawn.randomMob(x + 1250, y + -1200, mobSpawnChance);
spawn.randomMob(x + 300, y + -1200, Infinity); spawn.randomMob(x + 300, y + -1200, mobSpawnChance);
spawn.randomMob(x + 800, y + -125, Infinity); spawn.randomMob(x + 800, y + -125, mobSpawnChance);
let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)]; let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
spawn[pick](x + 1275, y + -150, 90 + Math.random() * 40); //one extra large mob spawn[pick](x + 1275, y + -150, 90 + Math.random() * 40); //one extra large mob
spawn.secondaryBossChance(x + 650, y + -875) spawn.secondaryBossChance(x + 650, y + -875)
@@ -1382,11 +1379,11 @@ const level = {
} }
} }
) )
spawn.randomMob(x + 2000 - 1600, y + -425, Infinity); spawn.randomMob(x + 2000 - 1600, y + -425, mobSpawnChance);
spawn.randomMob(x + 2000 - 1725, y + -1250, Infinity); spawn.randomMob(x + 2000 - 1725, y + -1250, mobSpawnChance);
spawn.randomMob(x + 2000 - 1250, y + -1200, Infinity); spawn.randomMob(x + 2000 - 1250, y + -1200, mobSpawnChance);
spawn.randomMob(x + 2000 - 300, y + -1200, Infinity); spawn.randomMob(x + 2000 - 300, y + -1200, mobSpawnChance);
spawn.randomMob(x + 2000 - 800, y + -125, Infinity); spawn.randomMob(x + 2000 - 800, y + -125, mobSpawnChance);
let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)]; let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
spawn[pick](x + 2000 - 1275, y + -150, 90 + Math.random() * 40); //one extra large mob spawn[pick](x + 2000 - 1275, y + -150, 90 + Math.random() * 40); //one extra large mob
spawn.secondaryBossChance(x + 650, y + -875) spawn.secondaryBossChance(x + 650, y + -875)
@@ -1439,11 +1436,11 @@ const level = {
} }
} }
) )
spawn.randomMob(x + 1600, y + -425, Infinity); spawn.randomMob(x + 1600, y + -425, mobSpawnChance);
spawn.randomMob(x + 1725, y + -1250, Infinity); spawn.randomMob(x + 1725, y + -1250, mobSpawnChance);
spawn.randomMob(x + 1250, y + -1200, Infinity); spawn.randomMob(x + 1250, y + -1200, mobSpawnChance);
spawn.randomMob(x + 300, y + -1200, Infinity); spawn.randomMob(x + 300, y + -1200, mobSpawnChance);
spawn.randomMob(x + 800, y + -125, Infinity); spawn.randomMob(x + 800, y + -125, mobSpawnChance);
let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)]; let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
spawn[pick](x + 1275, y + -150, 90 + Math.random() * 40); //one extra large mob spawn[pick](x + 1275, y + -150, 90 + Math.random() * 40); //one extra large mob
spawn.secondaryBossChance(x + 650, y - 875) spawn.secondaryBossChance(x + 650, y - 875)
@@ -1510,11 +1507,11 @@ const level = {
} }
} }
) )
spawn.randomMob(x + 2000 - 1600, y + -425, Infinity); spawn.randomMob(x + 2000 - 1600, y + -425, mobSpawnChance);
spawn.randomMob(x + 2000 - 1725, y + -1250, Infinity); spawn.randomMob(x + 2000 - 1725, y + -1250, mobSpawnChance);
spawn.randomMob(x + 2000 - 1250, y + -1200, Infinity); spawn.randomMob(x + 2000 - 1250, y + -1200, mobSpawnChance);
spawn.randomMob(x + 2000 - 300, y + -1200, Infinity); spawn.randomMob(x + 2000 - 300, y + -1200, mobSpawnChance);
spawn.randomMob(x + 2000 - 800, y + -125, Infinity); spawn.randomMob(x + 2000 - 800, y + -125, mobSpawnChance);
let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)]; let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
spawn[pick](x + 2000 - 1275, y + -150, 90 + Math.random() * 40); //one extra large mob spawn[pick](x + 2000 - 1275, y + -150, 90 + Math.random() * 40); //one extra large mob
spawn.secondaryBossChance(x + 650, y - 875) spawn.secondaryBossChance(x + 650, y - 875)
@@ -1578,11 +1575,11 @@ const level = {
} }
} }
) )
spawn.randomMob(x + 1600, y + -425, Infinity); spawn.randomMob(x + 1600, y + -425, mobSpawnChance);
spawn.randomMob(x + 1725, y + -1250, Infinity); spawn.randomMob(x + 1725, y + -1250, mobSpawnChance);
spawn.randomMob(x + 1250, y + -1200, Infinity); spawn.randomMob(x + 1250, y + -1200, mobSpawnChance);
spawn.randomMob(x + 300, y + -1200, Infinity); spawn.randomMob(x + 300, y + -1200, mobSpawnChance);
spawn.randomMob(x + 800, y + -125, Infinity); spawn.randomMob(x + 800, y + -125, mobSpawnChance);
let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)]; let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
spawn[pick](x + 1275, y + -150, 90 + Math.random() * 40); //one extra large mob spawn[pick](x + 1275, y + -150, 90 + Math.random() * 40); //one extra large mob
spawn.secondaryBossChance(x + 650, y - 875) spawn.secondaryBossChance(x + 650, y - 875)
@@ -1678,17 +1675,17 @@ const level = {
} else if (!isSpawnedMobs) { } else if (!isSpawnedMobs) {
isSpawnedMobs = true isSpawnedMobs = true
if (chamberY === -650) { //lower chamber if (chamberY === -650) { //lower chamber
spawn.randomGroup(x + 275, y + -1050, Infinity); spawn.randomMob(x + 250, y + -650, mobSpawnChance);
spawn.randomGroup(x + 675, y + -975, Infinity); spawn.randomMob(x + 1825, y + -600, mobSpawnChance);
spawn.randomGroup(x + 275, y + -1050, mobSpawnChance);
spawn.randomGroup(x + 675, y + -975, mobSpawnChance);
spawn.randomGroup(x + 1225, y + -975, Infinity); spawn.randomGroup(x + 1225, y + -975, Infinity);
spawn.randomMob(x + 250, y + -650, Infinity);
spawn.randomMob(x + 1825, y + -600, Infinity);
} else { //upper chamber } else { //upper chamber
spawn.randomGroup(x + 300, y + -300, Infinity); spawn.randomMob(x + 250, y + -650, mobSpawnChance);
spawn.randomGroup(x + 650, y + -275, Infinity); spawn.randomMob(x + 1800, y + -625, mobSpawnChance);
spawn.randomGroup(x + 300, y + -300, mobSpawnChance);
spawn.randomGroup(x + 650, y + -275, mobSpawnChance);
spawn.randomGroup(x + 1125, y + -300, Infinity); spawn.randomGroup(x + 1125, y + -300, Infinity);
spawn.randomMob(x + 250, y + -650, Infinity);
spawn.randomMob(x + 1800, y + -625, Infinity);
} }
} }
} }
@@ -1797,12 +1794,12 @@ const level = {
// simulation.draw.setPaths() //update map graphics // simulation.draw.setPaths() //update map graphics
// } // }
// }) // })
// spawn.randomMob(x + 225, y + -1025, Infinity); // spawn.randomMob(x + 225, y + -1025, mobSpawnChance);
// spawn.randomMob(x + 200, y + -675, Infinity); // spawn.randomMob(x + 200, y + -675, mobSpawnChance);
// spawn.randomMob(x + 225, y + -200, Infinity); // spawn.randomMob(x + 225, y + -200, mobSpawnChance);
// spawn.randomMob(x + 1750, y + -1075, Infinity); // spawn.randomMob(x + 1750, y + -1075, mobSpawnChance);
// spawn.randomMob(x + 1700, y + -650, Infinity); // spawn.randomMob(x + 1700, y + -650, mobSpawnChance);
// spawn.randomMob(x + 1675, y + -175, Infinity); // spawn.randomMob(x + 1675, y + -175, mobSpawnChance);
// spawn.randomGroup(x + 300, y + -2200); // spawn.randomGroup(x + 300, y + -2200);
// spawn.randomGroup(x + 1625, y + -2200); // spawn.randomGroup(x + 1625, y + -2200);
@@ -1847,12 +1844,12 @@ const level = {
const numberOfMapElementsAdded = 12 const numberOfMapElementsAdded = 12
for (let i = 0; i < numberOfMapElementsAdded; i++) addMapToLevelInProgress(map[map.length - 1 - i]) for (let i = 0; i < numberOfMapElementsAdded; i++) addMapToLevelInProgress(map[map.length - 1 - i])
spawn.randomMob(x + 225, y + -1775, Infinity); spawn.randomMob(x + 225, y + -1775, mobSpawnChance);
spawn.randomMob(x + 700, y + -1750, Infinity); spawn.randomMob(x + 700, y + -1750, mobSpawnChance);
spawn.randomMob(x + 1175, y + -1725, Infinity); spawn.randomMob(x + 1175, y + -1725, mobSpawnChance);
spawn.randomMob(x + 1700, y + -1700, Infinity); spawn.randomMob(x + 1700, y + -1700, mobSpawnChance);
spawn.randomMob(x + 1750, y + -250, Infinity); spawn.randomMob(x + 1750, y + -250, mobSpawnChance);
spawn.randomMob(x + 125, y + -250, Infinity); spawn.randomMob(x + 125, y + -250, mobSpawnChance);
} else { } else {
spawn.mapVertex(x + 775, y + -260, hexagon); spawn.mapVertex(x + 775, y + -260, hexagon);
spawn.mapVertex(x + 1225, y + -260, hexagon); spawn.mapVertex(x + 1225, y + -260, hexagon);
@@ -1873,12 +1870,12 @@ const level = {
const numberOfMapElementsAdded = 12 const numberOfMapElementsAdded = 12
for (let i = 0; i < numberOfMapElementsAdded; i++) addMapToLevelInProgress(map[map.length - 1 - i]) for (let i = 0; i < numberOfMapElementsAdded; i++) addMapToLevelInProgress(map[map.length - 1 - i])
spawn.randomMob(x + 225, y + -1025, Infinity); spawn.randomMob(x + 225, y + -1025, mobSpawnChance);
spawn.randomMob(x + 200, y + -675, Infinity); spawn.randomMob(x + 200, y + -675, mobSpawnChance);
spawn.randomMob(x + 225, y + -200, Infinity); spawn.randomMob(x + 225, y + -200, mobSpawnChance);
spawn.randomMob(x + 1750, y + -1075, Infinity); spawn.randomMob(x + 1750, y + -1075, mobSpawnChance);
spawn.randomMob(x + 1700, y + -650, Infinity); spawn.randomMob(x + 1700, y + -650, mobSpawnChance);
spawn.randomMob(x + 1675, y + -175, Infinity); spawn.randomMob(x + 1675, y + -175, mobSpawnChance);
} }
simulation.draw.setPaths() //update map graphics simulation.draw.setPaths() //update map graphics
spawn.randomGroup(x + 300, y + -2200); spawn.randomGroup(x + 300, y + -2200);
@@ -1940,15 +1937,15 @@ const level = {
const numberOfMapElementsAdded = 13 const numberOfMapElementsAdded = 13
for (let i = 0; i < numberOfMapElementsAdded; i++) addMapToLevelInProgress(map[map.length - 1 - i]) for (let i = 0; i < numberOfMapElementsAdded; i++) addMapToLevelInProgress(map[map.length - 1 - i])
spawn.randomMob(x + 1075, y + -1500, Infinity); spawn.randomMob(x + 1075, y + -1500, mobSpawnChance);
spawn.randomMob(x + 325, y + -550, Infinity); spawn.randomMob(x + 325, y + -550, mobSpawnChance);
spawn.randomMob(x + 800, y + -925, Infinity); spawn.randomMob(x + 800, y + -925, mobSpawnChance);
spawn.randomMob(x + 1400, y + -1250, Infinity); spawn.randomMob(x + 1400, y + -1250, mobSpawnChance);
spawn.randomMob(x + 1350, y + -1725, Infinity); spawn.randomMob(x + 1350, y + -1725, mobSpawnChance);
spawn.randomMob(x + 575, y + -1375, Infinity); spawn.randomMob(x + 575, y + -1375, mobSpawnChance);
spawn.randomMob(x + 225, y + -2275, Infinity); spawn.randomMob(x + 225, y + -2275, mobSpawnChance);
spawn.randomMob(x + 875, y + -2450, Infinity); spawn.randomMob(x + 875, y + -2450, mobSpawnChance);
spawn.randomMob(x + 1550, y + -2525, Infinity); spawn.randomMob(x + 1550, y + -2525, mobSpawnChance);
if (simulation.difficulty > 3) spawn.randomLevelBoss(x + 1075, y + -1500); if (simulation.difficulty > 3) spawn.randomLevelBoss(x + 1075, y + -1500);
simulation.draw.setPaths() //update map graphics simulation.draw.setPaths() //update map graphics
} }

View File

@@ -470,7 +470,7 @@ const m = {
} }
}, },
addHealth(heal) { addHealth(heal) {
if (!tech.isEnergyHealth && !tech.isNoHeals) { if (!tech.isEnergyHealth) {
m.health += heal * simulation.healScale; m.health += heal * simulation.healScale;
if (m.health > m.maxHealth) m.health = m.maxHealth; if (m.health > m.maxHealth) m.health = m.maxHealth;
m.displayHealth(); m.displayHealth();
@@ -495,7 +495,7 @@ const m = {
if (tech.isHarmMACHO) dmg *= 0.33 if (tech.isHarmMACHO) dmg *= 0.33
if (tech.isImmortal) dmg *= 0.66 if (tech.isImmortal) dmg *= 0.66
if (tech.isHarmReduceAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 0.33 : 1.15 if (tech.isHarmReduceAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 0.33 : 1.15
if (tech.healthDrain) dmg *= 1 + 2.667 * tech.healthDrain //tech.healthDrain = 0.03 at one stack //cause more damage if (tech.healthDrain) dmg *= 1 + 3.33 * tech.healthDrain //tech.healthDrain = 0.03 at one stack //cause more damage
if (tech.squirrelFx !== 1) dmg *= 1 + (tech.squirrelFx - 1) / 5 //cause more damage if (tech.squirrelFx !== 1) dmg *= 1 + (tech.squirrelFx - 1) / 5 //cause more damage
if (tech.isBlockHarm && m.isHolding) dmg *= 0.15 if (tech.isBlockHarm && m.isHolding) dmg *= 0.15
if (tech.isSpeedHarm) dmg *= 1 - Math.min(player.speed * 0.0165, 0.66) if (tech.isSpeedHarm) dmg *= 1 - Math.min(player.speed * 0.0165, 0.66)
@@ -1611,59 +1611,63 @@ const m = {
Matter.Query.ray(map, mob[i].position, m.fieldPosition).length === 0 Matter.Query.ray(map, mob[i].position, m.fieldPosition).length === 0
) { ) {
mob[i].locatePlayer(); mob[i].locatePlayer();
m.fieldCDcycle = m.cycle + m.fieldBlockCD;
if (tech.blockingIce) {
for (let i = 0; i < tech.blockingIce; i++) b.iceIX(10, m.fieldAngle + Math.random() - 0.5, m.fieldPosition)
}
const unit = Vector.normalise(Vector.sub(m.fieldPosition, mob[i].position)) const unit = Vector.normalise(Vector.sub(m.fieldPosition, mob[i].position))
if (tech.blockDmg) { if (m.fieldCDcycle < m.cycle) {
mob[i].damage(tech.blockDmg * b.dmgScale) m.fieldCDcycle = m.cycle + m.fieldBlockCD;
//draw electricity if (tech.blockingIce) {
const step = 40 for (let i = 0; i < tech.blockingIce; i++) b.iceIX(10, m.fieldAngle + Math.random() - 0.5, m.fieldPosition)
ctx.beginPath();
for (let i = 0, len = 1.5 * tech.blockDmg; i < len; i++) {
let x = m.fieldPosition.x - 20 * unit.x;
let y = m.fieldPosition.y - 20 * unit.y;
ctx.moveTo(x, y);
for (let i = 0; i < 8; i++) {
x += step * (-unit.x + 1.5 * (Math.random() - 0.5))
y += step * (-unit.y + 1.5 * (Math.random() - 0.5))
ctx.lineTo(x, y);
}
} }
ctx.lineWidth = 3; if (tech.blockDmg) {
ctx.strokeStyle = "#f0f"; mob[i].damage(tech.blockDmg * b.dmgScale)
ctx.stroke(); //draw electricity
} else if (!isFree) { const step = 40
//when blocking draw this graphic ctx.beginPath();
const eye = 15; for (let i = 0, len = 1.5 * tech.blockDmg; i < len; i++) {
const len = mob[i].vertices.length - 1; let x = m.fieldPosition.x - 20 * unit.x;
ctx.fillStyle = "rgba(110,170,200," + (0.2 + 0.4 * Math.random()) + ")"; let y = m.fieldPosition.y - 20 * unit.y;
ctx.lineWidth = 1; ctx.moveTo(x, y);
ctx.strokeStyle = "#000"; for (let i = 0; i < 8; i++) {
ctx.beginPath(); x += step * (-unit.x + 1.5 * (Math.random() - 0.5))
ctx.moveTo(m.fieldPosition.x + eye * Math.cos(m.fieldAngle), m.fieldPosition.y + eye * Math.sin(m.fieldAngle)); y += step * (-unit.y + 1.5 * (Math.random() - 0.5))
ctx.lineTo(mob[i].vertices[len].x, mob[i].vertices[len].y); ctx.lineTo(x, y);
ctx.lineTo(mob[i].vertices[0].x, mob[i].vertices[0].y); }
ctx.fill(); }
ctx.stroke(); ctx.lineWidth = 3;
for (let j = 0; j < len; j++) { ctx.strokeStyle = "#f0f";
ctx.stroke();
} else if (!isFree) {
//when blocking draw this graphic
const eye = 15;
const len = mob[i].vertices.length - 1;
ctx.fillStyle = "rgba(110,170,200," + (0.2 + 0.4 * Math.random()) + ")";
ctx.lineWidth = 1;
ctx.strokeStyle = "#000";
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(m.fieldPosition.x + eye * Math.cos(m.fieldAngle), m.fieldPosition.y + eye * Math.sin(m.fieldAngle)); ctx.moveTo(m.fieldPosition.x + eye * Math.cos(m.fieldAngle), m.fieldPosition.y + eye * Math.sin(m.fieldAngle));
ctx.lineTo(mob[i].vertices[j].x, mob[i].vertices[j].y); ctx.lineTo(mob[i].vertices[len].x, mob[i].vertices[len].y);
ctx.lineTo(mob[i].vertices[j + 1].x, mob[i].vertices[j + 1].y); ctx.lineTo(mob[i].vertices[0].x, mob[i].vertices[0].y);
ctx.fill(); ctx.fill();
ctx.stroke(); ctx.stroke();
for (let j = 0; j < len; j++) {
ctx.beginPath();
ctx.moveTo(m.fieldPosition.x + eye * Math.cos(m.fieldAngle), m.fieldPosition.y + eye * Math.sin(m.fieldAngle));
ctx.lineTo(mob[i].vertices[j].x, mob[i].vertices[j].y);
ctx.lineTo(mob[i].vertices[j + 1].x, mob[i].vertices[j + 1].y);
ctx.fill();
ctx.stroke();
}
} }
if (tech.isStunField) mobs.statusStun(mob[i], tech.isStunField)
//knock backs
const massRoot = Math.sqrt(Math.max(0.15, mob[i].mass)); // masses above 12 can start to overcome the push back
Matter.Body.setVelocity(mob[i], {
x: player.velocity.x - (20 * unit.x) / massRoot,
y: player.velocity.y - (20 * unit.y) / massRoot
});
if (mob[i].isOrbital) Matter.Body.setVelocity(mob[i], { x: 0, y: 0 });
} }
if (tech.isStunField) mobs.statusStun(mob[i], tech.isStunField)
//knock backs
const massRoot = Math.sqrt(Math.max(0.15, mob[i].mass)); // masses above 12 can start to overcome the push back
Matter.Body.setVelocity(mob[i], {
x: player.velocity.x - (20 * unit.x) / massRoot,
y: player.velocity.y - (20 * unit.y) / massRoot
});
if (mob[i].isOrbital) Matter.Body.setVelocity(mob[i], { x: 0, y: 0 });
if (isFree) { if (isFree) {
} else { } else {
@@ -1682,14 +1686,14 @@ const m = {
m.hold = function() { m.hold = function() {
const wave = Math.sin(m.cycle * 0.022); const wave = Math.sin(m.cycle * 0.022);
m.fieldRange = 170 + 12 * wave m.fieldRange = 190 + 12 * wave
m.fieldArc = 0.33 + 0.045 * wave //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob) m.fieldArc = 0.36 + 0.04 * wave //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
m.calculateFieldThreshold(); m.calculateFieldThreshold();
if (m.isHolding) { if (m.isHolding) {
m.drawHold(m.holdingTarget); m.drawHold(m.holdingTarget);
m.holding(); m.holding();
m.throwBlock(); m.throwBlock();
} else if ((input.field && m.fieldCDcycle < m.cycle)) { //not hold but field button is pressed } else if (input.field) { //not hold but field button is pressed
m.grabPowerUp(); m.grabPowerUp();
m.lookForPickUp(); m.lookForPickUp();
m.fieldPosition = { x: m.pos.x, y: m.pos.y } m.fieldPosition = { x: m.pos.x, y: m.pos.y }
@@ -1724,7 +1728,7 @@ const m = {
m.pickUp(); m.pickUp();
} else { } else {
m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists) m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
if (tech.isFieldFree && !input.field && m.fieldCDcycle < m.cycle) { if (tech.isFieldFree && !input.field) {
//draw field free of player //draw field free of player
ctx.fillStyle = "rgba(110,170,200," + (0.27 + 0.2 * Math.random() - 0.1 * wave) + ")"; ctx.fillStyle = "rgba(110,170,200," + (0.27 + 0.2 * Math.random() - 0.1 * wave) + ")";
ctx.strokeStyle = "rgba(110, 200, 235, " + (0.4 + 0.5 * Math.random()) + ")" ctx.strokeStyle = "rgba(110, 200, 235, " + (0.4 + 0.5 * Math.random()) + ")"

View File

@@ -322,7 +322,7 @@ const powerUps = {
// } // }
// } // }
// } // }
if (!tech.isEnergyHealth && m.alive) { if (!tech.isEnergyHealth && m.alive && !tech.isNoHeals) {
const heal = powerUps.heal.calculateHeal(this.size) const heal = powerUps.heal.calculateHeal(this.size)
if (heal > 0) { if (heal > 0) {
const overHeal = m.health + heal * simulation.healScale - m.maxHealth //used with tech.isOverHeal const overHeal = m.health + heal * simulation.healScale - m.maxHealth //used with tech.isOverHeal

View File

@@ -538,10 +538,11 @@ const simulation = {
} else { } else {
level.levels = shuffle(level.levels); //shuffles order of maps level.levels = shuffle(level.levels); //shuffles order of maps
} }
level.levels.unshift("intro"); //add level to the start of the randomized levels list if (!build.isExperimentSelection) { //experimental mode is endless
level.levels.push("labs"); //add level to the end of the randomized levels list level.levels.unshift("intro"); //add level to the start of the randomized levels list
level.levels.push("gauntlet"); //add level to the end of the randomized levels list level.levels.push("gauntlet"); //add level to the end of the randomized levels list
level.levels.push("final"); //add level to the end of the randomized levels list level.levels.push("final"); //add level to the end of the randomized levels list
}
input.endKeySensing(); input.endKeySensing();
b.removeAllGuns(); b.removeAllGuns();

View File

@@ -1973,18 +1973,18 @@ const spawn = {
mobs.spawn(x, y, 5, 50, "rgb(215,80,190)"); //"rgb(221,102,119)" mobs.spawn(x, y, 5, 50, "rgb(215,80,190)"); //"rgb(221,102,119)"
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
Matter.Body.rotate(me, Math.PI * 0.1); Matter.Body.rotate(me, Math.PI * 0.1);
Matter.Body.setDensity(me, 0.01); //extra dense //normal is 0.001 //makes effective life much larger Matter.Body.setDensity(me, 0.02); //extra dense //normal is 0.001 //makes effective life much larger
me.isBoss = true; me.isBoss = true;
me.damageReduction = 0.25; me.damageReduction = 0.25;
me.frictionStatic = 0; me.frictionStatic = 0;
me.friction = 0; me.friction = 0;
me.memory = 240 me.memory = 240
me.seePlayerFreq = 60 me.seePlayerFreq = 60
me.delay = 20 + 20 * simulation.CDScale; me.delay = 16 + 30 * simulation.CDScale;
me.nextBlinkCycle = me.delay; me.nextBlinkCycle = me.delay;
me.blinkRange = 235 me.blinkRange = 235
me.grenadeDelay = 30 + 50 * simulation.CDScale me.grenadeDelay = 30 + 60 * simulation.CDScale
me.pulseRadius = 2 * Math.min(550, 250 + simulation.difficulty * 3) me.pulseRadius = 2 * Math.min(550, 220 + simulation.difficulty * 4)
spawn.shield(me, x, y, 1); spawn.shield(me, x, y, 1);
me.onDamage = function() { me.onDamage = function() {
// this.cd = simulation.cycle + this.delay; // this.cd = simulation.cycle + this.delay;
@@ -2001,6 +2001,7 @@ const spawn = {
y: speed * Math.sin(angle) y: speed * Math.sin(angle)
}); });
} }
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
} }
me.do = function() { me.do = function() {
this.seePlayerByHistory() this.seePlayerByHistory()
@@ -3310,8 +3311,8 @@ const spawn = {
}; };
me.showHealthBar = false; me.showHealthBar = false;
me.collisionFilter.category = cat.mobBullet; me.collisionFilter.category = cat.mobBullet;
// me.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet; me.collisionFilter.mask = cat.map | cat.body
me.collisionFilter.mask = 0 // me.collisionFilter.mask = 0
me.do = function() { me.do = function() {
this.timeLimit(); this.timeLimit();
ctx.beginPath(); //draw explosion outline ctx.beginPath(); //draw explosion outline

View File

@@ -333,9 +333,9 @@
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return (tech.isDamageForGuns || tech.isFireRateForGuns) && (b.inventory.length + 5) < b.guns.length return (tech.isDamageForGuns || tech.isFireRateForGuns) && b.inventory.length + 5 < b.guns.length
}, },
requires: "arsenal or active cooling", requires: "arsenal or active cooling and less than 7 guns",
effect() { effect() {
tech.isGunCycle = true; tech.isGunCycle = true;
for (let i = 0; i < 8; i++) powerUps.spawn(m.pos.x + 10 * Math.random(), m.pos.y + 10 * Math.random(), "gun"); for (let i = 0; i < 8; i++) powerUps.spawn(m.pos.x + 10 * Math.random(), m.pos.y + 10 * Math.random(), "gun");
@@ -447,9 +447,9 @@
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
allowed() { allowed() {
return !tech.isEnergyHealth && !tech.isEnergyNoAmmo return !tech.isEnergyNoAmmo
}, },
requires: "not mass-energy equivalence or exciton-lattice", requires: "exciton-lattice",
effect: () => { effect: () => {
tech.isAmmoFromHealth = true; tech.isAmmoFromHealth = true;
}, },
@@ -2189,9 +2189,9 @@
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
allowed() { allowed() {
return !tech.isZeno && !tech.isAmmoFromHealth && !tech.isNoHeals && !tech.isEnergyLoss && !tech.isPiezo && !tech.isRewindAvoidDeath && !tech.isRewindGun && !tech.isSpeedHarm && m.fieldUpgrades[m.fieldMode].name !== "negative mass field" && !tech.isHealLowHealth && !tech.isTechDamage return !tech.isZeno && !tech.isNoHeals && !tech.isPiezo && !tech.isRewindAvoidDeath && !tech.isRewindGun && !tech.isTechDamage && !tech.isMutualism
}, },
requires: "not exothermic, Zeno, piezoelectricity, CPT, 1st law, negative mass, ...", requires: "not Zeno, ergodicity, piezoelectricity, CPT, rewind gun, antiscience, mutualism",
effect: () => { effect: () => {
m.health = 0 m.health = 0
document.getElementById("health").style.display = "none" document.getElementById("health").style.display = "none"
@@ -2202,13 +2202,15 @@
m.displayHealth(); m.displayHealth();
}, },
remove() { remove() {
tech.isEnergyHealth = false; if (tech.isEnergyHealth) {
document.getElementById("health").style.display = "inline" tech.isEnergyHealth = false;
document.getElementById("health-bg").style.display = "inline" document.getElementById("health").style.display = "inline"
document.getElementById("dmg").style.backgroundColor = "#f67"; document.getElementById("health-bg").style.display = "inline"
m.health = Math.max(Math.min(m.maxHealth, m.energy), 0.1); document.getElementById("dmg").style.backgroundColor = "#f67";
simulation.mobDmgColor = "rgba(255,0,0,0.7)" m.health = Math.max(Math.min(m.maxHealth, m.energy), 0.1);
m.displayHealth(); simulation.mobDmgColor = "rgba(255,0,0,0.7)"
m.displayHealth();
}
} }
}, },
{ {
@@ -2219,9 +2221,9 @@
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return tech.isEnergyHealth && !tech.isNoHeals return tech.isEnergyHealth
}, },
requires: "mass-energy equivalence, not ergodicity", requires: "mass-energy equivalence",
effect() { effect() {
tech.healGiveMaxEnergy = true; //tech.healMaxEnergyBonus given from heal power up tech.healGiveMaxEnergy = true; //tech.healMaxEnergyBonus given from heal power up
powerUps.heal.color = "#0ae" powerUps.heal.color = "#0ae"
@@ -2282,9 +2284,9 @@
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return true //m.maxEnergy > 1 || tech.isEnergyRecovery || tech.isPiezo || tech.energySiphon > 0 || tech.isBlockExplosion return true
}, },
requires: "", //"increased energy regen or max energy", requires: "",
effect: () => { effect: () => {
tech.isEnergyDamage = true tech.isEnergyDamage = true
}, },
@@ -2300,9 +2302,9 @@
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
allowed() { allowed() {
return true //(tech.haveGunCheck("nail gun") && tech.isIceCrystals) || tech.haveGunCheck("laser") || m.fieldUpgrades[m.fieldMode].name === "plasma torch" || m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" || m.fieldUpgrades[m.fieldMode].name === "pilot wave" return true
}, },
requires: "", //"energy based damage", requires: "",
effect() { effect() {
tech.isEnergyNoAmmo = true; tech.isEnergyNoAmmo = true;
}, },
@@ -2318,9 +2320,9 @@
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return !tech.isEnergyHealth return true
}, },
requires: "not mass-energy equivalence", requires: "",
effect() { effect() {
tech.isEnergyLoss = true; tech.isEnergyLoss = true;
}, },
@@ -2400,11 +2402,11 @@
}, },
requires: "a source of overfilled energy", requires: "a source of overfilled energy",
effect() { effect() {
tech.overfillDrain = 0.87 //70% = 1-(1-0.75)/(1-0.15) //92% = 1-(1-0.75)/(1-0.87) tech.overfillDrain = 0.85 //70% = 1-(1-0.75)/(1-0.15) //92% = 1-(1-0.75)/(1-0.87)
tech.addJunkTechToPool(18) tech.addJunkTechToPool(18)
}, },
remove() { remove() {
tech.overfillDrain = 0.75 tech.overfillDrain = 0.7
if (this.count > 0) tech.removeJunkTechFromPool(18) if (this.count > 0) tech.removeJunkTechFromPool(18)
} }
}, },
@@ -2453,9 +2455,9 @@
frequencyDefault: 1, frequencyDefault: 1,
isHealTech: true, isHealTech: true,
allowed() { allowed() {
return !tech.isEnergyHealth && !tech.isNoHeals return !tech.isEnergyHealth
}, },
requires: "not mass-energy equivalence, ergodicity", requires: "not mass-energy equivalence",
effect() { effect() {
tech.isHealthRecovery = true; tech.isHealthRecovery = true;
}, },
@@ -2556,16 +2558,16 @@
}, },
{ {
name: "entropy exchange", name: "entropy exchange",
description: "<strong class='color-h'>heal</strong> for <strong>3%</strong> of <strong class='color-d'>damage</strong> done<br>take <strong>8%</strong> more <strong class='color-harm'>harm</strong>", description: "<strong class='color-h'>heal</strong> for <strong>3%</strong> of <strong class='color-d'>damage</strong> done<br>take <strong>10%</strong> more <strong class='color-harm'>harm</strong>",
maxCount: 9, maxCount: 9,
count: 0, count: 0,
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
isHealTech: true, isHealTech: true,
allowed() { allowed() {
return !tech.isEnergyHealth && !tech.isNoHeals return !tech.isEnergyHealth
}, },
requires: "not mass-energy equivalence, ergodicity", requires: "not mass-energy equivalence",
effect() { effect() {
tech.healthDrain += 0.03; tech.healthDrain += 0.03;
}, },
@@ -2599,9 +2601,9 @@
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return !tech.isEnergyHealth && !tech.isNoHeals return !tech.isEnergyHealth
}, },
requires: "not mass-energy equivalence, ergodicity", requires: "not mass-energy equivalence",
effect() { effect() {
tech.isFallingDamage = true; tech.isFallingDamage = true;
m.setMaxHealth(); m.setMaxHealth();
@@ -2678,9 +2680,9 @@
isNonRefundable: true, isNonRefundable: true,
isBadRandomOption: true, isBadRandomOption: true,
allowed() { allowed() {
return !tech.isNoHeals return true
}, },
requires: "not ergodicity", requires: "",
effect() { effect() {
for (let i = 0; i < 11; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "heal"); for (let i = 0; i < 11; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "heal");
for (let i = 0, len = tech.tech.length; i < len; i++) { for (let i = 0, len = tech.tech.length; i < len; i++) {
@@ -3451,15 +3453,15 @@
}, },
{ {
name: "ergodicity", name: "ergodicity",
description: "reduce combat <strong>difficulty</strong> by <strong>2 levels</strong><br>all <strong class='color-h'>healing</strong> has <strong>no</strong> effect", description: "reduce combat <strong>difficulty</strong> by <strong>2 levels</strong><br><strong class='color-h'>heal</strong> power ups have <strong>no</strong> effect",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
allowed() { allowed() {
return level.onLevel > 1 && m.health > m.maxHealth - 0.1 && !tech.isEnergyHealth return level.onLevel > 1 && !tech.isEnergyHealth
}, },
requires: "past levels 1, full health, not mass-energy", requires: "past levels 1, not mass-energy",
effect() { effect() {
tech.isNoHeals = true; tech.isNoHeals = true;
level.difficultyDecrease(simulation.difficultyMode * 2) level.difficultyDecrease(simulation.difficultyMode * 2)

View File

@@ -1,22 +1,25 @@
******************************************************** NEXT PATCH ******************************************************** ******************************************************** NEXT PATCH ********************************************************
tech: Lenz's law -perfect diamagnetism field stays when you aren't holding field "labs" is now in the normal map rotation
tech: Zeno's paradox - every 5s lose 10% of your current health, but get 84% harm reduction experimental mode is now endless (no gauntlet, finalBoss, ...)
fixed a bug that was giving experimental mode full life at the start
perfect diamagnetism field has a 10% larger radius and arc
the 1/15 second cooldown after blocking with perfect diamagnetism no longer stops you from blocking
it still disables field damage effects and player recoil after blocking (for 1/15 of a second)
mass-energy now works with catabolism by removing max energy to make ammo
ergodicity - now reduces difficulty by 2 levels and prevent healing from heal power ups (was all healing)
Noether violation gives even more forward recoil
blinkBoss has more health, but it's much slower at easy difficulty
******************************************************** TODO ******************************************************** ******************************************************** TODO ********************************************************
remove cooldown on perfect diamagnetism?
make another var that tracks cooldown for other stuff?
like damage effects
is lab gun room always backwards?
using wormhole makes you immune to harm and drains energy until you run out using wormhole makes you immune to harm and drains energy until you run out
disable incoming energy, by saving current energy and just setting energy in the next cycle to be lower then the saved value disable incoming energy, by saving current energy and just setting energy in the next cycle to be lower then the saved value
pink seeker boss is cool as heck, make an alt version of it pink seeker boss is cool as heck, make an alt version of it
block shattering block shattering
get code from planetesimals get code from planetesimals
https://codepen.io/lilgreenland/pen/jrMvaB?editors=0010 https://codepen.io/lilgreenland/pen/jrMvaB?editors=0010
@@ -196,6 +199,10 @@ n-gon outreach ideas
******************************************************** BUGS ******************************************************** ******************************************************** BUGS ********************************************************
sharing builds as html doesn't work for long lists...
it shouldn't be sharing undefined at all
probably some other problems too
blocks on buttons teleport into the button endlessly if they are being slowly floated away blocks on buttons teleport into the button endlessly if they are being slowly floated away
maybe add a cooldown? maybe add a cooldown?
can't reproduce can't reproduce
@@ -230,6 +237,11 @@ is there a way to check if the player is stuck inside the map or block
******************************************************** LEVELS ******************************************************** ******************************************************** LEVELS ********************************************************
level element that goes away after touching player (also bullets?)
returns after a set time, or doesn't
applications:
doors, quick jumping platforming, secrets,
level with mobs that follow a genetic algorithm level with mobs that follow a genetic algorithm
mobs have genes mobs have genes
the last mob that did damage saves it's genes to local storage the last mob that did damage saves it's genes to local storage
@@ -318,6 +330,10 @@ map: observatory
******************************************************** MOBS ******************************************************** ******************************************************** MOBS ********************************************************
mob that charges up and then fires many bullets at once in a connect
mob that draws a lin from it to the player, and past. then it charges across that line
mob that spawns eggs after they die mob that spawns eggs after they die
eggs don't attack but grow back into a mob after about 10s eggs don't attack but grow back into a mob after about 10s