testChamber2

new level testChamber2
  New camera flip effect
  new laser level element now has collisions with blocks
  elevators are less deadly to mobs at low speeds

difficulty level progression reworked
no constraints on final boss
new constraint - healing disabled

quenching 0.3->0.4x overheal converted to max health
tungsten carbide 400->500 extra max health
paradigm shift's  health loss is no longer reduced by damage taken reduction
coherence no longer remembers tech that is set to zero frequency, like removed tech

JUNK tech: pet the bot - lets you pet your bots
JUNK tech: the upside down - flip everything

bug
  prevented possible duplicate choices with coherence tech
  fixed issues with showing and hiding health bars on that constraint
  fixed crash from autonomous defense
  mass-energy mode wasn't getting any benefit from damage taken reduction
    it now gets square root of damage taken reduction
This commit is contained in:
landgreen
2024-09-24 19:42:12 -07:00
parent ebd22741d4
commit cea1c64c6e
12 changed files with 1126 additions and 373 deletions

View File

@@ -162,8 +162,7 @@ function collisionChecks(event) {
const maxCount = 10 + 3 * tech.extraHarpoons //scale the number of hooks fired
let count = maxCount - 1
const angle = Math.atan2(mob[k].position.y - player.position.y, mob[k].position.x - player.position.x);
const mass = 0.75 * (tech.isLargeHarpoon ? 1 + 0.05 * Math.sqrt(this.ammo) : 1)
const mass = 0.75 * ((tech.isLargeHarpoon) ? 1 + Math.min(0.05 * Math.sqrt(b.guns[9].ammo), 10) : 1)
b.harpoon(m.pos, mob[k], angle, mass, true, 7) // harpoon(where, target, angle = m.angle, harpoonSize = 1, isReturn = false, totalCycles = 35, isReturnAmmo = true, thrust = 0.1) {
bullet[bullet.length - 1].drain = 0
for (; count > 0; count--) {
@@ -222,9 +221,9 @@ function collisionChecks(event) {
return;
}
//mob + body collisions
if (obj.classType === "body" && obj.speed > 6) {
if (obj.classType === "body" && obj.speed > 9) {
const v = Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity));
if (v > 9) {
if (v > 11) {
if (tech.blockDmg) { //electricity
Matter.Body.setVelocity(mob[k], { x: 0.5 * mob[k].velocity.x, y: 0.5 * mob[k].velocity.y });
if (tech.isBlockRadiation && !mob[k].isShielded && !mob[k].isMobBullet) {

View File

@@ -324,6 +324,11 @@ function setupCanvas() {
ctx.lineJoin = "round";
ctx.lineCap = "round";
simulation.setZoom();
if (simulation.isInvertedVertical) {
ctx.translate(0, canvas.height); // Move the origin down to the bottom
ctx.scale(1, -1); // Flip vertically
}
}
setupCanvas();
window.onresize = () => {
@@ -519,15 +524,16 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
<details id="difficulty-parameters-details" style="padding: 0 8px;">
<summary>difficulty parameters</summary>
<div class="pause-details">
${simulation.difficultyMode > 0 ? `<div class="pause-difficulty-row"><strong>0.87x</strong> <strong class='color-d'>damage</strong>, <strong>1.2x</strong> <strong class='color-defense'>damage taken</strong> per level<br><strong>+1</strong> boss on each level</div>` : " "}
${simulation.difficultyMode > 1 ? `<div class="pause-difficulty-row"><strong>more</strong> mob per level<br><strong>faster</strong> mobs per level</div>` : " "}
${simulation.difficultyMode > 2 ? `<div class="pause-difficulty-row"><strong>0.87x</strong> <strong class='color-d'>damage</strong>, <strong>1.2x</strong> <strong class='color-defense'>damage taken</strong> per level<br><strong>+1</strong> random <strong class="constraint">constraint</strong> on each level</div>` : " "}
${simulation.difficultyMode > 3 ? `<div class="pause-difficulty-row"><strong>+1</strong> boss on each level<br>bosses spawn <strong>1</strong> fewer ${powerUps.orb.tech()}</div>` : " "}
${simulation.difficultyMode > 4 ? `<div class="pause-difficulty-row"><strong>0.87x</strong> <strong class='color-d'>damage</strong>, <strong>1.2x</strong> <strong class='color-defense'>damage taken</strong> per level<br><strong>+1</strong> random <strong class="constraint">constraint</strong> on each level</div>` : " "}
${simulation.difficultyMode > 0 ? `<div class="pause-difficulty-row"><strong>0.85x</strong> <strong class='color-d'>damage</strong> per level<br><strong>1.25x</strong> <strong class='color-defense'>damage taken</strong> per level</div>` : " "}
${simulation.difficultyMode > 1 ? `<div class="pause-difficulty-row">spawn <strong>more</strong> mobs<br>mobs move <strong>faster</strong></div>` : " "}
${simulation.difficultyMode > 2 ? `<div class="pause-difficulty-row">spawn a <strong>2nd</strong> boss each level<br>bosses spawn <strong>0.5x</strong> power ups</div>` : " "}
${simulation.difficultyMode > 3 ? `<div class="pause-difficulty-row"><strong>0.85x</strong> <strong class='color-d'>damage</strong> per level<br><strong>1.25x</strong> <strong class='color-defense'>damage taken</strong> per level</div>` : " "}
${simulation.difficultyMode > 4 ? `<div class="pause-difficulty-row"><strong>+1</strong> random <strong class="constraint">constraint</strong> each level<br>fewer initial power ups</div>` : " "}
${simulation.difficultyMode > 5 ? `<div class="pause-difficulty-row"><strong>0.5x</strong> initial <strong class='color-d'>damage</strong><br><strong>2x</strong> initial <strong class='color-defense'>damage taken</strong></div>` : " "}
${simulation.difficultyMode > 6 ? `<div class="pause-difficulty-row"><strong>+1</strong> random <strong class="constraint">constraint</strong> each level<br>fewer ${powerUps.orb.tech()} spawn</div>` : " "}
</div>
</details>
${simulation.difficultyMode > 2 ? `<details id="constraints-details" style="padding: 0 8px;"><summary>active constraints</summary><div class="pause-details"><span class="constraint">${level.constraintDescription1}<br>${level.constraintDescription2}</span></div></details>` : ""}
${simulation.difficultyMode > 4 ? `<details id="constraints-details" style="padding: 0 8px;"><summary>active constraints</summary><div class="pause-details"><span class="constraint">${level.constraintDescription1}<br>${level.constraintDescription2}</span></div></details>` : ""}
</div>`
if (!localSettings.isHideHUD) text += `<div class="pause-grid-module card-background" style="height:auto;">
<details id = "console-log-details" style="padding: 0 8px;">
@@ -754,7 +760,7 @@ ${simulation.difficultyMode > 2 ? `<details id="constraints-details" style="padd
if (tech.isEnergyHealth) {
document.getElementById("health").style.display = "none"
document.getElementById("health-bg").style.display = "none"
} else {
} else if (!level.isHideHealth) {
document.getElementById("health").style.display = "inline"
document.getElementById("health-bg").style.display = "inline"
}
@@ -1019,7 +1025,6 @@ ${simulation.difficultyMode > 2 ? `<details id="constraints-details" style="padd
document.getElementById("experiment-grid").innerHTML = text
//add event listener for pressing enter key when in sort
function pressEnterSort(event) {
if (event.key === 'Enter') {
@@ -1029,14 +1034,6 @@ ${simulation.difficultyMode > 2 ? `<details id="constraints-details" style="padd
}
document.getElementById("sort-input").addEventListener('keydown', pressEnterSort);
// document.getElementById("difficulty-select-experiment").value = document.getElementById("difficulty-select").value
// document.getElementById("difficulty-select-experiment").addEventListener("input", () => {
// simulation.difficultyMode = Number(document.getElementById("difficulty-select-experiment").value)
// lore.setTechGoal()
// localSettings.difficultyMode = Number(document.getElementById("difficulty-select-experiment").value)
// document.getElementById("difficulty-select").value = document.getElementById("difficulty-select-experiment").value
// if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
// });
//add tooltips
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (document.getElementById(`tech-${i}`)) {
@@ -1066,8 +1063,8 @@ ${simulation.difficultyMode > 2 ? `<details id="constraints-details" style="padd
b.activeGun = null;
b.inventoryGun = 0;
simulation.makeGunHUD();
m.resetSkin()
tech.setupAllTech();
m.resetSkin();
build.populateGrid();
document.getElementById("field-0").classList.add("build-field-selected");
document.getElementById("experiment-grid").style.display = "grid"
@@ -1695,9 +1692,13 @@ window.addEventListener("keydown", function (event) {
}
});
//mouse move input
document.body.addEventListener("mousemove", (e) => {
function mouseMoveDefault(e) {
simulation.mouse.x = e.clientX;
simulation.mouse.y = e.clientY;
}
let mouseMove = mouseMoveDefault
document.body.addEventListener("mousemove", (e) => {
mouseMove(e)
});
document.body.addEventListener("mouseup", (e) => {
@@ -1835,7 +1836,7 @@ if (localSettings.isAllowed && !localSettings.isEmpty) {
document.getElementById("hide-hud").checked = localSettings.isHideHUD
if (localSettings.difficultyCompleted === undefined) {
localSettings.difficultyCompleted = [null, false, false, false, false, false, false] //null because there isn't a difficulty zero
localSettings.difficultyCompleted = [null, false, false, false, false, false, false, false] //null because there isn't a difficulty zero
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
}
@@ -1857,7 +1858,7 @@ if (localSettings.isAllowed && !localSettings.isEmpty) {
isJunkExperiment: false,
isCommunityMaps: false,
difficultyMode: '2',
difficultyCompleted: [null, false, false, false, false, false, false],
difficultyCompleted: [null, false, false, false, false, false, false, false],
fpsCapDefault: 'max',
runCount: 0,
isTrainingNotAttempted: true,

File diff suppressed because it is too large Load Diff

View File

@@ -358,7 +358,6 @@ const lore = {
setInterval(() => {
if (Math.random() < 0.5) {
spawn[spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]](1000 * (Math.random() - 0.5), -500 + 200 * (Math.random() - 0.5));
// level.difficultyIncrease(simulation.difficultyMode)
} else {
spawn.randomLevelBoss(500 * (Math.random() - 0.5), -500 + 200 * (Math.random() - 0.5))
}
@@ -693,9 +692,6 @@ const lore = {
setInterval(() => {
spawn[spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]](1000 * (Math.random() - 0.5), -500 + 200 * (Math.random() - 0.5));
}, 500); //every 1/2 seconds
// setInterval(() => {
// level.difficultyIncrease(simulation.difficultyMode)
// }, 5000); //every 5 seconds
},
() => {
lore.talkingColor = "#dff";

View File

@@ -1146,6 +1146,7 @@ const mobs = {
// ctx.stroke();
// },
leaveBody: true,
maxMobBody: 40,
isDropPowerUp: true,
death() {
if (tech.collidePowerUps && this.isDropPowerUp) powerUps.randomize(this.position) //needs to run before onDeath spawns power ups
@@ -1406,7 +1407,7 @@ const mobs = {
//replace dead mob with a regular body
replace(i) {
//if there are too many bodies don't turn into blocks to help performance
if (this.leaveBody && body.length < 40 && this.mass < 200 && this.radius > 18) {
if (this.leaveBody && body.length < mobs.maxMobBody && this.mass < 200 && this.radius > 18) {
let v = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices)) //might help with vertex collision issue, not sure
if (v.length > 5 && body.length < 35 && Math.random() < 0.25) {
const cutPoint = 3 + Math.floor((v.length - 6) * Math.random()) //Math.floor(v.length / 2)

View File

@@ -528,7 +528,7 @@ const m = {
// }
},
addHealth(heal) {
if (!tech.isEnergyHealth) {
if (!tech.isEnergyHealth && !level.isNoHeal) {
m.health += heal * simulation.healScale;
if (m.health > m.maxHealth) m.health = m.maxHealth;
m.displayHealth();
@@ -536,7 +536,7 @@ const m = {
},
baseHealth: 1,
setMaxHealth(isMessage) {
m.maxHealth = m.baseHealth + tech.extraMaxHealth + 4 * tech.isFallingDamage
m.maxHealth = m.baseHealth + tech.extraMaxHealth + 5 * tech.isFallingDamage
if (level.isReducedHealth) {
level.reducedHealthLost = Math.max(0, m.health - m.maxHealth * 0.5)
m.maxHealth *= 0.5
@@ -683,7 +683,7 @@ const m = {
}
},
collisionImmuneCycles: 30,
damage(dmg) {
damage(dmg, isDefense = true) {
if (tech.isRewindAvoidDeath && (m.energy + 0.05) > Math.min(0.95, m.maxEnergy) && dmg > 0.01) {
const steps = Math.floor(Math.min(299, 150 * m.energy))
simulation.inGameConsole(`<span class='color-var'>m</span>.rewind(${steps})`)
@@ -701,6 +701,7 @@ const m = {
}
}
if (tech.isEnergyHealth) {
if (isDefense) dmg *= Math.pow(m.defense(), 0.5)
m.energy -= 0.9 * dmg / Math.sqrt(simulation.healScale) //scale damage with heal reduction difficulty
if (m.energy < 0 || isNaN(m.energy)) { //taking deadly damage
if (tech.isDeathAvoid && powerUps.research.count && !tech.isDeathAvoidedThisLevel) {
@@ -727,15 +728,14 @@ const m = {
return;
}
} else {
dmg *= m.defense()
if (isDefense) dmg *= m.defense()
m.health -= dmg;
if (m.health < 0 || isNaN(m.health)) {
if (tech.isDeathAvoid && powerUps.research.count > 0 && !tech.isDeathAvoidedThisLevel) { //&& Math.random() < 0.5
tech.isDeathAvoidedThisLevel = true
m.health = 0.05
powerUps.research.changeRerolls(-1)
simulation.inGameConsole(`<span class='color-var'>m</span>.<span class='color-r'>research</span><span class='color-symbol'>--</span>
<br>${powerUps.research.count}`)
simulation.inGameConsole(`<span class='color-var'>m</span>.<span class='color-r'>research</span><span class='color-symbol'>--</span><br>${powerUps.research.count}`)
for (let i = 0; i < 16; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "heal", false);
if (m.immuneCycle < m.cycle + 300) m.immuneCycle = m.cycle + 300 //disable this.immuneCycle bonus seconds
simulation.wipe = function () { //set wipe to have trails

View File

@@ -347,6 +347,75 @@ const powerUps = {
})
},
instructions: {
name: "instructions",
color: "rgba(100,125,140,0.35)",
size() {
return 150
},
effect() {
requestAnimationFrame(() => { //add a background behind the power up menu
ctx.fillStyle = `rgba(150,150,150,0.9)`;
ctx.fillRect(0, 0, canvas.width, canvas.height);
});
powerUps.animatePowerUpGrab('rgba(0, 0, 0,0.6)')
if (!simulation.paused) {
simulation.paused = true;
simulation.isChoosing = true; //stops p from un pausing on key down
document.body.style.cursor = "auto";
document.getElementById("choose-grid").style.pointerEvents = "auto";
document.getElementById("choose-grid").style.transitionDuration = "0s";
}
//build level info
document.getElementById("choose-grid").classList.add('choose-grid-no-images');
document.getElementById("choose-grid").classList.remove('choose-grid');
document.getElementById("choose-grid").style.gridTemplateColumns = "800px"//adjust this to increase the width of the whole menu, but mostly the center column
let lore = localSettings.loreCount > 0 ? "lore.unlockTesting() //press T to enter testing" : ""
let text = `<div class="grid-container"><pre> <strong>//console commands</strong>
powerUps.instructions.effect() //reproduce this message
tech.giveTech("name") //replace "name" with tech name
m.setField("name") //standing wave perfect diamagnetism negative mass molecular assembler plasma torch time dilation metamaterial cloaking pilot wave wormhole grappling hook
b.giveGuns("name") //nail gun shotgun super balls wave missiles grenades spores drones foam harpoon mine laser
tech.damage *= 2 //2x damage
m.immuneCycle = Infinity //immune to damage
m.energy = 0 //set energy
m.health = 1 //set health
m.maxHealth = 1 //set max health
m.energy = 1 //set energy
m.maxEnergy = 1 //set max energy
simulation.enableConstructMode() //press T to build with mouse
${lore}
//tech gun field heal ammo research coupling boost instructions entanglement
powerUps.spawn(m.pos.x, m.pos.y, "name")
Matter.Body.setPosition(player, simulation.mouseInGame);
spawn.bodyRect(simulation.mouseInGame.x, simulation.mouseInGame.y, 50, 50)
spawn.randomLevelBoss(simulation.mouseInGame.x, simulation.mouseInGame.y)
<strong>chrome</strong> <strong>firefox</strong>
<strong>Win/Linux:</strong> Ctrl + Shift + J Ctrl + Shift + J
<strong>Mac:</strong> Cmd + Option + J Cmd + Shift + J</pre></div>
<div class="choose-grid-module" id="exit" style="text-align: center;font-size: 1.3rem;">exit</div>`
document.getElementById("choose-grid").innerHTML = text
//show level info
document.getElementById("choose-grid").style.opacity = "1"
document.getElementById("choose-grid").style.transitionDuration = "0.3s"; //how long is the fade in on
document.getElementById("choose-grid").style.visibility = "visible"
document.getElementById("exit").addEventListener("click", () => {
level.unPause()
document.body.style.cursor = "none";
//reset hide image style
if (localSettings.isHideImages) {
document.getElementById("choose-grid").classList.add('choose-grid-no-images');
document.getElementById("choose-grid").classList.remove('choose-grid');
} else {
document.getElementById("choose-grid").classList.add('choose-grid');
document.getElementById("choose-grid").classList.remove('choose-grid-no-images');
}
});
},
},
difficulty: {
name: "difficulty",
color: "#000",
@@ -371,12 +440,19 @@ const powerUps = {
//build level info
document.getElementById("choose-grid").classList.add('choose-grid-no-images');
document.getElementById("choose-grid").classList.remove('choose-grid');
document.getElementById("choose-grid").style.gridTemplateColumns = "505px" //adjust this to increase the width of the whole menu, but mostly the center column
document.getElementById("choose-grid").style.gridTemplateColumns = "390px" //adjust this to increase the width of the whole menu, but mostly the center column
//<div class="row" id="constraint-1"><strong>0.87x</strong> <strong class='color-d'>damage</strong>, <strong>1.22x</strong> <strong class='color-defense'>damage taken</strong> per level<br><strong>+1</strong> boss on each level</div>
//<div class="row" id="constraint-2"><strong>more</strong> mobs per level<br><strong>faster</strong> mobs per level</div>
//<div class="row" id="constraint-3"><strong>0.87x</strong> <strong class='color-d'>damage</strong>, <strong>1.22x</strong> <strong class='color-defense'>damage taken</strong> per level<br><strong>+1</strong> random <strong class="constraint">constraint</strong> on each level</div>
//<div class="row" id="constraint-4"><strong>+1</strong> boss on each level<br>bosses spawn <strong>1</strong> fewer ${powerUps.orb.tech()}</div>
//<div class="row" id="constraint-5"><strong>0.87x</strong> <strong class='color-d'>damage</strong>, <strong>1.22x</strong> <strong class='color-defense'>damage taken</strong> per level<br><strong>+1</strong> random <strong class="constraint">constraint</strong> on each level</div>
//<div class="row" id="constraint-6"><strong>0.5x</strong> initial <strong class='color-d'>damage</strong><br><strong>2x</strong> initial <strong class='color-defense'>damage taken</strong></div>
let text = `<div>
<div class="grid-container">
<div class="left-column">
<input type="range" id="difficulty-slider" name="temp" type="range" step="1" value="1" min="1" max="6" list="values" dir="ltr"/>
<input type="range" id="difficulty-slider" name="temp" type="range" step="1" value="1" min="1" max="7" list="values" dir="ltr"/>
<datalist id="values">
<option value="1"></option>
<option value="2"></option>
@@ -384,23 +460,26 @@ const powerUps = {
<option value="4"></option>
<option value="5"></option>
<option value="6"></option>
<option value="7"></option>
</datalist>
</div>
<div class="right-column">
<div class="row" id="constraint-1"><strong>0.87x</strong> <strong class='color-d'>damage</strong>, <strong>1.22x</strong> <strong class='color-defense'>damage taken</strong> per level<br><strong>+1</strong> boss on each level</div>
<div class="row" id="constraint-2"><strong>more</strong> mob per level<br><strong>faster</strong> mobs per level</div>
<div class="row" id="constraint-3"><strong>0.87x</strong> <strong class='color-d'>damage</strong>, <strong>1.22x</strong> <strong class='color-defense'>damage taken</strong> per level<br><strong>+1</strong> random <strong class="constraint">constraint</strong> on each level</div>
<div class="row" id="constraint-4"><strong>+1</strong> boss on each level<br>bosses spawn <strong>1</strong> fewer ${powerUps.orb.tech()}</div>
<div class="row" id="constraint-5"><strong>0.87x</strong> <strong class='color-d'>damage</strong>, <strong>1.22x</strong> <strong class='color-defense'>damage taken</strong> per level<br><strong>+1</strong> random <strong class="constraint">constraint</strong> on each level</div>
<div class="row" id="constraint-1"><strong>0.85x</strong> <strong class='color-d'>damage</strong> per level<br><strong>1.25x</strong> <strong class='color-defense'>damage taken</strong> per level</div>
<div class="row" id="constraint-2">spawn <strong>more</strong> mobs<br>mobs move <strong>faster</strong></div>
<div class="row" id="constraint-3">spawn a <strong>2nd</strong> boss each level<br>bosses spawn <strong>0.5x</strong> power ups</div>
<div class="row" id="constraint-4"><strong>0.85x</strong> <strong class='color-d'>damage</strong> per level<br><strong>1.25x</strong> <strong class='color-defense'>damage taken</strong> per level</div>
<div class="row" id="constraint-5"><strong>+1</strong> random <strong class="constraint">constraint</strong> each level<br>fewer initial power ups</div>
<div class="row" id="constraint-6"><strong>0.5x</strong> initial <strong class='color-d'>damage</strong><br><strong>2x</strong> initial <strong class='color-defense'>damage taken</strong></div>
<div class="row" id="constraint-7"><strong>+1</strong> random <strong class="constraint">constraint</strong> each level<br>fewer ${powerUps.orb.tech()} spawn</div>
</div>
<div class="far-right-column">
<div id = "constraint-1-record">${localSettings.difficultyCompleted[1] ? "⚆" : " "}</div>
<div id = "constraint-2-record">${localSettings.difficultyCompleted[2] ? "⚆" : " "}</div>
<div id = "constraint-3-record">${localSettings.difficultyCompleted[3] ? "⚆" : " "}</div>
<div id = "constraint-4-record">${localSettings.difficultyCompleted[4] ? "⚆" : " "}</div>
<div id = "constraint-5-record">${localSettings.difficultyCompleted[5] ? "" : " "}</div>
<div id = "constraint-5-record">${localSettings.difficultyCompleted[5] ? "" : " "}</div>
<div id = "constraint-6-record">${localSettings.difficultyCompleted[6] ? "⚇" : " "}</div>
<div id = "constraint-6-record">${localSettings.difficultyCompleted[7] ? "⚇" : " "}</div>
</div>
</div>
<div class="choose-grid-module" id="choose-difficulty">
@@ -433,7 +512,7 @@ const powerUps = {
});
let setDifficultyText = function (isReset = true) {
for (let i = 1; i < 7; i++) {
for (let i = 1; i < 8; i++) {
const id = document.getElementById("constraint-" + i)
if (simulation.difficultyMode < i) {
id.style.opacity = "0.15"
@@ -456,7 +535,7 @@ const powerUps = {
setDifficultyText()
level.setConstraints()
});
for (let i = 1; i < 7; i++) {
for (let i = 1; i < 8; i++) {
document.getElementById("constraint-" + i).addEventListener("click", () => {
simulation.difficultyMode = i
document.getElementById("difficulty-slider").value = simulation.difficultyMode
@@ -632,7 +711,7 @@ const powerUps = {
m.addHealth(heal);
if (healOutput > 0) simulation.inGameConsole(`<div class="circle-grid heal"></div> &nbsp; <span class='color-var'>m</span>.health <span class='color-symbol'>+=</span> ${(healOutput).toFixed(3)}`) // <br>${m.health.toFixed(3)}
if (tech.isOverHeal && overHeal > 0) { //tech quenching
tech.extraMaxHealth += 0.3 * overHeal //increase max health
tech.extraMaxHealth += 0.4 * overHeal //increase max health
m.setMaxHealth();
simulation.inGameConsole(`<div class="circle-grid heal"></div> &nbsp; <span class='color-var'>m</span>.maxHealth <span class='color-symbol'>+=</span> ${(0.3 * overHeal).toFixed(3)}`)
simulation.drawList.push({ //add dmg to draw queue
@@ -925,78 +1004,6 @@ const powerUps = {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ${tech.tech[choose].name} ${techCountText}</div>
${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}</div></div>`
},
// junkTechText(choose, click) { //old code with yahoo images
// const techCountText = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count + 1}x)` : "";
// const style = localSettings.isHideImages ? powerUps.hideStyle : `style="background-size: contain;background-repeat: no-repeat;background-image: url('img/junk.webp');"`
// if (!localSettings.isHideImages) {
// setTimeout(() => { //delay so that the html element exists
// if (tech.tech[choose].url === undefined) { //if on url has been set yet
// const url = "https://images.search.yahoo.com/search/images?p=" + tech.tech[choose].name;
// fetch(url, { signal: AbortSignal.timeout(1000) }) //give up if it takes over 1 second
// .then((response) => response.text())
// .then((html) => {
// const parser = new DOMParser();
// const doc = parser.parseFromString(html, "text/html");
// const elements = doc.getElementsByClassName("ld");
// // console.log(i, elements[i].getAttribute("data"), JSON.parse(elements[i].getAttribute("data")).iurl)
// const index = Math.floor(Math.random() * 4) //randomly choose from the first 4 images
// if (parseInt(JSON.parse(elements[index].getAttribute("data")).s.slice(0, -2)) < 500) { //make sure it isn't too big
// tech.tech[choose].url = JSON.parse(elements[index].getAttribute("data")).iurl //store the url
// document.getElementById(`junk-${choose}`).style.backgroundImage = `url('${tech.tech[choose].url}')` //make the url the background image
// } else if (parseInt(JSON.parse(elements[index + 1].getAttribute("data")).s.slice(0, -2)) < 500) { //try a different images and see if it is smaller
// tech.tech[choose].url = JSON.parse(elements[index + 1].getAttribute("data")).iurl
// document.getElementById(`junk-${choose}`).style.backgroundImage = `url('${tech.tech[choose].url}')`
// } else if (parseInt(JSON.parse(elements[index + 2].getAttribute("data")).s.slice(0, -2)) < 500) { //try a different images and see if it is smaller
// tech.tech[choose].url = JSON.parse(elements[index + 2].getAttribute("data")).iurl
// document.getElementById(`junk-${choose}`).style.backgroundImage = `url('${tech.tech[choose].url}')`
// }
// });
// } else {
// document.getElementById(`junk-${choose}`).style.backgroundImage = `url('${tech.tech[choose].url}')`
// }
// }, 1);
// }
// return `<div id = "junk-${choose}" class="choose-grid-module card-background" onclick="${click}" onauxclick="${click}"${style}>
// <div class="card-text">
// <div class="grid-title"><div class="circle-grid junk"></div> &nbsp; ${tech.tech[choose].name} ${techCountText}</div>
// ${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}</div></div>`
// },
// junkTechText(choose, click) {
// const techCountText = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count + 1}x)` : "";
// const style = localSettings.isHideImages ? powerUps.hideStyle : `style="background-size: contain;background-repeat: no-repeat;background-image: url('img/junk.webp');"`
// if (!localSettings.isHideImages) {
// setTimeout(() => { //delay so that the html element exists
// if (tech.tech[choose].url === undefined) { //if on url has been set yet
// const url = "https://images.search.yahoo.com/search/images?p=" + tech.tech[choose].name;
// fetch(url, { signal: AbortSignal.timeout(1000) }) //give up if it takes over 1 second
// .then((response) => response.text())
// .then((html) => {
// const parser = new DOMParser();
// const doc = parser.parseFromString(html, "text/html");
// const elements = doc.getElementsByClassName("ld");
// // console.log(i, elements[i].getAttribute("data"), JSON.parse(elements[i].getAttribute("data")).iurl)
// const index = Math.floor(Math.random() * 4) //randomly choose from the first 4 images
// if (parseInt(JSON.parse(elements[index].getAttribute("data")).s.slice(0, -2)) < 500) { //make sure it isn't too big
// tech.tech[choose].url = JSON.parse(elements[index].getAttribute("data")).iurl //store the url
// document.getElementById(`junk-${choose}`).style.backgroundImage = `url('${tech.tech[choose].url}')` //make the url the background image
// } else if (parseInt(JSON.parse(elements[index + 1].getAttribute("data")).s.slice(0, -2)) < 500) { //try a different images and see if it is smaller
// tech.tech[choose].url = JSON.parse(elements[index + 1].getAttribute("data")).iurl
// document.getElementById(`junk-${choose}`).style.backgroundImage = `url('${tech.tech[choose].url}')`
// } else if (parseInt(JSON.parse(elements[index + 2].getAttribute("data")).s.slice(0, -2)) < 500) { //try a different images and see if it is smaller
// tech.tech[choose].url = JSON.parse(elements[index + 2].getAttribute("data")).iurl
// document.getElementById(`junk-${choose}`).style.backgroundImage = `url('${tech.tech[choose].url}')`
// }
// });
// } else {
// document.getElementById(`junk-${choose}`).style.backgroundImage = `url('${tech.tech[choose].url}')`
// }
// }, 1);
// }
// return `<div id = "junk-${choose}" class="choose-grid-module card-background" onclick="${click}" onauxclick="${click}"${style}>
// <div class="card-text">
// <div class="grid-title"><div class="circle-grid junk"></div> &nbsp; ${tech.tech[choose].name} ${techCountText}</div>
// ${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}</div></div>`
// },
junkTechText(choose, click) {
const techCountText = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count + 1}x)` : "";
const style = localSettings.isHideImages ? powerUps.hideStyle : `style="background-size: contain;background-repeat: no-repeat;background-image: url('img/junk.webp');"`
@@ -1249,7 +1256,7 @@ const powerUps = {
for (let i = 0, len = powerUps.retainList.length; i < len; i++) {
//find index from name and add tech to options
for (let j = 0, len = tech.tech.length; j < len; j++) {
if (tech.tech[j].name === powerUps.retainList[i] && tech.tech[j].count < tech.tech[j].maxCount && tech.tech[j].allowed()) { //&& !tech.tech[j].isRecentlyShown
if (tech.tech[j].name === powerUps.retainList[i] && tech.tech[j].count < tech.tech[j].maxCount && tech.tech[j].allowed() && tech.tech[j].frequency > 0) { //&& !tech.tech[j].isRecentlyShown
addTech(j)
}
}
@@ -1276,7 +1283,7 @@ const powerUps = {
//this flag prevents this option from being shown the next time you pick up a tech power up
//check if not extra choices from "path integral"
tech.tech[choose].isRecentlyShown = true
if (tech.isRetain) powerUps.retainList.push(tech.tech[choose].name)
if (tech.isRetain && !powerUps.retainList.includes(tech.tech[choose].name)) powerUps.retainList.push(tech.tech[choose].name)
addTech(choose)
}
}
@@ -1504,7 +1511,7 @@ const powerUps = {
} else {
powerUpChance()
}
if (simulation.difficultyMode < 4) {//don't spawn second power up on difficulties with a second boss
if (simulation.difficultyMode < 3) {//don't spawn second power up on difficulties with a second boss
powerUpChance()
}
function powerUpChance() {
@@ -1550,7 +1557,6 @@ const powerUps = {
}
},
addResearchToLevel() { //add a random power up to a location that has a mob, mostly used to give each level a research
// if (simulation.difficultyMode < 4 && mob.length) { //don't spawn on higher difficulty settings
if ((level.levelsCleared < 17 - simulation.difficultyMode * 3) && mob.length) { //don't spawn late game
const index = Math.floor(Math.random() * mob.length)
powerUps.spawn(mob[index].position.x, mob[index].position.y, "research");
@@ -1558,7 +1564,7 @@ const powerUps = {
},
spawnStartingPowerUps(x, y) { //used for map specific power ups, mostly to give player a starting gun
if (level.levelsCleared < 4) { //runs on first 4 levels on all difficulties
if (level.levelsCleared > 1 && simulation.difficultyMode < 6) powerUps.spawn(x, y, "tech")
if (level.levelsCleared > 1 && simulation.difficultyMode < 7) powerUps.spawn(x, y, "tech")
if (b.inventory.length === 0) {
powerUps.spawn(x, y, "gun", false); //first gun
} else if (tech.totalCount === 0) { //first tech
@@ -1638,7 +1644,7 @@ const powerUps = {
// }
tech.tech[index].frequency = 0 //banish tech
powerUps.ejectTech(index)
if (m.immuneCycle < m.cycle) m.damage(tech.pauseEjectTech * 0.01)
if (m.immuneCycle < m.cycle) m.damage(tech.pauseEjectTech * 0.01, false)
tech.pauseEjectTech *= 1.3
document.getElementById(`${index}-pause-tech`).style.textDecoration = "line-through"
document.getElementById(`${index}-pause-tech`).style.animation = ""

View File

@@ -431,48 +431,6 @@ const simulation = {
}
}
document.getElementById("right-HUD").innerHTML = text
// let text = ""
// if (simulation.difficultyMode > 2 && level.constraintDescription1) {
// text += `<span class='constraint'>${level.constraintDescription1}</span>`
// // text += `${level.constraintDescription1}`
// }
// if (simulation.difficultyMode > 4 && level.constraintDescription2) {
// text += `<br><span class='constraint'>${level.constraintDescription2}</span>`
// }
// for (let i = 0, len = tech.tech.length; i < len; i++) { //add tech
// if (tech.tech[i].isLost) {
// if (text) text += "<br>" //add a new line, but not on the first line
// text += `<span style="text-decoration: line-through;">${tech.tech[i].name}</span>`
// } else if (tech.tech[i].count > 0 && !tech.tech[i].isInstant) {
// if (text) text += "<br>" //add a new line, but not on the first line
// text += tech.tech[i].name
// if (tech.tech[i].count > 1) text += ` (${tech.tech[i].count}x)`
// }
// }
// document.getElementById("right-HUD").innerHTML = text
// let constraints = ""
// if (simulation.difficultyMode > 2 && level.constraintDescription1) {
// constraints += `<span class='constraint' style="opacity: 0.35;">${level.constraintDescription1}</span>`
// // text += `${level.constraintDescription1}`
// }
// if (simulation.difficultyMode > 4 && level.constraintDescription2) {
// constraints += `<br><span class='constraint' style="opacity: 0.35;">${level.constraintDescription2}</span>`
// }
// let text = ""
// for (let i = 0, len = tech.tech.length; i < len; i++) { //add tech
// if (tech.tech[i].isLost) {
// if (text) text += "<br>" //add a new line, but not on the first line
// text += `<span style="text-decoration: line-through;">${tech.tech[i].name}</span>`
// } else if (tech.tech[i].count > 0 && !tech.tech[i].isInstant) {
// if (text) text += "<br>" //add a new line, but not on the first line
// text += tech.tech[i].name
// if (tech.tech[i].count > 1) text += ` (${tech.tech[i].count}x)`
// }
// }
// document.getElementById("right-HUD").innerHTML = constraints + `<div class="right-HUD-tech">` + text + `</div>`
},
lastLogTime: 0,
isTextLogOpen: true,
@@ -585,6 +543,97 @@ const simulation = {
})
}
},
isInvertedVertical: false,
flipCameraVertical(frames = 1, passFunction = () => { }) {
if (!simulation.isInvertedVertical) {
if (frames > 0) {
let count = 0
const loop = () => {
if (m.alive) {
if (simulation.paused) {
requestAnimationFrame(loop);
} else {
count++
ctx.setTransform(1, 0, 0, 1, 0, 0); ///reset to avoid build up of transformations
if (count === frames) {
// Flip the canvas vertically
ctx.translate(0, canvas.height); // Move the origin down to the bottom
ctx.scale(1, -1); // Flip vertically
simulation.isInvertedVertical = true
//flip mouse Y again to make sure it caught
mouseMove = function (e) {
simulation.mouse.x = e.clientX;
simulation.mouse.y = window.innerHeight - e.clientY;
}
} else {
requestAnimationFrame(loop);
ctx.translate(0, canvas.height * count / frames);
ctx.scale(1, 1 - 2 * count / frames);
}
if (count === Math.floor(frames / 2)) {
//flip mouse Y at the 1/2 way point
mouseMove = function (e) {
simulation.mouse.x = e.clientX;
simulation.mouse.y = window.innerHeight - e.clientY;
}
//passFunction probably flips the map elements
passFunction()
}
}
}
}
requestAnimationFrame(loop);
} else {
// Flip the canvas vertically
ctx.translate(0, canvas.height); // Move the origin down to the bottom
ctx.scale(1, -1); // Flip vertically
//flip mouse Y
simulation.isInvertedVertical = true
mouseMove = function (e) {
simulation.mouse.x = e.clientX;
simulation.mouse.y = window.innerHeight - e.clientY;
}
}
}
},
unFlipCameraVertical(frames = 0, passFunction = () => { }) {
if (frames) {
let count = 0
const loop = () => {
if (m.alive) {
if (simulation.paused) {
requestAnimationFrame(loop);
} else {
count++
ctx.setTransform(1, 0, 0, 1, 0, 0); ///reset to avoid build up of transformations
if (count === frames) {
// requestAnimationFrame(() => { ctx.reset(); });
// ctx.translate(0, 0);
// ctx.scale(1, 1);
simulation.isInvertedVertical = false
//flip mouse Y again to make sure it caught
mouseMove = mouseMoveDefault
} else {
requestAnimationFrame(loop);
ctx.translate(0, canvas.height - canvas.height * count / frames);
ctx.scale(1, -1 + 2 * count / frames);
}
if (count === Math.floor(frames / 2)) {
mouseMove = mouseMoveDefault//flip mouse Y at the 1/2 way point
passFunction()//passFunction probably draws new map elements
}
}
}
}
requestAnimationFrame(loop);
} else {
ctx.reset();
ctx.font = "25px Arial";
simulation.isInvertedVertical = false
mouseMove = mouseMoveDefault
}
},
translatePlayerAndCamera(where) {
//infinite falling. teleport to sky after falling
const before = { x: player.position.x, y: player.position.y, }
@@ -595,6 +644,7 @@ const simulation = {
m.transY += change.y
simulation.mouseInGame.x = (simulation.mouse.x - canvas.width2) / simulation.zoom * simulation.edgeZoomOutSmooth + canvas.width2 - m.transX;
simulation.mouseInGame.y = (simulation.mouse.y - canvas.height2) / simulation.zoom * simulation.edgeZoomOutSmooth + canvas.height2 - m.transY;
m.angle = Math.atan2(simulation.mouseInGame.y - m.pos.y, simulation.mouseInGame.x - m.pos.x);
//is there a reason to update m.pos here?
@@ -800,6 +850,8 @@ const simulation = {
document.getElementById("pause-grid-left").style.opacity = "1"
ctx.globalCompositeOperation = "source-over"
ctx.shadowBlur = 0;
mouseMove = mouseMoveDefault
requestAnimationFrame(() => {
ctx.setTransform(1, 0, 0, 1, 0, 0); //reset warp effect
ctx.setLineDash([]) //reset stroke dash effect
@@ -812,7 +864,7 @@ const simulation = {
} else {
Composite.add(engine.world, [player])
}
shuffle(level.constraint)
// shuffle(level.constraint)
level.populateLevels()
input.endKeySensing();
simulation.ephemera = []
@@ -993,8 +1045,6 @@ const simulation = {
} else { //get hurt and go to start
Matter.Body.setVelocity(player, { x: 0, y: 0 });
Matter.Body.setPosition(player, { x: level.enter.x + 50, y: level.enter.y - 20 });
// m.damage(0.02 * simulation.difficultyMode);
// m.energy -= 0.02 * simulation.difficultyMode
// move bots
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType) {
@@ -1137,6 +1187,7 @@ const simulation = {
clearMap() {
level.isProcedural = false;
level.fallMode = "";
simulation.unFlipCameraVertical()
ctx.setTransform(1, 0, 0, 1, 0, 0);
if (m.alive) {
if (tech.isLongitudinal) b.guns[3].waves = []; //empty array of wave bullets
@@ -1199,6 +1250,7 @@ const simulation = {
m.drop();
m.hole.isOn = false;
simulation.drawList = [];
mobs.maxMobBody = 40
if (tech.isHealAttract && m.alive) { //send health power ups to the next level
let healCount = 0

View File

@@ -48,7 +48,7 @@ const spawn = {
// spawn.pickList.push(spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]);
},
spawnChance(chance) {
const difficultyChance = simulation.difficultyMode === 1 ? 1 : simulation.difficulty
const difficultyChance = (simulation.difficultyMode === 1) ? 1 : simulation.difficulty
return (Math.random() < chance + 0.07 * difficultyChance) && (mob.length < -1 + 16 * Math.log10(simulation.difficulty + 1))
},
randomMob(x, y, chance = 1) {
@@ -114,7 +114,7 @@ const spawn = {
}
},
secondaryBossChance(x, y) {
if (simulation.difficultyMode > 3 && level.levelsCleared > 1) {
if (simulation.difficultyMode > 2 && level.levelsCleared > 1) {
spawn.randomLevelBoss(x, y);
powerUps.directSpawn(x - 30, y, "ammo");
powerUps.directSpawn(x + 30, y, "ammo");
@@ -977,7 +977,7 @@ const spawn = {
if (!simulation.paused && !simulation.onTitlePage) {
count++
if (count < 660) {
if (count === 1 && simulation.difficultyMode < 5) simulation.inGameConsole(`<em>//enter testing mode to set level.levels.length to <strong>Infinite</strong></em>`);
if (count === 1 && simulation.difficultyMode < 6) simulation.inGameConsole(`<em>//enter testing mode to set level.levels.length to <strong>Infinite</strong></em>`);
if (!(count % 60)) simulation.inGameConsole(`simulation.analysis <span class='color-symbol'>=</span> ${((count / 60 - Math.random()) * 0.1).toFixed(3)}`);
} else if (count === 660) {
simulation.inGameConsole(`simulation.analysis <span class='color-symbol'>=</span> 1 <em>//analysis complete</em>`);
@@ -2966,6 +2966,16 @@ const spawn = {
requestAnimationFrame(() => {
requestAnimationFrame(() => {
ctx.setTransform(1, 0, 0, 1, 0, 0); //reset warp effect
if (simulation.isInvertedVertical) { //redo vertical camera effects
ctx.translate(0, canvas.height); // Move the origin down to the bottom
ctx.scale(1, -1); // Flip vertically
//flip mouse Y
simulation.isInvertedVertical = true
mouseMove = function (e) {
simulation.mouse.x = e.clientX;
simulation.mouse.y = window.innerHeight - e.clientY;
}
}
ctx.setLineDash([]) //reset stroke dash effect
})
})
@@ -4647,7 +4657,7 @@ const spawn = {
if (simulation.cycle % this.laserInterval > this.laserInterval / 2) {
const seeRange = 8000;
best = {
let best = {
x: null,
y: null,
dist2: Infinity,

View File

@@ -349,7 +349,7 @@ const tech = {
},
tech: [{
name: "tungsten carbide",
description: "<strong>+400</strong> maximum <strong class='color-h'>health</strong><br><strong>lose</strong> <strong class='color-h'>health</strong> after hard <strong>landings</strong>",
description: "<strong>+500</strong> maximum <strong class='color-h'>health</strong><br><strong>lose</strong> <strong class='color-h'>health</strong> after hard <strong>landings</strong>",
maxCount: 1,
count: 0,
frequency: 1,
@@ -362,7 +362,7 @@ const tech = {
effect() {
tech.isFallingDamage = true;
m.setMaxHealth();
m.addHealth(3 / simulation.healScale)
m.addHealth(5 / simulation.healScale)
m.skin.tungsten()
},
remove() {
@@ -535,8 +535,13 @@ const tech = {
remove() {
if (this.count > 0) {
tech.isEnergyHealth = false;
if (tech.isEnergyHealth) {
document.getElementById("health").style.display = "none"
document.getElementById("health-bg").style.display = "none"
} else if (!level.isHideHealth) {
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)"
@@ -878,7 +883,7 @@ const tech = {
},
requires: "at least 2 guns",
effect() {
const delay = 20
const delay = 30
let i = (b.inventory.length) * delay
let gunIndex = -1
let cycle = () => {
@@ -3325,7 +3330,7 @@ const tech = {
{
name: "quenching",
descriptionFunction() {
return `<strong>0.3x</strong> of ${powerUps.orb.heal()} over<strong class='color-h'>healing</strong><br>is added to <strong>maximum</strong> <strong class='color-h'>health</strong>`
return `<strong>0.4x</strong> of ${powerUps.orb.heal()} over<strong class='color-h'>healing</strong><br>is added to <strong>maximum</strong> <strong class='color-h'>health</strong>`
},
maxCount: 1,
count: 0,
@@ -10699,6 +10704,24 @@ const tech = {
},
remove() { }
},
{
name: "the upside down",
description: `Flip the universe until the end of the level.<br>I'll give you 1.1x <strong class='color-d'>damage</strong> as well.`,
maxCount: 1,
count: 0,
frequency: 0,
isInstant: true,
isJunk: true,
allowed() {
return true
},
requires: "",
effect() {
simulation.flipCameraVertical(900)
tech.damage *= 1.1
},
remove() { }
},
{
name: "rewind",
description: "every 10 seconds <strong class='color-rewind'>rewind</strong> <strong>2</strong> seconds",
@@ -11134,6 +11157,46 @@ const tech = {
},
remove() { }
},
{
name: "pet bots",
description: "pet your <strong class='color-bot'>bots</strong>",
maxCount: 1,
count: 0,
frequency: 0,
isJunk: true,
isInstant: true,
allowed() {
return b.totalBots()
},
requires: "",
effect() {
simulation.ephemera.push({
name: "pet",
count: 0,
do() {
this.count++
if (!(this.count % 420)) {
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType && Math.random() < 0.3) {
simulation.inGameConsole(`${bullet[i].botType}<span class='color-symbol'>-</span>bot.pet<span class='color-symbol'>()</span>`)
if (m.onGround && !m.crouch) {
m.yOffGoal = m.yOffWhen.crouch;
setTimeout(() => {
if (!m.crouch) m.yOffGoal = m.yOffWhen.stand;
}, 1000);
if (m.immuneCycle < m.cycle + 90) m.immuneCycle = m.cycle + 90
}
if (Math.random() < 0.3) break
}
}
}
}
})
},
remove() {
}
},
{
name: "assimilation",
description: "all your <strong class='color-bot'>bots</strong> are converted to the <strong>same</strong> random model",

View File

@@ -1561,12 +1561,13 @@ summary {
.far-right-column {
display: grid;
grid-template-rows: repeat(6, 1fr);
grid-template-rows: repeat(7, 1fr);
font-size: 2rem;
font-family: monospace;
align-self: center;
justify-self: center;
width: 22px;
/* padding: 0rem; */
}
.far-right-column>div {
@@ -1575,19 +1576,20 @@ summary {
#difficulty-slider {
margin-top: 2.3rem;
height: 26.3rem;
/* height: 26.3rem; */
height: 31.4rem;
width: 2rem;
writing-mode: vertical-lr;
direction: ltr;
}
.left-column {
grid-row: 1 / span 6
grid-row: 1 / span 7
}
.right-column {
display: grid;
grid-template-rows: repeat(6, 1fr);
grid-template-rows: repeat(7, 1fr);
/* to adjust the width of this column edit the "gridTemplateColumns" in the difficulty power up js code*/
}
@@ -1630,6 +1632,10 @@ summary {
#constraint-6 {
background-color: hsl(240, 18%, 77%);
}
#constraint-7 {
background-color: hsl(240, 18%, 73%);
border-radius: 0 0 7px 7px;
}
@@ -1669,6 +1675,12 @@ summary {
padding: 9px;
}
#constraint-7:hover {
background-color: hsl(240, 18%, 71%);
border: 1px #444 solid;
padding: 9px;
}
#choose-difficulty {
text-align: center;
font-size: 1.1em;

110
todo.txt
View File

@@ -1,24 +1,32 @@
******************************************************** NEXT PATCH **************************************************
subway
2 new subway stations
more visible button graphics on subway
new level testChamber2
New camera flip effect
new laser level element now has collisions with blocks
elevators are less deadly to mobs at low speeds
new constraints
no health bars
no pause while choosing
difficulty level progression reworked
no constraints on final boss
new constraint - healing disabled
tech: coherence - past choices are added to all future tech
requires decoherence
research and cancel buttons have a sticky scroll positioning
eternalism: you can't pause while choosing, but you can otherwise pause now
1.25->1.3 damage
quenching 0.3->0.4x overheal converted to max health
tungsten carbide 400->500 extra max health
paradigm shift's health loss is no longer reduced by damage taken reduction
coherence no longer remembers tech that is set to zero frequency, like removed tech
bugs
MIRV missiles now interact with time dilation properly
JUNK tech: pet the bot - lets you pet your bots
JUNK tech: the upside down - flip everything
bug
prevented possible duplicate choices with coherence tech
fixed issues with showing and hiding health bars on that constraint
fixed crash from autonomous defense
mass-energy mode wasn't getting any benefit from damage taken reduction
it now gets square root of damage taken reduction
******************************************************** BUGS ********************************************************
figure out why seeded random isn't making runs the same:
shuffle is being used for a wide variety of things that don't need a seeded random
make two shuffle functions?
@@ -47,30 +55,36 @@ player can become crouched while not touching the ground if they exit the ground
*********************************************************** TODO *****************************************************
new level based laser element
!!update new version into other levels
level technique: pairs of touch activated elevators jump on one to get high enough to jump on the next one
flip player upside down
fieldTech: negative mass?
JUNK tech?
final boss effect
maybe just flip player camera and mouse
level effect flip map vertically also
new subway station
new full level
needs a device that will flip gravity
update to old level so it is more surreal
levels with few effects, just blocks and map
levels with a roof or infinite fall
towers, lab
constraints should show future constraints in pause menu
pre calculate all constraints for up to 13 levels?
loop constraints after that
procedural animation
https://www.youtube.com/watch?v=qlfh_rv6khY
maybe no constraints on final boss and reactor?
constraints balance
40% JUNK chance
-1 choice
no health bars
4x shielded mob chance
+33% chance for mobs to respawn
2x ammo costs
too hard
0 duplication
power ups in stasis
0.1x damage after a power up
0.5x energy regen
50% max energy
50% max health
bots follow slow
periodically spawn WIMPs
mob death heals mobs
mobs heal for your lost health
not implemented random constraint ideas________________________
mob death spawns something
mob bullets
@@ -83,22 +97,11 @@ not implemented random constraint ideas________________________
can't have more then 15 bullets
how to code?
remove 2 random tech and return them next level
too niche
player damage is 0.25x while player is invulnerable
all hazards: lasers and slime do 3x damage
player lasers and radiation do 0.5x damage
explosions do 0.5x damage
freeze effects last 0.25x time
tech: ice-VII - 1.5x duration for ice-IX
tech: - freezing grenades/explosions
tech: - randomize constraints somehow
in pause interface or power up selection menu?
each time you research the current constraints also randomize?
only allowed if difficulty is high enough
tech: - when you get a bot, get a second bot
tech: - after killing a Boss
@@ -107,8 +110,6 @@ tech: - after killing a Boss
new level - rework testChamber
skin with wheel instead of legs
Boss (or mob) that quickly moves towards player, but they moves perpendicularly to player, like dodging
could respond to when player presses fire key or to when it takes damage
@@ -155,9 +156,6 @@ increase mass and movement speed at the same time
possible player.mass bad interactions
grapple
JUNK tech - player takes damage from block collisions
is this gonna contribute to lag?
bullets should trigger shrinking platforms level element?
level element - player activated elevators
@@ -167,18 +165,6 @@ level element - player activated elevators
rework energy and health HUD
make both diegetic?
how? not sure there is a good way to do this...
should health be red or green?
flip player upside down
how
rotate player in matter.js
make sure floor sensor works
flip player crouch direction
redraw legs, orb
flip gravity
when to use?
fieldTech: negative mass?
effect in level
tech - after a power up is duplicated
update text to random effect after choosing tech, or after each trigger, or on first display of tech