switchWorlds

reworked m.switchWorlds() (used in many-worlds and similar effects)
  no longer has extra bot build up
  effects that carry over into next world:
    your total tech count
    effects of non-removeable tech, like determinism
mass production research ramps up by 5->4 each time
bot fabrications cost ramp is increased to (+1 per 4)-->(+1 per 3)
lowered minimum threshold for making small heals from over healing to 13->20 health
snakeBoss invulnerable phase is 5->4 seconds long

time dilation disables level based lasers
adjusted laser sensor paths on substructure level

move splash screen buttons to bottom right
added a start button
details menus in splash screen now have individual widths instead of sharing with each other

bugs
  non-renewables change color for ammo power ups on current level
This commit is contained in:
landgreen
2024-11-25 20:05:56 -08:00
parent 1fde74d65a
commit f1a6713f68
13 changed files with 535 additions and 291 deletions

View File

@@ -39,20 +39,22 @@
<div style="position: absolute; top:0;right:0;">
<div id="pause-grid-right" class="pause-grid"></div>
</div>
<svg class="SVG-button" id="experiment-button" width="170" height="45" style="border: 2px #333 solid;">
<g stroke='none' fill='#333' stroke-width="2" font-size="30px" font-family="Arial, sans-serif">
<text x="10" y="33">experiment</text>
</g>
<svg class="SVG-button SVG-button-splash" id="start-button" width="82" height="45" stroke='none' fill='#333' font-size="30px" font-family="Arial, sans-serif" onclick="simulation.startGame()">
<text x="10" y="32">start</text>
</svg>
<svg class="SVG-button" id="training-button" width="120" height="45" style="border: 2px #333 solid;" stroke='none' fill='#333' font-size="30px" font-family="Arial, sans-serif" onclick="simulation.startGame(false, true)">
<text x="10" y="33">training</text>
<svg class="SVG-button SVG-button-splash" id="training-button" width="120" height="45" stroke='none' fill='#333' font-size="30px" font-family="Arial, sans-serif" onclick="simulation.startGame(false, true)">
<text x="10" y="32">training</text>
</svg>
<svg class="SVG-button SVG-button-splash" id="experiment-button" width="170" height="45">
<text stroke='none' fill='#333' stroke-width="2" font-size="30px" font-family="Arial, sans-serif" x="10" y="32">experiment</text>
</svg>
<div id='info'>
<div id="settings" >
<details id = 'settings-details'>
<div>
<details id='settings-details'>
<summary>settings</summary>
<div style="line-height: 150%;" class="details-div">
<div class="details-div" style="max-width: 24rem; line-height: 150%;">
<input onclick="build.showImages('settings')" type="checkbox" id="hide-images" name="hide-images" style="width:17px; height:17px;">
<label for="hide-images" title="hide images for fields, guns, and tech">hide images</label>
<br>
@@ -103,7 +105,7 @@
<div>
<details id="control-details">
<summary>controls</summary>
<div class="details-div">
<div class="details-div" style="max-width: 24rem;">
To change controls click a box
<br>and press an unused key.
<br><br>
@@ -171,13 +173,13 @@
<div>
<details id="updates">
<summary>updates</summary>
<div id="updates-div" class="details-div" style="font-size: 70%;height: 400px;overflow: scroll;max-width: 800px;"></div>
<div id="updates-div" class="details-div" style="font-size: 70%;height: 400px;overflow: scroll;max-width: 50rem;"></div>
</details>
</div>
<div>
<details>
<summary>about</summary>
<div class="details-div" style="max-width: 450px;">
<div class="details-div" style="max-width: 24rem;">
n-gon is a solo project written in JavaScript, CSS, and HTML using the matter.js 2-D physics library. It's free and open source on <a href="https://github.com/landgreen/n-gon">Github</a>.
<a id="github" href="https://github.com/landgreen/n-gon" aria-label="github">
<svg viewBox="0 0 100 16" xmlns="http://www.w3.org/2000/svg" fill="#1B1F23">

View File

