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:
BIN
img/coherence.webp
Normal file
BIN
img/coherence.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 54 KiB |
27
js/bullet.js
27
js/bullet.js
@@ -6723,10 +6723,7 @@ const b = {
|
||||
// }
|
||||
// } else {
|
||||
m.fireCDcycle = m.cycle + tech.missileFireCD * b.fireCDscale / countReduction; // cool down
|
||||
const direction = {
|
||||
x: Math.cos(m.angle),
|
||||
y: Math.sin(m.angle)
|
||||
}
|
||||
const direction = { x: Math.cos(m.angle), y: Math.sin(m.angle) }
|
||||
// const where = {
|
||||
// x: m.pos.x + 30 * direction.x,
|
||||
// y: m.pos.y + 30 * direction.y
|
||||
@@ -6752,23 +6749,17 @@ const b = {
|
||||
let count = 0
|
||||
const fireMissile = () => {
|
||||
if (m.crouch) {
|
||||
b.missile({
|
||||
x: m.pos.x + 30 * direction.x,
|
||||
y: m.pos.y + 30 * direction.y
|
||||
}, m.angle, 20, sqrtCountReduction)
|
||||
b.missile({ 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.y += 0.004 + 0.5 * push.y * (Math.random() - 0.5)
|
||||
} else {
|
||||
b.missile({
|
||||
x: m.pos.x + 30 * direction.x,
|
||||
y: m.pos.y + 30 * direction.y
|
||||
}, m.angle, -15, sqrtCountReduction)
|
||||
b.missile({ 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.y += 0.005 + push.y * (Math.random() - 0.5)
|
||||
}
|
||||
}
|
||||
const cycle = () => {
|
||||
if ((simulation.paused || m.isBodiesAsleep) && m.alive) {
|
||||
if ((simulation.paused) && m.alive) {
|
||||
requestAnimationFrame(cycle)
|
||||
} else {
|
||||
count++
|
||||
@@ -6781,15 +6772,9 @@ const b = {
|
||||
requestAnimationFrame(cycle);
|
||||
} else {
|
||||
if (m.crouch) {
|
||||
b.missile({
|
||||
x: m.pos.x + 40 * direction.x,
|
||||
y: m.pos.y + 40 * direction.y
|
||||
}, m.angle, 25)
|
||||
b.missile({ x: m.pos.x + 40 * direction.x, y: m.pos.y + 40 * direction.y }, m.angle, 25)
|
||||
} else {
|
||||
b.missile({
|
||||
x: m.pos.x + 40 * direction.x,
|
||||
y: m.pos.y + 40 * direction.y
|
||||
}, m.angle, -12)
|
||||
b.missile({ 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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1421,7 +1421,7 @@ window.addEventListener("keydown", function (event) {
|
||||
// level.levelAnnounce();
|
||||
document.body.style.cursor = "none";
|
||||
requestAnimationFrame(cycle);
|
||||
} else if (!tech.isNoDraftPause) {
|
||||
} else { //if (!tech.isNoDraftPause)
|
||||
simulation.paused = true;
|
||||
build.pauseGrid()
|
||||
document.body.style.cursor = "auto";
|
||||
|
||||
297
js/level.js
297
js/level.js
@@ -17,7 +17,9 @@ const 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.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()
|
||||
// tech.giveTech("performance")
|
||||
// m.maxHealth = m.health = 1//00000000
|
||||
@@ -44,17 +46,20 @@ const level = {
|
||||
// b.guns[8].ammo = 100000000
|
||||
// requestAnimationFrame(() => { tech.giveTech("stimulated emission") });
|
||||
// tech.giveTech("Hilbert space")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("decoherence")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("mass-energy equivalence")
|
||||
// tech.addJunkTechToPool(0.5)
|
||||
// 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")
|
||||
// requestAnimationFrame(() => { for (let i = 0; i < 1; i++) tech.giveTech("wikipedia") });
|
||||
// requestAnimationFrame(() => { for (let i = 0; i < 1; i++) tech.giveTech("field coupling") });
|
||||
// for (let i = 0; i < 1; i++) tech.giveTech("interest")
|
||||
// m.lastKillCycle = m.cycle
|
||||
// for (let i = 0; i < 1; 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 < 4; i++) powerUps.directSpawn(450, -50, "tech");
|
||||
// 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
|
||||
// level.heal();
|
||||
// level.subway();
|
||||
|
||||
level[simulation.isTraining ? "walk" : "initial"]() //normal starting level **************************************************
|
||||
|
||||
@@ -334,6 +339,30 @@ const level = {
|
||||
constraintDescription1: "", //used in pause menu and console
|
||||
constraintDescription2: "",
|
||||
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",
|
||||
effect() {
|
||||
@@ -561,6 +590,8 @@ const level = {
|
||||
reducedHealthLost: 0,
|
||||
isReducedHealth: false,
|
||||
isReducedRegen: 1,
|
||||
isHideHealth: false,
|
||||
isNoPause: false,
|
||||
levelAnnounce() {
|
||||
const cheating = simulation.isCheating ? "(testing)" : ""
|
||||
if (level.levelsCleared === 0) {
|
||||
@@ -2604,7 +2635,6 @@ const level = {
|
||||
//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 (!simulation.isCheating && localSettings.loreCount < lore.conversation.length) {
|
||||
tech.isNoDraftPause = true //disable pause
|
||||
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.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 }
|
||||
|
||||
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);
|
||||
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
|
||||
@@ -3201,6 +3231,8 @@ const level = {
|
||||
}
|
||||
removeAll(map);
|
||||
map = [];
|
||||
removeAll(composite);
|
||||
composite = []
|
||||
//remove any powerUp that is too far from player
|
||||
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
|
||||
@@ -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
|
||||
@@ -3940,8 +3990,235 @@ const level = {
|
||||
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
|
||||
//add in standard station map infrastructure
|
||||
spawn.mapRect(x + -8000, 0, 16000, 800);//tunnel floor
|
||||
|
||||
19
js/mob.js
19
js/mob.js
@@ -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() {
|
||||
for (let i = 0, len = mob.length; i < len; i++) {
|
||||
if (mob[i].seePlayer.recall && mob[i].showHealthBar) {
|
||||
@@ -1010,8 +1024,9 @@ const mobs = {
|
||||
this.death(); //death with no power up
|
||||
}
|
||||
},
|
||||
healthBar() { //draw health by mob //most health bars are drawn in mobs.healthbar();
|
||||
if (this.seePlayer.recall) {
|
||||
//draw health by mob //most health bars are drawn in mobs.healthBar(); , not this
|
||||
healthBar() {
|
||||
if (this.seePlayer.recall && !level.isHideHealth) {
|
||||
const h = this.radius * 0.3;
|
||||
const w = this.radius * 2;
|
||||
const x = this.position.x - w / 2;
|
||||
|
||||
116
js/player.js
116
js/player.js
@@ -987,6 +987,121 @@ const m = {
|
||||
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() {
|
||||
m.isAltSkin = true
|
||||
m.yOffWhen.stand = 52
|
||||
@@ -1031,6 +1146,7 @@ const m = {
|
||||
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);
|
||||
|
||||
@@ -250,7 +250,6 @@ const powerUps = {
|
||||
} else if (type === "field") {
|
||||
m.setField(index)
|
||||
} else if (type === "tech") {
|
||||
// if (tech.isBanish && tech.tech[index].isBanished) tech.tech[index].isBanished = false
|
||||
simulation.inGameConsole(`<div class="circle-grid tech"></div> <span class='color-var'>tech</span>.giveTech("<strong class='color-text'>${tech.tech[index].name}</strong>")`);
|
||||
tech.giveTech(index)
|
||||
}
|
||||
@@ -261,7 +260,6 @@ const powerUps = {
|
||||
document.getElementById("choose-grid").style.pointerEvents = "none";
|
||||
document.body.style.cursor = "none";
|
||||
setTimeout(() => {
|
||||
// if (!tech.isNoDraftPause)
|
||||
document.body.style.cursor = "auto";
|
||||
document.getElementById("choose-grid").style.pointerEvents = "auto";
|
||||
document.getElementById("choose-grid").style.transitionDuration = "0s";
|
||||
@@ -269,7 +267,7 @@ const powerUps = {
|
||||
simulation.isChoosing = true; //stops p from un pausing on key down
|
||||
|
||||
if (!simulation.paused) {
|
||||
if (tech.isNoDraftPause) {
|
||||
if (tech.isNoDraftPause || level.isNoPause) {
|
||||
document.getElementById("choose-grid").style.opacity = "1"
|
||||
} else {
|
||||
simulation.paused = true;
|
||||
@@ -610,14 +608,6 @@ const powerUps = {
|
||||
tech.addJunkTechToPool(0.01)
|
||||
}
|
||||
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) {
|
||||
m.switchWorlds()
|
||||
simulation.trails()
|
||||
@@ -769,24 +759,24 @@ const powerUps = {
|
||||
if (tech.isSuperDeterminism) {
|
||||
return `<div></div>`
|
||||
} 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
|
||||
return `<div class='cancel-card' style="visibility: hidden;"></div>`
|
||||
return `<div class='cancel-card sticky' style="visibility: hidden;"></div>`
|
||||
} 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) {
|
||||
let text = ""
|
||||
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) {
|
||||
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 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> <span class='research-select'>pseudoscience</span></div></div></div>`
|
||||
} 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;">`
|
||||
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> <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) {
|
||||
let text = `<div class='research-cancel'>`
|
||||
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>` //‌
|
||||
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) {
|
||||
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;">`
|
||||
@@ -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
|
||||
if (options.length > 0) {
|
||||
let text = powerUps.buildColumns(totalChoices, "tech")
|
||||
for (let i = 0; i < totalChoices; i++) {
|
||||
if (options.length < 1) break
|
||||
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 {
|
||||
|
||||
addTech = (choose) => {
|
||||
if (tech.tech[choose].isFieldTech) {
|
||||
text += powerUps.fieldTechText(choose, `powerUps.choose('tech',${choose})`)
|
||||
} else if (tech.tech[choose].isGunTech) {
|
||||
@@ -1269,7 +1244,40 @@ const powerUps = {
|
||||
} else { //normal tech
|
||||
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 (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) {
|
||||
@@ -1360,6 +1368,7 @@ const powerUps = {
|
||||
}
|
||||
},
|
||||
},
|
||||
retainList: [],
|
||||
entanglement: {
|
||||
name: "entanglement",
|
||||
color: "#fff", //"hsl(248,100%,65%)",
|
||||
|
||||
44
js/tech.js
44
js/tech.js
@@ -1497,7 +1497,7 @@ const tech = {
|
||||
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>`
|
||||
},
|
||||
maxCount: 9,
|
||||
maxCount: 1,
|
||||
count: 1,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
@@ -3598,7 +3598,7 @@ const tech = {
|
||||
allowed() {
|
||||
return !tech.isSuperDeterminism
|
||||
},
|
||||
requires: "not superdeterminism",
|
||||
requires: "not, superdeterminism",
|
||||
bonusResearch: 7,
|
||||
effect() {
|
||||
tech.isBanish = true
|
||||
@@ -3614,6 +3614,24 @@ const tech = {
|
||||
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",
|
||||
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,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return !tech.isSuperDeterminism && !tech.isNoDraftPause
|
||||
return !tech.isSuperDeterminism
|
||||
},
|
||||
requires: "not superdeterminism, eternalism",
|
||||
requires: "not superdeterminism",
|
||||
effect() {
|
||||
tech.isPauseSwitchField = true;
|
||||
for (let i = 0, len = tech.tech.length; i < len; i++) {
|
||||
@@ -3763,7 +3781,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
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,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -3772,7 +3790,7 @@ const tech = {
|
||||
return !tech.isPauseSwitchField && !tech.isPauseEjectTech && !tech.isWormHolePause
|
||||
},
|
||||
requires: "not unified field theory, paradigm shift, invariant",
|
||||
damage: 1.25,
|
||||
damage: 1.3,
|
||||
effect() {
|
||||
tech.damage *= this.damage
|
||||
tech.isNoDraftPause = true
|
||||
@@ -3960,7 +3978,7 @@ const tech = {
|
||||
{
|
||||
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>",
|
||||
maxCount: 9,
|
||||
maxCount: 3,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
@@ -4604,9 +4622,9 @@ const tech = {
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return !tech.isSuperDeterminism && !tech.isNoDraftPause
|
||||
return !tech.isSuperDeterminism
|
||||
},
|
||||
requires: "not superdeterminism, eternalism",
|
||||
requires: "not superdeterminism",
|
||||
effect() {
|
||||
tech.isPauseEjectTech = true;
|
||||
},
|
||||
@@ -6181,7 +6199,7 @@ const tech = {
|
||||
{
|
||||
name: "water shielding",
|
||||
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,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -7735,7 +7753,7 @@ const tech = {
|
||||
// },
|
||||
name: "electronegativity",
|
||||
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>",
|
||||
isFieldTech: true,
|
||||
@@ -11020,7 +11038,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "rhythm",
|
||||
description: "you oscillate up and down",
|
||||
description: "you oscillate up and down<br>also you look like an egg",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 0,
|
||||
@@ -11031,6 +11049,7 @@ const tech = {
|
||||
},
|
||||
requires: "",
|
||||
effect() {
|
||||
m.skin.egg();
|
||||
setInterval(() => {
|
||||
m.yOffWhen.stand = 53 + 28 * Math.sin(simulation.cycle * 0.2)
|
||||
if (m.onGround && !m.crouch) m.yOffGoal = m.yOffWhen.stand
|
||||
@@ -11929,6 +11948,7 @@ const tech = {
|
||||
cancelTechCount: null,
|
||||
isBotDamage: null,
|
||||
isBanish: null,
|
||||
isRetain: null,
|
||||
isMaxEnergyTech: null,
|
||||
isLowEnergyDamage: null,
|
||||
isRewindBot: null,
|
||||
|
||||
@@ -434,6 +434,15 @@ summary {
|
||||
line-height: 160%;
|
||||
/* background-color: var(--card-color); */
|
||||
font-size: 1em;
|
||||
position: sticky;
|
||||
top: 0px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.sticky {
|
||||
position: sticky;
|
||||
top: 0px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
/* keeps 5 columns at 1440px */
|
||||
|
||||
85
todo.txt
85
todo.txt
@@ -1,33 +1,21 @@
|
||||
******************************************************** NEXT PATCH **************************************************
|
||||
|
||||
tech: hidden-variable theory - after choosing a fieldtech gain 1.15x damage
|
||||
for pilot wave only
|
||||
polariton - boosts also give 0.3x damage taken
|
||||
subway
|
||||
2 new subway stations
|
||||
more visible button graphics on subway
|
||||
|
||||
constraints
|
||||
removed
|
||||
full damage taken after boss dies
|
||||
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
|
||||
new constraints
|
||||
no health bars
|
||||
no pause while choosing
|
||||
|
||||
|
||||
heuristics gives (1-1.5x)->(1-2x) fire rate and +5% JUNK
|
||||
autonomous defense harpoon now scale from Bessemer process
|
||||
but at half the rate since there are 6 harpoons
|
||||
Bessemer process and rail gun scale at 0.1->0.07
|
||||
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
|
||||
crash with training level "heal" and power ups
|
||||
set difficulty mode level 2 for training
|
||||
MIRV missiles now interact with time dilation properly
|
||||
|
||||
******************************************************** BUGS ********************************************************
|
||||
|
||||
@@ -65,25 +53,24 @@ procedural animation
|
||||
maybe no constraints on final boss and reactor?
|
||||
|
||||
constraints balance
|
||||
50% JUNK chance
|
||||
4x shielded mob chance
|
||||
power ups are sent to next level
|
||||
+33% chance for mobs to respawn
|
||||
40% JUNK chance
|
||||
-1 choice
|
||||
no health bars
|
||||
4x shielded mob chance
|
||||
+33% chance for mobs to respawn
|
||||
2x ammo costs
|
||||
maybe nerf...
|
||||
too hard
|
||||
0 duplication
|
||||
power ups in stasis
|
||||
0.1x damage after a power up
|
||||
0.5x energy regen
|
||||
50% max energy
|
||||
50% max health
|
||||
bots follow slow
|
||||
0.1x damage after a power up
|
||||
periodically spawn WIMPs
|
||||
mob death heals mobs
|
||||
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________________________
|
||||
mob death spawns something
|
||||
mob bullets
|
||||
@@ -93,9 +80,8 @@ each difficulty setting adds a chance for a random effect
|
||||
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
|
||||
how to code?
|
||||
remove 2 random tech and return them next level
|
||||
too niche
|
||||
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
|
||||
freeze effects last 0.25x time
|
||||
|
||||
tech: - lower damage taken over 10s to 0x but after taking damage increase damage taken to 1x
|
||||
isn't this just CPT skin with less steps?
|
||||
maybe skin
|
||||
tech: ice-VII - 1.5x duration for ice-IX
|
||||
|
||||
tech: - freezing grenades/explosions
|
||||
|
||||
@@ -117,28 +101,10 @@ tech: - randomize constraints somehow
|
||||
|
||||
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
|
||||
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?
|
||||
give damage immunity after teleport for 1+ seconds to balance
|
||||
|
||||
new level - rework testChamber
|
||||
|
||||
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?
|
||||
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
|
||||
mouse smooth makes the text position jitter when it moves sub pixels
|
||||
hide the jitter with artificial jitter to make it seem intentional
|
||||
@@ -1392,6 +1355,8 @@ possible names for tech
|
||||
cryocoolers - freezing effects
|
||||
metaphysics - maybe this changes something deep and universal about physics? not sure
|
||||
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 ******************************************************
|
||||
|
||||
|
||||
Reference in New Issue
Block a user