From 045039171e87a6fc37f35f40bcdcfc38c62522f1 Mon Sep 17 00:00:00 2001 From: landgreen Date: Tue, 9 Feb 2021 05:46:43 -0800 Subject: [PATCH] restitution several new junk tech unified field theory: now cycles fields after you click the field box when paused tech: restitution - mobs killed by blocks spawn power ups tech: inelastic collision - 60% harm reduction when holding a block --- .DS_Store | Bin 6148 -> 6148 bytes js/bullet.js | 2 +- js/engine.js | 11 ++++ js/index.js | 21 ++++++- js/level.js | 7 ++- js/mob.js | 4 +- js/player.js | 10 ++-- js/simulation.js | 15 ----- js/spawn.js | 27 +++++---- js/tech.js | 150 +++++++++++++++++++++++++++++++++++++++-------- todo.txt | 29 +++++---- 11 files changed, 201 insertions(+), 75 deletions(-) diff --git a/.DS_Store b/.DS_Store index 392d3dcc375524f62639cea6020752ba9cf168ea..523eb0246ac9b14eb918884c3e63d2bcd05b0eac 100644 GIT binary patch delta 21 ccmZoMXffEJ#mwYXF 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