@@ -624,7 +624,7 @@ const b = {
clusterExplode(where, size) { //can occur after grenades detonate
const cycle = () => {
if (m.alive) {
if (simulation.paused || m.isBodiesAsleep) {
if (simulation.paused || m.isTimeDilated) {
requestAnimationFrame(cycle)
} else {
count++
@@ -643,7 +643,7 @@ const b = {
const color = `hsla(${360 * Math.random()},100%,66%,0.6)`
const cycle = () => {
if (m.alive) {
if (simulation.paused || m.isBodiesAsleep) {
if (simulation.paused || m.isTimeDilated) {
requestAnimationFrame(cycle)
} else {
count++
@@ -668,7 +668,7 @@ const b = {
const range = size * Math.sqrt(b.explosionRange())
const cycle = () => {
if (m.alive) {
if (simulation.paused || m.isBodiesAsleep) {
if (simulation.paused || m.isTimeDilated) {
requestAnimationFrame(cycle)
} else {
if (count < 30 && m.alive) requestAnimationFrame(cycle);
@@ -4505,14 +4505,15 @@ const b = {
}
},
zeroBotCount() { //remove all bots
tech.dynamoBotCount = 0
tech.laserBotCount = 0
tech.nailBotCount = 0
tech.foamBotCount = 0
tech.soundBotCount = 0
tech.boomBotCount = 0
tech.orbitBotCount = 0
tech.missileBotCount = 0
tech.dynamoBotCount = 0;
tech.nailBotCount = 0;
tech.laserBotCount = 0;
tech.orbitBotCount = 0;
tech.foamBotCount = 0;
tech.soundBotCount = 0;
tech.boomBotCount = 0;
tech.plasmaBotCount = 0;
tech.missileBotCount = 0;
},
respawnBots() {
for (let i = 0; i < tech.dynamoBotCount; i++) b.dynamoBot({
@@ -5032,7 +5033,7 @@ const b = {
} else { //fire mode: quickly fire at targets and doesn't follow player
this.fire()
}
if (!m.isBodiesAsleep) { //update current waves
if (!m.isTimeDilated) { //update current waves
ctx.strokeStyle = "rgba(0,0,0,0.6)" //"000";
ctx.lineWidth = 2 * tech.wavePacketDamage
ctx.beginPath();
@@ -5713,7 +5714,7 @@ const b = {
b.needle()
function cycle() {
if (simulation.paused || m.isBodiesAsleep) {
if (simulation.paused || m.isTimeDilated) {
requestAnimationFrame(cycle)
} else {
count++
@@ -5728,7 +5729,7 @@ const b = {
b.needle()
function cycle() {
if (simulation.paused || m.isBodiesAsleep) {
if (simulation.paused || m.isTimeDilated) {
requestAnimationFrame(cycle)
} else {
count++
@@ -6356,7 +6357,7 @@ const b = {
},
do() { },
do360Longitudinal() {
if (!m.isBodiesAsleep) {
if (!m.isTimeDilated) {
ctx.strokeStyle = "rgba(0,0,0,0.6)" //"000";
ctx.lineWidth = 2 * tech.wavePacketDamage
ctx.beginPath();
@@ -6453,7 +6454,7 @@ const b = {
})
},
doLongitudinal() {
if (!m.isBodiesAsleep) {
if (!m.isTimeDilated) {
ctx.strokeStyle = "rgba(0,0,0,0.6)" //"000";
ctx.lineWidth = 2 * tech.wavePacketDamage
ctx.beginPath();

View File

@@ -116,7 +116,7 @@ function collisionChecks(event) {
m.damage(dmg); //normal damage
if (tech.isCollisionRealitySwitch && m.alive) {
m.switchWorlds()
m.switchWorlds("Hilbert space")
simulation.trails(90)
simulation.inGameConsole(`simulation.amplitude <span class='color-symbol'>=</span> ${Math.random()}`);
}

View File

@@ -1066,8 +1066,7 @@ ${simulation.difficultyMode > 4 ? `<details id="constraints-details" style="padd
b.activeGun = null;
b.inventoryGun = 0;
simulation.makeGunHUD();
tech.setupAllTech();
m.resetSkin();
tech.resetAllTech();
build.populateGrid();
document.getElementById("field-0").classList.add("build-field-selected");
document.getElementById("experiment-grid").style.display = "grid"
@@ -1168,6 +1167,7 @@ ${simulation.difficultyMode > 4 ? `<details id="constraints-details" style="padd
function openExperimentMenu() {
document.getElementById("experiment-button").style.display = "none";
document.getElementById("training-button").style.display = "none";
document.getElementById("start-button").style.display = "none";
const el = document.getElementById("experiment-grid")
el.style.display = "grid"
document.body.style.overflowY = "scroll";

View File

@@ -31,7 +31,7 @@ const level = {
// tech.tech[297].frequency = 100
// tech.addJunkTechToPool(0.5)
// m.couplingChange(10)
// m.setField("negative mass") //1 standing wave 2 perfect diamagnetism 3 negative mass 4 molecular assembler 5 plasma torch 6 time dilation 7 metamaterial cloaking 8 pilot wave 9 wormhole 10 grappling hook
// m.setField("time dilation") //1 standing wave 2 perfect diamagnetism 3 negative mass 4 molecular assembler 5 plasma torch 6 time dilation 7 metamaterial cloaking 8 pilot wave 9 wormhole 10 grappling hook
// m.energy = 0
// powerUps.research.count = 3
// tech.isHookWire = true
@@ -52,7 +52,7 @@ const level = {
// for (let i = 0; i < 1; ++i) tech.giveTech("quantum immortality")
// m.skin.egg();
// for (let i = 0; i < 1; ++i) tech.giveTech("non-renewables")
// for (let i = 0; i < 1; ++i) tech.giveTech("many-worlds")
// requestAnimationFrame(() => { for (let i = 0; i < 1; i++) tech.giveTech("quasiparticles") });
// requestAnimationFrame(() => { for (let i = 0; i < 1; i++) tech.giveTech("field coupling") });
// for (let i = 0; i < 1; i++) tech.giveTech("interest")
@@ -178,10 +178,9 @@ const level = {
}
if (tech.isSwitchReality && level.levelsCleared !== 0) {
simulation.inGameConsole(`simulation.amplitude <span class='color-symbol'>=</span> ${Math.random()}`);
m.switchWorlds()
m.switchWorlds("many-worlds")
simulation.trails()
powerUps.spawn(player.position.x + 50, player.position.y - Math.random() * 50, "tech", false);
powerUps.spawnDelay("coupling", 3);
}
if (tech.isHealLowHealth) {
const len = tech.isEnergyHealth ? 5 * Math.max(0, m.maxEnergy - m.energy) : 5 * Math.max(0, m.maxHealth - m.health)
@@ -1075,7 +1074,7 @@ const level = {
y: who.position.y
}
who.rotate = function () {
if (!m.isBodiesAsleep) {
if (!m.isTimeDilated) {
Matter.Body.applyForce(this, {
x: this.position.x + 100,
y: this.position.y + 100
@@ -1089,7 +1088,7 @@ const level = {
}
// if (rotate) {
// rotor.rotate = function() {
// if (!m.isBodiesAsleep) {
// if (!m.isTimeDilated) {
// Matter.Body.applyForce(rotor, {
// x: rotor.position.x + 100,
// y: rotor.position.y + 100
@@ -1241,7 +1240,7 @@ const level = {
frictionAir: 0.001,
holdX: x,
move() {
if (!m.isBodiesAsleep) {
if (!m.isTimeDilated) {
if (this.isUp) { //moving up still with high air friction
this.force.y -= force * this.mass //hard force propels up, even with high friction
@@ -1274,7 +1273,7 @@ const level = {
Matter.Body.setPosition(this, { x: this.holdX, y: this.position.y });
},
moveOnTouch() {
if (!m.isBodiesAsleep) {
if (!m.isTimeDilated) {
if (this.isUp) { //moving up still with high air friction
this.force.y -= force * this.mass //hard force propels up, even with high friction
@@ -1477,7 +1476,7 @@ const level = {
// if (rotate) {
// rotor.rotate = function() {
// if (!m.isBodiesAsleep) {
// if (!m.isTimeDilated) {
// Matter.Body.applyForce(rotor, {
// x: rotor.position.x + 100,
// y: rotor.position.y + 100
@@ -1802,7 +1801,7 @@ const level = {
query() {
if (this.isThere) {
if (this.isTouched) {
if (!m.isBodiesAsleep) {
if (!m.isTimeDilated) {
this.fadeCount--
Matter.Body.setVertices(this, this.shrinkVertices(Math.max(this.fadeCount / this.fadeTime, 0.03)))
}
@@ -1820,7 +1819,7 @@ const level = {
this.fadeCount = this.fadeTime;
}
} else {
if (!m.isBodiesAsleep) {
if (!m.isTimeDilated) {
this.returnCount--
if (this.returnCount < 1) {
Matter.Body.setPosition(this, {
@@ -1901,7 +1900,7 @@ const level = {
restitution: 0,
isClosing: false,
openClose() {
if (!m.isBodiesAsleep) {
if (!m.isTimeDilated) {
if (this.isClosing) {
if (this.position.y < y) { //try to close
if ( //if clear of stuff
@@ -1961,7 +1960,7 @@ const level = {
restitution: 0,
isClosing: false,
openClose(isSetPaths = false) {
if (!m.isBodiesAsleep) {
if (!m.isTimeDilated) {
if (this.isClosing) {
if (this.position.y < y) { //try to close
if ( //if clear of stuff
@@ -2192,7 +2191,7 @@ const level = {
dropCycle: 0,
speed: 0,
draw() {
if (!m.isBodiesAsleep) {
if (!m.isTimeDilated) {
if (this.dropCycle < simulation.cycle) { //reset
this.dropCycle = simulation.cycle + this.period + Math.floor(40 * Math.random())
this.y = yMin
@@ -2218,50 +2217,11 @@ const level = {
look: p2,
color: color,
query() {
let best = { x: null, y: null, dist2: Infinity, who: null, v1: null, v2: null }
best = vertexCollision(this.position, this.look, m.isCloak ? [map, body] : [map, body, [playerBody, playerHead]]);
// hitting player
if ((best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) {
m.immuneCycle = m.cycle + m.collisionImmuneCycles + 60; //player is immune to damage for an extra second
const dmg = damage * simulation.dmgScale;
m.damage(dmg);
simulation.drawList.push({ //add dmg to draw queue
x: best.x,
y: best.y,
radius: dmg * 1500,
color: "rgba(255,0,0,0.5)",
time: 20
});
}
//draw
if (best.dist2 === Infinity) best = this.look;
ctx.beginPath();
ctx.moveTo(this.position.x, this.position.y);
ctx.lineTo(best.x, best.y);
ctx.strokeStyle = this.color;
ctx.lineWidth = 5;
ctx.setLineDash([50 + 200 * Math.random(), 50 * Math.random()]);
ctx.stroke();
ctx.setLineDash([]);
},
countDown: 0,
countTotal: 480,
countDelay: 440,
motionQuery() {
let best = { x: null, y: null, dist2: Infinity, who: null, v1: null, v2: null }
best = vertexCollision(this.position, this.look, m.isCloak ? [map, body] : [map, body, [playerBody, playerHead]]);
if (this.countDown === 0) {
if ((best.who === playerBody || best.who === playerHead)) this.countDown = this.countTotal // hitting player
ctx.strokeStyle = `rgba(255,255,255,0.4)`;
ctx.lineWidth = 8 + 3 * Math.sin(simulation.cycle * 0.3);
} else if (this.countDown > this.countDelay) {
ctx.strokeStyle = `rgba(255,255,255,0.8)`;
ctx.lineWidth = 11;
this.countDown--
} else {
this.countDown--
if ((best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) { // hitting player
if (!m.isTimeDilated) {
let best = { x: null, y: null, dist2: Infinity, who: null, v1: null, v2: null }
best = vertexCollision(this.position, this.look, m.isCloak ? [map, body] : [map, body, [playerBody, playerHead]]);
// hitting player
if ((best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) {
m.immuneCycle = m.cycle + m.collisionImmuneCycles + 60; //player is immune to damage for an extra second
const dmg = damage * simulation.dmgScale;
m.damage(dmg);
@@ -2273,17 +2233,60 @@ const level = {
time: 20
});
}
//draw
if (best.dist2 === Infinity) best = this.look;
ctx.beginPath();
ctx.moveTo(this.position.x, this.position.y);
ctx.lineTo(best.x, best.y);
ctx.strokeStyle = this.color;
ctx.lineWidth = 5;
ctx.setLineDash([50 + 200 * Math.random(), 50 * Math.random()]);
ctx.stroke();
ctx.setLineDash([]);
}
},
countDown: 0,
countTotal: 480,
countDelay: 440,
motionQuery() {
if (!m.isTimeDilated) {
let best = { x: null, y: null, dist2: Infinity, who: null, v1: null, v2: null }
best = vertexCollision(this.position, this.look, m.isCloak ? [map, body] : [map, body, [playerBody, playerHead]]);
if (this.countDown === 0) {
if ((best.who === playerBody || best.who === playerHead)) this.countDown = this.countTotal // hitting player
ctx.strokeStyle = `rgba(255,255,255,0.4)`;
ctx.lineWidth = 8 + 3 * Math.sin(simulation.cycle * 0.3);
} else if (this.countDown > this.countDelay) {
ctx.strokeStyle = `rgba(255,255,255,0.8)`;
ctx.lineWidth = 11;
this.countDown--
} else {
this.countDown--
if ((best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) { // hitting player
m.immuneCycle = m.cycle + m.collisionImmuneCycles + 60; //player is immune to damage for an extra second
const dmg = damage * simulation.dmgScale;
m.damage(dmg);
simulation.drawList.push({ //add dmg to draw queue
x: best.x,
y: best.y,
radius: dmg * 1500,
color: "rgba(255,0,0,0.5)",
time: 20
});
}
ctx.strokeStyle = this.color;
ctx.lineWidth = 5;
ctx.setLineDash([50 + 200 * Math.random(), 50 * Math.random()]);
}
//draw
if (best.dist2 === Infinity) best = this.look;
ctx.beginPath();
ctx.moveTo(this.position.x, this.position.y);
ctx.lineTo(best.x, best.y);
ctx.stroke();
ctx.setLineDash([]);
}
//draw
if (best.dist2 === Infinity) best = this.look;
ctx.beginPath();
ctx.moveTo(this.position.x, this.position.y);
ctx.lineTo(best.x, best.y);
ctx.stroke();
ctx.setLineDash([]);
},
}
},
@@ -2365,21 +2368,21 @@ const level = {
// }
// },
levelRise(growRate = 1) {
if (this.height < this.maxHeight && !m.isBodiesAsleep) {
if (this.height < this.maxHeight && !m.isTimeDilated) {
this.height += growRate
this.min.y -= growRate
this.max.y = this.min.y + this.height
}
},
levelFall(fallRate = 1) {
if (this.height > 0 && !m.isBodiesAsleep) {
if (this.height > 0 && !m.isTimeDilated) {
this.height -= fallRate
this.min.y += fallRate
this.max.y = this.min.y + this.height
}
},
level(isFill, growSpeed = 1) {
if (!m.isBodiesAsleep) {
if (!m.isTimeDilated) {
if (isFill) {
if (this.height < this.maxHeight) {
this.height += growSpeed
@@ -2414,7 +2417,7 @@ const level = {
VxGoal: VxGoal,
force: force,
push() {
if (!m.isBodiesAsleep) {
if (!m.isTimeDilated) {
const touchingPlayer = Matter.Query.collides(this, [jumpSensor])
if (touchingPlayer.length) {
m.moverX = this.VxGoal
@@ -2496,7 +2499,7 @@ const level = {
VxGoal: VxGoal,
force: force,
move() {
if (!m.isBodiesAsleep) {
if (!m.isTimeDilated) {
Matter.Body.setPosition(this, { x: this.position.x + this.VxGoal, y: this.position.y }); //horizontal movement
const touchingPlayer = Matter.Query.collides(this, [jumpSensor])
if (touchingPlayer.length) {
@@ -3182,7 +3185,7 @@ const level = {
// spawn.mapRect(-2750, -2800, 2600, 4600); //left wall
spawn.mapRect(-2750, -2800, 2600, 2515);
spawn.mapRect(-3275, -185, 3125, 1985);
powerUps.directSpawn(-2315, -3050, "instructions", false);
requestAnimationFrame(() => { powerUps.directSpawn(-2315, -3050, "instructions", false); });
spawn.mapRect(-3275, -2800, 400, 3250);
spawn.mapRect(-2775, -575, 50, 25);
spawn.mapRect(-2775, -950, 50, 25);
@@ -4650,7 +4653,7 @@ const level = {
//draw slime fill
ctx.fillStyle = `hsla(160, 100%, 43%,${0.3 + 0.07 * Math.random()})`
ctx.fillRect(waterFallX, -5050, waterFallWidth, 6175 - slime.height)
if (!m.isBodiesAsleep) {
if (!m.isTimeDilated) {
waterFallWidth = 0.98 * waterFallWidth + 4.7 * Math.random()
waterFallSmoothX = 0.98 * waterFallSmoothX + 3.5 * Math.random()
waterFallX = 1857 - waterFallSmoothX
@@ -4766,7 +4769,7 @@ const level = {
//draw slime fill
ctx.fillStyle = `hsla(160, 100%, 43%,${0.3 + 0.07 * Math.random()})`
ctx.fillRect(waterFallX, -5050, waterFallWidth, 6175 - slime.height)
if (!m.isBodiesAsleep) {
if (!m.isTimeDilated) {
waterFallWidth = 0.98 * waterFallWidth + 4.7 * Math.random()
waterFallSmoothX = 0.98 * waterFallSmoothX + 3.5 * Math.random()
waterFallX = waterFallSmoothX - 1985
@@ -5383,7 +5386,7 @@ const level = {
}
}
}
if (mob.length < 100 && !m.isBodiesAsleep) {
if (mob.length < 100 && !m.isTimeDilated) {
block2Mob(0)
block2Mob(1)
block2Mob(2)
@@ -7134,7 +7137,7 @@ const level = {
drag: 0.01,
move() {
this.force.y -= this.mass * simulation.g; //undo gravity
if (!m.isBodiesAsleep) {
if (!m.isTimeDilated) {
if (level.isFlipped) {
ctx.fillStyle = "#ccc"
ctx.fillRect(this.holdX, -this.maxHeight, 5, this.maxHeight - this.minHeight) //draw path
@@ -7936,31 +7939,25 @@ const level = {
// spawn.bodyRect(1900, 1875, 100, 125, 0.5);
spawn.bodyRect(-2569, 825, 25, 165);
spawn.randomMob(-3750, -400, 0.2);
spawn.randomMob(-3425, -600, 0.2);
spawn.randomMob(-3225, -625, 0.3);
spawn.randomMob(-2850, -500, 0.3);
spawn.randomMob(-2450, -675, 0.3);
spawn.randomMob(-2150, -650, 0.4);
spawn.randomMob(-1650, -500, 0.4);
spawn.randomMob(-1325, 275, 0.4);
spawn.randomMob(-825, 425, 0.5);
spawn.randomMob(-400, -575, 0.5);
spawn.randomMob(-1275, -900, 0.5);
spawn.randomMob(-675, -775, 0.6);
spawn.randomMob(150, -725, 0.6);
spawn.randomMob(475, 925, 0.7);
spawn.randomMob(1500, 550, 0.7);
spawn.randomMob(1850, 500, 0.7);
spawn.randomMob(2025, 925, 0.8);
spawn.randomMob(1575, 875, 0.8);
spawn.randomMob(2650, 650, 0.9);
spawn.randomMob(3100, 700, 0.9);
spawn.randomMob(3050, 100, 1);
spawn.randomMob(2350, 100, 1);
spawn.randomMob(3400, 875, 1);
spawn.randomMob(3375, -725, 1);
spawn.randomMob(3925, 100, 1);
spawn.randomMob(-2275, -675, 0);
spawn.randomMob(-1200, 475, 0);
spawn.randomMob(525, 875, 0.1);
spawn.randomMob(1975, 900, 0.2);
spawn.randomMob(2800, 875, 0.2);
spawn.randomMob(-3275, -600, 0.3);
spawn.randomMob(-1250, -900, 0.3);
spawn.randomMob(-475, -600, 0.3);
spawn.randomMob(-1750, 850, 0.4);
spawn.randomMob(1700, 525, 0.4);
spawn.randomMob(2925, 175, 0.5);
spawn.randomMob(-2300, -825, 0.5);
spawn.randomMob(-1625, -450, 0.6);
spawn.randomMob(-225, 900, 0.6);
spawn.randomMob(275, -775, 0.7);
spawn.randomMob(2800, 875, 0.8);
spawn.randomMob(3825, -750, 0.9);
spawn.randomMob(2825, 150, 1);
spawn.randomMob(-1900, 875, 1);
powerUps.spawnStartingPowerUps(-825, -600);
spawn.randomLevelBoss(1550, 200);
@@ -7982,11 +7979,11 @@ const level = {
const boost2 = level.boost(3400, 1000, 1750)
const lasers = []
const center = { x: 2800, y: 300 }
const center = { x: 2800, y: 200 }
map[map.length] = Matter.Bodies.polygon(center.x, center.y, 20, 100) //center circle with lasers
lasers.push(level.laser({ x: center.x, y: center.y }, { x: center.x, y: center.y })) //oscillating laser
lasers[lasers.length - 1].oscillate = function () {
const angle = Math.PI / 2 - 1.55 * Math.sin(0.02 * simulation.cycle) //oscillate around circle
const angle = -0.45 + Math.PI / 2 - 1.47 * Math.sin(0.02 * simulation.cycle) //oscillate around circle
this.position = {
x: center.x + 102 * Math.cos(angle),
y: center.y + 102 * Math.sin(angle)
@@ -7998,7 +7995,7 @@ const level = {
}
lasers.push(level.laser({ x: center.x, y: center.y }, { x: center.x, y: center.y })) //oscillating laser
lasers[lasers.length - 1].oscillate = function () {
const angle = -Math.PI / 2 + 1.55 * Math.sin(0.02 * simulation.cycle) //oscillate around circle
const angle = -0.45 + -Math.PI / 2 + 1.47 * Math.sin(0.02 * simulation.cycle) //oscillate around circle
this.position = {
x: center.x + 102 * Math.cos(angle),
y: center.y + 102 * Math.sin(angle)
@@ -8066,7 +8063,7 @@ const level = {
boost2.query();
ctx.fillStyle = "#cacfcf"
ctx.fillRect(2787, -425, 25, 800);
ctx.fillRect(2787, -425, 25, 650);
ctx.fillRect(-600, -1050, 400, 1800);
level.exit.drawAndCheck();
@@ -20336,7 +20333,7 @@ const level = {
restitution: 0,
isClosing: false,
openClose() {
if (!m.isBodiesAsleep) {
if (!m.isTimeDilated) {
if (this.isClosing) {
if (this.position.x > x) { //try to close
if ( //if clear of stuff
@@ -21006,7 +21003,7 @@ const level = {
drawBackgroundGear(-1010, -2380, 30, 100, -0.1, "#ccc", 0.05);
// pendulum gears
if (!m.isBodiesAsleep) smallGearPosRot += Math.sin((simulation.cycle - startCycle) / 50) * 0.3 - Math.sin((simulation.cycle - startCycle - 1) / 50) * 0.3;
if (!m.isTimeDilated) smallGearPosRot += Math.sin((simulation.cycle - startCycle) / 50) * 0.3 - Math.sin((simulation.cycle - startCycle - 1) / 50) * 0.3;
if (smallGearPosRot > 0.1) smallGearPosRot = 0.1;
if (smallGearPosRot < -0.1) smallGearPosRot = -0.1;
var circ = 2 * Math.PI * 150;
@@ -24558,7 +24555,7 @@ const level = {
}
me.waves = [];
me.doLongitudinal = function () {
if (!m.isBodiesAsleep) {
if (!m.isTimeDilated) {
ctx.strokeStyle = "rgba(0,0,0,0.6)" //"000";
ctx.lineWidth = 2 * tech.wavePacketDamage
ctx.beginPath();
@@ -27286,7 +27283,7 @@ const level = {
ctx.fillRect(-50000, -50000, 100000, 100000)
ctx.globalCompositeOperation = "source-over"
// stop time
// m.isBodiesAsleep = true;
// m.isTimeDilated = true;
// function sleep(who) {
// for (let i = 0, len = who.length; i < len; ++i) {
// if (!who[i].isSleeping) {
@@ -27683,7 +27680,7 @@ const level = {
}
me.waves = [];
me.doLongitudinal = function () {
if (!m.isBodiesAsleep) {
if (!m.isTimeDilated) {
ctx.strokeStyle = "rgba(0,0,0,0.6)" //"000";
ctx.lineWidth = 2 * tech.wavePacketDamage
ctx.beginPath();

View File

@@ -1232,7 +1232,7 @@ const mobs = {
});
}
if (tech.isVerlet && !m.isBodiesAsleep) {
if (tech.isVerlet && !m.isTimeDilated) {
requestAnimationFrame(() => {
simulation.timePlayerSkip(this.isBoss ? 60 : 30)
simulation.loop(); //ending with a wipe and normal loop fixes some very minor graphical issues where things are draw in the wrong locations

View File

@@ -317,62 +317,29 @@ const m = {
},
alive: false,
isSwitchingWorlds: false,
switchWorlds() {
switchWorlds(giveTech = "") {
if (!m.isSwitchingWorlds) {
powerUps.boost.endCycle = 0
const totalGuns = b.inventory.length
//track ammo/ ammoPack count
let ammoCount = 0
for (let i = 0, len = b.inventory.length; i < len; i++) {
if (b.guns[b.inventory[i]].ammo !== Infinity) {
ammoCount += b.guns[b.inventory[i]].ammo / b.guns[b.inventory[i]].ammoPack
} else {
ammoCount += 5
}
}
simulation.isTextLogOpen = false; //prevent console spam
//remove all tech and count current tech total
let totalTech = 0;
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].isJunk) tech.tech[i].frequency = 0
if (tech.tech[i].count > 0 && !tech.tech[i].isLore) {
if (tech.tech[i].frequencyDefault) {
tech.tech[i].frequency = tech.tech[i].frequencyDefault
} else {
tech.tech[i].frequency = 1
}
if (
!tech.tech[i].isNonRefundable &&
// !tech.tech[i].isFromAppliedScience &&
!tech.tech[i].isAltRealityTech
) {
totalTech += tech.tech[i].count
tech.tech[i].remove();
tech.tech[i].isLost = false
tech.tech[i].count = 0
}
for (let i = tech.tech.length - 1; i > -1; i--) {
if (tech.tech[i].count > 0 && !tech.tech[i].isLore && !tech.tech[i].isNonRefundable && !tech.tech[i].isAltRealityTech) {
totalTech += tech.tech[i].count
}
}
// lore.techCount = 0;
// tech.removeLoreTechFromPool();
// tech.addLoreTechToPool();
// tech.removeJunkTechFromPool();
tech.junkChance = 0;
tech.duplication = 0;
tech.extraMaxHealth = 0;
tech.totalCount = 0;
tech.removeCount = 0;
const randomBotCount = b.totalBots()
b.zeroBotCount()
//remove all bullets, respawn bots
powerUps.boost.endCycle = 0
simulation.isTextLogOpen = false; //prevent console spam
tech.resetAllTech()
if (giveTech) tech.giveTech(giveTech) //give many worlds back
//remove all bullets
for (let i = 0; i < bullet.length; ++i) Matter.Composite.remove(engine.world, bullet[i]);
bullet = [];
//randomize
powerUps.research.count = Math.floor(powerUps.research.count * (0.5 + 1.5 * Math.random()))
m.coupling = Math.floor(m.coupling * (0.5 + 1.5 * Math.random()))
//randomize health
m.health = m.health * (1 + 0.5 * (Math.random() - 0.5))
if (m.health > 1) m.health = 1;
m.displayHealth();
//randomize field
m.setField(Math.ceil(Math.random() * (m.fieldUpgrades.length - 1)))
//removes guns and ammo
@@ -387,25 +354,15 @@ const m = {
}
}
//give random guns
// const totalGuns = 1 + Math.floor(b.inventory.length * (0.5 + 1.5 * Math.random()))
const totalGuns = 1 + Math.floor(Math.random() * Math.random() * 7)
for (let i = 0; i < totalGuns; i++) b.giveGuns()
//randomize ammo based on ammo/ammoPack count
for (let i = 0, len = b.inventory.length; i < len; i++) {
if (b.guns[b.inventory[i]].ammo !== Infinity) b.guns[b.inventory[i]].ammo = Math.max(0, Math.floor(ammoCount / b.inventory.length * b.guns[b.inventory[i]].ammoPack * (2.5 + 0.3 * (Math.random() - 0.5))))
if (b.guns[b.inventory[i]].ammo !== Infinity) b.guns[b.inventory[i]].ammo = Math.floor(b.guns[b.inventory[i]].ammo * (0.25 + Math.random() + Math.random() + Math.random()))
}
//randomize tech
// for (let i = 0; i < totalTech; i++) {
// let options = [];
// for (let i = 0, len = tech.tech.length; i < len; i++) {
// if (tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed() && !tech.tech[i].isBadRandomOption && !tech.tech[i].isLore && !tech.tech[i].isJunk) {
// for (let j = 0; j < tech.tech[i].frequency; j++) options.push(i);
// }
// }
// if (options.length > 0) tech.giveTech(options[Math.floor(Math.random() * options.length)]) //add a new tech from options pool
// }
let loop = () => {
if (!(m.cycle % 10)) {
if (totalTech > 0 && m.alive) {
@@ -430,14 +387,257 @@ const m = {
requestAnimationFrame(loop);
b.respawnBots();
for (let i = 0; i < randomBotCount; i++) b.randomBot()
// for (let i = 0; i < randomBotCount; i++) b.randomBot()
simulation.makeGunHUD(); //update gun HUD
simulation.updateTechHUD();
m.displayHealth();
simulation.isTextLogOpen = true;
m.drop();
if (simulation.paused) build.pauseGrid() //update the build when paused
}
},
// switchWorlds() {
// if (!m.isSwitchingWorlds) {
// powerUps.boost.endCycle = 0
// const totalGuns = b.inventory.length
// //track ammo/ ammoPack count
// let ammoCount = 0
// for (let i = 0, len = b.inventory.length; i < len; i++) {
// if (b.guns[b.inventory[i]].ammo !== Infinity) {
// ammoCount += b.guns[b.inventory[i]].ammo / b.guns[b.inventory[i]].ammoPack
// } else {
// ammoCount += 5
// }
// }
// simulation.isTextLogOpen = false; //prevent console spam
// //remove all tech and count current tech total
// let totalTech = 0;
// for (let i = tech.tech.length - 1; i > -1; i--) {
// if (tech.tech[i].isJunk) tech.tech[i].frequency = 0
// if (tech.tech[i].count > 0 && !tech.tech[i].isLore) {
// if (tech.tech[i].frequencyDefault) {
// tech.tech[i].frequency = tech.tech[i].frequencyDefault
// } else {
// tech.tech[i].frequency = 1
// }
// if (!tech.tech[i].isNonRefundable && !tech.tech[i].isAltRealityTech) {
// totalTech += tech.tech[i].count
// tech.tech[i].remove();
// tech.tech[i].isLost = false
// tech.tech[i].count = 0
// }
// }
// }
// // lore.techCount = 0;
// // tech.removeLoreTechFromPool();
// // tech.addLoreTechToPool();
// // tech.removeJunkTechFromPool();
// // tech.junkChance = 0;
// // tech.duplication = 0;
// // tech.extraMaxHealth = 0;
// // tech.totalCount = 0;
// // tech.removeCount = 0;
// // const randomBotCount = b.totalBots()
// // b.zeroBotCount()
// //remove all bullets, respawn bots
// for (let i = 0; i < bullet.length; ++i) Matter.Composite.remove(engine.world, bullet[i]);
// bullet = [];
// //randomize health
// m.health = m.health * (1 + 0.5 * (Math.random() - 0.5))
// if (m.health > 1) m.health = 1;
// m.displayHealth();
// //randomize field
// m.setField(Math.ceil(Math.random() * (m.fieldUpgrades.length - 1)))
// //removes guns and ammo
// b.inventory = [];
// b.activeGun = null;
// b.inventoryGun = 0;
// for (let i = 0, len = b.guns.length; i < len; ++i) {
// b.guns[i].have = false;
// if (b.guns[i].ammo !== Infinity) {
// b.guns[i].ammo = 0;
// b.guns[i].ammoPack = b.guns[i].defaultAmmoPack;
// }
// }
// //give random guns
// for (let i = 0; i < totalGuns; i++) b.giveGuns()
// //randomize ammo based on ammo/ammoPack count
// for (let i = 0, len = b.inventory.length; i < len; i++) {
// if (b.guns[b.inventory[i]].ammo !== Infinity) b.guns[b.inventory[i]].ammo = Math.max(0, Math.floor(ammoCount / b.inventory.length * b.guns[b.inventory[i]].ammoPack * (2.5 + 0.3 * (Math.random() - 0.5))))
// }
// //randomize tech
// // for (let i = 0; i < totalTech; i++) {
// // let options = [];
// // for (let i = 0, len = tech.tech.length; i < len; i++) {
// // if (tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed() && !tech.tech[i].isBadRandomOption && !tech.tech[i].isLore && !tech.tech[i].isJunk) {
// // for (let j = 0; j < tech.tech[i].frequency; j++) options.push(i);
// // }
// // }
// // if (options.length > 0) tech.giveTech(options[Math.floor(Math.random() * options.length)]) //add a new tech from options pool
// // }
// let loop = () => {
// if (!(m.cycle % 10)) {
// if (totalTech > 0 && m.alive) {
// totalTech--
// let options = [];
// for (let i = 0, len = tech.tech.length; i < len; i++) {
// if (tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed() && !tech.tech[i].isBadRandomOption && !tech.tech[i].isLore && !tech.tech[i].isJunk) {
// for (let j = 0; j < tech.tech[i].frequency; j++) options.push(i);
// }
// }
// if (options.length > 0) tech.giveTech(options[Math.floor(Math.random() * options.length)]) //add a new tech from options pool
// requestAnimationFrame(loop);
// } else {
// m.isSwitchingWorlds = false
// }
// } else if (m.alive) {
// requestAnimationFrame(loop);
// } else {
// m.isSwitchingWorlds = false
// }
// }
// requestAnimationFrame(loop);
// b.respawnBots();
// // for (let i = 0; i < randomBotCount; i++) b.randomBot()
// simulation.makeGunHUD(); //update gun HUD
// simulation.updateTechHUD();
// simulation.isTextLogOpen = true;
// m.drop();
// if (simulation.paused) build.pauseGrid() //update the build when paused
// }
// },
// switchWorlds() {
// if (!m.isSwitchingWorlds) {
// powerUps.boost.endCycle = 0
// const totalGuns = b.inventory.length
// //track ammo/ ammoPack count
// let ammoCount = 0
// for (let i = 0, len = b.inventory.length; i < len; i++) {
// if (b.guns[b.inventory[i]].ammo !== Infinity) {
// ammoCount += b.guns[b.inventory[i]].ammo / b.guns[b.inventory[i]].ammoPack
// } else {
// ammoCount += 5
// }
// }
// simulation.isTextLogOpen = false; //prevent console spam
// //remove all tech and count current tech total
// let totalTech = 0;
// for (let i = 0, len = tech.tech.length; i < len; i++) {
// if (tech.tech[i].isJunk) tech.tech[i].frequency = 0
// if (tech.tech[i].count > 0 && !tech.tech[i].isLore) {
// if (tech.tech[i].frequencyDefault) {
// tech.tech[i].frequency = tech.tech[i].frequencyDefault
// } else {
// tech.tech[i].frequency = 1
// }
// if (
// !tech.tech[i].isNonRefundable &&
// // !tech.tech[i].isFromAppliedScience &&
// !tech.tech[i].isAltRealityTech
// ) {
// totalTech += tech.tech[i].count
// tech.tech[i].remove();
// tech.tech[i].isLost = false
// tech.tech[i].count = 0
// }
// }
// }
// // lore.techCount = 0;
// // tech.removeLoreTechFromPool();
// // tech.addLoreTechToPool();
// // tech.removeJunkTechFromPool();
// tech.junkChance = 0;
// tech.duplication = 0;
// tech.extraMaxHealth = 0;
// tech.totalCount = 0;
// tech.removeCount = 0;
// // const randomBotCount = b.totalBots()
// b.zeroBotCount()
// //remove all bullets, respawn bots
// for (let i = 0; i < bullet.length; ++i) Matter.Composite.remove(engine.world, bullet[i]);
// bullet = [];
// //randomize health
// m.health = m.health * (1 + 0.5 * (Math.random() - 0.5))
// if (m.health > 1) m.health = 1;
// m.displayHealth();
// //randomize field
// m.setField(Math.ceil(Math.random() * (m.fieldUpgrades.length - 1)))
// //removes guns and ammo
// b.inventory = [];
// b.activeGun = null;
// b.inventoryGun = 0;
// for (let i = 0, len = b.guns.length; i < len; ++i) {
// b.guns[i].have = false;
// if (b.guns[i].ammo !== Infinity) {
// b.guns[i].ammo = 0;
// b.guns[i].ammoPack = b.guns[i].defaultAmmoPack;
// }
// }
// //give random guns
// for (let i = 0; i < totalGuns; i++) b.giveGuns()
// //randomize ammo based on ammo/ammoPack count
// for (let i = 0, len = b.inventory.length; i < len; i++) {
// if (b.guns[b.inventory[i]].ammo !== Infinity) b.guns[b.inventory[i]].ammo = Math.max(0, Math.floor(ammoCount / b.inventory.length * b.guns[b.inventory[i]].ammoPack * (2.5 + 0.3 * (Math.random() - 0.5))))
// }
// //randomize tech
// // for (let i = 0; i < totalTech; i++) {
// // let options = [];
// // for (let i = 0, len = tech.tech.length; i < len; i++) {
// // if (tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed() && !tech.tech[i].isBadRandomOption && !tech.tech[i].isLore && !tech.tech[i].isJunk) {
// // for (let j = 0; j < tech.tech[i].frequency; j++) options.push(i);
// // }
// // }
// // if (options.length > 0) tech.giveTech(options[Math.floor(Math.random() * options.length)]) //add a new tech from options pool
// // }
// let loop = () => {
// if (!(m.cycle % 10)) {
// if (totalTech > 0 && m.alive) {
// totalTech--
// let options = [];
// for (let i = 0, len = tech.tech.length; i < len; i++) {
// if (tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed() && !tech.tech[i].isBadRandomOption && !tech.tech[i].isLore && !tech.tech[i].isJunk) {
// for (let j = 0; j < tech.tech[i].frequency; j++) options.push(i);
// }
// }
// if (options.length > 0) tech.giveTech(options[Math.floor(Math.random() * options.length)]) //add a new tech from options pool
// requestAnimationFrame(loop);
// } else {
// m.isSwitchingWorlds = false
// }
// } else if (m.alive) {
// requestAnimationFrame(loop);
// } else {
// m.isSwitchingWorlds = false
// }
// }
// requestAnimationFrame(loop);
// b.respawnBots();
// // for (let i = 0; i < randomBotCount; i++) b.randomBot()
// simulation.makeGunHUD(); //update gun HUD
// simulation.updateTechHUD();
// simulation.isTextLogOpen = true;
// m.drop();
// if (simulation.paused) build.pauseGrid() //update the build when paused
// }
// },
dmgScale: null, //scales all damage, but not raw .dmg
death() {
if (tech.isImmortal) { //if player has the immortality buff, spawn on the same level with randomized damage
@@ -1795,20 +1995,15 @@ const m = {
ctx.beginPath();
ctx.arc(m.hip.x, m.hip.y, 9, 0, 2 * Math.PI);
ctx.fillStyle = "#222";
// ctx.fillStyle = "#1b85cf";
ctx.fill();
//knee joint
ctx.beginPath();
ctx.arc(m.knee.x, m.knee.y, 5, 0, 2 * Math.PI);
// ctx.fillStyle = "#ffa050";
ctx.fill();
//foot joint
ctx.beginPath();
ctx.arc(m.foot.x, m.foot.y, 4, 0, 2 * Math.PI);
// ctx.fillStyle = "#878cf0";
ctx.fill();
// ctx.lineWidth = 3;
// ctx.stroke();
ctx.restore();
}
},
@@ -2574,7 +2769,7 @@ const m = {
m.holdingMassScale = 0.5;
m.fieldArc = 0.2; //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
m.calculateFieldThreshold(); //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
m.isBodiesAsleep = true;
m.isTimeDilated = true;
m.wakeCheck();
m.setMaxEnergy(false);
m.setMaxHealth(false);
@@ -3338,8 +3533,8 @@ const m = {
m.holdingTarget.collisionFilter.mask = 0;
},
wakeCheck() {
if (m.isBodiesAsleep) {
m.isBodiesAsleep = false;
if (m.isTimeDilated) {
m.isTimeDilated = false;
function wake(who) {
for (let i = 0, len = who.length; i < len; ++i) {
@@ -4593,7 +4788,7 @@ const m = {
ctx.fillRect(-50000, -50000, 100000, 100000)
ctx.globalCompositeOperation = "source-over"
//stop time
m.isBodiesAsleep = true;
m.isTimeDilated = true;
function sleep(who) {
for (let i = 0, len = who.length; i < len; ++i) {
@@ -4717,7 +4912,7 @@ const m = {
}
} else {
m.fieldFire = true;
m.isBodiesAsleep = false;
m.isTimeDilated = false;
m.hold = function () {
if (m.isHolding) {
m.wakeCheck();
@@ -5335,7 +5530,7 @@ const m = {
if (m.energy > drain) {
m.energy -= drain
if (m.immuneCycle < m.cycle + 1) m.immuneCycle = m.cycle + 1; //player is immune to damage for 1 cycle
m.isBodiesAsleep = true;
m.isTimeDilated = true;
function sleep(who) {
for (let i = 0, len = who.length; i < len; ++i) {
@@ -5409,7 +5604,7 @@ const m = {
ctx.setLineDash([]);
}
} else {
if (tech.isWormHolePause && m.isBodiesAsleep) m.wakeCheck();
if (tech.isWormHolePause && m.isTimeDilated) m.wakeCheck();
//make new wormhole
if (

View File

@@ -212,7 +212,7 @@ const powerUps = {
dupExplode() {
for (let i = 0, len = powerUp.length; i < len; ++i) {
if (powerUp[i].isDuplicated) {
if (Math.random() < 0.003 && !m.isBodiesAsleep) { // (1-0.003)^240 = chance to be removed after 4 seconds, 240 = 4 seconds * 60 cycles per second
if (Math.random() < 0.003 && !m.isTimeDilated) { // (1-0.003)^240 = chance to be removed after 4 seconds, 240 = 4 seconds * 60 cycles per second
b.explosion(powerUp[i].position, 175 + (11 + 3 * Math.random()) * powerUp[i].size);
if (powerUp[i]) {
Matter.Composite.remove(engine.world, powerUp[i]);
@@ -708,7 +708,7 @@ const powerUps = {
if (amount !== 0) powerUps.research.count += amount
if (tech.isRerollBots && !this.isMakingBots) {
let cycle = () => {
const cost = 2 + Math.floor(0.25 * b.totalBots())
const cost = 2 + Math.floor(b.totalBots() / 3)
if (m.alive && powerUps.research.count >= cost) {
requestAnimationFrame(cycle);
this.isMakingBots = true
@@ -762,7 +762,7 @@ const powerUps = {
}
powerUps.research.currentRerollCount++
if (tech.isResearchReality) {
m.switchWorlds()
m.switchWorlds("Ψ(t) collapse")
simulation.trails()
simulation.inGameConsole(`simulation.amplitude <span class='color-symbol'>=</span> ${Math.random()}`);
}
@@ -812,7 +812,7 @@ const powerUps = {
// color: simulation.mobDmgColor,
// time: simulation.drawTime
// });
} else if (overHeal > 0.13) { //if leftover heals spawn a new spammer heal power up
} else if (overHeal > 0.2) { //if leftover heals spawn a new spammer heal power up
requestAnimationFrame(() => {
powerUps.directSpawn(this.position.x, this.position.y, "heal", true, Math.min(1, overHeal) * 40 * (simulation.healScale ** 0.25))// directSpawn(x, y, name, moving = true, mode = null, size = powerUps[name].size()) {
});

View File

@@ -21,7 +21,7 @@ const simulation = {
// mobs.draw();
// simulation.draw.cons();
// simulation.draw.body();
// if (!m.isBodiesAsleep) mobs.loop();
// if (!m.isTimeDilated) mobs.loop();
// mobs.healthBar();
// m.draw();
// m.hold();
@@ -30,7 +30,7 @@ const simulation = {
// b.fire();
// b.bulletRemove();
// b.bulletDraw();
// if (!m.isBodiesAsleep) b.bulletDo();
// if (!m.isTimeDilated) b.bulletDo();
// simulation.drawCircle();
// simulation.runEphemera();
// ctx.restore();
@@ -98,7 +98,7 @@ const simulation = {
mobs.draw();
simulation.draw.cons();
simulation.draw.body();
if (!m.isBodiesAsleep) mobs.loop();
if (!m.isTimeDilated) mobs.loop();
mobs.healthBar();
m.draw();
m.hold();
@@ -107,7 +107,7 @@ const simulation = {
b.fire();
b.bulletRemove();
b.bulletDraw();
if (!m.isBodiesAsleep) b.bulletDo();
if (!m.isTimeDilated) b.bulletDo();
simulation.drawCircle();
simulation.runEphemera();
ctx.restore();
@@ -183,10 +183,10 @@ const simulation = {
Engine.update(engine, simulation.delta);
// level.custom();
// level.customTopLayer();
if (!m.isBodiesAsleep) mobs.loop();
if (!m.isTimeDilated) mobs.loop();
if (m.fieldMode !== 7) m.hold();
b.bulletRemove();
if (!m.isBodiesAsleep) b.bulletDo();
if (!m.isTimeDilated) b.bulletDo();
simulation.runEphemera();
}
simulation.isTimeSkipping = false;
@@ -223,7 +223,7 @@ const simulation = {
// mobs.draw();
// simulation.draw.cons();
// simulation.draw.body();
// if (!m.isBodiesAsleep) {
// if (!m.isTimeDilated) {
// // mobs.loop();
// }
// mobs.healthBar();
@@ -235,7 +235,7 @@ const simulation = {
// b.fire();
// b.bulletRemove();
// b.bulletDraw();
// if (!m.isBodiesAsleep) b.bulletDo();
// if (!m.isTimeDilated) b.bulletDo();
// simulation.drawCircle();
// // simulation.clip();
// ctx.restore();
@@ -425,7 +425,7 @@ const simulation = {
if (simulation.drawList[i].time) {
simulation.drawList[i].time--;
} else {
if (!m.isBodiesAsleep) simulation.drawList.splice(i, 1); //remove when timer runs out
if (!m.isTimeDilated) simulation.drawList.splice(i, 1); //remove when timer runs out
}
}
},
@@ -496,6 +496,32 @@ const simulation = {
}
simulation.boldActiveGunHUD();
},
// updateTechHUD() {
// let text = ""
// for (let i = 0, len = tech.tech.length; i < len; i++) { //add tech
// if (tech.tech[i].isLost) {
// if (text) text += "<br>" //add a new line, but not on the first line
// text += `<span style="text-decoration: line-through;">${tech.tech[i].name}</span>`
// } else if (tech.tech[i].count > 0 && !tech.tech[i].isInstant) {
// if (text) text += "<br>" //add a new line, but not on the first line
// text += `<span id = "${tech.tech[i].name}">${tech.tech[i].name}${tech.tech[i].count > 1 ? ` (${tech.tech[i].count}x)` : ""}</span>`
// // document.getElementById(tech.tech[i].name).style.fontWeight = 'bold';
// // simulation.ephemera.push({
// // name: "bold",
// // count: 180,
// // do() {
// // this.count--
// // if (this.count < 0) {
// // simulation.removeEphemera(this.name)
// // if (document.getElementById(tech.tech[i].name)) document.getElementById(tech.tech[i].name).style.fontWeight = 'normal';
// // }
// // }
// // })
// }
// }
// document.getElementById("right-HUD").innerHTML = text
// },
updateTechHUD() {
let text = ""
for (let i = 0, len = tech.tech.length; i < len; i++) { //add tech
@@ -837,7 +863,7 @@ const simulation = {
bodies[i].force.y += bodies[i].mass * magnitude;
}
}
if (!m.isBodiesAsleep) {
if (!m.isTimeDilated) {
addGravity(powerUp, simulation.g);
addGravity(body, simulation.g);
}
@@ -865,6 +891,8 @@ const simulation = {
document.getElementById("experiment-button").style.opacity = "0";
document.getElementById("training-button").style.display = "inline"
document.getElementById("training-button").style.opacity = "0";
document.getElementById("start-button").style.display = "inline"
document.getElementById("start-button").style.opacity = "0";
document.getElementById("experiment-grid").style.display = "none"
document.getElementById("pause-grid-left").style.display = "none"
document.getElementById("pause-grid-right").style.display = "none"
@@ -878,6 +906,7 @@ const simulation = {
setTimeout(() => {
document.getElementById("experiment-button").style.opacity = "1";
document.getElementById("training-button").style.opacity = "1";
document.getElementById("start-button").style.opacity = "1";
document.getElementById("info").style.opacity = "1";
document.getElementById("splash").style.opacity = "1";
}, 200);
@@ -904,6 +933,7 @@ const simulation = {
document.getElementById("info").style.display = "none";
document.getElementById("experiment-button").style.display = "none";
document.getElementById("training-button").style.display = "none";
document.getElementById("start-button").style.display = "none";
// document.getElementById("experiment-button").style.opacity = "0";
document.getElementById("splash").onclick = null; //removes the onclick effect so the function only runs once
document.getElementById("splash").style.display = "none"; //hides the element that spawned the function
@@ -948,9 +978,8 @@ const simulation = {
input.endKeySensing();
simulation.ephemera = []
powerUps.powerUpStorage = []
tech.setupAllTech(); //sets tech to default values
tech.resetAllTech(); //sets tech to default values
b.resetAllGuns();
tech.duplication = 0;
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "laser") b.guns[i].chooseFireMethod()
if (b.guns[i].name === "nail gun") b.guns[i].chooseFireMethod()
@@ -958,15 +987,7 @@ const simulation = {
if (b.guns[i].name === "harpoon") b.guns[i].chooseFireMethod()
if (b.guns[i].name === "foam") b.guns[i].chooseFireMethod()
}
tech.dynamoBotCount = 0;
tech.nailBotCount = 0;
tech.laserBotCount = 0;
tech.orbitBotCount = 0;
tech.foamBotCount = 0;
tech.soundBotCount = 0;
tech.boomBotCount = 0;
tech.plasmaBotCount = 0;
tech.missileBotCount = 0;
b.zeroBotCount()
m.isSwitchingWorlds = false
simulation.isChoosing = false;
@@ -1044,12 +1065,12 @@ const simulation = {
simulation.ephemera.push({
name: "dmgDefBars", count: 0, do() {
if (!(m.cycle % 15)) { //4 times a second
const defense = m.defense() //update defense bar
const defense = m.defense() //* simulation.dmgScale //update defense bar
if (m.lastCalculatedDefense !== defense) {
document.getElementById("defense-bar").style.width = Math.floor(300 * m.maxHealth * (1 - defense)) + "px";
m.lastCalculatedDefense = defense
}
const damage = tech.damageFromTech() //update damage bar
const damage = tech.damageFromTech() //* m.dmgScale //update damage bar
if (m.lastCalculatedDamage !== damage) {
document.getElementById("damage-bar").style.height = Math.floor((Math.atan(0.25 * damage - 0.25) + 0.25) * 0.53 * canvas.height) + "px";
m.lastCalculatedDamage = damage

View File

@@ -195,7 +195,7 @@ const spawn = {
ctx.strokeStyle = "#000"
ctx.lineWidth = 1;
ctx.stroke();
if (tech.isDarkStar && !m.isCloak) { //&& !m.isBodiesAsleep
if (tech.isDarkStar && !m.isCloak) { //&& !m.isTimeDilated
ctx.fillStyle = "rgba(10,0,40,0.4)"
ctx.fill()
//damage mobs
@@ -3896,7 +3896,7 @@ const spawn = {
if (this.health < this.nextHealthThreshold) {
this.health = this.nextHealthThreshold - 0.01
this.nextHealthThreshold = Math.floor(this.health * 4) / 4 //0.75,0.5,0.25
this.invulnerableCount = 300
this.invulnerableCount = 240
this.isInvulnerable = true
this.damageReduction = 0
if (this.history.length < 200) for (let i = 0; i < 11; i++) this.history.unshift(this.history[0])

View File

@@ -1,7 +1,7 @@
const tech = {
totalCount: null,
removeCount: 0,
setupAllTech() {
resetAllTech() {
for (let i = 0, len = tech.tech.length; i < len; i++) {
tech.tech[i].isLost = false
tech.tech[i].isBanished = false
@@ -12,24 +12,15 @@ const tech = {
} else if (tech.tech[i].frequencyDefault) {
tech.tech[i].frequency = tech.tech[i].frequencyDefault
} else {
tech.tech[i].frequency = 2
tech.tech[i].frequency = 1
}
if (tech.tech[i].name === "heals" || tech.tech[i].name === "ammo" || tech.tech[i].name === "research") tech.tech[i].value = tech.tech[i].defaultValue
}
//remove lore if it's your first time playing since it's confusing
//also remove lore if cheating
m.resetSkin();
tech.removeCount = 0;
tech.pauseEjectTech = 1; //used in paradigm shift
lore.techCount = 0;
if (simulation.isCheating || localSettings.runCount < 1) { //simulation.isCommunityMaps ||
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].isLore) {
tech.tech[i].frequency = 0;
tech.tech[i].count = 0;
}
}
}
tech.duplication = 0;
tech.damage = 1
tech.junkChance = 0;
tech.extraMaxHealth = 0;
@@ -66,7 +57,7 @@ const tech = {
tech.removeCount += totalRemoved
tech.tech[index].count = 0;
tech.totalCount -= totalRemoved
simulation.updateTechHUD();
// simulation.updateTechHUD();
tech.tech[index].isLost = true
simulation.updateTechHUD();
return totalRemoved //return the total number of tech removed
@@ -1115,11 +1106,19 @@ const tech = {
tech.damage *= this.damage
tech.isEnergyNoAmmo = true;
powerUps.ammo.color = "#c1c6c9"//"#abb3b8"// "#535e63"
for (let i = 0; i < powerUp.length; i++) {
if (powerUp[i].name === "ammo") powerUp[i].color = powerUps.ammo.color
}
},
remove() {
if (this.count && m.alive) tech.damage /= this.damage
tech.isEnergyNoAmmo = false;
powerUps.ammo.color = "#467"
for (let i = 0; i < powerUp.length; i++) {
if (powerUp[i].name === "ammo") powerUp[i].color = powerUps.ammo.color
}
}
},
{
@@ -2119,7 +2118,7 @@ const tech = {
name: "bot fabrication",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Robot' class="link">bot fabrication</a>`,
descriptionFunction() {
return `after you collect ${powerUps.orb.research(2 + Math.floor(0.25 * b.totalBots()))}use them<br>to construct a random <strong class='color-bot'>bot</strong> <em style ="float: right;">(+1 cost every 4 bots)</em>`
return `after you collect ${powerUps.orb.research(2 + Math.floor(0.25 * b.totalBots()))}use them<br>to construct a random <strong class='color-bot'>bot</strong> <em style ="float: right;">(+1 cost every 3 bots)</em>`
},
// description: `if you collect ${powerUps.orb.research(2)}use them to build a<br>random <strong class='color-bot'>bot</strong> <em>(+1 cost every 5 bots)</em>`,
maxCount: 1,
@@ -3540,6 +3539,7 @@ const tech = {
count: 0,
frequency: 1,
frequencyDefault: 1,
isAltRealityTech: true,
allowed() {
return true
},
@@ -3553,7 +3553,7 @@ const tech = {
},
{
name: "many-worlds",
description: `at the start of each <strong>level</strong> spawn ${powerUps.orb.tech()} ${powerUps.orb.coupling(3)}<br>and enter an <strong class='alt'>alternate reality</strong>`,
description: `at the start of each <strong>level</strong> spawn ${powerUps.orb.tech()}<br>and enter an <strong class='alt'>alternate reality</strong>`,
maxCount: 1,
count: 0,
frequency: 1,
@@ -4048,7 +4048,7 @@ const tech = {
{
name: "research",
descriptionFunction() {
return `spawn ${this.value > 36 ? this.value + powerUps.orb.research(1) : powerUps.orb.research(this.value)} <br>next time increase amount spawned by +5${powerUps.orb.research(1)}`
return `spawn ${this.value > 36 ? this.value + powerUps.orb.research(1) : powerUps.orb.research(this.value)} <br>next time increase amount spawned by +4${powerUps.orb.research(1)}`
},
maxCount: 9,
count: 0,
@@ -4062,7 +4062,7 @@ const tech = {
defaultValue: 8,
effect() {
powerUps.spawnDelay("research", this.value);
this.value += 5
this.value += 4
},
remove() { }
},
@@ -4661,7 +4661,7 @@ const tech = {
// if (tech.isDeterminism) count -= 4 //remove the bonus tech
// if (tech.isSuperDeterminism) count -= 4 //remove the bonus tech
// const removeCount = tech.removeCount
// tech.setupAllTech(); // remove all tech
// tech.resetAllTech(); // remove all tech
// tech.removeCount = removeCount
// if (simulation.isCheating) tech.setCheating();
// lore.techCount = 0;
@@ -8894,7 +8894,7 @@ const tech = {
tech.isWormHolePause = true
},
remove() {
if (tech.isWormHolePause && m.isBodiesAsleep) m.wakeCheck();
if (tech.isWormHolePause && m.isTimeDilated) m.wakeCheck();
tech.isWormHolePause = false
}
},

View File

@@ -124,21 +124,45 @@ summary {
background-color: #eee;
}
.SVG-button-splash {
border: 2px #333 solid;
border-radius: 8px;
background-color: #fff;
transition: opacity 5s ease-in;
}
.SVG-button-splash:hover {
background-color: #eee;
}
#start-button {
position: absolute;
bottom: 108px;
right: 4px;
z-index: 12;
/* top-left | top-right | bottom-right | bottom-left */
/* border-radius: 8px 8px 0 0; */
}
#training-button {
position: absolute;
bottom: 56px;
right: 4px;
z-index: 12;
/* border-radius: 8px 0px 0 0; */
}
#experiment-button {
position: absolute;
bottom: 4px;
right: 4px;
z-index: 12;
transition: opacity 5s ease-in;
/* border-radius: 8px 0 8px 8px; */
}
#training-button {
position: absolute;
top: 4px;
right: 4px;
z-index: 12;
transition: opacity 5s ease-in;
}
#construct {
display: none;
@@ -570,6 +594,7 @@ summary {
z-index: 12;
font-size: 1.5em;
transition: opacity 5s ease-in;
width: 100%;
/* border: 1.5px #333 solid; */
/* border-radius: 8px; */

View File

@@ -1,30 +1,24 @@
******************************************************** NEXT PATCH **************************************************
new level substructure
featured element - motion triggered lasers
reworked m.switchWorlds() (used in many-worlds and similar effects)
no longer has extra bot build up
effects that carry over into next world:
your total tech count
effects of non-removeable tech, like determinism
mass production research ramps up by 5->4 each time
bot fabrications cost ramp is increased to (+1 per 4)-->(+1 per 3)
lowered minimum threshold for making small heals from over healing to 13->20 health
snakeBoss invulnerable phase is 5->4 seconds long
futures exchange 5->6% duplication per cancel
plasma torch coupling 0.015->0.025x damage per coupling
Gibbs free energy 1.005->1.006x damage per missing energy
compound lens arc adds 25->30 degrees
instability 2->2.5x damage when damage taken is 1x
constraint: after 30->40 seconds spawn WIMPs
constraint: 0.1->0.3x damage after getting power ups
renamed holographic principle -> charmed baryons
time dilation disables level based lasers
adjusted laser sensor paths on substructure level
updates to community map: downpour
updated lasers in labs and testChamber to the new more realistic laser
move splash screen buttons to bottom right
added a start button
details menus in splash screen now have individual widths instead of sharing with each other
bugs
returning to the old console.log system from last patch
I rather read bugs in the browser console not the n-gon console
bots properly follow player when level flips vertically
community map: arena's sword is properly removed at end of level
rewrote shaped charge to be better at protecting you from all explosions
pause correctly lists both mobs types for the level
for quasiparticles "boost" replaces ammo in more edge cases
bug with removing surfactant setting b.activeGun false and crashing game with checking active gun
not sure if this is fixed or not?
non-renewables change color for ammo power ups on current level
******************************************************** BUGS ********************************************************
@@ -64,6 +58,15 @@ player can become crouched while not touching the ground if they exit the ground
*********************************************************** TODO *****************************************************
animate adding new tech or guns or field to the text menu
css transitions or trigger an animation?
bold for 3-5 seconds
is bold going to move other text up and down?
dark opacity 1 font
new level - something with movers
rework focuser mobs to fire blue laser instead of charging player
like in classic 7-1-2017
this makes more sense that a bean is focusing