`
document.getElementById("choose-grid").innerHTML = text
//show level info
document.getElementById("choose-grid").style.opacity = "1"
document.getElementById("choose-grid").style.transitionDuration = "0.25s"; //how long is the fade in on
document.getElementById("choose-grid").style.visibility = "visible"
-
+ // }
simulation.draw.cons();
simulation.draw.body();
level.customTopLayer();
@@ -386,37 +667,6 @@ const level = {
}
requestAnimationFrame(newLevelDraw);
}
- // else {
- // //pause
- // if (!simulation.paused) {
- // simulation.paused = true;
- // simulation.isChoosing = true; //stops p from un pausing on key down
- // }
- // let count = countMax = simulation.testing ? 0 : 60
- // let newLevelDraw = () => {
- // count--
- // if (count > 0) {
- // requestAnimationFrame(newLevelDraw);
- // } else { //unpause
- // // if (m.immuneCycle < m.cycle + 15) m.immuneCycle = m.cycle + 30; //player is immune to damage for 30 cycles
- // if (simulation.paused) requestAnimationFrame(cycle);
- // if (m.alive) simulation.paused = false;
- // simulation.isChoosing = false; //stops p from un pausing on key down
- // build.unPauseGrid()
- // }
- // //draw
- // simulation.wipe();
- // m.look();
- // simulation.camera();
- // const scale = 30
- // ctx.setLineDash([scale * (countMax - count), scale * count]);
- // simulation.draw.wireFrame();
- // ctx.setLineDash([]);
- // ctx.restore();
- // simulation.drawCursor();
- // }
- // requestAnimationFrame(newLevelDraw);
- // }
}
},
unPause() {
@@ -515,21 +765,6 @@ const level = {
level.exit.x = -level.exit.x - 100 //minus the 100 because of the width of the graphic
},
exitCount: 0,
- // playerExitCheck() {
- // if (
- // player.position.x > level.exit.x &&
- // player.position.x < level.exit.x + 100 &&
- // player.position.y > level.exit.y - 150 &&
- // player.position.y < level.exit.y - 40 &&
- // player.velocity.y < 0.1
- // ) {
- // level.exitCount++
- // if (level.exitCount > 120) {
- // level.exitCount = 0
- // level.nextLevel()
- // }
- // }
- // },
setPosToSpawn(xPos, yPos) {
m.spawnPos.x = m.pos.x = xPos;
m.spawnPos.y = m.pos.y = yPos;
@@ -626,7 +861,7 @@ const level = {
let text = `
training
- Begin the guided tutorial that shows you how to use your ${powerUps.field()} and ${powerUps.orb.gun()}.
+ Begin the guided tutorial that shows you how to use your ${powerUps.orb.field()} and ${powerUps.orb.gun()}.
@@ -434,7 +434,7 @@ const powerUps = {
}
});
- let setConstraintText = function (isReset = true) {
+ let setDifficultyText = function (isReset = true) {
for (let i = 1; i < 7; i++) {
const id = document.getElementById("constraint-" + i)
if (simulation.difficultyMode < i) {
@@ -451,17 +451,19 @@ const powerUps = {
if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
}
}
- setConstraintText(false)
+ setDifficultyText(false)
document.getElementById("difficulty-slider").value = simulation.difficultyMode
document.getElementById("difficulty-slider").addEventListener("input", () => {
simulation.difficultyMode = document.getElementById("difficulty-slider").value
- setConstraintText()
+ setDifficultyText()
+ level.setConstraints()
});
for (let i = 1; i < 7; i++) {
document.getElementById("constraint-" + i).addEventListener("click", () => {
simulation.difficultyMode = i
document.getElementById("difficulty-slider").value = simulation.difficultyMode
- setConstraintText()
+ setDifficultyText()
+ level.setConstraints()
});
}
},
@@ -503,17 +505,38 @@ const powerUps = {
damage: null, //set by "tech: band gap"
effect() {
powerUps.animatePowerUpGrab('rgba(255, 0, 0, 0.5)')
- powerUps.boost.endCycle = m.cycle + Math.floor(Math.max(0, powerUps.boost.endCycle - m.cycle) * 0.6) + powerUps.boost.duration //duration+seconds plus 2/3 of current time left
+ powerUps.boost.endCycle = simulation.cycle + Math.floor(Math.max(0, powerUps.boost.endCycle - simulation.cycle) * 0.6) + powerUps.boost.duration //duration+seconds plus 2/3 of current time left
},
draw() {
// console.log(this.endCycle)
- if (powerUps.boost.endCycle > m.cycle) {
- ctx.strokeStyle = "rgba(255,0,0,0.8)" //m.fieldMeterColor; //"rgba(255,255,0,0.2)" //ctx.strokeStyle = `rgba(0,0,255,${0.5+0.5*Math.random()})`
+ // if (powerUps.boost.endCycle > m.cycle) {
+ // ctx.strokeStyle = "rgba(255,0,0,0.8)" //m.fieldMeterColor; //"rgba(255,255,0,0.2)" //ctx.strokeStyle = `rgba(0,0,255,${0.5+0.5*Math.random()})`
+ // ctx.beginPath();
+ // const arc = (powerUps.boost.endCycle - m.cycle) / powerUps.boost.duration
+ // ctx.arc(m.pos.x, m.pos.y, 28, m.angle - Math.PI * arc, m.angle + Math.PI * arc); //- Math.PI / 2
+ // ctx.lineWidth = 4
+ // ctx.stroke();
+ // }
+
+ if (powerUps.boost.endCycle > simulation.cycle) {
+ //gel that acts as if the wind is blowing it when player moves
+ ctx.save();
+ ctx.translate(m.pos.x, m.pos.y);
+ m.velocitySmooth = Vector.add(Vector.mult(m.velocitySmooth, 0.8), Vector.mult(player.velocity, 0.2))
+ ctx.rotate(Math.atan2(m.velocitySmooth.y, m.velocitySmooth.x))
ctx.beginPath();
- const arc = (powerUps.boost.endCycle - m.cycle) / powerUps.boost.duration
- ctx.arc(m.pos.x, m.pos.y, 28, m.angle - Math.PI * arc, m.angle + Math.PI * arc); //- Math.PI / 2
- ctx.lineWidth = 4
+ const radius = 40
+ const mag = 8 * Vector.magnitude(m.velocitySmooth) + radius
+ ctx.arc(0, 0, radius, -Math.PI / 2, Math.PI / 2);
+ ctx.bezierCurveTo(-radius, radius, -radius, 0, -mag, 0); // bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
+ ctx.bezierCurveTo(-radius, 0, -radius, -radius, 0, -radius);
+ const time = Math.min(0.5, (powerUps.boost.endCycle - simulation.cycle) / powerUps.boost.duration)
+ ctx.fillStyle = `rgba(255,0,200,${time})`
+ ctx.fill()
+ ctx.strokeStyle = "#f09"
+ ctx.lineWidth = 0.3 + 4 * time
ctx.stroke();
+ ctx.restore();
}
},
},
@@ -533,7 +556,7 @@ const powerUps = {
if (amount !== 0) powerUps.research.count += amount
if (tech.isRerollBots && !this.isMakingBots) {
let cycle = () => {
- const cost = 2 + Math.floor(0.2 * b.totalBots())
+ const cost = 2 + Math.floor(0.25 * b.totalBots())
if (m.alive && powerUps.research.count >= cost) {
requestAnimationFrame(cycle);
this.isMakingBots = true
@@ -647,7 +670,7 @@ const powerUps = {
// });
} else if (overHeal > 0.13) { //if leftover heals spawn a new spammer heal power up
requestAnimationFrame(() => {
- powerUps.directSpawn(this.position.x, this.position.y, "heal", true, null, Math.min(1, overHeal) * 40 * (simulation.healScale ** 0.25))// directSpawn(x, y, target, moving = true, mode = null, size = powerUps[target].size()) {
+ powerUps.directSpawn(this.position.x, this.position.y, "heal", true, Math.min(1, overHeal) * 40 * (simulation.healScale ** 0.25))// directSpawn(x, y, name, moving = true, mode = null, size = powerUps[name].size()) {
});
}
if (tech.isHealBrake) {
@@ -699,9 +722,9 @@ const powerUps = {
}
},
spawn(x, y, size) { //used to spawn a heal with a specific size / heal amount, not normally used
- powerUps.directSpawn(x, y, "heal", false, null, size)
- if (Math.random() < tech.duplicationChance()) {
- powerUps.directSpawn(x, y, "heal", false, null, size)
+ powerUps.directSpawn(x, y, "heal", false, size)
+ if (!level.isNextLevelPowerUps && Math.random() < tech.duplicationChance()) {
+ powerUps.directSpawn(x, y, "heal", false, size)
powerUp[powerUp.length - 1].isDuplicated = true
}
}
@@ -717,22 +740,22 @@ const powerUps = {
if (b.inventory.length > 0) {
powerUps.animatePowerUpGrab('rgba(68, 102, 119,0.25)')
if (tech.isAmmoForGun && b.activeGun !== null) { //give extra ammo to one gun only with tech logistics
- const target = b.guns[b.activeGun]
- if (target.ammo !== Infinity) {
+ const name = b.guns[b.activeGun]
+ if (name.ammo !== Infinity) {
if (tech.ammoCap) {
- target.ammo = Math.ceil(2 * target.ammoPack * tech.ammoCap * couplingExtraAmmo)
+ name.ammo = Math.ceil(2 * name.ammoPack * tech.ammoCap * couplingExtraAmmo)
} else {
- target.ammo += Math.ceil(2 * (Math.random() + Math.random()) * target.ammoPack * couplingExtraAmmo)
+ name.ammo += Math.ceil(2 * (Math.random() + Math.random()) * name.ammoPack * couplingExtraAmmo)
}
}
} else { //give ammo to all guns in inventory
for (let i = 0, len = b.inventory.length; i < len; i++) {
- const target = b.guns[b.inventory[i]]
- if (target.ammo !== Infinity) {
+ const name = b.guns[b.inventory[i]]
+ if (name.ammo !== Infinity) {
if (tech.ammoCap) {
- target.ammo = Math.ceil(target.ammoPack * tech.ammoCap * couplingExtraAmmo)
+ name.ammo = Math.ceil(name.ammoPack * tech.ammoCap * couplingExtraAmmo)
} else { //default ammo behavior
- target.ammo += Math.ceil((Math.random() + Math.random()) * target.ammoPack * couplingExtraAmmo)
+ name.ammo += Math.ceil((Math.random() + Math.random()) * name.ammoPack * couplingExtraAmmo)
}
}
}
@@ -844,9 +867,9 @@ const powerUps = {
gunText(choose, click) {
const style = localSettings.isHideImages ? powerUps.hideStyle : `style="background-image: url('img/gun/${b.guns[choose].name}.webp');"`
return `
-
-
${b.guns[choose].name}
- ${b.guns[choose].descriptionFunction()}
`
+
+
${b.guns[choose].name}
+ ${b.guns[choose].descriptionFunction()}
`
},
fieldText(choose, click) {
const style = localSettings.isHideImages ? powerUps.hideStyle : `style="background-image: url('img/field/${m.fieldUpgrades[choose].name}${choose === 0 ? Math.floor(Math.random() * 10) : ""}.webp');"`
@@ -1034,13 +1057,13 @@ const powerUps = {
}
// console.log(options.length)
if (options.length > 0 || !tech.isSuperDeterminism) {
- let totalChoices = 2 + tech.extraChoices + 3 * (m.fieldMode === 8)
+ let totalChoices = 2 + tech.extraChoices + 3 * (m.fieldMode === 8) - level.fewerChoices
if (tech.isCancelTech && tech.cancelTechCount === 1) {
totalChoices *= 3
tech.cancelTechCount++
}
if (tech.isDeterminism) totalChoices = 1
- totalChoices = Math.min(options.length, totalChoices)
+ totalChoices = Math.min(totalChoices, options.length)
function removeOption(index) {
for (let i = 0; i < options.length; i++) {
if (options[i] === index) {
@@ -1101,13 +1124,13 @@ const powerUps = {
for (let i = 1; i < m.fieldUpgrades.length; i++) { //skip field emitter
if (i !== m.fieldMode) options.push(i);
}
- let totalChoices = 2 + tech.extraChoices + 3 * (m.fieldMode === 8)
+ let totalChoices = 2 + tech.extraChoices + 3 * (m.fieldMode === 8) - level.fewerChoices
if (tech.isCancelTech && tech.cancelTechCount === 1) {
totalChoices *= 3
tech.cancelTechCount++
}
if (tech.isDeterminism) totalChoices = 1
- totalChoices = Math.min(options.length, totalChoices)
+ totalChoices = Math.max(1, Math.min(totalChoices, options.length))
function removeOption(index) {
for (let i = 0; i < options.length; i++) {
if (options[i] === index) {
@@ -1181,13 +1204,13 @@ const powerUps = {
}
}
//set total choices
- let totalChoices = 3 + tech.extraChoices + 3 * (m.fieldMode === 8)
+ let totalChoices = 3 + tech.extraChoices + 3 * (m.fieldMode === 8) - level.fewerChoices
if (tech.isCancelTech && tech.cancelTechCount === 1) {
totalChoices *= 3
tech.cancelTechCount++
}
if (tech.isDeterminism) totalChoices = 1
- totalChoices = Math.min(options.length, totalChoices)
+ totalChoices = Math.max(1, Math.min(totalChoices, options.length))
if (optionLengthNoDuplicates < totalChoices + 1) { //if not enough options for all the choices
totalChoices = optionLengthNoDuplicates
@@ -1220,11 +1243,11 @@ const powerUps = {
const choose = options[Math.floor(Math.seededRandom(0, options.length))] //pick an element from the array of options
if (tech.isBanish) {
tech.tech[choose].isBanished = true
- if (i === 0) simulation.inGameConsole(`options.length = ${optionLengthNoDuplicates} //tech removed from pool by decoherence`)
+ if (i === 0) simulation.inGameConsole(`options.length = ${optionLengthNoDuplicates} //removed from pool by decoherence`)
}
removeOption(choose) //move from future options pool to avoid repeats on this selection
tech.tech[choose].isRecentlyShown = true //this flag prevents this option from being shown the next time you pick up a tech power up
- if (Math.random() < tech.junkChance) { // choose is set to a random JUNK tech
+ if (Math.random() < tech.junkChance + level.junkAdded) { // choose is set to a random JUNK tech
const list = []
for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].isJunk) list.push(i)
@@ -1433,6 +1456,7 @@ const powerUps = {
b.mine(who.position, { x: 0, y: 0 }, 0)
}
}
+ if (level.isNoDamage) level.noDamageCycle = m.cycle
},
spawnRandomPowerUp(x, y) { //mostly used after mob dies, doesn't always return a power up
if (!tech.isEnergyHealth && (Math.random() * Math.random() - 0.3 > Math.sqrt(m.health)) || Math.random() < 0.04) { //spawn heal chance is higher at low health
@@ -1447,10 +1471,6 @@ const powerUps = {
powerUps.spawn(x, y, "gun");
return;
}
- // if (Math.random() < 0.005 * (10 - level.levelsCleared)) { //a new tech has a low chance that decreases in later levels
- // powerUps.spawn(x, y, "tech");
- // return;
- // }
if (Math.random() < 0.0016) {
powerUps.spawn(x, y, "field");
return;
@@ -1459,35 +1479,28 @@ const powerUps = {
powerUps.spawn(x, y, "coupling");
return;
}
- if (tech.isBoostPowerUps && Math.random() < 0.14) {
+ if (Math.random() < 0.02 || (tech.isBoostPowerUps && Math.random() < 0.14)) {
powerUps.spawn(x, y, "boost");
return;
}
- // if (Math.random() < 0.01) {
- // powerUps.spawn(x, y, "research");
- // return;
- // }
},
randomPowerUpCounter: 0,
isFieldSpawned: false, //makes it so a field spawns once but not more times
spawnBossPowerUp(x, y) { //boss spawns field and gun tech upgrades
if (level.levels[level.onLevel] !== "final") {
- // if (level.levelsCleared === 1) powerUps.spawn(x, y, "field")
- // if (m.fieldMode === 0 && !m.coupling) {
if (!powerUps.isFieldSpawned) {
powerUps.isFieldSpawned = true
powerUps.spawn(x, y, "field")
} else {
- powerUps.randomPowerUpCounter++;
- powerUpChance(Math.max(level.levelsCleared, 10) * 0.1)
+ powerUpChance()
}
- if (!(simulation.difficultyMode > 2 && level.levelsCleared > 1)) {
- powerUps.randomPowerUpCounter += 0.6;
- powerUpChance(Math.max(level.levelsCleared, 6) * 0.1)
+ if (simulation.difficultyMode < 4) {//don't spawn second power up on difficulties with a second boss
+ powerUpChance()
}
- function powerUpChance(chanceToFail) {
- if (Math.random() * chanceToFail < powerUps.randomPowerUpCounter) {
- powerUps.randomPowerUpCounter = 0;
+ function powerUpChance() {
+ powerUps.randomPowerUpCounter++
+ if (powerUps.randomPowerUpCounter > Math.max(level.levelsCleared, 9) * 0.1 * Math.random()) {
+ powerUps.randomPowerUpCounter = 0; //reset odds
if (Math.random() < 0.97) {
powerUps.spawn(x, y, "tech")
} else {
@@ -1528,14 +1541,14 @@ 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 < 13 - simulation.difficultyMode * 2 && mob.length) { //don't spawn late game
+ 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");
}
},
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) powerUps.spawn(x, y, "tech")
+ if (level.levelsCleared > 1 && simulation.difficultyMode < 6) 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
@@ -1574,7 +1587,6 @@ const powerUps = {
for (let i = 0; i < tech.tech[choose].count; i++) {
powerUps.directSpawn(m.pos.x, m.pos.y, "tech");
- // powerUp[powerUp.length - 1].isDuplicated = true
}
// remove a random tech from the list of tech you have
tech.removeCount += tech.tech[choose].count
@@ -1593,7 +1605,6 @@ const powerUps = {
for (let i = 0; i < tech.tech[choose].count; i++) {
powerUps.directSpawn(m.pos.x, m.pos.y, "tech");
- // powerUp[powerUp.length - 1].isDuplicated = true
}
// remove a random tech from the list of tech you have
tech.tech[choose].remove();
@@ -1675,7 +1686,28 @@ const powerUps = {
powerUp.splice(index, 1);
}
},
- directSpawn(x, y, target, moving = true, mode = null, size = powerUps[target].size(), isDuplicated = false) {
+ spawn(x, y, name, moving = true, size = powerUps[name].size()) {
+ if (
+ (!tech.isSuperDeterminism || (name !== 'research')) &&
+ !(tech.isEnergyNoAmmo && name === 'ammo')
+ ) {
+ if (tech.isBoostReplaceAmmo && name === 'ammo') {
+ name = 'boost'
+ size = powerUps[name].size()
+ }
+ powerUps.directSpawn(x, y, name, moving, size)
+ if (!level.isNextLevelPowerUps && Math.random() < tech.duplicationChance()) {
+ powerUps.directSpawn(x, y, name, moving, size, true)
+ powerUp[powerUp.length - 1].isDuplicated = true
+ if (tech.isDupEnergy) m.energy *= 2
+ }
+ }
+ },
+ directSpawn(x, y, name, moving = true, size = powerUps[name].size(), isDuplicated = false) {
+ if (level.isNextLevelPowerUps) {
+ powerUps.powerUpStorage.push({ name: name, size: size })
+ return
+ }
let index = powerUp.length;
let properties = {
density: 0.001,
@@ -1686,9 +1718,9 @@ const powerUps = {
category: cat.powerUp,
mask: cat.map | cat.powerUp
},
- color: powerUps[target].color,
- effect: powerUps[target].effect,
- name: powerUps[target].name,
+ color: powerUps[name].color,
+ effect: powerUps[name].effect,
+ name: powerUps[name].name,
size: size
}
let polygonSides
@@ -1700,26 +1732,8 @@ const powerUps = {
polygonSides = 12
}
powerUp[index] = Matter.Bodies.polygon(x, y, polygonSides, size, properties);
- if (mode) powerUp[index].mode = mode
if (moving) Matter.Body.setVelocity(powerUp[index], { x: (Math.random() - 0.5) * 15, y: Math.random() * -9 - 3 });
Composite.add(engine.world, powerUp[index]);
},
- spawn(x, y, target, moving = true, mode = null, size = powerUps[target].size()) {
- if (
- (!tech.isSuperDeterminism || (target !== 'research')) &&
- !(tech.isEnergyNoAmmo && target === 'ammo')
- ) {
- if (tech.isBoostReplaceAmmo && target === 'ammo') {
- target = 'boost'
- size = powerUps[target].size()
- }
- powerUps.directSpawn(x, y, target, moving, mode, size)
- if (Math.random() < tech.duplicationChance()) {
- powerUps.directSpawn(x, y, target, moving, mode, size, true)
- powerUp[powerUp.length - 1].isDuplicated = true
- // if (tech.isPowerUpsVanish) powerUp[powerUp.length - 1].endCycle = simulation.cycle + 300
- if (tech.isDupEnergy) m.energy *= 2
- }
- }
- },
+ powerUpStorage: [],//used when power ups are sent to the next level (for the constraint, level.isNextLevelPowerUps)
};
\ No newline at end of file
diff --git a/js/simulation.js b/js/simulation.js
index 72eb1c7..c991fab 100644
--- a/js/simulation.js
+++ b/js/simulation.js
@@ -419,15 +419,6 @@ const simulation = {
simulation.boldActiveGunHUD();
},
updateTechHUD() {
-
- // tech.tech.sort((a, b) => {
- // console.log(a.cycle, b.cycle)
- // if (a.cycle === undefined && b.cycle !== undefined) return -1;
- // if (a.cycle !== undefined && b.cycle === undefined) return 1;
- // if (a.cycle === undefined && b.cycle === undefined) return 0;
- // if (a.cycle !== b.cycle) return a.cycle - b.cycle;
- // });
-
let text = ""
for (let i = 0, len = tech.tech.length; i < len; i++) { //add tech
if (tech.tech[i].isLost) {
@@ -436,21 +427,55 @@ const simulation = {
} else if (tech.tech[i].count > 0 && !tech.tech[i].isInstant) {
if (text) text += " " //add a new line, but not on the first line
text += tech.tech[i].name
- // if (tech.tech[i].nameInfo) {
- // text += tech.tech[i].nameInfo
- // tech.tech[i].addNameInfo();
- // }
if (tech.tech[i].count > 1) text += ` (${tech.tech[i].count}x)`
}
}
- document.getElementById("tech").innerHTML = text
+ document.getElementById("right-HUD").innerHTML = text
+
+
+ // let text = ""
+ // if (simulation.difficultyMode > 2 && level.constraintDescription1) {
+ // text += `${level.constraintDescription1}`
+ // // text += `${level.constraintDescription1}`
+ // }
+ // if (simulation.difficultyMode > 4 && level.constraintDescription2) {
+ // text += ` ${level.constraintDescription2}`
+ // }
+ // for (let i = 0, len = tech.tech.length; i < len; i++) { //add tech
+ // if (tech.tech[i].isLost) {
+ // if (text) text += " " //add a new line, but not on the first line
+ // text += `${tech.tech[i].name}`
+ // } else if (tech.tech[i].count > 0 && !tech.tech[i].isInstant) {
+ // if (text) text += " " //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 += `${level.constraintDescription1}`
+ // // text += `${level.constraintDescription1}`
+ // }
+ // if (simulation.difficultyMode > 4 && level.constraintDescription2) {
+ // constraints += ` ${level.constraintDescription2}`
+ // }
+ // let text = ""
+ // for (let i = 0, len = tech.tech.length; i < len; i++) { //add tech
+ // if (tech.tech[i].isLost) {
+ // if (text) text += " " //add a new line, but not on the first line
+ // text += `${tech.tech[i].name}`
+ // } else if (tech.tech[i].count > 0 && !tech.tech[i].isInstant) {
+ // if (text) text += " " //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 + `
` + text + `
`
},
lastLogTime: 0,
isTextLogOpen: true,
- //
- // SVGleftMouse: '',
- // SVGrightMouse: '',
inGameConsole(text, time = 240) {
if (!localSettings.isHideHUD && simulation.isTextLogOpen && !build.isExperimentSelection) {
if (simulation.lastLogTime > m.cycle) { //if there is an older message
@@ -757,11 +782,11 @@ const simulation = {
document.getElementById("health").style.display = "inline"
document.getElementById("health-bg").style.display = "inline";
if (!localSettings.isHideHUD) {
- document.getElementById("tech").style.display = "inline"
+ document.getElementById("right-HUD").style.display = "inline"
document.getElementById("defense-bar").style.display = "inline"
document.getElementById("damage-bar").style.display = "inline"
} else {
- document.getElementById("tech").style.display = "none"
+ document.getElementById("right-HUD").style.display = "none"
document.getElementById("defense-bar").style.display = "none"
document.getElementById("damage-bar").style.display = "none"
}
@@ -787,10 +812,11 @@ const simulation = {
} else {
Composite.add(engine.world, [player])
}
+ shuffle(level.constraint)
level.populateLevels()
-
input.endKeySensing();
simulation.ephemera = []
+ powerUps.powerUpStorage = []
tech.setupAllTech(); //sets tech to default values
b.resetAllGuns();
tech.duplication = 0;
@@ -843,6 +869,7 @@ const simulation = {
level.onLevel = 0;
level.levelsCleared = 0;
level.updateDifficulty()
+ // level.setConstraints()
simulation.clearNow = true;
document.getElementById("text-log").style.display = "none"
@@ -948,7 +975,7 @@ const simulation = {
},
})
const before = { x: player.position.x, y: player.position.y, }
- let posXClamped = Math.min(Math.max(level.fallModeBounds.left, player.position.x), level.fallModeBounds.right)
+ const posXClamped = Math.min(Math.max(level.fallModeBounds.left, player.position.x), level.fallModeBounds.right)
Matter.Body.setPosition(player, { x: posXClamped, y: level.enter.y - 4000 });
// translate camera smoothly to preserve illusion to endless fall
@@ -1042,7 +1069,6 @@ const simulation = {
},
})
}
-
if (tech.isZeno) {
if (tech.isEnergyHealth) {
m.energy *= 0.95
@@ -1054,28 +1080,41 @@ const simulation = {
}
if (tech.cyclicImmunity && m.immuneCycle < m.cycle + tech.cyclicImmunity) m.immuneCycle = m.cycle + tech.cyclicImmunity; //player is immune to damage for 60 cycles
- fallCheck = function (who, save = false) {
- let i = who.length;
- while (i--) {
- if (who[i].position.y > simulation.fallHeight) {
- if (save) {
- Matter.Body.setVelocity(who[i], { x: 0, y: 0 });
- Matter.Body.setPosition(who[i], {
- x: level.exit.x + 30 * (Math.random() - 0.5),
- y: level.exit.y + 30 * (Math.random() - 0.5)
- });
- } else {
- Matter.Composite.remove(engine.world, who[i]);
- who.splice(i, 1);
- }
+
+
+ let i = body.length;
+ while (i--) {
+ if (body[i].position.y > simulation.fallHeight) {
+ Matter.Composite.remove(engine.world, body[i]);
+ body.splice(i, 1);
+ }
+ }
+ i = powerUp.length
+ while (i--) {
+ if (powerUp[i].position.y > simulation.fallHeight) {
+ Matter.Body.setVelocity(powerUp[i], { x: 0, y: 0 });
+ if (level.fallMode === "position") {
+ const posXClamped = Math.min(Math.max(level.fallModeBounds.left, powerUp[i].position.x), level.fallModeBounds.right)
+ Matter.Body.setPosition(powerUp[i], { x: posXClamped, y: level.enter.y - 3000 });
+ } else {
+ Matter.Body.setPosition(powerUp[i], {
+ x: level.exit.x + 30 * (Math.random() - 0.5),
+ y: level.exit.y + 30 * (Math.random() - 0.5)
+ });
}
}
- };
- fallCheck(body);
- fallCheck(powerUp, true);
- let i = mob.length;
+ }
+ i = mob.length;
while (i--) {
- if (mob[i].position.y > simulation.fallHeight) mob[i].death();
+ if (mob[i].position.y > simulation.fallHeight) {
+ if (mob[i].isBoss && level.fallMode === "position") {
+ Matter.Body.setVelocity(mob[i], { x: 0, y: 0 });
+ const posXClamped = Math.min(Math.max(level.fallModeBounds.left, mob[i].position.x), level.fallModeBounds.right)
+ Matter.Body.setPosition(mob[i], { x: posXClamped, y: level.enter.y - 3000 });
+ } else {
+ mob[i].death();
+ }
+ }
}
}
diff --git a/js/spawn.js b/js/spawn.js
index 9694499..98f6775 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -114,7 +114,7 @@ const spawn = {
}
},
secondaryBossChance(x, y) {
- if (simulation.difficultyMode > 2 && level.levelsCleared > 2) {
+ if (simulation.difficultyMode > 3 && level.levelsCleared > 1) {
spawn.randomLevelBoss(x, y);
powerUps.directSpawn(x - 30, y, "ammo");
powerUps.directSpawn(x + 30, y, "ammo");
@@ -1014,7 +1014,7 @@ const spawn = {
return
}
}
- if (simulation.testing || simulation.difficultyMode > 4) {
+ if (simulation.testing || simulation.difficultyMode > 5) {
unlockExit()
setTimeout(function () {
simulation.inGameConsole(`level.levels.length =Infinite`);
@@ -2347,7 +2347,7 @@ const spawn = {
ctx.fill();
}
}
- if (simulation.difficultyMode === 6) spawn.shield(me, x, y);
+ if (level.isMobShields) spawn.shield(me, x, y);
},
// timeBoss(x, y, radius = 25) {
// mobs.spawn(x, y, 12, radius, "#000");
@@ -7726,7 +7726,7 @@ const spawn = {
};
},
//chance = Math.min(0.02 + simulation.difficulty * 0.005, 0.2) + tech.duplicationChance()
- shield(target, x, y, chance = (simulation.difficultyMode === 6 ? 3 : 1) * Math.min(0.02 + simulation.difficulty * 0.005, 0.2)) {
+ shield(target, x, y, chance = (level.isMobShields ? 3.25 : 1) * Math.min(0.02 + simulation.difficulty * 0.005, 0.2)) {
if (this.allowShields && Math.random() < chance) {
mobs.spawn(x, y, 9, target.radius + 30, "rgba(220,220,255,0.9)");
let me = mob[mob.length - 1];
@@ -8086,7 +8086,7 @@ const spawn = {
if (this.freeOfWires) {
this.gravity();
} else {
- if (m.pos.x > breakingPoint) {
+ if (m.pos.x > breakingPoint || simulation.isCheating) {
this.freeOfWires = true;
this.fill = "#000"
this.force.x += -0.003;
@@ -8158,7 +8158,7 @@ const spawn = {
if (this.freeOfWires) {
this.gravity();
} else {
- if (m.pos.x > breakingPoint) {
+ if (m.pos.x > breakingPoint || simulation.isCheating) {
this.freeOfWires = true;
this.force.x -= 0.0004;
this.fill = "#222";
@@ -8210,7 +8210,7 @@ const spawn = {
if (this.freeOfWires) {
this.gravity();
} else {
- if (m.pos.x > breakingPoint) {
+ if (m.pos.x > breakingPoint || simulation.isCheating) {
this.freeOfWires = true;
this.force.x += -0.0003;
this.fill = "#333";
@@ -8261,7 +8261,7 @@ const spawn = {
if (this.freeOfWires) {
this.gravity();
} else {
- if (m.pos.x > breakingPoint) {
+ if (m.pos.x > breakingPoint || simulation.isCheating) {
this.freeOfWires = true;
this.force.x += -0.0006;
this.fill = "#111";
@@ -8312,7 +8312,7 @@ const spawn = {
if (this.freeOfWires) {
this.gravity();
} else {
- if (m.pos.x > breakingPoint) {
+ if (m.pos.x > breakingPoint || simulation.isCheating) {
this.freeOfWires = true;
this.force.x += -0.0005;
this.fill = "#222";
diff --git a/js/tech.js b/js/tech.js
index 1b541e5..1b2c526 100644
--- a/js/tech.js
+++ b/js/tech.js
@@ -188,13 +188,13 @@ const tech = {
console.log(introArray[wordNumber])
if (introArray[wordNumber]) {
if (answer && answer.toLowerCase() === introArray[wordNumber].toLowerCase().replace(/[^a-zA-Z]/g, '')) {
- powerUps.spawnDelay("research", 5)
+ powerUps.spawnDelay("research", 4)
simulation.inGameConsole(`correct!`, 360)
} else {
simulation.inGameConsole(`${answer} is wrong, it was ${introArray[wordNumber]}`, 360)
}
let text = `"`
- for (let i = 0; i < wordLimit; i++) {
+ for (let i = 0; i < wordLimit + 3; i++) {
if (i === wordNumber) {
text += `${introArray[i]} `
} else {
@@ -204,7 +204,7 @@ const tech = {
simulation.inGameConsole(text + `..."`, 360)
} else {
simulation.inGameConsole(`hmmm I'm not sure the answer, so I'll say it's correct!`, 360)
- powerUps.spawnDelay("research", 5)
+ powerUps.spawnDelay("research", 3)
}
}
}, 1000); // Check every 1 second
@@ -271,9 +271,10 @@ const tech = {
damage: 1, //used for tech changes to player damage that don't have complex conditions
damageFromTech() {
let dmg = tech.damage * m.fieldDamage
+ if (level.isNoDamage && (m.cycle - 180 < level.noDamageCycle)) dmg *= 0.1
if (tech.isMaxHealthDamage && m.health === m.maxHealth) dmg *= 1.5
- if (tech.isNoDefenseDamage && m.defense() === 1) dmg *= 2
- if (tech.isImmunityDamage && m.immuneCycle > m.cycle) dmg *= 4
+ if (tech.noDefenseSettingDamage && m.defense() === 1) dmg *= 2
+ if (tech.isImmunityDamage && m.immuneCycle > m.cycle) dmg *= 3
if (tech.isPowerUpDamage) dmg *= 1 + 0.07 * powerUp.length
if (tech.isDamageCooldown) dmg *= m.lastKillCycle + tech.isDamageCooldownTime > m.cycle ? 0.4 : 4
if (tech.isDamageAfterKillNoRegen && m.lastKillCycle + 300 > m.cycle) dmg *= 2
@@ -281,7 +282,7 @@ const tech = {
if (tech.isNoGroundDamage) dmg *= m.onGround ? 0.9 : 2
if (tech.isDilate) dmg *= 1.9 + 1.1 * Math.sin(m.cycle * 0.01)
if (tech.isGunChoice && tech.buffedGun === b.inventoryGun) dmg *= 1 + 0.3 * b.inventory.length
- if (powerUps.boost.endCycle > m.cycle) dmg *= 1 + powerUps.boost.damage
+ if (powerUps.boost.endCycle > simulation.cycle) dmg *= 1 + powerUps.boost.damage
if (m.coupling && (m.fieldMode === 0 || m.fieldMode === 5)) dmg *= 1 + 0.015 * m.coupling
if (tech.isVerlet) dmg *= 3
if (tech.isTechDebt) dmg *= tech.totalCount > 20 ? Math.pow(0.85, tech.totalCount - 20) : 4 - 0.15 * tech.totalCount
@@ -297,16 +298,17 @@ const tech = {
if (tech.energyDamage) dmg *= 1 + m.energy * 0.23 * tech.energyDamage;
if (tech.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.01
if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 2
- if (tech.isSpeedDamage) dmg *= 1 + Math.min(1, (tech.speedAdded + player.speed) * 0.0193)
+ if (tech.isSpeedDamage) dmg *= 1 + Math.min(2, ((tech.speedAdded + player.speed) * 0.033))//1 + Math.min(1, (tech.speedAdded + player.speed) * 0.0193)
if (tech.isAxion && tech.isHarmDarkMatter) dmg *= ((tech.isMoveDarkMatter || tech.isNotDarkMatter) ? 3.2 : 2)
if (tech.isHarmDamage && m.lastHarmCycle + 480 > m.cycle) dmg *= 3;
if (tech.lastHitDamage && m.lastHit) dmg *= 1 + tech.lastHitDamage * m.lastHit
// if (tech.isLowHealthDmg) dmg *= 1 + 0.6 * Math.max(0, 1 - (tech.isEnergyHealth ? m.energy : m.health))
if (tech.isLowHealthDmg) dmg *= 1 + 0.6 * Math.max(0, (tech.isEnergyHealth ? m.maxEnergy - m.energy : m.maxHealth - m.health))
- if (tech.isJunkDNA) dmg *= 1 + 2 * tech.junkChance
+ if (tech.isJunkDNA) dmg *= 1 + 2 * (tech.junkChance + level.junkAdded)
return dmg
},
duplicationChance() {
+ if (level.isNoDuplicate) return 0
return Math.min(1, Math.max(0, (tech.isPowerUpsVanish ? 0.13 : 0) + (tech.isStimulatedEmission ? 0.2 : 0) + tech.duplication + tech.duplicateChance + 0.05 * tech.isExtraGunField + m.duplicateChance + tech.fieldDuplicate + 0.08 * tech.isDuplicateMobs + 0.03 * tech.isMassProduction + 0.04 * tech.isHealAttract + tech.cloakDuplication + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.6 : 0) + 0.06 * tech.isDupEnergy))
},
setTechFrequency(name, frequency) {
@@ -1162,67 +1164,6 @@ const tech = {
tech.restDamage = 1;
}
},
- {
- name: "Newtons 1st law",
- descriptionFunction() {
- return `damage taken is proportional to your speed up to 0.2xdamage taken at 55speed(${(1 - Math.min((tech.speedAdded + player.speed) * 0.0193, 0.8)).toFixed(2)}x)`
- },
- description: "",
- maxCount: 1,
- count: 0,
- frequency: 1,
- frequencyDefault: 1,
- allowed() {
- return true
- },
- requires: "",
- effect() {
- tech.isSpeedHarm = true //max at speed = 40
- },
- remove() {
- tech.isSpeedHarm = false
- }
- },
- {
- name: "Newtons 2nd law",
- descriptionFunction() {
- return `damage is proportional to your speed up to 2xdamage at 55speed(${(1 + Math.min(1, ((tech.speedAdded + player.speed) * 0.0193))).toFixed(2)}x)`
- },
- maxCount: 1,
- count: 0,
- frequency: 1,
- frequencyDefault: 1,
- allowed() {
- return true
- },
- requires: "",
- effect() {
- tech.isSpeedDamage = true //max at speed = 40
- },
- remove() {
- tech.isSpeedDamage = false
- }
- },
- {
- name: "modified Newtonian dynamics",
- descriptionFunction() {
- return `your speed counts as +20 higher (for Newton's 1st and 2nd laws)`
- },
- maxCount: 1,
- count: 0,
- frequency: 2,
- frequencyDefault: 2,
- allowed() {
- return tech.isSpeedDamage || tech.isSpeedHarm
- },
- requires: "Newtons 1st or 2nd law",
- effect() {
- tech.speedAdded = 20
- },
- remove() {
- tech.speedAdded = 0
- }
- },
{
name: "kinetic bombardment",
description: "far away mobs take more damage up to 1.3xdamage at 3000 displacement",
@@ -1501,7 +1442,7 @@ const tech = {
{
name: "exciton",
descriptionFunction() {
- return `after mobs die they have a 14% chance to spawn ${powerUps.orb.boost(1)} that give ${(1 + powerUps.boost.damage).toFixed(2)}xdamage for ${(powerUps.boost.duration / 60).toFixed(0)} seconds`
+ return `after mobs die they have a +14% chance to spawn ${powerUps.orb.boost(1)} that give ${(1 + powerUps.boost.damage).toFixed(2)}xdamage for ${(powerUps.boost.duration / 60).toFixed(0)} seconds`
},
maxCount: 1,
count: 0,
@@ -1823,7 +1764,7 @@ const tech = {
{
name: "sound-bot upgrade",
link: `sound-bot upgrade`,
- description: "convert your bots to sound-bots 2x wave fire rate, damage, and duration",
+ description: "convert your bots to sound-bots 6x wave damage",
maxCount: 1,
count: 0,
frequency: 3,
@@ -2139,7 +2080,7 @@ const tech = {
name: "bot fabrication",
link: `bot fabrication`,
descriptionFunction() {
- return `after you collect ${powerUps.orb.research(2 + Math.floor(0.1666 * b.totalBots()))}use them to construct a random bot(+1 cost every 5 bots)`
+ return `after you collect ${powerUps.orb.research(2 + Math.floor(0.25 * b.totalBots()))}use them to construct a random bot(+1 cost every 4 bots)`
},
// description: `if you collect ${powerUps.orb.research(2)}use them to build a random bot(+1 cost every 5 bots)`,
maxCount: 1,
@@ -2657,7 +2598,9 @@ const tech = {
},
{
name: "ablative drones",
- description: "after losing health there is a chance to rebuild your broken parts as drones",
+ descriptionFunction() {
+ return `after losing ${tech.isEnergyHealth ? "energy" : "health"} there is a chance to rebuild your broken parts as drones`
+ },
maxCount: 1,
count: 0,
frequency: 1,
@@ -2715,7 +2658,7 @@ const tech = {
},
{
name: "Pauli exclusion",
- description: `for 8 seconds after mob collisions become invulnerable and inhibit energy regen`,
+ description: `for 7 seconds after mob collisions become invulnerable and inhibit energy regen`,
maxCount: 9,
count: 0,
frequency: 1,
@@ -2770,7 +2713,7 @@ const tech = {
},
{
name: "abelian group",
- description: `4xdamage while invulnerable`,
+ description: `3xdamage while invulnerable`,
maxCount: 1,
count: 0,
frequency: 2,
@@ -3115,10 +3058,10 @@ const tech = {
},
requires: "",
effect() {
- tech.isNoDefenseDamage = true;
+ tech.noDefenseSettingDamage = true;
},
remove() {
- tech.isNoDefenseDamage = false;
+ tech.noDefenseSettingDamage = false;
}
},
{
@@ -4009,7 +3952,7 @@ const tech = {
{
name: "junk DNA",
descriptionFunction() {
- return `increase damage by twice the JUNK chance (${(1 + 2 * tech.junkChance).toFixed(2)}x)`
+ return `increase damage by twice the JUNK chance (${(1 + 2 * (tech.junkChance + level.junkAdded)).toFixed(2)}x)`
},
maxCount: 1,
count: 0,
@@ -7930,8 +7873,8 @@ const tech = {
requires: "negative mass",
effect() {
tech.isNeutronium = true
- tech.baseFx *= 0.8
- tech.baseJumpForce *= 0.8
+ tech.baseFx *= 0.86
+ tech.baseJumpForce *= 0.87
m.setMovement()
},
//also removed in m.setHoldDefaults() if player switches into a bad field
@@ -8002,6 +7945,68 @@ const tech = {
remove() {
tech.isFlyFaster = false;
}
+ }, {
+ name: "Newtons 1st law",
+ descriptionFunction() {
+ return `damage taken reduces as your speed increases up to 0.05xdamage taken at 60speed(${(1 - Math.min((tech.speedAdded + player.speed) * 0.01583, 0.95)).toFixed(2)}x)`
+ },
+ isFieldTech: true,
+ maxCount: 1,
+ count: 0,
+ frequency: 1,
+ frequencyDefault: 1,
+ allowed() {
+ return m.fieldMode === 3 || m.fieldMode === 10
+ },
+ requires: "negative mass, grappling hook",
+ effect() {
+ tech.isSpeedHarm = true //max at speed = 40
+ },
+ remove() {
+ tech.isSpeedHarm = false
+ }
+ },
+ {
+ name: "Newtons 2nd law",
+ descriptionFunction() {
+ return `damage increases proportional to your speed up to 3xdamage at 60speed(${(1 + Math.min(2, ((tech.speedAdded + player.speed) * 0.033))).toFixed(2)}x)`
+ },
+ isFieldTech: true,
+ maxCount: 1,
+ count: 0,
+ frequency: 1,
+ frequencyDefault: 1,
+ allowed() {
+ return m.fieldMode === 3 || m.fieldMode === 10
+ },
+ requires: "negative mass, grappling hook",
+ effect() {
+ tech.isSpeedDamage = true //max at speed = 40
+ },
+ remove() {
+ tech.isSpeedDamage = false
+ }
+ },
+ {
+ name: "modified Newtonian dynamics",
+ descriptionFunction() {
+ return `your speed counts as +20 higher (for Newton's 1st and 2nd laws)`
+ },
+ isFieldTech: true,
+ maxCount: 1,
+ count: 0,
+ frequency: 2,
+ frequencyDefault: 2,
+ allowed() {
+ return tech.isSpeedDamage || tech.isSpeedHarm
+ },
+ requires: "Newtons 1st or 2nd law",
+ effect() {
+ tech.speedAdded = 20
+ },
+ remove() {
+ tech.speedAdded = 0
+ }
},
{
name: "additive manufacturing",
@@ -8235,7 +8240,7 @@ const tech = {
frequency: 2,
frequencyDefault: 2,
allowed() {
- return (m.fieldMode === 10 || m.fieldMode === 5 || m.fieldMode === 8) //1 standing wave 2 perfect diamagnetism 3 negative mass 4 molecular assembler 5 plasma torch 6 time dilation 7 metamaterial cloaking 8 pilot wave 9 wormhole 10 grappling hook
+ return (m.fieldMode === 10 || m.fieldMode === 5 || m.fieldMode === 8)
},
requires: "plasma torch, grappling hook, pilot wave",
effect() {
@@ -9413,7 +9418,7 @@ const tech = {
effect() {
// tech.damage *= 1.33
setInterval(() => {
- if (powerUps.boost.endCycle < m.cycle && !simulation.paused && m.alive) {
+ if (powerUps.boost.endCycle < simulation.cycle && !simulation.paused && m.alive) {
for (let i = 0; i < mob.length; i++) {
if (mob[i].distanceToPlayer2() < 400000) { //650
canvas.requestPointerLock();
@@ -9596,12 +9601,6 @@ const tech = {
mob[i].death();
}
}
- // for (let i = powerUp.length - 1; i > -1; i--) {
- // if (powerUp[i].name !== "ammo") {
- // Matter.Composite.remove(engine.world, powerUp[i]);
- // powerUp.splice(i, 1);
- // }
- // }
},
remove() { }
},
@@ -10098,12 +10097,31 @@ const tech = {
},
requires: "not pilot wave, tokamak, wormhole",
effect() {
-
+ m.throwBlock = m.throwSelf
},
remove() {
m.throwBlock = m.throwBlockDefault
}
},
+ {
+ name: "stationary",
+ description: "thrown blocks can't move, but somehow they still have momentum...",
+ maxCount: 1,
+ count: 0,
+ frequency: 0,
+ // isInstant: true,
+ isJunk: true,
+ allowed() {
+ return m.fieldMode !== 8 && m.fieldMode !== 9 && !tech.isTokamak
+ },
+ requires: "not pilot wave, tokamak, wormhole",
+ effect() {
+ tech.isStaticBlock = true
+ },
+ remove() {
+ tech.isStaticBlock = false
+ }
+ },
{
name: "spinor",
description: "the direction you aim is determined by your position",
@@ -10724,7 +10742,7 @@ const tech = {
},
{
name: "expert system",
- description: "spawn JUNK +50%JUNK chance",
+ description: `spawn ${powerUps.orb.tech()} +50%JUNK chance`,
maxCount: 9,
count: 0,
frequency: 0,
@@ -11430,7 +11448,7 @@ const tech = {
},
{
name: "wikipedia",
- description: `After you get ${powerUps.orb.tech()} you have 7 seconds to study for a quiz. If you ace the quiz you get ${powerUps.orb.research(5)}`,
+ description: `After you get ${powerUps.orb.tech()} you have 7 seconds to study for a quiz. If you ace the quiz you get ${powerUps.orb.research(4)}`,
maxCount: 1,
count: 0,
frequency: 0,
@@ -12053,8 +12071,9 @@ const tech = {
isImmunityDamage: null,
isMobDeathImmunity: null,
isMaxHealthDefense: null,
- isNoDefenseDamage: null,
+ noDefenseSettingDamage: null,
isMaxHealthDamage: null,
isEjectOld: null,
isWiki: null,
+ isStaticBlock: null,
}
\ No newline at end of file
diff --git a/style.css b/style.css
index 5c0ab6e..965a2fb 100644
--- a/style.css
+++ b/style.css
@@ -694,22 +694,44 @@ summary {
border-radius: 5px;
}
-#tech {
+#right-HUD {
position: absolute;
top: 15px;
right: 15px;
z-index: 2;
font-size: 20px;
- color: #222;
text-align: right;
- opacity: 0.35;
line-height: 120%;
- background-color: rgba(255, 255, 255, 0.4);
user-select: none;
pointer-events: none;
+ /*border: 2px solid rgba(0, 0, 0, 0.4);*/
+ color: #222;
padding: 0px 5px 0px 5px;
border-radius: 5px;
- /*border: 2px solid rgba(0, 0, 0, 0.4);*/
+ opacity: 0.35;
+ background-color: rgba(255, 255, 255, 0.4);
+}
+
+#right-HUD-constraint {
+ position: absolute;
+ top: 12px;
+ right: 15px;
+ z-index: 2;
+ font-size: 20px;
+ text-align: right;
+ line-height: 120%;
+ user-select: none;
+ pointer-events: none;
+ padding: 5px 10px 5px 10px;
+ border-radius: 8px;
+ color: #624;
+ opacity: 0.35;
+ background-color: rgba(255, 215, 241, 0.4);
+ /* color: rgb(141, 23, 88);
+ opacity: 0.35;
+ background-color: rgba(141, 23, 88, 0.1); */
+ /* font-weight: 400; */
+ transition: all 0.5s linear;
}
#text-log {
@@ -727,6 +749,12 @@ summary {
user-select: none;
}
+.constraint {
+ color: rgb(141, 23, 88);
+ /* font-weight: 100; */
+ /* text-decoration: underline; */
+}
+
.color-text {
color: #000;
}
diff --git a/todo.txt b/todo.txt
index 504eece..5f1086c 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,55 +1,137 @@
******************************************************** NEXT PATCH **************************************************
-JUNK: wikipedia - After you get a new tech you have 7 seconds to study before a quiz, 4 research if you aces the quiz.
- this code for this works 80% of the time every time
+difficulty
+ difficulty level 6 adds flat damage and damage taken
+ bonus tech no longer spawns on level 2 and 3 on difficulty level 6
+ at the end of subway you get 1 tech, but not on difficulty level 6
+ difficulty level 3 and 5 add a random constraint that changes each level
+constraints are effects that only last until the level ends
+ 50% JUNK chance
+ 4x shielded mob chance
+ power ups are sent to next level
+ +33% chance for mobs to respawn
+ -1 choice
+ 2x ammo costs
+ duplication is set to zero
+ 50% max energy
+ 50% max health
+ bots follow slow
+ full damage taken after boss dies
+ 0.1x damage after a power up
+ mob death heals mobs
+ mobs heal for your lost health
+ periodically spawn WIMPs
+
+exciton damage boost power up has a chance to spawn without the tech (~3%/mob)
+ damage boost has a unique gel/hair aura for each skin
+ damage boost timer no longer ticks with time dilation field
+JUNK tech: stationary - thrown blocks can't move, but they still have momentum
+added a classic n-gon link for the previous patch in settings
+ but images are disabled to save space
+on levels where you can fall endlessly, power ups will also fall endlessly
+ they no longer teleport to the exit, sorry
-renamed propagator->Verlet integration it's now a skin tech
- 1.6->3x damage
- slightly increased the time skip amount
-on some skins the feet will hang lower while player is in the air
-on some skins the upper legs are skinnier
-mouse over on orbs for tech, field, and gun has a tooltip with text
-added keyword CSS style for "bot"
-added an aura around powerUpBoss so you can kinda see it inside walls
-
-quenching just gives max health from over healing instead of damaging you first
-depolarization does 0.5->0.4x damage when on cooldown
-many-worlds spawns a tech and also 3 coupling at the start of each new level
-dynamic equilibrium does 1.15x more damage and only stacks to 9->3
-orbital bots collide with a 1.2x larger range
-Zectron no longer drains energy when balls hit you, but the balls still stop
-supply chain just gives a gun and a flat 10 ammo
-
-polyurethane foam will only trigger up to 55 total foam per harpoon
- to prevent a huge number of foam bubbles causing lag
- no cap for super balls for now
-fixed bug with planned obsolescence + instant tech
-fixed bug with ice crystal nucleation
-applied science gives each gunTech with a short delay
- this helps with sorting and maybe other rare bugs
-fixed bug with delivery drones and path integration
-you can no longer deflect snakeBoss, but it moves a bit slower
+Newton's 1st and 2nd laws are field tech, and they give twice the effect
+abelian group 4->3x damage while invulnerable
+bot fabrication price increases after 5->4 bots
+wikipedia 4->3 research per correct quiz
+upgraded sound bots fire fewer waves but do more damage per wave
+ not much changed except improved performance, I think
+incendiary ammunition drones explode when they run out of durability not on the first hit
+ this allows better synergy with other drone tech
+grappling hook retract momentum no longer scales with distance
+ this should give you more control
+pressing the 3rd button in factory will remove blocks resting on the second block
+ preventing an endless toggle
+bug fixes
+ fleas no longer die early after hitting a high health target only once
+ something with super ball density calculations for tech rebound
+ grabbing a big block can make grappling hook go flying
+ added 3 potential fixes, but the bug is too rare know if it's fixed
******************************************************** 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?
+ check which of these is working
+ level order
+ is flipped
+ constraint order
+ mob type order
+ boss order
+ gun, field, tech options
+ make field options offered precalculated so it doesn't depend on player choices?
+ generate all constraints at the start of the game
+ doesn't seem to be determined by the seed...
+ display future constraints in pause menu?
+
+at start of level game go stuck in pause state
+ no crash or bug report
+ occur level 8
+ after 2 levels of sending power ups to next level
+ auto drones grabbed a power up and game froze while in power up mode
+ running code to exit pause kinda worked
+
ants marching outline on splash screen doesn't sync right on safari
player can become crouched while not touching the ground if they exit the ground while crouched
*********************************************************** TODO *****************************************************
+each difficulty setting adds a chance for a random effect
+ make some effects only possible on certain levels, or with certain bosses?
+ not implemented random constraint ideas________________________
+ if player takes too long on a level
+ spawn mobs at the end of player's history
+ give a warning before they spawn
+ black holes, sneakers, bullets
+ mob death spawns something
+ bullets
+ bosses heals nearby mobs
+ ammo power ups give 0.7x ammo
+ 2x energy costs
+ 0.5x energy regen from all sources
+ 2x research costs
+ mobs slowly regen health
+ exit door takes 10x time to open,
+ and while door is opening (ghosters, suckers) attack?
+ can't pause while choosing tech, gun, field similar to eternalism
+ can't have more then 15 bullets
+ bots do 0.5x damage
+ 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: - 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: - boost power ups also give 0.1x damage taken
+
tech: - tech have +3 choices to eject your tech
tech name
no description?
+copy negative-player as a boss? or a JUNK tech?
+ code is in community map (not sure which)
+
harpoon tech: - after firing 4 harpoons your next harpoon has 4x damage
need to track number fired
-JUNK tech - similar to cosmogonic myth, open and close tabs
- after you learn a new tech open it's wiki and spawn a few research?
- open the wiki for each tech you have,
- tabs close after 1 minute, and you have to learn something and answer a prompt to get a reward
+tech: - after killing a Boss
+ heal to full
+ gain 3x damage for the rest of the level
+
+tech: clicking on this tech in the pause menu will teleport you to the next level
tech: - instead of reeling in grappling hook teleport to the hook after releasing field button
this might need another buff?
@@ -57,6 +139,11 @@ tech: - instead of reeling in grappling hook teleport to the hook after releas
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
+
new snakeBoss type that eats mobs
each time it eats:
heal?
@@ -80,13 +167,6 @@ Boss mob - records the position of mobs every few cycles
gives mobs short snake tails, like snakeBoss
brings 1 mob back to life every few seconds
-
-merge multiple power ups of the same type if nearby
- 5-10 ammo, research, coupling can merge to form a slightly larger power up version
- check for merger possibility every 60 seconds?
- adjust mass spawns to just spawn larger power ups versions and change?
- spawnDelay
-
tech: atomic pile - lose 1 health if you are above the maximum energy
generate energy for each nearby mob?
do damage?
@@ -160,9 +240,6 @@ after picking up research gain ____
tech: Energy generation increases with you velocity
Newtons' 3rd law?
-after clicking on a new tech (or getting it in any way) animate adding the tech to your collection
- fade in on right side text list?
-
tech - getting caught in an explosion gives you _____
damage for 10 seconds?
heals
@@ -1310,6 +1387,9 @@ possible names for tech
Coalescence - things merging together like clouds. maybe mergin power ups?
trihydrogen cation - common molecule in space, dark matter tech?
superradiance - laser tech
+ cryocoolers - freezing effects
+ metaphysics - maybe this changes something deep and universal about physics? not sure
+ cork - used as a heat shield for rockets
******************************************************* DESIGN ******************************************************