diff --git a/.DS_Store b/.DS_Store
index 392d3dc..523eb02 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/js/bullet.js b/js/bullet.js
index 98bdbf8..4c89959 100644
--- a/js/bullet.js
+++ b/js/bullet.js
@@ -3674,7 +3674,7 @@ const b = {
bullet[me] = Bodies.polygon(m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle), 20, 4.5, b.fireAttributes(dir, false));
b.fireProps(m.crouch ? 45 : 25, m.crouch ? 30 : 16, dir, me); //cd , speed
Matter.Body.setDensity(bullet[me], 0.000001);
- bullet[me].endCycle = Infinity;
+ bullet[me].endCycle = simulation.cycle + 600;
bullet[me].frictionAir = 0;
bullet[me].friction = 0.5;
bullet[me].radius = 4.5;
diff --git a/js/engine.js b/js/engine.js
index 7c4cc17..f74a265 100644
--- a/js/engine.js
+++ b/js/engine.js
@@ -169,6 +169,17 @@ function collisionChecks(event) {
let dmg = 0.05 * b.dmgScale * v * obj.mass * tech.throwChargeRate;
if (mob[k].isShielded) dmg *= 0.35
mob[k].damage(dmg, true);
+ if (tech.isBlockPowerUps && !mob[k].alive && mob[k].dropPowerUp) {
+ let type = tech.isEnergyNoAmmo ? "heal" : "ammo"
+ if (Math.random() < 0.4) {
+ type = "heal"
+ } else if (Math.random() < 0.3 && !tech.isSuperDeterminism) {
+ type = "research"
+ }
+ powerUps.spawn(mob[k].position.x, mob[k].position.y, type);
+ // for (let i = 0, len = Math.ceil(2 * Math.random()); i < len; i++) {}
+ }
+
const stunTime = dmg / Math.sqrt(obj.mass)
if (stunTime > 0.5) mobs.statusStun(mob[k], 30 + 60 * Math.sqrt(stunTime))
if (mob[k].distanceToPlayer2() < 1000000 && !m.isCloak) mob[k].foundPlayer();
diff --git a/js/index.js b/js/index.js
index 605689f..d009870 100644
--- a/js/index.js
+++ b/js/index.js
@@ -214,7 +214,7 @@ const build = {
el.style.display = "grid"
el.innerHTML = text
text = "";
- text += `
${m.fieldUpgrades[m.fieldMode].name}
${m.fieldUpgrades[m.fieldMode].description}
`
+ text += ` ${m.fieldUpgrades[m.fieldMode].name}
${m.fieldUpgrades[m.fieldMode].description}
`
let countTech = 0
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].count > 0) {
@@ -729,6 +729,24 @@ window.addEventListener("keydown", function(event) {
simulation.paused = true;
build.pauseGrid()
document.body.style.cursor = "auto";
+
+ if (tech.isGunSwitchField || simulation.testing) {
+ document.getElementById("pause-field").addEventListener("click", () => {
+ const energy = m.energy
+ m.setField((m.fieldMode === m.fieldUpgrades.length - 1) ? 1 : m.fieldMode + 1) //cycle to next field
+ m.energy = energy
+ document.getElementById("pause-field").innerHTML = ` ${m.fieldUpgrades[m.fieldMode].name}
${m.fieldUpgrades[m.fieldMode].description}`
+ });
+ }
+ if (simulation.testing) {
+
+
+
+
+
+
+
+ }
}
}
break
@@ -876,7 +894,6 @@ window.addEventListener("keydown", function(event) {
}
break
case "u":
- simulation.clearTimeouts();
level.nextLevel();
break
}
diff --git a/js/level.js b/js/level.js
index c8f2a79..fe5a8fe 100644
--- a/js/level.js
+++ b/js/level.js
@@ -20,7 +20,8 @@ const level = {
// tech.isExplodeRadio = true
// for (let i = 0; i < 1; i++) tech.giveTech("dynamo-bot")
// tech.giveTech("supercritical fission")
- // tech.giveTech("irradiated nails")
+ // tech.giveTech("CPT reversal")
+ // tech.giveTech("causality bombs")
// tech.giveTech("cardinality")
// tech.giveTech("Bayesian statistics")
// tech.isExplodeRadio = true;
@@ -30,6 +31,7 @@ const level = {
// tech.giveTech("missile-bot")
// tech.giveTech("nail-bot")
// for (let i = 0; i < 15; i++) tech.giveTech("plasma jet")
+ // tech.isBlockPowerUps = true;
level.intro(); //starting level
// level.testing(); //not in rotation
@@ -1052,7 +1054,8 @@ const level = {
// spawn.boost(1500, 0, 900);
// spawn.starter(1900, -500, 200) //big boy
- spawn.historyBoss(1900, -500)
+ spawn.starter(1900, -500)
+ // spawn.historyBoss(1900, -500)
// spawn.sneaker(2900, -500)
// spawn.launcherBoss(1200, -500)
// spawn.laserTargetingBoss(1600, -400)
diff --git a/js/mob.js b/js/mob.js
index 9f33f1b..c4e12ff 100644
--- a/js/mob.js
+++ b/js/mob.js
@@ -1038,9 +1038,7 @@ const mobs = {
m.lastKillCycle = m.cycle; //tracks the last time a kill was made, mostly used in simulation.checks()
if (Math.random() < tech.sporesOnDeath) {
const len = Math.min(25, Math.floor(2 + this.mass * (0.5 + 0.5 * Math.random())))
- for (let i = 0; i < len; i++) {
- b.spore(this.position)
- }
+ for (let i = 0; i < len; i++) b.spore(this.position)
} else if (tech.isExplodeMob) {
b.explosion(this.position, Math.min(600, Math.sqrt(this.mass + 2.75) * 55))
} else if (tech.nailsDeathMob) {
diff --git a/js/player.js b/js/player.js
index 5568105..7f419af 100644
--- a/js/player.js
+++ b/js/player.js
@@ -497,6 +497,7 @@ const m = {
harmReduction() {
let dmg = 1
dmg *= m.fieldHarmReduction
+ if (tech.isBlockHarm && m.isHolding) dmg *= 0.4
if (tech.squirrelFx !== 1) dmg *= 1 + (tech.squirrelFx - 1) / 5 //cause more damage
if (tech.isSpeedHarm) dmg *= 1 - Math.min(player.speed * 0.0185, 0.55)
if (tech.isSlowFPS) dmg *= 0.8
@@ -606,13 +607,14 @@ const m = {
m.defaultFPSCycle = m.cycle
if (tech.isRewindBot) {
const len = steps * 0.052 * tech.isRewindBot
+ const botStep = Math.floor(steps / len)
for (let i = 0; i < len; i++) {
- const where = m.history[Math.abs(m.cycle - i * 40) % 600].position //spread out spawn locations along past history
+ const where = m.history[Math.abs(m.cycle - i * botStep) % 600].position //spread out spawn locations along past history
b.randomBot({
- x: where.x + 100 * (Math.random() - 0.5),
- y: where.y + 100 * (Math.random() - 0.5)
+ x: where.x + 20 * (Math.random() - 0.5),
+ y: where.y + 20 * (Math.random() - 0.5)
}, false, false)
- bullet[bullet.length - 1].endCycle = simulation.cycle + 360 + Math.floor(180 * Math.random()) //6-9 seconds
+ bullet[bullet.length - 1].endCycle = simulation.cycle + 480 + Math.floor(120 * Math.random()) //8-10 seconds
}
}
},
diff --git a/js/simulation.js b/js/simulation.js
index 5074ef6..4295a5d 100644
--- a/js/simulation.js
+++ b/js/simulation.js
@@ -358,21 +358,6 @@ const simulation = {
}
},
switchGun() {
- if (tech.isGunSwitchField) {
- // const energy = m.energy
- // m.energy = energy //field swap sets energy to max, this undoes that
- m.setField((m.fieldMode === m.fieldUpgrades.length - 1) ? 1 : m.fieldMode + 1) //cycle to next field
-
- //update text to show next field
- for (let i = tech.tech.length - 1; i > 0; i--) {
- if (tech.tech[i].name === "unified field theory") {
- const index = (m.fieldMode === m.fieldUpgrades.length - 1) ? 1 : m.fieldMode + 1
- tech.tech[i].description = `switching guns also cycles your field
-
(next field: ${m.fieldUpgrades[index].name})`
- break
- }
- }
- }
if (tech.isCrouchAmmo) tech.isCrouchAmmo = 1 //this prevents hacking the tech by switching guns
b.activeGun = b.inventory[b.inventoryGun];
simulation.updateGunHUD();
diff --git a/js/spawn.js b/js/spawn.js
index a6ac7dd..4bb5d7b 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -99,8 +99,6 @@ const spawn = {
// spawn.shield(me, x, y, 1);
me.onDeath = function() {
//add lore level as next level if player took lore tech earlier in the game
- simulation.makeTextLog(`simulation.end()`);
-
if (lore.techCount > 9 && !simulation.isCheating) {
level.levels.push("null")
level.exit.x = 5500;
@@ -113,18 +111,21 @@ const spawn = {
simulation.draw.setPaths(); //redraw map draw path
} else {
//reset game
- let delay = 1000
- for (let i = 20; i > 0; i--) {
- setTimeout(function() {
- simulation.makeTextLog(`delay = ${i*1000}`);
- }, delay);
+ setTimeout(() => {
+ simulation.makeTextLog(`simulation.end()`);
+ let delay = 1000
+ for (let i = 20; i > 0; i--) {
+ setTimeout(function() {
+ simulation.makeTextLog(`delay = ${i*1000}`);
+ }, delay);
+ delay += 1000
+ }
delay += 1000
- }
- delay += 1000
- setTimeout(function() {
- simulation.makeTextLog(`World.clear(engine.world)`);
- setTimeout(function() { m.death() }, 1000);
- }, delay);
+ setTimeout(() => {
+ simulation.makeTextLog(`World.clear(engine.world)`);
+ setTimeout(() => { m.death() }, 1000);
+ }, delay);
+ }, 5000);
}
//ramp up damage
for (let i = 0; i < 3; i++) level.difficultyIncrease(simulation.difficultyMode)
diff --git a/js/tech.js b/js/tech.js
index df07070..8768e86 100644
--- a/js/tech.js
+++ b/js/tech.js
@@ -19,6 +19,14 @@ const tech = {
tech.tech[index].count = 0;
simulation.updateTechHUD();
},
+ // onclick="tech.removeTechPaused(${i}, this)" //add this to tech elements in pause menu
+ // removeTechPaused(index, who) {
+ // tech.tech[index].remove();
+ // tech.tech[index].count = 0;
+ // simulation.updateTechHUD();
+ // who.innerHTML = "removed"
+ // // who.style.display = "none"
+ // },
removeLoreTechFromPool() {
for (let i = tech.tech.length - 1; i > 0; i--) {
if (tech.tech[i].isLore && tech.tech[i].count === 0) tech.tech.splice(i, 1)
@@ -1089,6 +1097,38 @@ const tech = {
tech.throwChargeRate = 1
}
},
+ {
+ name: "restitution",
+ description: "mobs killed by collisions with blocks
spawn a heal, ammo, or research",
+ maxCount: 1,
+ count: 0,
+ allowed() {
+ return tech.throwChargeRate > 1
+ },
+ requires: "mass driver",
+ effect() {
+ tech.isBlockPowerUps = true
+ },
+ remove() {
+ tech.isBlockPowerUps = false
+ }
+ },
+ {
+ name: "inelastic collision",
+ description: "while you are holding a block
reduce harm by 60%",
+ maxCount: 1,
+ count: 0,
+ allowed() {
+ return tech.throwChargeRate > 1
+ },
+ requires: "mass driver",
+ effect() {
+ tech.isBlockHarm = true
+ },
+ remove() {
+ tech.isBlockHarm = false
+ }
+ },
{
name: "perpetual stun",
description: "stun all mobs for up to 12 seconds
at the start of each level",
@@ -1255,7 +1295,7 @@ const tech = {
},
{
name: "causality bots",
- description: "when you rewind, build some bots
that protect you for about 7 seconds",
+ description: "when you rewind, build several bots
that protect you for about 9 seconds",
maxCount: 3,
count: 0,
allowed() {
@@ -1271,7 +1311,7 @@ const tech = {
},
{
name: "causality bombs",
- description: "before you rewind drop some grenades",
+ description: "before you rewind drop several grenades",
maxCount: 1,
count: 0,
allowed() {
@@ -1782,7 +1822,7 @@ const tech = {
},
{
name: "replication",
- description: "8% chance to duplicate spawned power ups
add 10 junk tech to the potential pool",
+ description: "7.5% chance to duplicate spawned power ups
add 16 junk tech to the potential pool",
maxCount: 9,
count: 0,
allowed() {
@@ -1790,9 +1830,9 @@ const tech = {
},
requires: "below 100% duplication chance",
effect() {
- tech.duplicateChance += 0.08
+ tech.duplicateChance += 0.075
simulation.draw.powerUp = simulation.draw.powerUpBonus //change power up draw
- tech.addJunkTechToPool(10)
+ tech.addJunkTechToPool(16)
},
remove() {
tech.duplicateChance = 0
@@ -1965,7 +2005,7 @@ const tech = {
},
{
name: "unified field theory",
- description: "",
+ description: `in the pause menu, change your field
by clicking on your field's box`,
maxCount: 1,
count: 0,
allowed() {
@@ -1974,25 +2014,9 @@ const tech = {
requires: "at least 2 guns, not superdeterminism",
effect() {
tech.isGunSwitchField = true;
- for (let i = tech.tech.length - 1; i > 0; i--) {
- if (tech.tech[i].name === "unified field theory") {
- const index = (m.fieldMode === m.fieldUpgrades.length - 1) ? 1 : m.fieldMode + 1
- tech.tech[i].description = `switching guns also cycles your field
-
(next field: ${m.fieldUpgrades[index].name})`
- break
- }
- }
},
remove() {
tech.isGunSwitchField = false;
- for (let i = tech.tech.length - 1; i > 0; i--) {
- if (tech.tech[i].name === "unified field theory") {
- const index = (m.fieldMode === m.fieldUpgrades.length - 1) ? 1 : m.fieldMode + 1
- tech.tech[i].description = `switching guns also cycles your field
-
(next field: ${m.fieldUpgrades[index].name})`
- break
- }
- }
}
},
{
@@ -3155,7 +3179,7 @@ const tech = {
maxCount: 1,
count: 0,
allowed() {
- return tech.haveGunCheck("foam") || tech.foamBotCount > 2
+ return tech.haveGunCheck("foam")
},
requires: "foam",
effect() {
@@ -4197,6 +4221,81 @@ const tech = {
// },
// remove() {}
// },
+ {
+ name: "pitch",
+ description: "oscillate the pitch of your world",
+ maxCount: 9,
+ count: 0,
+ numberInPool: 0,
+ isNonRefundable: true,
+ isCustomHide: true,
+ isJunk: true,
+ allowed() {
+ return true
+ },
+ requires: "",
+ effect() {
+ setInterval(() => { if (!simulation.paused) ctx.rotate(0.001 * Math.sin(simulation.cycle * 0.01)) }, 16);
+ },
+ remove() {}
+ },
+ {
+ name: "umbra",
+ description: "produce a blue glow around everything
and probably some simulation lag",
+ maxCount: 9,
+ count: 0,
+ numberInPool: 0,
+ isNonRefundable: true,
+ isCustomHide: true,
+ isJunk: true,
+ allowed() {
+ return true
+ },
+ requires: "",
+ effect() {
+ ctx.shadowColor = '#06f';
+ ctx.shadowBlur = 25;
+ },
+ remove() {}
+ },
+ {
+ name: "lighter",
+ description: `ctx.globalCompositeOperation = "lighter"`,
+ maxCount: 9,
+ count: 0,
+ numberInPool: 0,
+ isNonRefundable: true,
+ isCustomHide: true,
+ isJunk: true,
+ allowed() {
+ return m.fieldUpgrades[m.fieldMode].name !== "negative mass field"
+ },
+ requires: "",
+ effect() {
+ ctx.globalCompositeOperation = "lighter";
+ },
+ remove() {}
+ },
+ {
+ name: "rewind",
+ description: "every 5 seconds rewind 2 seconds
lasts 120 seconds",
+ maxCount: 9,
+ count: 0,
+ numberInPool: 0,
+ isNonRefundable: true,
+ isCustomHide: true,
+ isJunk: true,
+ allowed() {
+ return true
+ },
+ requires: "",
+ effect() {
+ for (let i = 0; i < 24; i++) {
+ setTimeout(() => { m.rewind(120) }, i * 5000);
+ }
+ },
+ remove() {}
+ },
{
name: "energy to mass conversion",
description: "convert your energy into blocks",
@@ -4229,7 +4328,7 @@ const tech = {
},
{
name: "level.nextLevel()",
- description: "teleport to the start of the next level",
+ description: "advance to the next level",
maxCount: 9,
count: 0,
numberInPool: 0,
@@ -4241,7 +4340,6 @@ const tech = {
},
requires: "",
effect() {
- simulation.clearTimeouts();
level.nextLevel();
},
remove() {}
@@ -4941,4 +5039,6 @@ const tech = {
isNeedleShieldPierce: null,
isDuplicateBoss: null,
isDynamoBotUpgrade: null,
+ isBlockPowerUps: null,
+ isBlockHarm: null
}
\ No newline at end of file
diff --git a/todo.txt b/todo.txt
index 42d0f7e..c76d1be 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,10 +1,10 @@
******************************************************** NEXT PATCH ********************************************************
+several new junk tech
-tech change: commodities exchange 6 -> 8 power ups on cancel
-tech change: MIRV - doesn't reduce the missile size as much, has a better missile spread, and a very short fire delay
+unified field theory: now cycles fields after you click the field box when paused
-tech: replication - gain 8% duplication, but add in 10 junk tech to the pool
-added several new junk tech (18 possible junk tech now)
+tech: restitution - mobs killed by blocks spawn power ups
+tech: inelastic collision - 60% harm reduction when holding a block
******************************************************** BUGS ********************************************************
@@ -34,6 +34,21 @@ use the floor of portal sensor on the player? to unstuck player
******************************************************** TODO ********************************************************
+holding a block gives some defense
+ can still block?
+ just make the block more transparent so it's clear you can't block
+
+
+When you beat the boss without lore the output thing should read simulation complete, processing results, terminating simulation
+shutdown progress: 0%
+And count up by ten to 100% before you die, so that players know they won and don't think theyre stuck or something, and so its not surprising when you die
+
+Additionally, a stats screen would be nice. Like when you die, and it fades to white, output reads simulation result: failure (or success if you beat the boss)
+Then reads some stats like kills, tech picked up, research picked up, damage dealt/taken, etc
+
+
+
+
tech fire gun in the future
laser doesn't work because of draw, needs to be a bullet
foam? shotgun?
@@ -44,12 +59,6 @@ tech fire gun in the future
setTimeout(() => {
}, 1000);
-
-historyBoss needs legs?
-
-unified field theory is too weak
- fill energy make immune to damage on swap?
-
tech: when you switch guns switch a random bot to a different bot. If the bot you had was upgraded the new one will be too.
or switch all bots