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:
25
js/bullet.js
25
js/bullet.js
@@ -96,17 +96,20 @@ const b = {
|
||||
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`);
|
||||
m.fireCDcycle = m.cycle + 30; //fire cooldown
|
||||
if (tech.isAmmoFromHealth && m.maxHealth > 0.01) {
|
||||
tech.extraMaxHealth -= 0.01 //decrease max health
|
||||
m.setMaxHealth();
|
||||
if (tech.isAmmoFromHealth) {
|
||||
if (tech.isEnergyHealth) {
|
||||
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");
|
||||
// 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) {
|
||||
if (tech.isOneGun) b.removeAllGuns();
|
||||
@@ -3794,8 +3797,8 @@ const b = {
|
||||
}
|
||||
|
||||
if (tech.isShotgunReversed) {
|
||||
player.force.x += 2 * knock * Math.cos(m.angle)
|
||||
player.force.y += 2 * knock * Math.sin(m.angle) - 6 * player.mass * simulation.g
|
||||
player.force.x += 4 * knock * Math.cos(m.angle)
|
||||
player.force.y += 4 * knock * Math.sin(m.angle) - 6 * player.mass * simulation.g
|
||||
} else if (tech.isShotgunRecoil) {
|
||||
m.fireCDcycle -= 0.66 * (45 * b.fireCDscale)
|
||||
player.force.x -= 2 * knock * Math.cos(m.angle)
|
||||
|
||||
11
js/index.js
11
js/index.js
@@ -106,7 +106,7 @@ window.addEventListener('load', () => {
|
||||
simulation.difficultyMode = 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])
|
||||
}
|
||||
}
|
||||
@@ -275,7 +275,7 @@ const build = {
|
||||
document.getElementById("pause-grid-right").style.display = "none"
|
||||
window.scrollTo(0, 0);
|
||||
},
|
||||
isExperimentSelection: true,
|
||||
isExperimentSelection: false,
|
||||
choosePowerUp(who, index, type, isAllowed = false) {
|
||||
if (type === "gun") {
|
||||
let isDeselect = false
|
||||
@@ -413,7 +413,7 @@ const build = {
|
||||
</svg>
|
||||
</div>
|
||||
<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>
|
||||
<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">
|
||||
@@ -466,7 +466,7 @@ const build = {
|
||||
},
|
||||
reset() {
|
||||
simulation.startGame(true); //starts game, but pauses it
|
||||
build.isExperimentSelection = true;
|
||||
build.isExperimentSelection = false;
|
||||
simulation.paused = true;
|
||||
m.setField(0)
|
||||
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]);
|
||||
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.levelsCleared += levelsCleared;
|
||||
simulation.isNoPowerUps = document.getElementById("no-power-ups").checked
|
||||
@@ -573,6 +573,7 @@ function openExperimentMenu() {
|
||||
document.body.style.overflowY = "scroll";
|
||||
document.body.style.overflowX = "hidden";
|
||||
document.getElementById("info").style.display = 'none'
|
||||
build.isExperimentSelection = true
|
||||
build.reset();
|
||||
}
|
||||
|
||||
|
||||
179
js/level.js
179
js/level.js
@@ -7,7 +7,7 @@ const level = {
|
||||
defaultZoom: 1400,
|
||||
onLevel: -1,
|
||||
levelsCleared: 0,
|
||||
playableLevels: ["skyscrapers", "rooftops", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber"],
|
||||
playableLevels: ["skyscrapers", "rooftops", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber", "labs"],
|
||||
levels: [],
|
||||
start() {
|
||||
if (level.levelsCleared === 0) { //this code only runs on the first level
|
||||
@@ -17,16 +17,9 @@ const level = {
|
||||
// tech.isFieldFree = true
|
||||
// m.setField("perfect diamagnetism")
|
||||
// b.giveGuns("shotgun")
|
||||
// tech.isNeedleShot = true
|
||||
// tech.isIceShot = true
|
||||
// tech.isFoamShot = true
|
||||
// tech.isWormShot = true
|
||||
// tech.giveTech("CPT reversal")
|
||||
// tech.giveTech("causality bombs")
|
||||
// tech.giveTech("Noether violation")
|
||||
// b.giveGuns("wave beam")
|
||||
// tech.giveTech("phonon")
|
||||
// tech.giveTech("cardinality")
|
||||
// tech.giveTech("isotropic radiator")
|
||||
// tech.giveTech("Lenz's law")
|
||||
// for (let i = 0; i < 3; i++) tech.giveTech("packet length")
|
||||
// for (let i = 0; i < 4; i++) tech.giveTech()
|
||||
|
||||
@@ -233,6 +226,9 @@ const level = {
|
||||
player.force.y = 0;
|
||||
Matter.Body.setPosition(player, m.spawnPos);
|
||||
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: {
|
||||
x: 0,
|
||||
@@ -1082,6 +1078,7 @@ const level = {
|
||||
doCustom = []
|
||||
doCustomTopLayer = []
|
||||
offset = { x: 0, y: 0 }
|
||||
const mobSpawnChance = 0 // Math.random() < chance + 0.07 * simulation.difficulty
|
||||
enterOptions = [
|
||||
(x = offset.x, y = offset.y) => { //lasers
|
||||
level.setPosToSpawn(x + 1750, y - 800);
|
||||
@@ -1127,12 +1124,12 @@ const level = {
|
||||
hazard4.opticalQuery();
|
||||
if (!isSpawnedMobs && !toggle.isOn) {
|
||||
isSpawnedMobs = true
|
||||
spawn.randomMob(x + 150, y + -1100, Infinity);
|
||||
spawn.randomMob(x + 175, y + -775, Infinity);
|
||||
spawn.randomMob(x + 150, y + -350, Infinity);
|
||||
spawn.randomMob(x + 150, y + -75, Infinity);
|
||||
spawn.randomMob(x + 650, y + -125, Infinity);
|
||||
spawn.randomMob(x + 1200, y + -75, Infinity);
|
||||
spawn.randomMob(x + 150, y + -1100, mobSpawnChance);
|
||||
spawn.randomMob(x + 175, y + -775, mobSpawnChance);
|
||||
spawn.randomMob(x + 150, y + -350, mobSpawnChance);
|
||||
spawn.randomMob(x + 150, y + -75, mobSpawnChance);
|
||||
spawn.randomMob(x + 650, y + -125, mobSpawnChance);
|
||||
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
|
||||
isInRoom = true
|
||||
spawn.randomMob(x + 1175, y - 725, Infinity);
|
||||
spawn.randomMob(x + 1450, y - 725, Infinity);
|
||||
spawn.randomMob(x + 425, y - 100, Infinity);
|
||||
spawn.randomMob(x + 1200, y - 125, Infinity);
|
||||
spawn.randomMob(x + 1300, y - 375, Infinity);
|
||||
spawn.randomMob(x + 1175, y - 725, mobSpawnChance);
|
||||
spawn.randomMob(x + 1450, y - 725, mobSpawnChance);
|
||||
spawn.randomMob(x + 425, y - 100, mobSpawnChance);
|
||||
spawn.randomMob(x + 1200, y - 125, mobSpawnChance);
|
||||
spawn.randomMob(x + 1300, y - 375, mobSpawnChance);
|
||||
}
|
||||
ctx.fillStyle = "#d4f4f4"
|
||||
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
|
||||
isInRoom = true
|
||||
spawn.randomMob(x + 1175, y - 725, Infinity);
|
||||
spawn.randomMob(x + 1450, y - 725, Infinity);
|
||||
spawn.randomMob(x + 425, y - 100, Infinity);
|
||||
spawn.randomMob(x + 1200, y - 125, Infinity);
|
||||
spawn.randomMob(x + 1300, y - 375, Infinity);
|
||||
spawn.randomMob(x + 1175, y - 725, mobSpawnChance);
|
||||
spawn.randomMob(x + 1450, y - 725, mobSpawnChance);
|
||||
spawn.randomMob(x + 425, y - 100, mobSpawnChance);
|
||||
spawn.randomMob(x + 1200, y - 125, mobSpawnChance);
|
||||
spawn.randomMob(x + 1300, y - 375, mobSpawnChance);
|
||||
}
|
||||
ctx.fillStyle = "#d4f4f4"
|
||||
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 - 1725, y + -1250, Infinity);
|
||||
spawn.randomMob(x + 2000 - 1250, y + -1200, Infinity);
|
||||
spawn.randomMob(x + 2000 - 300, y + -1200, Infinity);
|
||||
spawn.randomMob(x + 2000 - 800, y + -125, Infinity);
|
||||
spawn.randomMob(x + 2000 - 1600, y + -425, mobSpawnChance);
|
||||
spawn.randomMob(x + 2000 - 1725, y + -1250, mobSpawnChance);
|
||||
spawn.randomMob(x + 2000 - 1250, y + -1200, mobSpawnChance);
|
||||
spawn.randomMob(x + 2000 - 300, y + -1200, mobSpawnChance);
|
||||
spawn.randomMob(x + 2000 - 800, y + -125, mobSpawnChance);
|
||||
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.secondaryBossChance(x + 2000 - 650, y + -875)
|
||||
@@ -1322,11 +1319,11 @@ const level = {
|
||||
}
|
||||
}
|
||||
)
|
||||
spawn.randomMob(x + 1600, y + -425, Infinity);
|
||||
spawn.randomMob(x + 1725, y + -1250, Infinity);
|
||||
spawn.randomMob(x + 1250, y + -1200, Infinity);
|
||||
spawn.randomMob(x + 300, y + -1200, Infinity);
|
||||
spawn.randomMob(x + 800, y + -125, Infinity);
|
||||
spawn.randomMob(x + 1600, y + -425, mobSpawnChance);
|
||||
spawn.randomMob(x + 1725, y + -1250, mobSpawnChance);
|
||||
spawn.randomMob(x + 1250, y + -1200, mobSpawnChance);
|
||||
spawn.randomMob(x + 300, y + -1200, mobSpawnChance);
|
||||
spawn.randomMob(x + 800, y + -125, mobSpawnChance);
|
||||
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.secondaryBossChance(x + 650, y + -875)
|
||||
@@ -1382,11 +1379,11 @@ const level = {
|
||||
}
|
||||
}
|
||||
)
|
||||
spawn.randomMob(x + 2000 - 1600, y + -425, Infinity);
|
||||
spawn.randomMob(x + 2000 - 1725, y + -1250, Infinity);
|
||||
spawn.randomMob(x + 2000 - 1250, y + -1200, Infinity);
|
||||
spawn.randomMob(x + 2000 - 300, y + -1200, Infinity);
|
||||
spawn.randomMob(x + 2000 - 800, y + -125, Infinity);
|
||||
spawn.randomMob(x + 2000 - 1600, y + -425, mobSpawnChance);
|
||||
spawn.randomMob(x + 2000 - 1725, y + -1250, mobSpawnChance);
|
||||
spawn.randomMob(x + 2000 - 1250, y + -1200, mobSpawnChance);
|
||||
spawn.randomMob(x + 2000 - 300, y + -1200, mobSpawnChance);
|
||||
spawn.randomMob(x + 2000 - 800, y + -125, mobSpawnChance);
|
||||
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.secondaryBossChance(x + 650, y + -875)
|
||||
@@ -1439,11 +1436,11 @@ const level = {
|
||||
}
|
||||
}
|
||||
)
|
||||
spawn.randomMob(x + 1600, y + -425, Infinity);
|
||||
spawn.randomMob(x + 1725, y + -1250, Infinity);
|
||||
spawn.randomMob(x + 1250, y + -1200, Infinity);
|
||||
spawn.randomMob(x + 300, y + -1200, Infinity);
|
||||
spawn.randomMob(x + 800, y + -125, Infinity);
|
||||
spawn.randomMob(x + 1600, y + -425, mobSpawnChance);
|
||||
spawn.randomMob(x + 1725, y + -1250, mobSpawnChance);
|
||||
spawn.randomMob(x + 1250, y + -1200, mobSpawnChance);
|
||||
spawn.randomMob(x + 300, y + -1200, mobSpawnChance);
|
||||
spawn.randomMob(x + 800, y + -125, mobSpawnChance);
|
||||
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.secondaryBossChance(x + 650, y - 875)
|
||||
@@ -1510,11 +1507,11 @@ const level = {
|
||||
}
|
||||
}
|
||||
)
|
||||
spawn.randomMob(x + 2000 - 1600, y + -425, Infinity);
|
||||
spawn.randomMob(x + 2000 - 1725, y + -1250, Infinity);
|
||||
spawn.randomMob(x + 2000 - 1250, y + -1200, Infinity);
|
||||
spawn.randomMob(x + 2000 - 300, y + -1200, Infinity);
|
||||
spawn.randomMob(x + 2000 - 800, y + -125, Infinity);
|
||||
spawn.randomMob(x + 2000 - 1600, y + -425, mobSpawnChance);
|
||||
spawn.randomMob(x + 2000 - 1725, y + -1250, mobSpawnChance);
|
||||
spawn.randomMob(x + 2000 - 1250, y + -1200, mobSpawnChance);
|
||||
spawn.randomMob(x + 2000 - 300, y + -1200, mobSpawnChance);
|
||||
spawn.randomMob(x + 2000 - 800, y + -125, mobSpawnChance);
|
||||
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.secondaryBossChance(x + 650, y - 875)
|
||||
@@ -1578,11 +1575,11 @@ const level = {
|
||||
}
|
||||
}
|
||||
)
|
||||
spawn.randomMob(x + 1600, y + -425, Infinity);
|
||||
spawn.randomMob(x + 1725, y + -1250, Infinity);
|
||||
spawn.randomMob(x + 1250, y + -1200, Infinity);
|
||||
spawn.randomMob(x + 300, y + -1200, Infinity);
|
||||
spawn.randomMob(x + 800, y + -125, Infinity);
|
||||
spawn.randomMob(x + 1600, y + -425, mobSpawnChance);
|
||||
spawn.randomMob(x + 1725, y + -1250, mobSpawnChance);
|
||||
spawn.randomMob(x + 1250, y + -1200, mobSpawnChance);
|
||||
spawn.randomMob(x + 300, y + -1200, mobSpawnChance);
|
||||
spawn.randomMob(x + 800, y + -125, mobSpawnChance);
|
||||
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.secondaryBossChance(x + 650, y - 875)
|
||||
@@ -1678,17 +1675,17 @@ const level = {
|
||||
} else if (!isSpawnedMobs) {
|
||||
isSpawnedMobs = true
|
||||
if (chamberY === -650) { //lower chamber
|
||||
spawn.randomGroup(x + 275, y + -1050, Infinity);
|
||||
spawn.randomGroup(x + 675, y + -975, Infinity);
|
||||
spawn.randomMob(x + 250, y + -650, mobSpawnChance);
|
||||
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.randomMob(x + 250, y + -650, Infinity);
|
||||
spawn.randomMob(x + 1825, y + -600, Infinity);
|
||||
} else { //upper chamber
|
||||
spawn.randomGroup(x + 300, y + -300, Infinity);
|
||||
spawn.randomGroup(x + 650, y + -275, Infinity);
|
||||
spawn.randomMob(x + 250, y + -650, mobSpawnChance);
|
||||
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.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
|
||||
// }
|
||||
// })
|
||||
// spawn.randomMob(x + 225, y + -1025, Infinity);
|
||||
// spawn.randomMob(x + 200, y + -675, Infinity);
|
||||
// spawn.randomMob(x + 225, y + -200, Infinity);
|
||||
// spawn.randomMob(x + 1750, y + -1075, Infinity);
|
||||
// spawn.randomMob(x + 1700, y + -650, Infinity);
|
||||
// spawn.randomMob(x + 1675, y + -175, Infinity);
|
||||
// spawn.randomMob(x + 225, y + -1025, mobSpawnChance);
|
||||
// spawn.randomMob(x + 200, y + -675, mobSpawnChance);
|
||||
// spawn.randomMob(x + 225, y + -200, mobSpawnChance);
|
||||
// spawn.randomMob(x + 1750, y + -1075, mobSpawnChance);
|
||||
// spawn.randomMob(x + 1700, y + -650, mobSpawnChance);
|
||||
// spawn.randomMob(x + 1675, y + -175, mobSpawnChance);
|
||||
|
||||
// spawn.randomGroup(x + 300, y + -2200);
|
||||
// spawn.randomGroup(x + 1625, y + -2200);
|
||||
@@ -1847,12 +1844,12 @@ const level = {
|
||||
|
||||
const numberOfMapElementsAdded = 12
|
||||
for (let i = 0; i < numberOfMapElementsAdded; i++) addMapToLevelInProgress(map[map.length - 1 - i])
|
||||
spawn.randomMob(x + 225, y + -1775, Infinity);
|
||||
spawn.randomMob(x + 700, y + -1750, Infinity);
|
||||
spawn.randomMob(x + 1175, y + -1725, Infinity);
|
||||
spawn.randomMob(x + 1700, y + -1700, Infinity);
|
||||
spawn.randomMob(x + 1750, y + -250, Infinity);
|
||||
spawn.randomMob(x + 125, y + -250, Infinity);
|
||||
spawn.randomMob(x + 225, y + -1775, mobSpawnChance);
|
||||
spawn.randomMob(x + 700, y + -1750, mobSpawnChance);
|
||||
spawn.randomMob(x + 1175, y + -1725, mobSpawnChance);
|
||||
spawn.randomMob(x + 1700, y + -1700, mobSpawnChance);
|
||||
spawn.randomMob(x + 1750, y + -250, mobSpawnChance);
|
||||
spawn.randomMob(x + 125, y + -250, mobSpawnChance);
|
||||
} else {
|
||||
spawn.mapVertex(x + 775, y + -260, hexagon);
|
||||
spawn.mapVertex(x + 1225, y + -260, hexagon);
|
||||
@@ -1873,12 +1870,12 @@ const level = {
|
||||
const numberOfMapElementsAdded = 12
|
||||
for (let i = 0; i < numberOfMapElementsAdded; i++) addMapToLevelInProgress(map[map.length - 1 - i])
|
||||
|
||||
spawn.randomMob(x + 225, y + -1025, Infinity);
|
||||
spawn.randomMob(x + 200, y + -675, Infinity);
|
||||
spawn.randomMob(x + 225, y + -200, Infinity);
|
||||
spawn.randomMob(x + 1750, y + -1075, Infinity);
|
||||
spawn.randomMob(x + 1700, y + -650, Infinity);
|
||||
spawn.randomMob(x + 1675, y + -175, Infinity);
|
||||
spawn.randomMob(x + 225, y + -1025, mobSpawnChance);
|
||||
spawn.randomMob(x + 200, y + -675, mobSpawnChance);
|
||||
spawn.randomMob(x + 225, y + -200, mobSpawnChance);
|
||||
spawn.randomMob(x + 1750, y + -1075, mobSpawnChance);
|
||||
spawn.randomMob(x + 1700, y + -650, mobSpawnChance);
|
||||
spawn.randomMob(x + 1675, y + -175, mobSpawnChance);
|
||||
}
|
||||
simulation.draw.setPaths() //update map graphics
|
||||
spawn.randomGroup(x + 300, y + -2200);
|
||||
@@ -1940,15 +1937,15 @@ const level = {
|
||||
const numberOfMapElementsAdded = 13
|
||||
for (let i = 0; i < numberOfMapElementsAdded; i++) addMapToLevelInProgress(map[map.length - 1 - i])
|
||||
|
||||
spawn.randomMob(x + 1075, y + -1500, Infinity);
|
||||
spawn.randomMob(x + 325, y + -550, Infinity);
|
||||
spawn.randomMob(x + 800, y + -925, Infinity);
|
||||
spawn.randomMob(x + 1400, y + -1250, Infinity);
|
||||
spawn.randomMob(x + 1350, y + -1725, Infinity);
|
||||
spawn.randomMob(x + 575, y + -1375, Infinity);
|
||||
spawn.randomMob(x + 225, y + -2275, Infinity);
|
||||
spawn.randomMob(x + 875, y + -2450, Infinity);
|
||||
spawn.randomMob(x + 1550, y + -2525, Infinity);
|
||||
spawn.randomMob(x + 1075, y + -1500, mobSpawnChance);
|
||||
spawn.randomMob(x + 325, y + -550, mobSpawnChance);
|
||||
spawn.randomMob(x + 800, y + -925, mobSpawnChance);
|
||||
spawn.randomMob(x + 1400, y + -1250, mobSpawnChance);
|
||||
spawn.randomMob(x + 1350, y + -1725, mobSpawnChance);
|
||||
spawn.randomMob(x + 575, y + -1375, mobSpawnChance);
|
||||
spawn.randomMob(x + 225, y + -2275, mobSpawnChance);
|
||||
spawn.randomMob(x + 875, y + -2450, mobSpawnChance);
|
||||
spawn.randomMob(x + 1550, y + -2525, mobSpawnChance);
|
||||
if (simulation.difficulty > 3) spawn.randomLevelBoss(x + 1075, y + -1500);
|
||||
simulation.draw.setPaths() //update map graphics
|
||||
}
|
||||
|
||||
106
js/player.js
106
js/player.js
@@ -470,7 +470,7 @@ const m = {
|
||||
}
|
||||
},
|
||||
addHealth(heal) {
|
||||
if (!tech.isEnergyHealth && !tech.isNoHeals) {
|
||||
if (!tech.isEnergyHealth) {
|
||||
m.health += heal * simulation.healScale;
|
||||
if (m.health > m.maxHealth) m.health = m.maxHealth;
|
||||
m.displayHealth();
|
||||
@@ -495,7 +495,7 @@ const m = {
|
||||
if (tech.isHarmMACHO) dmg *= 0.33
|
||||
if (tech.isImmortal) dmg *= 0.66
|
||||
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.isBlockHarm && m.isHolding) dmg *= 0.15
|
||||
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
|
||||
) {
|
||||
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))
|
||||
if (tech.blockDmg) {
|
||||
mob[i].damage(tech.blockDmg * b.dmgScale)
|
||||
//draw electricity
|
||||
const step = 40
|
||||
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);
|
||||
}
|
||||
if (m.fieldCDcycle < m.cycle) {
|
||||
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)
|
||||
}
|
||||
ctx.lineWidth = 3;
|
||||
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.moveTo(m.fieldPosition.x + eye * Math.cos(m.fieldAngle), m.fieldPosition.y + eye * Math.sin(m.fieldAngle));
|
||||
ctx.lineTo(mob[i].vertices[len].x, mob[i].vertices[len].y);
|
||||
ctx.lineTo(mob[i].vertices[0].x, mob[i].vertices[0].y);
|
||||
ctx.fill();
|
||||
ctx.stroke();
|
||||
for (let j = 0; j < len; j++) {
|
||||
if (tech.blockDmg) {
|
||||
mob[i].damage(tech.blockDmg * b.dmgScale)
|
||||
//draw electricity
|
||||
const step = 40
|
||||
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;
|
||||
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.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.lineTo(mob[i].vertices[len].x, mob[i].vertices[len].y);
|
||||
ctx.lineTo(mob[i].vertices[0].x, mob[i].vertices[0].y);
|
||||
ctx.fill();
|
||||
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) {
|
||||
|
||||
} else {
|
||||
@@ -1682,14 +1686,14 @@ const m = {
|
||||
|
||||
m.hold = function() {
|
||||
const wave = Math.sin(m.cycle * 0.022);
|
||||
m.fieldRange = 170 + 12 * wave
|
||||
m.fieldArc = 0.33 + 0.045 * wave //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
|
||||
m.fieldRange = 190 + 12 * wave
|
||||
m.fieldArc = 0.36 + 0.04 * wave //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
|
||||
m.calculateFieldThreshold();
|
||||
if (m.isHolding) {
|
||||
m.drawHold(m.holdingTarget);
|
||||
m.holding();
|
||||
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.lookForPickUp();
|
||||
m.fieldPosition = { x: m.pos.x, y: m.pos.y }
|
||||
@@ -1724,7 +1728,7 @@ const m = {
|
||||
m.pickUp();
|
||||
} 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)
|
||||
if (tech.isFieldFree && !input.field && m.fieldCDcycle < m.cycle) {
|
||||
if (tech.isFieldFree && !input.field) {
|
||||
//draw field free of player
|
||||
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()) + ")"
|
||||
|
||||
@@ -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)
|
||||
if (heal > 0) {
|
||||
const overHeal = m.health + heal * simulation.healScale - m.maxHealth //used with tech.isOverHeal
|
||||
|
||||
@@ -538,10 +538,11 @@ const simulation = {
|
||||
} else {
|
||||
level.levels = shuffle(level.levels); //shuffles order of maps
|
||||
}
|
||||
level.levels.unshift("intro"); //add level to the start of the randomized levels list
|
||||
level.levels.push("labs"); //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
|
||||
if (!build.isExperimentSelection) { //experimental mode is endless
|
||||
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("final"); //add level to the end of the randomized levels list
|
||||
}
|
||||
|
||||
input.endKeySensing();
|
||||
b.removeAllGuns();
|
||||
|
||||
13
js/spawn.js
13
js/spawn.js
@@ -1973,18 +1973,18 @@ const spawn = {
|
||||
mobs.spawn(x, y, 5, 50, "rgb(215,80,190)"); //"rgb(221,102,119)"
|
||||
let me = mob[mob.length - 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.damageReduction = 0.25;
|
||||
me.frictionStatic = 0;
|
||||
me.friction = 0;
|
||||
me.memory = 240
|
||||
me.seePlayerFreq = 60
|
||||
me.delay = 20 + 20 * simulation.CDScale;
|
||||
me.delay = 16 + 30 * simulation.CDScale;
|
||||
me.nextBlinkCycle = me.delay;
|
||||
me.blinkRange = 235
|
||||
me.grenadeDelay = 30 + 50 * simulation.CDScale
|
||||
me.pulseRadius = 2 * Math.min(550, 250 + simulation.difficulty * 3)
|
||||
me.grenadeDelay = 30 + 60 * simulation.CDScale
|
||||
me.pulseRadius = 2 * Math.min(550, 220 + simulation.difficulty * 4)
|
||||
spawn.shield(me, x, y, 1);
|
||||
me.onDamage = function() {
|
||||
// this.cd = simulation.cycle + this.delay;
|
||||
@@ -2001,6 +2001,7 @@ const spawn = {
|
||||
y: speed * Math.sin(angle)
|
||||
});
|
||||
}
|
||||
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||
}
|
||||
me.do = function() {
|
||||
this.seePlayerByHistory()
|
||||
@@ -3310,8 +3311,8 @@ const spawn = {
|
||||
};
|
||||
me.showHealthBar = false;
|
||||
me.collisionFilter.category = cat.mobBullet;
|
||||
// me.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet;
|
||||
me.collisionFilter.mask = 0
|
||||
me.collisionFilter.mask = cat.map | cat.body
|
||||
// me.collisionFilter.mask = 0
|
||||
me.do = function() {
|
||||
this.timeLimit();
|
||||
ctx.beginPath(); //draw explosion outline
|
||||
|
||||
72
js/tech.js
72
js/tech.js
@@ -333,9 +333,9 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
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() {
|
||||
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");
|
||||
@@ -447,9 +447,9 @@
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return !tech.isEnergyHealth && !tech.isEnergyNoAmmo
|
||||
return !tech.isEnergyNoAmmo
|
||||
},
|
||||
requires: "not mass-energy equivalence or exciton-lattice",
|
||||
requires: "exciton-lattice",
|
||||
effect: () => {
|
||||
tech.isAmmoFromHealth = true;
|
||||
},
|
||||
@@ -2189,9 +2189,9 @@
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
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: () => {
|
||||
m.health = 0
|
||||
document.getElementById("health").style.display = "none"
|
||||
@@ -2202,13 +2202,15 @@
|
||||
m.displayHealth();
|
||||
},
|
||||
remove() {
|
||||
tech.isEnergyHealth = false;
|
||||
document.getElementById("health").style.display = "inline"
|
||||
document.getElementById("health-bg").style.display = "inline"
|
||||
document.getElementById("dmg").style.backgroundColor = "#f67";
|
||||
m.health = Math.max(Math.min(m.maxHealth, m.energy), 0.1);
|
||||
simulation.mobDmgColor = "rgba(255,0,0,0.7)"
|
||||
m.displayHealth();
|
||||
if (tech.isEnergyHealth) {
|
||||
tech.isEnergyHealth = false;
|
||||
document.getElementById("health").style.display = "inline"
|
||||
document.getElementById("health-bg").style.display = "inline"
|
||||
document.getElementById("dmg").style.backgroundColor = "#f67";
|
||||
m.health = Math.max(Math.min(m.maxHealth, m.energy), 0.1);
|
||||
simulation.mobDmgColor = "rgba(255,0,0,0.7)"
|
||||
m.displayHealth();
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -2219,9 +2221,9 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.isEnergyHealth && !tech.isNoHeals
|
||||
return tech.isEnergyHealth
|
||||
},
|
||||
requires: "mass-energy equivalence, not ergodicity",
|
||||
requires: "mass-energy equivalence",
|
||||
effect() {
|
||||
tech.healGiveMaxEnergy = true; //tech.healMaxEnergyBonus given from heal power up
|
||||
powerUps.heal.color = "#0ae"
|
||||
@@ -2282,9 +2284,9 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
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: () => {
|
||||
tech.isEnergyDamage = true
|
||||
},
|
||||
@@ -2300,9 +2302,9 @@
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
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() {
|
||||
tech.isEnergyNoAmmo = true;
|
||||
},
|
||||
@@ -2318,9 +2320,9 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return !tech.isEnergyHealth
|
||||
return true
|
||||
},
|
||||
requires: "not mass-energy equivalence",
|
||||
requires: "",
|
||||
effect() {
|
||||
tech.isEnergyLoss = true;
|
||||
},
|
||||
@@ -2400,11 +2402,11 @@
|
||||
},
|
||||
requires: "a source of overfilled energy",
|
||||
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)
|
||||
},
|
||||
remove() {
|
||||
tech.overfillDrain = 0.75
|
||||
tech.overfillDrain = 0.7
|
||||
if (this.count > 0) tech.removeJunkTechFromPool(18)
|
||||
}
|
||||
},
|
||||
@@ -2453,9 +2455,9 @@
|
||||
frequencyDefault: 1,
|
||||
isHealTech: true,
|
||||
allowed() {
|
||||
return !tech.isEnergyHealth && !tech.isNoHeals
|
||||
return !tech.isEnergyHealth
|
||||
},
|
||||
requires: "not mass-energy equivalence, ergodicity",
|
||||
requires: "not mass-energy equivalence",
|
||||
effect() {
|
||||
tech.isHealthRecovery = true;
|
||||
},
|
||||
@@ -2556,16 +2558,16 @@
|
||||
},
|
||||
{
|
||||
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,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
isHealTech: true,
|
||||
allowed() {
|
||||
return !tech.isEnergyHealth && !tech.isNoHeals
|
||||
return !tech.isEnergyHealth
|
||||
},
|
||||
requires: "not mass-energy equivalence, ergodicity",
|
||||
requires: "not mass-energy equivalence",
|
||||
effect() {
|
||||
tech.healthDrain += 0.03;
|
||||
},
|
||||
@@ -2599,9 +2601,9 @@
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return !tech.isEnergyHealth && !tech.isNoHeals
|
||||
return !tech.isEnergyHealth
|
||||
},
|
||||
requires: "not mass-energy equivalence, ergodicity",
|
||||
requires: "not mass-energy equivalence",
|
||||
effect() {
|
||||
tech.isFallingDamage = true;
|
||||
m.setMaxHealth();
|
||||
@@ -2678,9 +2680,9 @@
|
||||
isNonRefundable: true,
|
||||
isBadRandomOption: true,
|
||||
allowed() {
|
||||
return !tech.isNoHeals
|
||||
return true
|
||||
},
|
||||
requires: "not ergodicity",
|
||||
requires: "",
|
||||
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, len = tech.tech.length; i < len; i++) {
|
||||
@@ -3451,15 +3453,15 @@
|
||||
},
|
||||
{
|
||||
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,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
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() {
|
||||
tech.isNoHeals = true;
|
||||
level.difficultyDecrease(simulation.difficultyMode * 2)
|
||||
|
||||
34
todo.txt
34
todo.txt
@@ -1,22 +1,25 @@
|
||||
******************************************************** NEXT PATCH ********************************************************
|
||||
|
||||
tech: Lenz's law -perfect diamagnetism field stays when you aren't holding field
|
||||
tech: Zeno's paradox - every 5s lose 10% of your current health, but get 84% harm reduction
|
||||
"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
|
||||
|
||||
******************************************************** 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
|
||||
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
|
||||
|
||||
|
||||
block shattering
|
||||
get code from planetesimals
|
||||
https://codepen.io/lilgreenland/pen/jrMvaB?editors=0010
|
||||
@@ -196,6 +199,10 @@ n-gon outreach ideas
|
||||
|
||||
******************************************************** 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
|
||||
maybe add a cooldown?
|
||||
can't reproduce
|
||||
@@ -230,6 +237,11 @@ is there a way to check if the player is stuck inside the map or block
|
||||
|
||||
******************************************************** 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
|
||||
mobs have genes
|
||||
the last mob that did damage saves it's genes to local storage
|
||||
@@ -318,6 +330,10 @@ map: observatory
|
||||
|
||||
******************************************************** 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
|
||||
eggs don't attack but grow back into a mob after about 10s
|
||||
|
||||
|
||||
Reference in New Issue
Block a user