subway stations

subway
  2 new subway stations
  more visible button graphics on subway

new constraints
  no health bars
  no pause while choosing

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

bugs
  MIRV missiles now interact with time dilation properly
This commit is contained in:
landgreen
2024-08-31 08:28:05 -07:00
parent 220a6b4c15
commit ebd22741d4
10 changed files with 557 additions and 161 deletions

BIN
img/coherence.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

View File

@@ -6723,10 +6723,7 @@ const b = {
// } // }
// } else { // } else {
m.fireCDcycle = m.cycle + tech.missileFireCD * b.fireCDscale / countReduction; // cool down m.fireCDcycle = m.cycle + tech.missileFireCD * b.fireCDscale / countReduction; // cool down
const direction = { const direction = { x: Math.cos(m.angle), y: Math.sin(m.angle) }
x: Math.cos(m.angle),
y: Math.sin(m.angle)
}
// const where = { // const where = {
// x: m.pos.x + 30 * direction.x, // x: m.pos.x + 30 * direction.x,
// y: m.pos.y + 30 * direction.y // y: m.pos.y + 30 * direction.y
@@ -6752,23 +6749,17 @@ const b = {
let count = 0 let count = 0
const fireMissile = () => { const fireMissile = () => {
if (m.crouch) { if (m.crouch) {
b.missile({ b.missile({ x: m.pos.x + 30 * direction.x, y: m.pos.y + 30 * direction.y }, m.angle, 20, sqrtCountReduction)
x: m.pos.x + 30 * direction.x,
y: m.pos.y + 30 * direction.y
}, m.angle, 20, sqrtCountReduction)
bullet[bullet.length - 1].force.x += 0.5 * push.x * (Math.random() - 0.5) bullet[bullet.length - 1].force.x += 0.5 * push.x * (Math.random() - 0.5)
bullet[bullet.length - 1].force.y += 0.004 + 0.5 * push.y * (Math.random() - 0.5) bullet[bullet.length - 1].force.y += 0.004 + 0.5 * push.y * (Math.random() - 0.5)
} else { } else {
b.missile({ b.missile({ x: m.pos.x + 30 * direction.x, y: m.pos.y + 30 * direction.y }, m.angle, -15, sqrtCountReduction)
x: m.pos.x + 30 * direction.x,
y: m.pos.y + 30 * direction.y
}, m.angle, -15, sqrtCountReduction)
bullet[bullet.length - 1].force.x += push.x * (Math.random() - 0.5) bullet[bullet.length - 1].force.x += push.x * (Math.random() - 0.5)
bullet[bullet.length - 1].force.y += 0.005 + push.y * (Math.random() - 0.5) bullet[bullet.length - 1].force.y += 0.005 + push.y * (Math.random() - 0.5)
} }
} }
const cycle = () => { const cycle = () => {
if ((simulation.paused || m.isBodiesAsleep) && m.alive) { if ((simulation.paused) && m.alive) {
requestAnimationFrame(cycle) requestAnimationFrame(cycle)
} else { } else {
count++ count++
@@ -6781,15 +6772,9 @@ const b = {
requestAnimationFrame(cycle); requestAnimationFrame(cycle);
} else { } else {
if (m.crouch) { if (m.crouch) {
b.missile({ b.missile({ x: m.pos.x + 40 * direction.x, y: m.pos.y + 40 * direction.y }, m.angle, 25)
x: m.pos.x + 40 * direction.x,
y: m.pos.y + 40 * direction.y
}, m.angle, 25)
} else { } else {
b.missile({ b.missile({ x: m.pos.x + 40 * direction.x, y: m.pos.y + 40 * direction.y }, m.angle, -12)
x: m.pos.x + 40 * direction.x,
y: m.pos.y + 40 * direction.y
}, m.angle, -12)
bullet[bullet.length - 1].force.y += 0.04 * (Math.random() - 0.2) bullet[bullet.length - 1].force.y += 0.04 * (Math.random() - 0.2)
} }
} }

View File

@@ -1421,7 +1421,7 @@ window.addEventListener("keydown", function (event) {
// level.levelAnnounce(); // level.levelAnnounce();
document.body.style.cursor = "none"; document.body.style.cursor = "none";
requestAnimationFrame(cycle); requestAnimationFrame(cycle);
} else if (!tech.isNoDraftPause) { } else { //if (!tech.isNoDraftPause)
simulation.paused = true; simulation.paused = true;
build.pauseGrid() build.pauseGrid()
document.body.style.cursor = "auto"; document.body.style.cursor = "auto";

View File

@@ -17,7 +17,9 @@ const level = {
if (level.levelsCleared === 0) { //this code only runs on the first level if (level.levelsCleared === 0) { //this code only runs on the first level
// simulation.enableConstructMode() //tech.giveTech('motion sickness') //used to build maps in testing mode // simulation.enableConstructMode() //tech.giveTech('motion sickness') //used to build maps in testing mode
// simulation.isHorizontalFlipped = true // simulation.isHorizontalFlipped = true
// level.levelsCleared = 4 // spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns
// spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns
// level.levelsCleared = 11
// level.updateDifficulty() // level.updateDifficulty()
// tech.giveTech("performance") // tech.giveTech("performance")
// m.maxHealth = m.health = 1//00000000 // m.maxHealth = m.health = 1//00000000
@@ -44,17 +46,20 @@ const level = {
// b.guns[8].ammo = 100000000 // b.guns[8].ammo = 100000000
// requestAnimationFrame(() => { tech.giveTech("stimulated emission") }); // requestAnimationFrame(() => { tech.giveTech("stimulated emission") });
// tech.giveTech("Hilbert space") // tech.giveTech("Hilbert space")
// for (let i = 0; i < 1; ++i) tech.giveTech("decoherence") // tech.addJunkTechToPool(0.5)
// for (let i = 0; i < 1; ++i) tech.giveTech("mass-energy equivalence") // for (let i = 0; i < 1; ++i) tech.giveTech("coherence")
// for (let i = 0; i < 1; ++i) tech.giveTech("nitinol")
// m.skin.egg();
// for (let i = 0; i < 1; ++i) tech.giveTech("depolarization") // for (let i = 0; i < 1; ++i) tech.giveTech("depolarization")
// requestAnimationFrame(() => { for (let i = 0; i < 1; i++) tech.giveTech("wikipedia") }); // requestAnimationFrame(() => { for (let i = 0; i < 1; i++) tech.giveTech("wikipedia") });
// requestAnimationFrame(() => { for (let i = 0; i < 1; i++) tech.giveTech("field coupling") }); // requestAnimationFrame(() => { for (let i = 0; i < 1; i++) tech.giveTech("field coupling") });
// for (let i = 0; i < 1; i++) tech.giveTech("interest") // for (let i = 0; i < 1; i++) tech.giveTech("interest")
// m.lastKillCycle = m.cycle // m.lastKillCycle = m.cycle
// for (let i = 0; i < 1; i++) powerUps.directSpawn(450, -50, "tech"); // for (let i = 0; i < 4; i++) powerUps.directSpawn(450, -50, "tech");
// for (let i = 0; i < 3; i++) powerUps.directSpawn(m.pos.x + 200, m.pos.y - 50, "boost", false); // for (let i = 0; i < 7; i++) powerUps.directSpawn(m.pos.x + 200, m.pos.y - 250, "research", false);
// spawn.bodyRect(575, -700, 150, 150); //block mob line of site on testing // spawn.bodyRect(575, -700, 150, 150); //block mob line of site on testing
// level.heal(); // level.subway();
level[simulation.isTraining ? "walk" : "initial"]() //normal starting level ************************************************** level[simulation.isTraining ? "walk" : "initial"]() //normal starting level **************************************************
@@ -334,6 +339,30 @@ const level = {
constraintDescription1: "", //used in pause menu and console constraintDescription1: "", //used in pause menu and console
constraintDescription2: "", constraintDescription2: "",
constraint: [ constraint: [
{
description: "no pause while choosing",
effect() {
level.isNoPause = true
},
remove() {
level.isNoPause = false
}
},
{
description: "no health bars",
effect() {
mobs.healthBar = () => { }
level.isHideHealth = true
document.getElementById("health").style.display = "none"
document.getElementById("health-bg").style.display = "none"
},
remove() {
mobs.healthBar = mobs.defaultHealthBar
level.isHideHealth = false
document.getElementById("health").style.display = "inline"
document.getElementById("health-bg").style.display = "inline"
}
},
{ {
description: "0.5x energy regen", description: "0.5x energy regen",
effect() { effect() {
@@ -561,6 +590,8 @@ const level = {
reducedHealthLost: 0, reducedHealthLost: 0,
isReducedHealth: false, isReducedHealth: false,
isReducedRegen: 1, isReducedRegen: 1,
isHideHealth: false,
isNoPause: false,
levelAnnounce() { levelAnnounce() {
const cheating = simulation.isCheating ? "(testing)" : "" const cheating = simulation.isCheating ? "(testing)" : ""
if (level.levelsCleared === 0) { if (level.levelsCleared === 0) {
@@ -2604,7 +2635,6 @@ const level = {
//start a conversation based on the number of conversations seen //start a conversation based on the number of conversations seen
if (localSettings.loreCount > lore.conversation.length - 1) localSettings.loreCount = lore.conversation.length - 1; //repeat final conversation if lore count is too high if (localSettings.loreCount > lore.conversation.length - 1) localSettings.loreCount = lore.conversation.length - 1; //repeat final conversation if lore count is too high
if (!simulation.isCheating && localSettings.loreCount < lore.conversation.length) { if (!simulation.isCheating && localSettings.loreCount < lore.conversation.length) {
tech.isNoDraftPause = true //disable pause
lore.testSpeechAPI() //see if speech is working lore.testSpeechAPI() //see if speech is working
lore.chapter = localSettings.loreCount //set the chapter to listen to to be the lore level (you can't use the lore level because it changes during conversations) lore.chapter = localSettings.loreCount //set the chapter to listen to to be the lore level (you can't use the lore level because it changes during conversations)
lore.sentence = 0 //what part of the conversation to start on lore.sentence = 0 //what part of the conversation to start on
@@ -3185,7 +3215,7 @@ const level = {
train[train.length - 1].stops = { left: -7225, right: -1725 } train[train.length - 1].stops = { left: -7225, right: -1725 }
const stationList = [] //use to randomize station order const stationList = [] //use to randomize station order
for (let i = 1, totalNumberOfStations = 8; i < totalNumberOfStations; ++i) stationList.push(i) //!!!! update station number when you add a new station for (let i = 1, totalNumberOfStations = 10; i < totalNumberOfStations; ++i) stationList.push(i) //!!!! update station number when you add a new station
shuffle(stationList); shuffle(stationList);
stationList.splice(0, 3); //remove some stations to keep it to 4 stations stationList.splice(0, 3); //remove some stations to keep it to 4 stations
stationList.unshift(0) //add index zero to the front of the array stationList.unshift(0) //add index zero to the front of the array
@@ -3201,6 +3231,8 @@ const level = {
} }
removeAll(map); removeAll(map);
map = []; map = [];
removeAll(composite);
composite = []
//remove any powerUp that is too far from player //remove any powerUp that is too far from player
for (let i = 0; i < powerUp.length; ++i) { for (let i = 0; i < powerUp.length; ++i) {
if (Vector.magnitudeSquared(Vector.sub(player.position, powerUp[i].position)) > 9000000) { //remove any powerUp farther then 3000 pixels from player if (Vector.magnitudeSquared(Vector.sub(player.position, powerUp[i].position)) > 9000000) { //remove any powerUp farther then 3000 pixels from player
@@ -3244,7 +3276,25 @@ const level = {
} }
} }
} }
gateButton.draw(); // gateButton.draw();
if (gateButton.isUp) {
//aura around button
ctx.beginPath();
ctx.ellipse(gateButton.min.x + gateButton.width * 0.5, gateButton.min.y + 6, 0.75 * gateButton.width, 0.5 * gateButton.width, 0, Math.PI, 0); //ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, counterclockwise)
ctx.fillStyle = `hsla(345, 100%, 80%,${0.1 + 0.4 * Math.random()})`
ctx.fill();
ctx.fillStyle = "hsl(345, 100%, 75%)"
ctx.fillRect(gateButton.min.x, gateButton.min.y - 10, gateButton.width, 25)
ctx.strokeStyle = "#000"//"rgba(255,255,255,0.2)"
ctx.lineWidth = 2
ctx.strokeRect(gateButton.min.x, gateButton.min.y - 10, gateButton.width, 25)
} else {
ctx.fillStyle = "hsl(345, 100%, 75%)"
ctx.fillRect(gateButton.min.x, gateButton.min.y, gateButton.width, 10)
ctx.strokeStyle = "#000"//"rgba(255,255,255,0.2)"
ctx.lineWidth = 2
ctx.strokeRect(gateButton.min.x, gateButton.min.y, gateButton.width, 10)
}
} }
} }
const stations = [ //update totalNumberOfStations as you add more stations const stations = [ //update totalNumberOfStations as you add more stations
@@ -3940,8 +3990,235 @@ const level = {
ctx.fillRect(x + 950, -675, 400, 125); ctx.fillRect(x + 950, -675, 400, 125);
} }
}, },
() => { //angled jumps
const buttonsCoords = [{ x: x + 50, y: -1395 }, { x: x - 625, y: -2945 }, { x: x + 900, y: -2945 }]
const buttonsCoordsIndex = Math.floor(Math.random() * buttonsCoords.length) //pick a random element from the array
spawn.mapRect(x + -1500, -210, 3000, 400);//station floor
boosts = []
boosts.push(level.boost(x - 311, -218, 1200, 1.85))
spawn.mapRect(x + -225, -525, 675, 375);
spawn.mapRect(x + -1350, -1175, 400, 675);
spawn.mapRect(x + -225, -2125, 675, 400);
// spawn.mapRect(x + -225, -1325, 675, 550);
spawn.mapRect(x + -225, -1400, 675, 650);
boosts.push(level.boost(x - 1335, -1200, 1800, 1))
boosts.push(level.boost(x + 1272, -1300, 1550, 2.75)) //far right
//high up walls
boosts.push(level.boost(x + 1455, -2048, 1450, 2.5))
spawn.mapRect(x + 1500, -3825, 325, 1900);
boosts.push(level.boost(x - 1555, -2048, 1450, 0.64))
// spawn.mapRect(x + -1625, -3975, 3450, 325);
spawn.mapRect(x + -1825, -4000, 325, 2150);
spawn.mapRect(x + -1825, -4070, 3650, 375);//roof
spawn.randomMob(x + 100, -2125, 0);
boosts.push(level.boost(x + 75, -2175, 2800))
spawn.mapRect(x + -100, -3900, 400, 400);
Matter.Body.setAngle(map[map.length - 1], map[map.length - 1].angle - Math.PI / 4);
spawn.mapRect(x + 225, -2950, 1100, 150);
spawn.mapRect(x + -1325, -2950, 1325, 150);
if (isExitOpen) {
level.exit.x = buttonsCoords[buttonsCoordsIndex].x;
level.exit.y = buttonsCoords[buttonsCoordsIndex].y - 25;
} else {
var gateButton = level.button(buttonsCoords[buttonsCoordsIndex].x, buttonsCoords[buttonsCoordsIndex].y, 126, false) //x, y, width = 126, isSpawnBase = true
gateButton.isUp = true
if (stationNumber > gatesOpenRight) {
var gate = level.doorMap(x + 1375, -525, 50, 375, 300, 20, false) //x, y, width, height, distance, speed = 20
} else if (stationNumber < gatesOpenLeft) {
var gate = level.doorMap(x - 1375, -525, 50, 375, 300, 20, false) //x, y, width, height, distance, speed = 20
}
}
if (!isExitOpen) {
spawn.randomMob(x + 350, -600, 0);
spawn.randomMob(x + -25, -600, 0);
spawn.randomMob(x + 600, -300, 0);
spawn.randomMob(x + 1050, -300, 0);
spawn.randomMob(x + 350, -1525, 0);
spawn.randomMob(x + -75, -1525, 0);
spawn.randomMob(x + -1075, -1275, 0);
spawn.randomMob(x + -1350, -2050, 0);
spawn.randomMob(x + -50, -2250, 0);
spawn.randomMob(x + -200, -3050, 0);
spawn.randomMob(x + -925, -3150, 0);
spawn.randomMob(x + 450, -3125, 0);
spawn.randomMob(x + 1075, -3025, 0);
spawn.randomMob(x + 750, -3125, 0);
spawn.randomMob(x + -725, -3125, 0);
}
stationCustom = () => {
for (let i = 0; i < boosts.length; i++) {
boosts[i].query()
}
}
stationCustomTopLayer = () => {
checkGate(gate, gateButton)
ctx.fillStyle = "rgba(0,0,0,0.08)"
ctx.fillRect(x - 225, -775, 675, 275);
ctx.fillRect(x - 225, -1750, 675, 375);
}
},
() => { //people movers
simulation.removeEphemera("zoom")//stop previous zooms
simulation.zoomTransition(2000)
const buttonsCoords = [{ x: x - 65, y: -2045 }] //only one button location?
const buttonsCoordsIndex = Math.floor(Math.random() * buttonsCoords.length) //pick a random element from the array
const moverDirection = stationNumber > 0 ? 1 : -1
console.log(stationNumber)
if (isExitOpen) {
level.exit.x = buttonsCoords[buttonsCoordsIndex].x;
level.exit.y = buttonsCoords[buttonsCoordsIndex].y - 25;
} else {
var gateButton = level.button(buttonsCoords[buttonsCoordsIndex].x, buttonsCoords[buttonsCoordsIndex].y, 126, false) //x, y, width = 126, isSpawnBase = true
gateButton.isUp = true
if (stationNumber > gatesOpenRight) {
var gate = level.doorMap(x + 1375, -525, 50, 375, 300, 20, false) //x, y, width, height, distance, speed = 20
} else if (stationNumber < gatesOpenLeft) {
var gate = level.doorMap(x - 1375, -525, 50, 375, 300, 20, false) //x, y, width, height, distance, speed = 20
}
}
//floor 0
spawn.mapRect(x + -1500, -210, 3000, 400);//station floor
const movers = []
movers.push(level.mover(x + -1200, -220, 900, 50, 3 * moverDirection))
movers.push(level.mover(x + 300, -220, 900, 50, 3 * moverDirection))
spawn.mapRect(x + -4700, -7000, 700, 5200);//Left wall
spawn.mapRect(x + 4000, -7000, 500, 5200);//Right wall
const portals = []
portals.push(level.portal({ x: x - 315, y: -310 }, Math.PI, { x: x - 3985, y: -2110 }, 0))
spawn.mapRect(x - 1375, -1100, 2750, 300);
spawn.mapRect(x + -300, -525, 600, 550);
//floor 1 fast with jump in middle
movers.push(level.mover(x - 4000, -2025, 2700, 50, 30 * moverDirection))
movers.push(level.mover(x + 1300, -2025, 2700, 50, 30 * moverDirection))
portals.push(level.portal({ x: x + 3985, y: -2110 }, Math.PI, { x: x - 3985, y: -3410 }, 0))
spawn.mapRect(x + -500, -2050, 1000, 150);
spawn.mapRect(x + -4200, -2300, 1225, 125);
spawn.mapRect(x + 2675, -2350, 1625, 150);
//up mode triggered by player contact
const elevator0 = level.elevator(x - 1300, -1175, 175, 50, -1600, 0.011, { up: 0.01, down: 0.7 })
const elevator1 = level.elevator(x + 1125, -1175, 175, 50, -1600, 0.011, { up: 0.01, down: 0.7 })
//floor 2 slow with some things to jump on and mobs
portals.push(level.portal({ x: x + 3985, y: -3410 }, Math.PI, { x: x - 3985, y: -5110 }, 0))
movers.push(level.mover(x - 4000, -3325, 8000, 50, 7 * moverDirection))
if (Math.random() < 0.5) {
spawn.mapRect(x + 1125, -3625, 325, 200);
spawn.mapRect(x - 1350, -3600, 375, 175);
spawn.mapRect(x + 325, -3825, 325, 100);
spawn.mapRect(x - 675, -3800, 450, 75);
spawn.mapRect(x - 1775, -3900, 175, 400);
spawn.mapRect(x - 2100, -4275, 325, 775);
spawn.mapRect(x + 2625, -3700, 450, 125);
spawn.mapRect(x - 3350, -3335, 175, 50);
spawn.mapRect(x - 200, -3335, 500, 50);
spawn.mapRect(x + 3200, -3335, 325, 50);
} else {
spawn.mapRect(x + -325, -3550, 425, 125);
spawn.mapRect(x + -1100, -3750, 425, 75);
spawn.mapRect(x + -2175, -3500, 200, 200);
spawn.mapRect(x + 675, -3700, 175, 75);
spawn.mapRect(x + 2375, -3425, 275, 125);
spawn.mapRect(x + 1750, -3650, 275, 75);
spawn.mapRect(x + 1125, -3850, 175, 550);
spawn.mapRect(x + -3300, -4175, 675, 550);
}
spawn.mapRect(x + 3550, -3625, 550, 100);
spawn.mapRect(x + -4100, -3650, 325, 100);
if (!isExitOpen) {
spawn.randomMob(x + 3900, -3725, 0);
spawn.randomMob(x + 3675, -3700, 0);
spawn.randomMob(x + 2075, -3400, 0);
spawn.randomMob(x + 2500, -3500, 0);
spawn.randomMob(x + 1975, -3700, 0);
spawn.randomMob(x + 1250, -3900, 0);
spawn.randomMob(x + 800, -3750, 0);
spawn.randomMob(x + 2700, -4700, 0);
spawn.randomMob(x + -75, -3650, 0);
spawn.randomMob(x + 575, -3500, 0);
spawn.randomMob(x + -850, -3900, 0);
spawn.randomMob(x + -2725, -4350, 0);
spawn.randomMob(x + -2975, -4300, 0);
spawn.randomMob(x + -3950, -3675, 0);
spawn.randomMob(x + -2950, -3450, 0);
spawn.randomMob(x + -2075, -3575, 0);
spawn.randomMob(x + -1650, -3450, 0);
spawn.randomMob(x + -2825, -4400, 0);
spawn.randomMob(x + -900, -4475, 0);
spawn.randomMob(x + -75, -3575, 0);
spawn.randomMob(x + 3900, -3775, 0);
spawn.randomMob(x + 2825, -3375, 0);
spawn.randomMob(x + 2075, -3425, 0);
spawn.randomMob(x + 1525, -3425, 0);
spawn.randomMob(x + 350, -3500, 0);
spawn.randomMob(x + -1675, -3650, 0);
spawn.randomMob(x + -3025, -3450, 0);
spawn.randomMob(x + -3850, -3750, 0);
}
//floor 3 fast with bumps
spawn.mapRect(x + -4250, -7000, 8475, 325);//roof
portals.push(level.portal({ x: x + 3985, y: -5110 }, Math.PI, { x: x + 320, y: -310 }, 0))
movers.push(level.mover(x - 4000, -5025, 8000, 50, 50 * moverDirection))
if (Math.random() < 0.5) {
spawn.mapVertex(x - 2100, -5050, "-150 0 150 0 5 -150 -5 -150")
spawn.mapVertex(x - 0, -5100, "-500 0 500 0 25 -300 -25 -300")
spawn.mapVertex(x + 2100, -5050, "-300 0 300 0 100 -100 -100 -100")
} else {
spawn.mapVertex(x - 2100, -5050, "-100 0 100 0 25 -100 -25 -100")
spawn.mapVertex(x - 0, -5050, "-400 0 400 0 100 -100 -100 -100")
spawn.mapVertex(x + 2100, -5050, "-400 0 400 0 100 -100 -100 -100")
}
spawn.mapRect(x + 2000, -6700, 200, 1250);
spawn.mapRect(x + -100, -6700, 200, 1075);
spawn.mapRect(x + -2125, -6700, 50, 925);
// spawn.mapRect(x + -4150, -5325, 975, 125); //portal over hang
// spawn.mapRect(x + 3325, -5300, 850, 100);//portal over hang
stationCustom = () => {
for (let i = 0; i < movers.length; i++) movers[i].push();
for (let i = 0; i < portals.length; i++) {
portals[i][2].query()
portals[i][3].query()
}
}
stationCustomTopLayer = () => {
for (let i = 0; i < portals.length; i++) {
portals[i][0].draw()
portals[i][1].draw()
portals[i][2].draw()
portals[i][3].draw()
}
elevator0.moveOnTouch()
elevator1.moveOnTouch()
//custom draw so you can see the mover tracks on subway map with the Line of sight graphics
ctx.strokeStyle = "#000"
ctx.lineWidth = 4;
ctx.setLineDash([40, 40]);
for (let i = 0; i < movers.length; i++) {
ctx.beginPath();
ctx.moveTo(movers[i].vertices[0].x + 2, movers[i].vertices[0].y - 3);
ctx.lineTo(movers[i].vertices[1].x - 2, movers[i].vertices[1].y - 3);
ctx.lineDashOffset = (-simulation.cycle * movers[i].VxGoal) % 80;
ctx.stroke();
}
ctx.setLineDash([0, 0]);
checkGate(gate, gateButton)
}
},
] ]
// stations[4]() //for testing a specific station //update totalNumberOfStations to a higher number when adding new maps
simulation.zoomTransition(level.defaultZoom)
// stations[9]() //for testing a specific station
stations[stationList[Math.abs(stationNumber % stationList.length)]]() //*************** run this one when uploading stations[stationList[Math.abs(stationNumber % stationList.length)]]() //*************** run this one when uploading
//add in standard station map infrastructure //add in standard station map infrastructure
spawn.mapRect(x + -8000, 0, 16000, 800);//tunnel floor spawn.mapRect(x + -8000, 0, 16000, 800);//tunnel floor

View File

@@ -30,6 +30,20 @@ const mobs = {
// } // }
} }
}, },
defaultHealthBar() {
for (let i = 0, len = mob.length; i < len; i++) {
if (mob[i].seePlayer.recall && mob[i].showHealthBar) {
const h = mob[i].radius * 0.3;
const w = mob[i].radius * 2;
const x = mob[i].position.x - w / 2;
const y = mob[i].position.y - w * 0.7;
ctx.fillStyle = "rgba(100, 100, 100, 0.3)";
ctx.fillRect(x, y, w, h);
ctx.fillStyle = "rgba(255,0,0,0.7)";
ctx.fillRect(x, y, w * mob[i].health, h);
}
}
},
healthBar() { healthBar() {
for (let i = 0, len = mob.length; i < len; i++) { for (let i = 0, len = mob.length; i < len; i++) {
if (mob[i].seePlayer.recall && mob[i].showHealthBar) { if (mob[i].seePlayer.recall && mob[i].showHealthBar) {
@@ -1010,8 +1024,9 @@ const mobs = {
this.death(); //death with no power up this.death(); //death with no power up
} }
}, },
healthBar() { //draw health by mob //most health bars are drawn in mobs.healthbar(); //draw health by mob //most health bars are drawn in mobs.healthBar(); , not this
if (this.seePlayer.recall) { healthBar() {
if (this.seePlayer.recall && !level.isHideHealth) {
const h = this.radius * 0.3; const h = this.radius * 0.3;
const w = this.radius * 2; const w = this.radius * 2;
const x = this.position.x - w / 2; const x = this.position.x - w / 2;

View File

@@ -987,6 +987,121 @@ const m = {
powerUps.boost.draw() powerUps.boost.draw()
} }
}, },
egg() {
m.isAltSkin = true
m.yOffWhen.stand = 52
m.yOffWhen.jump = 72
m.coyoteCycles = 11
m.hardLandCDScale = 0.5
m.hardLanding = 160
m.squirrelFx = 1.4;
m.squirrelJump = 1.16;
m.setMovement()
m.draw = function () {
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 radius = 39
const mag = 14 * 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 = (powerUps.boost.endCycle - m.cycle) / powerUps.boost.duration
const time = Math.min(0.5, (powerUps.boost.endCycle - simulation.cycle) / powerUps.boost.duration)
ctx.fillStyle = `rgba(0,0,0,${0.04 + 0.3 * time})`
ctx.fill()
// ctx.strokeStyle = "#333"
// ctx.lineWidth = 1
// ctx.stroke();
ctx.restore();
}
m.walk_cycle += m.flipLegs * m.Vx;
ctx.save();
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5 //|| (m.cycle % 40 > 20)
ctx.translate(m.pos.x, m.pos.y);
m.calcLeg(Math.PI, -1.25);
m.drawLeg("#606060");
m.calcLeg(0, 0);
m.drawLeg("#444");
ctx.rotate(m.angle);
ctx.beginPath();
// ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.ellipse(0, 0, 0.9 * 31, 1.05 * 31, 0, 0, 2 * Math.PI);
ctx.fillStyle = m.bodyGradient
ctx.fill();
// ctx.arc(15, 0, 4, 0, 2 * Math.PI);
ctx.ellipse(15, 0, 0.8 * 4, 1.1 * 4, 0, 0, 2 * Math.PI);
ctx.strokeStyle = "#333";
ctx.lineWidth = 2;
ctx.stroke();
ctx.restore();
m.yOff = m.yOff * 0.75 + m.yOffGoal * 0.25; //smoothly move leg height towards height goal
}
m.drawLeg = function (stroke) {
if (m.angle > -Math.PI / 2 && m.angle < Math.PI / 2) {
m.flipLegs = 1;
} else {
m.flipLegs = -1;
}
const hip = { x: m.hip.x - 5, y: m.hip.y + 5 }
const sub = Vector.sub(m.knee, hip)
const off = Vector.mult(Vector.rotate(Vector.normalise(sub), Math.PI / 2), 8)
const kneeBraceHigh = Vector.add(hip, off)
const kneeBraceLow = Vector.add(kneeBraceHigh, Vector.mult(sub, 0.9))
const foot = { x: m.foot.x - 10, y: m.foot.y - 15 }
ctx.save();
ctx.scale(m.flipLegs, 1); //leg lines
ctx.beginPath();
ctx.moveTo(hip.x, hip.y);
ctx.lineTo(m.knee.x, m.knee.y);
ctx.lineTo(foot.x, foot.y);
//extra upper leg brace
ctx.moveTo(kneeBraceHigh.x, kneeBraceHigh.y);
ctx.lineTo(kneeBraceLow.x, kneeBraceLow.y);
ctx.lineTo(m.knee.x, m.knee.y);
ctx.strokeStyle = stroke;
ctx.lineWidth = 3;
ctx.stroke();
//foot
ctx.beginPath();
ctx.moveTo(foot.x, foot.y);
ctx.quadraticCurveTo(m.foot.x - 30, m.foot.y + 12, m.foot.x + 13, m.foot.y + 3);
ctx.lineWidth = 1.5;
ctx.stroke();
//hip joint
ctx.beginPath();
ctx.arc(m.hip.x, m.hip.y - 2, 11, 0, 2 * Math.PI);
//knee joint
ctx.moveTo(m.knee.x + 3, m.knee.y);
ctx.arc(m.knee.x, m.knee.y, 3, 0, 2 * Math.PI);
//knee brace
// ctx.moveTo(kneeBraceHigh.x + 4, kneeBraceHigh.y);
// ctx.arc(kneeBraceHigh.x, kneeBraceHigh.y, 4, 0, 2 * Math.PI);
ctx.moveTo(kneeBraceLow.x + 2.5, kneeBraceLow.y);
ctx.arc(kneeBraceLow.x, kneeBraceLow.y, 2.5, 0, 2 * Math.PI);
//foot joint
ctx.moveTo(foot.x + 2.5, foot.y);
ctx.arc(foot.x, foot.y, 2.5, 0, 2 * Math.PI);
ctx.fillStyle = "#f6f6f6"//m.fillColor;
ctx.fill();
ctx.lineWidth = 1;
// ctx.strokeStyle = "#333"
ctx.stroke();
ctx.restore();
}
},
mech() { mech() {
m.isAltSkin = true m.isAltSkin = true
m.yOffWhen.stand = 52 m.yOffWhen.stand = 52
@@ -1031,6 +1146,7 @@ const m = {
m.drawLeg("#606060"); m.drawLeg("#606060");
m.calcLeg(0, 0); m.calcLeg(0, 0);
m.drawLeg("#444"); m.drawLeg("#444");
ctx.rotate(m.angle); ctx.rotate(m.angle);
ctx.beginPath(); ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI); ctx.arc(0, 0, 30, 0, 2 * Math.PI);

View File

@@ -250,7 +250,6 @@ const powerUps = {
} else if (type === "field") { } else if (type === "field") {
m.setField(index) m.setField(index)
} else if (type === "tech") { } else if (type === "tech") {
// if (tech.isBanish && tech.tech[index].isBanished) tech.tech[index].isBanished = false
simulation.inGameConsole(`<div class="circle-grid tech"></div> &nbsp; <span class='color-var'>tech</span>.giveTech("<strong class='color-text'>${tech.tech[index].name}</strong>")`); simulation.inGameConsole(`<div class="circle-grid tech"></div> &nbsp; <span class='color-var'>tech</span>.giveTech("<strong class='color-text'>${tech.tech[index].name}</strong>")`);
tech.giveTech(index) tech.giveTech(index)
} }
@@ -261,7 +260,6 @@ const powerUps = {
document.getElementById("choose-grid").style.pointerEvents = "none"; document.getElementById("choose-grid").style.pointerEvents = "none";
document.body.style.cursor = "none"; document.body.style.cursor = "none";
setTimeout(() => { setTimeout(() => {
// if (!tech.isNoDraftPause)
document.body.style.cursor = "auto"; document.body.style.cursor = "auto";
document.getElementById("choose-grid").style.pointerEvents = "auto"; document.getElementById("choose-grid").style.pointerEvents = "auto";
document.getElementById("choose-grid").style.transitionDuration = "0s"; document.getElementById("choose-grid").style.transitionDuration = "0s";
@@ -269,7 +267,7 @@ const powerUps = {
simulation.isChoosing = true; //stops p from un pausing on key down simulation.isChoosing = true; //stops p from un pausing on key down
if (!simulation.paused) { if (!simulation.paused) {
if (tech.isNoDraftPause) { if (tech.isNoDraftPause || level.isNoPause) {
document.getElementById("choose-grid").style.opacity = "1" document.getElementById("choose-grid").style.opacity = "1"
} else { } else {
simulation.paused = true; simulation.paused = true;
@@ -610,14 +608,6 @@ const powerUps = {
tech.addJunkTechToPool(0.01) tech.addJunkTechToPool(0.01)
} }
powerUps.research.currentRerollCount++ powerUps.research.currentRerollCount++
// if (tech.isBanish && type === 'tech') { // banish researched tech
// const banishLength = tech.isDeterminism ? 1 : 3 + tech.extraChoices * 2
// for (let i = 0; i < banishLength; i++) {
// const index = powerUps.tech.choiceLog.length - i - 1
// if (powerUps.tech.choiceLog[index] && tech.tech[powerUps.tech.choiceLog[index]]) tech.tech[powerUps.tech.choiceLog[index]].isBanished = true
// }
// simulation.inGameConsole(`powerUps.tech.length: ${Math.max(0,powerUps.tech.lastTotalChoices - banishLength)}`)
// }
if (tech.isResearchReality) { if (tech.isResearchReality) {
m.switchWorlds() m.switchWorlds()
simulation.trails() simulation.trails()
@@ -769,24 +759,24 @@ const powerUps = {
if (tech.isSuperDeterminism) { if (tech.isSuperDeterminism) {
return `<div></div>` return `<div></div>`
} else if (tech.isCancelTech && tech.cancelTechCount === 0) { } else if (tech.isCancelTech && tech.cancelTechCount === 0) {
return `<div class='cancel-card' onclick='powerUps.endDraft("${type}",true)' style="width: 115px;"><span class="color-randomize">randomize</span></div>` return `<div class='cancel-card sticky' onclick='powerUps.endDraft("${type}",true)' style="width: 115px;"><span class="color-randomize">randomize</span></div>`
} else if (level.levelsCleared === 0 && localSettings.isTrainingNotAttempted && b.inventory.length === 0) { //don't show cancel if on initial level and haven't done tutorial } else if (level.levelsCleared === 0 && localSettings.isTrainingNotAttempted && b.inventory.length === 0) { //don't show cancel if on initial level and haven't done tutorial
return `<div class='cancel-card' style="visibility: hidden;"></div>` return `<div class='cancel-card sticky' style="visibility: hidden;"></div>`
} else { } else {
return `<div class='cancel-card' onclick='powerUps.endDraft("${type}",true)' style="width: 85px;">cancel</div>` return `<div class='cancel-card sticky' onclick='powerUps.endDraft("${type}",true)' style="width: 85px;">cancel</div>`
} }
}, },
researchText(type) { researchText(type) {
let text = "" let text = ""
if (type === "entanglement") { if (type === "entanglement") {
text += `<div class='choose-grid-module entanglement flipX' onclick='powerUps.endDraft("${type}",true)'>entanglement</div>` text += `<div class='choose-grid-module entanglement flipX sticky' onclick='powerUps.endDraft("${type}",true)'>entanglement</div>`
} else if (tech.isJunkResearch && powerUps.research.currentRerollCount < 2) { } else if (tech.isJunkResearch && powerUps.research.currentRerollCount < 2) {
text += `<div onclick="powerUps.research.use('${type}')" class='research-card'>` // style = "margin-left: 192px; margin-right: -192px;" text += `<div onclick="powerUps.research.use('${type}')" class='research-card sticky'>` // style = "margin-left: 192px; margin-right: -192px;"
text += `<div><div> <span style="position:relative;">` text += `<div><div> <span style="position:relative;">`
text += `<div class="circle-grid junk" style="position:absolute; top:0; left:${15 * i}px ;opacity:0.8; border: 1px #fff solid;width: 1.15em;height: 1.15em;"></div>` text += `<div class="circle-grid junk" style="position:absolute; top:0; left:${15 * i}px ;opacity:0.8; border: 1px #fff solid;width: 1.15em;height: 1.15em;"></div>`
text += `</span>&nbsp; <span class='research-select'>pseudoscience</span></div></div></div>` text += `</span>&nbsp; <span class='research-select'>pseudoscience</span></div></div></div>`
} else if (powerUps.research.count > 0) { } else if (powerUps.research.count > 0) {
text += `<div onclick="powerUps.research.use('${type}')" class='research-card' >` // style = "margin-left: 192px; margin-right: -192px;" text += `<div onclick="powerUps.research.use('${type}')" class='research-card sticky' >` // style = "margin-left: 192px; margin-right: -192px;"
text += `<div><div><span style="position:relative;">` text += `<div><div><span style="position:relative;">`
for (let i = 0, len = Math.min(powerUps.research.count, 30); i < len; i++) text += `<div class="circle-grid research" style="font-size:0.82em; position:absolute; top:0; left:${(18 - len * 0.21) * i}px ;opacity:0.8; border: 1px #fff solid;"></div>` for (let i = 0, len = Math.min(powerUps.research.count, 30); i < len; i++) text += `<div class="circle-grid research" style="font-size:0.82em; position:absolute; top:0; left:${(18 - len * 0.21) * i}px ;opacity:0.8; border: 1px #fff solid;"></div>`
text += `</span>&nbsp; <span class='research-select'>${tech.isResearchReality ? "<span class='alt'>alternate reality</span>" : "research"}</span></div></div></div>` text += `</span>&nbsp; <span class='research-select'>${tech.isResearchReality ? "<span class='alt'>alternate reality</span>" : "research"}</span></div></div></div>`
@@ -798,7 +788,7 @@ const powerUps = {
researchAndCancelText(type) { researchAndCancelText(type) {
let text = `<div class='research-cancel'>` let text = `<div class='research-cancel'>`
if (type === "entanglement") { if (type === "entanglement") {
text += `<span class='research-card entanglement flipX' style="width: 275px;" onclick='powerUps.endDraft("${type}",true)'><span style="letter-spacing: 6px;">entanglement</span></span>` //&zwnj; text += `<span class='research-card entanglement flipX' style="width: 275px;" onclick='powerUps.endDraft("${type}",true)'><span style="letter-spacing: 6px;">entanglement</span></span>`
} else if (tech.isJunkResearch && powerUps.research.currentRerollCount < 2) { } else if (tech.isJunkResearch && powerUps.research.currentRerollCount < 2) {
text += `<span onclick="powerUps.research.use('${type}')" class='research-card' style="width: 275px;float: left;">` // style = "margin-left: 192px; margin-right: -192px;" text += `<span onclick="powerUps.research.use('${type}')" class='research-card' style="width: 275px;float: left;">` // style = "margin-left: 192px; margin-right: -192px;"
text += `<div><div><span style="position:relative;">` text += `<div><div><span style="position:relative;">`
@@ -1239,23 +1229,8 @@ const powerUps = {
for (let i = 0; i < tech.tech.length; i++) tech.tech[i].isRecentlyShown = false //reset recently shown back to zero for (let i = 0; i < tech.tech.length; i++) tech.tech[i].isRecentlyShown = false //reset recently shown back to zero
if (options.length > 0) { if (options.length > 0) {
let text = powerUps.buildColumns(totalChoices, "tech") let text = powerUps.buildColumns(totalChoices, "tech")
for (let i = 0; i < totalChoices; i++) {
if (options.length < 1) break addTech = (choose) => {
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} <em class='color-text'>//removed from pool by decoherence</em>`)
}
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 + 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)
}
chooseJUNK = list[Math.floor(Math.random() * list.length)]
text += powerUps.junkTechText(chooseJUNK, `powerUps.choose('tech',${chooseJUNK})`)
} else {
if (tech.tech[choose].isFieldTech) { if (tech.tech[choose].isFieldTech) {
text += powerUps.fieldTechText(choose, `powerUps.choose('tech',${choose})`) text += powerUps.fieldTechText(choose, `powerUps.choose('tech',${choose})`)
} else if (tech.tech[choose].isGunTech) { } else if (tech.tech[choose].isGunTech) {
@@ -1269,7 +1244,40 @@ const powerUps = {
} else { //normal tech } else { //normal tech
text += powerUps.techText(choose, `powerUps.choose('tech',${choose})`) text += powerUps.techText(choose, `powerUps.choose('tech',${choose})`)
} }
}
if (tech.isRetain) {
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
addTech(j)
}
}
}
}
for (let i = 0; i < totalChoices; i++) {
if (options.length < 1) break if (options.length < 1) break
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)
}
chooseJUNK = list[Math.floor(Math.random() * list.length)]
if (tech.isRetain) powerUps.retainList.push(tech.tech[chooseJUNK].name)
text += powerUps.junkTechText(chooseJUNK, `powerUps.choose('tech',${chooseJUNK})`)
} else {
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} <em class='color-text'>//removed from pool by decoherence</em>`)
}
removeOption(choose) //remove from future options pool to avoid repeats on this selection
//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)
addTech(choose)
} }
} }
if (tech.isExtraBotOption) { if (tech.isExtraBotOption) {
@@ -1360,6 +1368,7 @@ const powerUps = {
} }
}, },
}, },
retainList: [],
entanglement: { entanglement: {
name: "entanglement", name: "entanglement",
color: "#fff", //"hsl(248,100%,65%)", color: "#fff", //"hsl(248,100%,65%)",

View File

@@ -1497,7 +1497,7 @@ const tech = {
descriptionFunction() { descriptionFunction() {
return `${powerUps.orb.boost(1)} also give <strong>0.3x</strong> <strong class='color-defense'>damage taken</strong><br>for <strong>${(powerUps.boost.duration / 60).toFixed(0)}</strong> seconds</span>` return `${powerUps.orb.boost(1)} also give <strong>0.3x</strong> <strong class='color-defense'>damage taken</strong><br>for <strong>${(powerUps.boost.duration / 60).toFixed(0)}</strong> seconds</span>`
}, },
maxCount: 9, maxCount: 1,
count: 1, count: 1,
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
@@ -3598,7 +3598,7 @@ const tech = {
allowed() { allowed() {
return !tech.isSuperDeterminism return !tech.isSuperDeterminism
}, },
requires: "not superdeterminism", requires: "not, superdeterminism",
bonusResearch: 7, bonusResearch: 7,
effect() { effect() {
tech.isBanish = true tech.isBanish = true
@@ -3614,6 +3614,24 @@ const tech = {
tech.isBanish = false tech.isBanish = false
} }
}, },
{
name: "coherence",
description: `after observing a ${powerUps.orb.tech()} <strong class='color-choice'><span>ch</span><span>oi</span><span>ce</span></strong><br>that <strong class='color-choice'><span>ch</span><span>oi</span><span>ce</span></strong> is available for all <strong>all</strong> future ${powerUps.orb.tech()}`,
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
allowed() {
return tech.isBanish
},
requires: "decoherence",
effect() {
tech.isRetain = true
},
remove() {
tech.isRetain = false
}
},
{ {
name: "peer review", name: "peer review",
description: `after you <strong class='color-r'>research</strong> gain <strong>1.05x</strong> <strong class='color-d'>damage</strong><br>and <strong>+1%</strong> <strong class='color-junk'>JUNK</strong> <strong class='color-choice'><span>ch</span><span>oi</span><span>ces</span></strong>`, description: `after you <strong class='color-r'>research</strong> gain <strong>1.05x</strong> <strong class='color-d'>damage</strong><br>and <strong>+1%</strong> <strong class='color-junk'>JUNK</strong> <strong class='color-choice'><span>ch</span><span>oi</span><span>ces</span></strong>`,
@@ -3743,9 +3761,9 @@ const tech = {
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
allowed() { allowed() {
return !tech.isSuperDeterminism && !tech.isNoDraftPause return !tech.isSuperDeterminism
}, },
requires: "not superdeterminism, eternalism", requires: "not superdeterminism",
effect() { effect() {
tech.isPauseSwitchField = true; tech.isPauseSwitchField = true;
for (let i = 0, len = tech.tech.length; i < len; i++) { for (let i = 0, len = tech.tech.length; i < len; i++) {
@@ -3763,7 +3781,7 @@ const tech = {
}, },
{ {
name: "eternalism", name: "eternalism",
description: `<strong>1.25x</strong> <strong class='color-d'>damage</strong><br><strong>time</strong> can't be <strong>paused</strong> <em style ="float: right;">(time can still be dilated)</em>`, description: `<strong>1.3x</strong> <strong class='color-d'>damage</strong>, but <strong>time</strong> doesn't <strong>pause</strong><br>while <strong class='color-choice'><span>ch</span><span>oos</span><span>ing</span></strong> ${powerUps.orb.field()}, ${powerUps.orb.tech()}, or ${powerUps.orb.gun()}`,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -3772,7 +3790,7 @@ const tech = {
return !tech.isPauseSwitchField && !tech.isPauseEjectTech && !tech.isWormHolePause return !tech.isPauseSwitchField && !tech.isPauseEjectTech && !tech.isWormHolePause
}, },
requires: "not unified field theory, paradigm shift, invariant", requires: "not unified field theory, paradigm shift, invariant",
damage: 1.25, damage: 1.3,
effect() { effect() {
tech.damage *= this.damage tech.damage *= this.damage
tech.isNoDraftPause = true tech.isNoDraftPause = true
@@ -3960,7 +3978,7 @@ const tech = {
{ {
name: "dark patterns", name: "dark patterns",
description: "<strong>1.3x</strong> <strong class='color-d'>damage</strong><br><strong>+15%</strong> <strong class='color-junk'>JUNK</strong> <strong class='color-choice'><span>ch</span><span>oi</span><span>ces</span></strong>", description: "<strong>1.3x</strong> <strong class='color-d'>damage</strong><br><strong>+15%</strong> <strong class='color-junk'>JUNK</strong> <strong class='color-choice'><span>ch</span><span>oi</span><span>ces</span></strong>",
maxCount: 9, maxCount: 3,
count: 0, count: 0,
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
@@ -4604,9 +4622,9 @@ const tech = {
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
allowed() { allowed() {
return !tech.isSuperDeterminism && !tech.isNoDraftPause return !tech.isSuperDeterminism
}, },
requires: "not superdeterminism, eternalism", requires: "not superdeterminism",
effect() { effect() {
tech.isPauseEjectTech = true; tech.isPauseEjectTech = true;
}, },
@@ -6181,7 +6199,7 @@ const tech = {
{ {
name: "water shielding", name: "water shielding",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Radiation_protection#Radiation_shielding' class="link">water shielding</a>`, link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Radiation_protection#Radiation_shielding' class="link">water shielding</a>`,
description: "reduce <strong class='color-p'>radioactive</strong> effects on you by <strong>0.8x</strong><br><em>neutron bomb, drones, explosions, slime</em>", description: "reduce <strong class='color-p'>radioactive</strong> effects on you by <strong>0.2x</strong><br><em>neutron bomb, drones, explosions, slime</em>",
isGunTech: true, isGunTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -7735,7 +7753,7 @@ const tech = {
// }, // },
name: "electronegativity", name: "electronegativity",
descriptionFunction() { descriptionFunction() {
return `<strong>1.0023x</strong> <strong class='color-d'>damage</strong> per <strong class='color-f'>energy</strong><br><em style ="float: right;">(${(1 + 0.23 * m.energy).toFixed(2)} at current energy, ${(1 + 0.23 * m.maxEnergy).toFixed(2)}x at maximum energy)</em>` return `<strong>1.0023x</strong> <strong class='color-d'>damage</strong> per <strong class='color-f'>energy</strong><br><em style ="float: right;">(${(1 + 0.23 * m.energy).toFixed(2)}x, ${(1 + 0.23 * m.maxEnergy).toFixed(2)}x at max energy)</em>`
}, },
// description: "<strong>+1%</strong> <strong class='color-d'>damage</strong> per <strong>8</strong> stored <strong class='color-f'>energy</strong>", // description: "<strong>+1%</strong> <strong class='color-d'>damage</strong> per <strong>8</strong> stored <strong class='color-f'>energy</strong>",
isFieldTech: true, isFieldTech: true,
@@ -11020,7 +11038,7 @@ const tech = {
}, },
{ {
name: "rhythm", name: "rhythm",
description: "you oscillate up and down", description: "you oscillate up and down<br>also you look like an egg",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 0, frequency: 0,
@@ -11031,6 +11049,7 @@ const tech = {
}, },
requires: "", requires: "",
effect() { effect() {
m.skin.egg();
setInterval(() => { setInterval(() => {
m.yOffWhen.stand = 53 + 28 * Math.sin(simulation.cycle * 0.2) m.yOffWhen.stand = 53 + 28 * Math.sin(simulation.cycle * 0.2)
if (m.onGround && !m.crouch) m.yOffGoal = m.yOffWhen.stand if (m.onGround && !m.crouch) m.yOffGoal = m.yOffWhen.stand
@@ -11929,6 +11948,7 @@ const tech = {
cancelTechCount: null, cancelTechCount: null,
isBotDamage: null, isBotDamage: null,
isBanish: null, isBanish: null,
isRetain: null,
isMaxEnergyTech: null, isMaxEnergyTech: null,
isLowEnergyDamage: null, isLowEnergyDamage: null,
isRewindBot: null, isRewindBot: null,

View File

@@ -434,6 +434,15 @@ summary {
line-height: 160%; line-height: 160%;
/* background-color: var(--card-color); */ /* background-color: var(--card-color); */
font-size: 1em; font-size: 1em;
position: sticky;
top: 0px;
z-index: 10;
}
.sticky {
position: sticky;
top: 0px;
z-index: 10;
} }
/* keeps 5 columns at 1440px */ /* keeps 5 columns at 1440px */

View File

@@ -1,33 +1,21 @@
******************************************************** NEXT PATCH ************************************************** ******************************************************** NEXT PATCH **************************************************
tech: hidden-variable theory - after choosing a fieldtech gain 1.15x damage subway
for pilot wave only 2 new subway stations
polariton - boosts also give 0.3x damage taken more visible button graphics on subway
constraints new constraints
removed no health bars
full damage taken after boss dies no pause while choosing
wording is too unclear
new
0.5x energy regen from all sources
balanced
slow bots
bots have roughly 15% reduction in damage in addition to a slow follow speed
mob death heals mobs
has 1000->700 range and 1->0.33 healing
periodically spawn WIMPs
has a 30s delay and a 15->6s spawn rate
50->40% JUNK chance
tech: coherence - past choices are added to all future tech
heuristics gives (1-1.5x)->(1-2x) fire rate and +5% JUNK requires decoherence
autonomous defense harpoon now scale from Bessemer process research and cancel buttons have a sticky scroll positioning
but at half the rate since there are 6 harpoons eternalism: you can't pause while choosing, but you can otherwise pause now
Bessemer process and rail gun scale at 0.1->0.07 1.25->1.3 damage
bugs bugs
crash with training level "heal" and power ups MIRV missiles now interact with time dilation properly
set difficulty mode level 2 for training
******************************************************** BUGS ******************************************************** ******************************************************** BUGS ********************************************************
@@ -65,25 +53,24 @@ procedural animation
maybe no constraints on final boss and reactor? maybe no constraints on final boss and reactor?
constraints balance constraints balance
50% JUNK chance 40% JUNK chance
4x shielded mob chance
power ups are sent to next level
+33% chance for mobs to respawn
-1 choice -1 choice
no health bars
4x shielded mob chance
+33% chance for mobs to respawn
2x ammo costs 2x ammo costs
maybe nerf... too hard
0 duplication 0 duplication
power ups in stasis
0.1x damage after a power up
0.5x energy regen
50% max energy 50% max energy
50% max health 50% max health
bots follow slow bots follow slow
0.1x damage after a power up periodically spawn WIMPs
mob death heals mobs mob death heals mobs
mobs heal for your lost health mobs heal for your lost health
periodically spawn WIMPs
0.5x energy regen
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________________________ not implemented random constraint ideas________________________
mob death spawns something mob death spawns something
mob bullets mob bullets
@@ -93,9 +80,8 @@ each difficulty setting adds a chance for a random effect
mobs slowly regen health mobs slowly regen health
exit door takes 10x time to open, exit door takes 10x time to open,
and while door is opening (ghosters, suckers) attack? 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 can't have more then 15 bullets
bots do 0.5x damage how to code?
remove 2 random tech and return them next level remove 2 random tech and return them next level
too niche too niche
player damage is 0.25x while player is invulnerable player damage is 0.25x while player is invulnerable
@@ -104,9 +90,7 @@ each difficulty setting adds a chance for a random effect
explosions do 0.5x damage explosions do 0.5x damage
freeze effects last 0.25x time freeze effects last 0.25x time
tech: - lower damage taken over 10s to 0x but after taking damage increase damage taken to 1x tech: ice-VII - 1.5x duration for ice-IX
isn't this just CPT skin with less steps?
maybe skin
tech: - freezing grenades/explosions tech: - freezing grenades/explosions
@@ -117,28 +101,10 @@ tech: - randomize constraints somehow
tech: - when you get a bot, get a second bot 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
<eject> 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
tech: - after killing a Boss tech: - after killing a Boss
heal to full heal to full
gain 3x damage for the rest of the level 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?
give damage immunity after teleport for 1+ seconds to balance
new level - rework testChamber new level - rework testChamber
skin with wheel instead of legs skin with wheel instead of legs
@@ -174,9 +140,6 @@ tech: atomic pile - lose 1 health if you are above the maximum energy
do damage? do damage?
plasma torch tech? plasma torch tech?
field tech: molecular assembler - every time you spawn a drone/spore/... become immune to damage for time
scales with how much energy was used to spawn drone/...
figure out how to put instructions for controls in background on initial level figure out how to put instructions for controls in background on initial level
mouse smooth makes the text position jitter when it moves sub pixels mouse smooth makes the text position jitter when it moves sub pixels
hide the jitter with artificial jitter to make it seem intentional hide the jitter with artificial jitter to make it seem intentional
@@ -1392,6 +1355,8 @@ possible names for tech
cryocoolers - freezing effects cryocoolers - freezing effects
metaphysics - maybe this changes something deep and universal about physics? not sure metaphysics - maybe this changes something deep and universal about physics? not sure
cork - used as a heat shield for rockets cork - used as a heat shield for rockets
P = NP - something with speeding up calculation times
transistivity - something where a>b and b>c -> a>c
******************************************************* DESIGN ****************************************************** ******************************************************* DESIGN ******************************************************