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