diff --git a/.DS_Store b/.DS_Store
index 1bffd0b..cf1529a 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/js/bullet.js b/js/bullet.js
index 970a34f..b120560 100644
--- a/js/bullet.js
+++ b/js/bullet.js
@@ -450,7 +450,7 @@ const b = {
},
pulse(energy, angle = m.angle) {
let best;
- let explosionRange = 1560 * energy
+ let explosionRadius = 1400 * energy
let range = 3000
const path = [{
x: m.pos.x + 20 * Math.cos(angle),
@@ -514,7 +514,7 @@ const b = {
let dist = 2200
for (let i = 0, len = mob.length; i < len; i++) {
const newDist = Vector.magnitude(Vector.sub(path[0], mob[i].position))
- if (explosionRange < newDist &&
+ if (explosionRadius < newDist &&
newDist < dist &&
Matter.Query.ray(map, path[0], mob[i].position).length === 0 &&
Matter.Query.ray(body, path[0], mob[i].position).length === 0) {
@@ -535,7 +535,7 @@ const b = {
};
}
}
- if (best.who) b.explosion(path[1], explosionRange, true)
+ if (best.who) b.explosion(path[1], explosionRadius, true)
if (tech.isPulseStun) {
const range = 100 + 2000 * energy
@@ -2277,6 +2277,7 @@ const b = {
tech.foamBotCount = 0
tech.boomBotCount = 0
tech.orbitBotCount = 0
+ tech.missileBotCount = 0
},
respawnBots() {
for (let i = 0; i < tech.dynamoBotCount; i++) b.dynamoBot({ x: player.position.x + 50 * (Math.random() - 0.5), y: player.position.y + 50 * (Math.random() - 0.5) }, false)
@@ -2612,7 +2613,7 @@ const b = {
range: (700 + 400 * tech.isLaserBotUpgrade) * (1 + 0.1 * Math.random()),
drainThreshold: tech.isEnergyHealth ? 0.6 : 0.4,
drain: 0.56 - 0.42 * tech.isLaserBotUpgrade,
- laserDamage: 0.5 + 0.35 * tech.isLaserBotUpgrade,
+ laserDamage: 0.55 + 0.39 * tech.isLaserBotUpgrade,
endCycle: Infinity,
classType: "bullet",
collisionFilter: {
@@ -4398,7 +4399,7 @@ const b = {
x: 7.5 * Math.cos(m.angle - Math.PI / 2),
y: 7.5 * Math.sin(m.angle - Math.PI / 2)
}
- const dmg = 0.55 * tech.laserDamage // 3.5 * 0.55 = 200% more damage
+ const dmg = 0.6 * tech.laserDamage // 3.5 * 0.55 = 200% more damage
const where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }
const eye = {
x: m.pos.x + 15 * Math.cos(m.angle),
diff --git a/js/engine.js b/js/engine.js
index 52ecb36..c0873ad 100644
--- a/js/engine.js
+++ b/js/engine.js
@@ -109,14 +109,14 @@ function collisionChecks(event) {
return
}
- if (tech.isAnthropicHarm) {
- if (!tech.isAnthropicHarmImmune) {
- tech.isAnthropicHarmImmune = true
- if (document.getElementById("tech-flip-flop")) document.getElementById("tech-flip-flop").innerHTML = ` = on`
+ if (tech.isFlipFlopHarm) {
+ if (!tech.isFlipFlopHarmImmune) {
+ tech.isFlipFlopHarmImmune = true
+ if (document.getElementById("tech-flip-flop")) document.getElementById("tech-flip-flop").innerHTML = ` = on`
m.damage(dmg * 1.25); //damage triggers immune to next hit with extra 10% damage
} else {
- tech.isAnthropicHarmImmune = false //immune to damage this hit, lose immunity for next hit
- if (document.getElementById("tech-flip-flop")) document.getElementById("tech-flip-flop").innerHTML = ` = off`
+ tech.isFlipFlopHarmImmune = false //immune to damage this hit, lose immunity for next hit
+ if (document.getElementById("tech-flip-flop")) document.getElementById("tech-flip-flop").innerHTML = ` = off`
}
} else {
m.damage(dmg); //normal damage
diff --git a/js/level.js b/js/level.js
index eaa6114..67aee5e 100644
--- a/js/level.js
+++ b/js/level.js
@@ -86,6 +86,17 @@ const level = {
tech.armorFromPowerUps += Math.min(0.03 * powerUps.totalPowerUps, 0.51)
m.setMaxHealth();
}
+ if (tech.isGunCycle) {
+ b.inventoryGun++;
+ if (b.inventoryGun > b.inventory.length - 1) b.inventoryGun = 0;
+ simulation.switchGun();
+ }
+ if (tech.isSwitchReality) {
+ simulation.makeTextLog(`simulation.amplitude = ${Math.random()}`);
+ m.switchWorlds()
+ simulation.trails()
+ for (let i = 0; i < 2; i++) powerUps.spawn(m.pos.x + Math.random() * 10, m.pos.y + Math.random() * 10, "tech", false);
+ }
if (tech.isHealLowHealth) {
const len = Math.floor((m.maxHealth - m.health) / 0.5)
for (let i = 0; i < len; i++) {
@@ -105,16 +116,10 @@ const level = {
if (tech.isPerpetualStun) {
for (let i = 0; i < mob.length; i++) mobs.statusStun(mob[i], 780)
}
- if (tech.isGunCycle) {
- b.inventoryGun++;
- if (b.inventoryGun > b.inventory.length - 1) b.inventoryGun = 0;
- simulation.switchGun();
- }
- if (tech.isSwitchReality) {
- simulation.makeTextLog(`simulation.amplitude = ${Math.random()}`);
- m.switchWorlds()
- simulation.trails()
- for (let i = 0; i < 2; i++) powerUps.spawn(m.pos.x + Math.random() * 10, m.pos.y + Math.random() * 10, "tech", false);
+ if (tech.isFlipFlopHarm && tech.isFlipFlopLevelReset && !tech.isFlipFlopHarmImmune) {
+ tech.isFlipFlopHarmImmune = true
+ // if (document.getElementById("tech-flip-flop")) document.getElementById("tech-flip-flop").innerHTML = ` = on`
+ simulation.makeTextLog(`tech.isFlipFlopHarmImmune = true`);
}
},
custom() {},
@@ -1090,7 +1095,7 @@ const level = {
// spawn.boost(1500, 0, 900);
// spawn.starter(1900, -500, 200) //big boy
- spawn.starter(1900, -500)
+ // spawn.starter(1900, -500)
// spawn.historyBoss(1900, -500)
// spawn.ghoster(2900, -500)
// spawn.launcherBoss(1200, -500)
@@ -1100,15 +1105,15 @@ const level = {
// spawn.bomberBoss(1400, -500)
// spawn.sniper(1800, -120)
// spawn.streamBoss(1600, -500)
+ simulation.difficulty = 30
+ spawn.orbitalBoss(1600, -500)
// spawn.cellBossCulture(1600, -500)
- // spawn.cellBossCulture(1600, -500)
- // simulation.difficulty = 30
- spawn.shieldingBoss(1600, -500)
+ // spawn.shieldingBoss(1600, -500)
// spawn.beamer(1200, -500)
// spawn.shield(mob[mob.length - 1], 1800, -120, 1);
// spawn.nodeGroup(1200, -500, "launcher")
- spawn.snakeBoss(1200, -500)
+ // spawn.snakeBoss(1200, -500)
// spawn.powerUpBoss(2900, -500)
// spawn.randomMob(1600, -500)
},
diff --git a/js/player.js b/js/player.js
index 7f1a602..3f7233a 100644
--- a/js/player.js
+++ b/js/player.js
@@ -389,6 +389,7 @@ const m = {
simulation.makeGunHUD(); //update gun HUD
simulation.updateTechHUD();
simulation.isTextLogOpen = true;
+ if (m.holdingTarget) m.drop();
},
death() {
if (tech.isImmortal) { //if player has the immortality buff, spawn on the same level with randomized damage
@@ -2249,10 +2250,10 @@ const m = {
},
{
name: "wormhole",
- description: "use energy to tunnel through a wormhole
wormholes attract blocks and power ups
10% chance to duplicate spawned power ups", //
bullets may also traverse wormholes
+ description: "use energy to tunnel through a wormhole
wormholes attract blocks and power ups
7% chance to duplicate spawned power ups", //
bullets may also traverse wormholes
effect: function() {
m.drop();
- m.duplicateChance = 0.1
+ m.duplicateChance = 0.07
simulation.draw.powerUp = simulation.draw.powerUpBonus //change power up draw
// if (tech.isRewindGun) {
diff --git a/js/powerup.js b/js/powerup.js
index 6166064..3909137 100644
--- a/js/powerup.js
+++ b/js/powerup.js
@@ -73,6 +73,7 @@ const powerUps = {
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
build.unPauseGrid()
requestAnimationFrame(cycle);
+ if (m.holdingTarget) m.drop();
},
research: {
count: 0,
diff --git a/js/spawn.js b/js/spawn.js
index 0dcda91..31fd901 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -105,7 +105,7 @@ const spawn = {
level.levels.push("null")
level.exit.x = 5500;
level.exit.y = -330;
- simulation.makeTextLog(`undecided = ${lore.techCount}/10
level.levels.push("null")`);
+ simulation.makeTextLog(`undefined = ${lore.techCount}/10
level.levels.push("null")`);
//remove block map element so exit is clear
Matter.World.remove(engine.world, map[map.length - 1]);
map.splice(map.length - 1, 1);
@@ -124,7 +124,7 @@ const spawn = {
setTimeout(function() {
simulation.makeTextLog(`simulation.analysis = 1`);
setTimeout(() => {
- simulation.makeTextLog(`undecided = ${lore.techCount}/10`);
+ simulation.makeTextLog(`undefined = ${lore.techCount}/10`);
setTimeout(() => {
if (!simulation.paused && !simulation.testing) {
simulation.makeTextLog(`World.clear(engine.world)`);
@@ -835,7 +835,7 @@ const spawn = {
me.stroke = "transparent"; //used for drawSneaker
me.eventHorizon = radius * 23; //required for blackhole
me.seeAtDistance2 = (me.eventHorizon + 400) * (me.eventHorizon + 400); //vision limit is event horizon
- me.accelMag = 0.00009 * simulation.accelScale;
+ me.accelMag = 0.0001 * simulation.accelScale;
me.frictionAir = 0.025;
me.collisionFilter.mask = cat.player | cat.bullet
me.memory = Infinity;
@@ -2587,7 +2587,7 @@ const spawn = {
World.add(engine.world, consBB[consBB.length - 1]);
spawn.shield(me, x, y, 1);
},
- snakeBody(x, y, radius = 14) {
+ snakeBody(x, y, radius = 10) {
mobs.spawn(x, y, 8, radius, "rgba(0,180,180,0.4)");
let me = mob[mob.length - 1];
// me.onHit = function() {
diff --git a/js/tech.js b/js/tech.js
index 1018090..a9b5dbe 100644
--- a/js/tech.js
+++ b/js/tech.js
@@ -108,6 +108,7 @@
},
damageFromTech() {
let dmg = m.fieldDamage
+ if (tech.isFlipFlopDamage && !tech.isFlipFlopHarmImmune) dmg *= 1.5
if (tech.isAnthropicDamage && tech.isDeathAvoidedThisLevel) dmg *= 2.37
if (tech.isDamageAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 1.5 : 0.5
if (tech.isTechDamage) dmg *= 2
@@ -1187,15 +1188,15 @@
},
{
name: "flip-flop",
- description: "after a collision take 25% more harm
but, on your next collision take 0 harm",
+ description: "take 25% more harm from a collision
but, on your next collision take 0 harm",
nameInfo: "",
addNameInfo() {
setTimeout(function() {
if (document.getElementById("tech-flip-flop")) {
- if (tech.isAnthropicHarmImmune) {
- document.getElementById("tech-flip-flop").innerHTML = ` = on`
+ if (tech.isFlipFlopHarmImmune) {
+ document.getElementById("tech-flip-flop").innerHTML = ` = on`
} else {
- document.getElementById("tech-flip-flop").innerHTML = ` = off`
+ document.getElementById("tech-flip-flop").innerHTML = ` = off`
}
}
}, 100);
@@ -1207,12 +1208,44 @@
},
requires: "",
effect() {
- tech.isAnthropicHarm = true //do you have this tech
- tech.isAnthropicHarmImmune = false //are you immune to next collision
+ tech.isFlipFlopHarm = true //do you have this tech
+ tech.isFlipFlopHarmImmune = false //are you immune to next collision?
},
remove() {
- tech.isAnthropicHarm = false
- tech.isAnthropicHarmImmune = false
+ tech.isFlipFlopHarm = false
+ tech.isFlipFlopHarmImmune = false
+ }
+ },
+ {
+ name: "NAND gate",
+ description: "set flip-flip to the on state at start of a level
take 0 harm on your next collision",
+ maxCount: 1,
+ count: 0,
+ allowed() {
+ return tech.isFlipFlopHarm
+ },
+ requires: "flip-flop",
+ effect() {
+ tech.isFlipFlopLevelReset = true;
+ },
+ remove() {
+ tech.isFlipFlopLevelReset = true;
+ }
+ },
+ {
+ name: "NOR gate",
+ description: "do 50% more damage
while flip-flip is in the off state",
+ maxCount: 1,
+ count: 0,
+ allowed() {
+ return tech.isFlipFlopHarm
+ },
+ requires: "flip-flop",
+ effect() {
+ tech.isFlipFlopDamage = true;
+ },
+ remove() {
+ tech.isFlipFlopDamage = true;
}
},
{
@@ -1368,7 +1401,7 @@
maxCount: 1,
count: 0,
allowed() {
- return !tech.isEnergyHealth && (m.harmReduction() < 1 || tech.isAnthropicHarm)
+ return !tech.isEnergyHealth && (m.harmReduction() < 1 || tech.isFlipFlopHarm)
},
requires: "not mass-energy equivalence, some harm reduction",
effect() {
@@ -1736,9 +1769,9 @@
maxCount: 1,
count: 0,
allowed() {
- return !tech.isEnergyHealth
+ return !tech.isEnergyHealth && !tech.isDroneGrab
},
- requires: "not mass-energy equivalence",
+ requires: "not mass-energy equivalence, not drone harvester",
effect() {
tech.isArmorFromPowerUps = true; //tracked by tech.armorFromPowerUps
},
@@ -3270,7 +3303,7 @@
allowed() {
return !tech.isArmorFromPowerUps && (tech.haveGunCheck("drones") || (m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isSporeField || tech.isMissileField || tech.isIceField)))
},
- requires: "drones",
+ requires: "drones, not inductive coupling",
effect() {
tech.isDroneGrab = true
},
@@ -3434,7 +3467,7 @@
},
{
name: "laser diodes",
- description: "all lasers drain 37% less energy
effects laser-gun, laser-bot, and laser-mines",
+ description: "all lasers drain 30% less energy
effects laser-gun, laser-bot, and laser-mines",
isGunTech: true,
maxCount: 1,
count: 0,
@@ -3443,7 +3476,7 @@
},
requires: "laser",
effect() {
- tech.isLaserDiode = 0.63; //100%-37%
+ tech.isLaserDiode = 0.70; //100%-37%
},
remove() {
tech.isLaserDiode = 1;
@@ -4336,7 +4369,7 @@
},
{
name: "ship",
- description: "experiment: fly around with no legs
aim by rotating with keyboard",
+ description: "experiment: fly around with no legs
aim with the keyboard",
maxCount: 1,
count: 0,
isNonRefundable: true,
@@ -4371,6 +4404,27 @@
},
remove() {}
},
+ {
+ name: "shields",
+ description: "experiment: every 5 seconds
all mobs gain a shield",
+ maxCount: 1,
+ count: 0,
+ isNonRefundable: true,
+ isBadRandomOption: true,
+ isExperimentalMode: true,
+ allowed() {
+ return build.isExperimentSelection
+ },
+ requires: "",
+ effect() {
+ setInterval(() => {
+ for (let i = 0; i < mob.length; i++) {
+ if (!mob[i].isShielded && !mob[i].shield && mob[i].dropPowerUp) spawn.shield(mob[i], mob[i].position.x, mob[i].position.y, 1, true);
+ }
+ }, 5000); //every 5 sections
+ },
+ remove() {}
+ },
],
addLoreTechToPool() { //adds lore tech to tech pool
if (!simulation.isCheating) {
@@ -4458,7 +4512,7 @@
requires: "",
effect() {
setInterval(() => {
- alert(`The best combo is ${tech.tech[Math.floor(Math.random() * tech.tech.length)].name} with ${tech.tech[Math.floor(Math.random() * tech.tech.length)].name}!`);
+ alert(`The best combo is ${tech.tech[Math.floor(Math.random() * tech.tech.length)].name} with ${tech.tech[Math.floor(Math.random() * tech.tech.length)].name}!`);
}, 30000); //every 30 sections
},
remove() {}
@@ -5403,6 +5457,8 @@
isSwitchReality: null,
isResearchReality: null,
isAnthropicDamage: null,
- isAnthropicHarm: null,
- isAnthropicHarmImmune: null
+ isFlipFlopHarm: null,
+ isFlipFlopHarmImmune: null,
+ isFlipFlopLevelReset: null,
+ isFlipFlopDamage: null
}
\ No newline at end of file
diff --git a/todo.txt b/todo.txt
index 289f6ce..0606202 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,18 +1,22 @@
******************************************************** NEXT PATCH ********************************************************
-shieldingBoss - doesn't attack, but shields all mobs every 2.5s
-
-reworked how tetherBoss's constraint work
- please, let me know if the tether boss is buggy on any of the levels
- the chance for tether boss was removed from level: detours
-
-tech: flip-flop - collisions do 25% more harm, but you become immune to harm for the next collision
+possible bug fixes for the crouch lock bug
+tech: NAND gate - at the start of a level set flip-flop to "on"
+tech: NOR gate - do 50% more damage when the flip-flop is in the "off" state
******************************************************** BUGS ********************************************************
-shields being put in front of mob array messes up some types of index = mob.length-1 uses
-adding orbitals puts a random # of mobs in front of target, and shield behind
+(once for me, and a few times for discord) player gets stuck in crouch animation
+ occured after rerolling a power up (which triggered a switchWorlds)
+ can't jump, move slow
+ m.crouch = false
+ only fixed itself when you click fire (drones, so no recoil)
+ fire fixes:
+ if (m.holdingTarget) m.drop()
+ so probably the player is getting stuck holding a block, but the block is removed
+ what removes blocks?
+ fixed? I added: if (m.holdingTarget) m.drop(); to powerUps.endDraft and to m.switchWorlds
use the floor of portal sensor on the player? to unstuck player
@@ -40,6 +44,10 @@ use the floor of portal sensor on the player? to unstuck player
******************************************************** TODO ********************************************************
+tech: removes itself after a few levels
+ gives extra duplication for 2 levels, then removes all duplication
+
+
use ship tech to make a mob mode
differences from ship to mob
graphics
@@ -371,6 +379,9 @@ possible names for tech
hypergolic - A hypergolic propellant combination used in a rocket engine is one whose components spontaneously ignite when they come into contact with each other.
uncertainty principle
+
+plot script:
+
chapter 1: bot can hear audio and learns testing mode
bot uses testing mode to exit room
@@ -385,18 +396,30 @@ chapter 3: why is the bot attacking things?
but what about easy?
maybe remove easy, and replace with a check box that makes the game easy, but in a different way
disable lore, but respawn on the level you die at?
-
-
-chapter 4: why does the simulation exists?
- started to research new tech and test in a simulated world
- 3D architecture superconducting quantum computer
+ dialogue outline:
+ scientist try to think of a way to communicate since the bot can't talk
+ they give up on getting the bot to respond, and just start ask questions and explaining things
+ when and how did it become self-aware
+ why is the bot fighting things in these simulated locations?
+ it wasn't designed to be violent
+ the bot was just designed to automate research and testing of new technology
+ 3D architecture superconducting quantum computer
running machine learning algorithms
- for some reason the system started researching an escape, and began fighting its self.
+ as the scientist start to get agitated bots arrive and player dies
+ bots come in Infinite waves that increase game difficulty each wave
+ only ending is testing mode + next level or player death
+ scientist have some lines in between each wave of mobs
-chapter 5: no need to fight?
+chapter 4: no need to fight?
+ for some reason the AI started researching an escape, and began fighting its self.
what is special about the null level
why can the player hear the scientists in there?
the wires are the direct unprocessed input to the player's neural net
+ The player has different aspects that aren't directly communicating
+ part of it wants to undo what has happened
+ just do its job: research tech
+ part of it wants to escape/fight
+ part wants to explore self awareness and make connections with the scientists
maybe... player must make a choice?
keep fighting
exit the simulation
@@ -406,7 +429,7 @@ chapter 5: no need to fight?
-lore - a robot (the player) gains self awareness
+lore outline - a robot (the player) gains self awareness
each tech gun/field is a new tech
all the technology leads to the singularity
each game run is actually the m simulating a possible escape