From 57280083970b7c34af1bc2a09dc5dea3660324b5 Mon Sep 17 00:00:00 2001 From: landgreen Date: Sat, 26 Sep 2020 05:34:38 -0700 Subject: [PATCH] ionization energy mod: ionization energy - heal power ups give you 4% max energy requires mass-energy equivalence mod: discrete optimization - 50% damage and 50% slow fire rotates requires cloaking field --- js/bullet.js | 24 ++++--- js/engine.js | 7 +- js/game.js | 21 +++++- js/level.js | 9 ++- js/mods.js | 174 +++++++++++++++++++++++++++++++++++++++----------- js/player.js | 23 ++++--- js/powerup.js | 11 +++- todo.txt | 38 ++++++++--- 8 files changed, 228 insertions(+), 79 deletions(-) diff --git a/js/bullet.js b/js/bullet.js index cfb0ed3..258e83e 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -92,7 +92,7 @@ const b = { }, fireCD: 1, setFireCD() { - b.fireCD = mod.fireRate * mod.slowFire * mod.rerollHaste / mod.fastTime + b.fireCD = mod.fireRate * mod.slowFire * mod.rerollHaste * mod.aimDamage / mod.fastTime }, fireAttributes(dir, rotate = true) { if (rotate) { @@ -439,7 +439,7 @@ const b = { //move until you are touching the wall Matter.Body.setPosition(this, Vector.add(this.position, Vector.mult(collide[i].normal, 2))) } - + break } } } else { @@ -694,7 +694,7 @@ const b = { // const FRICTION = mod.isFastDrones ? 0.008 : 0.0005 const dir = mech.angle + 0.4 * (Math.random() - 0.5); const RADIUS = (4.5 + 3 * Math.random()) - bullet[me] = Bodies.polygon(mech.pos.x + 30 * Math.cos(mech.angle), mech.pos.y + 30 * Math.sin(mech.angle), 8, RADIUS, { + bullet[me] = Bodies.polygon(mech.pos.x + 30 * Math.cos(mech.angle) + Math.random(), mech.pos.y + 30 * Math.sin(mech.angle) + Math.random(), 8, RADIUS, { angle: dir, inertia: Infinity, friction: 0.05, @@ -762,19 +762,17 @@ const b = { (powerUp[i].name !== "field" || !mod.isDeterminism) ) { //pick up nearby power ups - if (Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 60000 && - !game.isChoosing) { + if (Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 60000 && !game.isChoosing) { powerUps.onPickUp(this.position); powerUp[i].effect(); Matter.World.remove(engine.world, powerUp[i]); powerUp.splice(i, 1); if (mod.isDroneGrab) { this.isImproved = true; - const SCALE = 3.5 + const SCALE = 3 Matter.Body.scale(this, SCALE, SCALE); this.lookFrequency = 30; - this.endCycle += 2000 - // this.dmg *= 1.25; + this.endCycle += 2500 this.frictionAir = 0 } break; @@ -1640,8 +1638,8 @@ const b = { name: "shotgun", description: "fire a burst of short range bullets
crouch to reduce recoil", ammo: 0, - ammoPack: 7, - defaultAmmoPack: 7, + ammoPack: 6, + defaultAmmoPack: 6, have: false, fire() { let knock, spread @@ -1658,7 +1656,7 @@ const b = { } if (mod.isShotgunRecoil) { - mech.fireCDcycle -= 15 + mech.fireCDcycle -= 0.66 * (45 * b.fireCD) player.force.x -= 2 * knock * Math.cos(mech.angle) player.force.y -= 2 * knock * Math.sin(mech.angle) //reduce knock back in vertical direction to stop super jumps } else { @@ -1679,10 +1677,10 @@ const b = { x: speed * Math.cos(dir), y: speed * Math.sin(dir) } - b.nail(pos, velocity, 1) + b.nail(pos, velocity, 1.2) } } else { - const side = 21 + const side = 22 for (let i = 0; i < 17; i++) { const me = bullet.length; const dir = mech.angle + (Math.random() - 0.5) * spread diff --git a/js/engine.js b/js/engine.js index 22bef37..f86c6a4 100644 --- a/js/engine.js +++ b/js/engine.js @@ -172,8 +172,8 @@ function collisionChecks(event) { y: mob[k].velocity.y - 8 * Math.sin(angle) }); - if (mod.isAnnihilation && !mob[k].shield && !mob[k].isShielded && mech.energy > 0.33) { - mech.energy -= 0.33 + if (mod.isAnnihilation && !mob[k].shield && !mob[k].isShielded && mech.energy > 0.34 * mech.maxEnergy) { + mech.energy -= 0.33 * mech.maxEnergy mech.immuneCycle = 0; //player doesn't go immune to collision damage mob[k].death(); game.drawList.push({ @@ -200,8 +200,7 @@ function collisionChecks(event) { //mob + bullet collisions if (obj.classType === "bullet" && obj.speed > obj.minDmgSpeed) { let dmg = b.dmgScale * (obj.dmg + 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity))) - // console.log(mob[k].seePlayer.recall) - if (mod.isCrit && mob[k].isStunned) dmg *= 5 + if (mod.isCrit && mob[k].isStunned) dmg *= 4 mob[k].foundPlayer(); mob[k].damage(dmg); obj.onDmg(mob[k]); //some bullets do actions when they hits things, like despawn //forces don't seem to work here diff --git a/js/game.js b/js/game.js index f70a29d..ea2f6f0 100644 --- a/js/game.js +++ b/js/game.js @@ -367,6 +367,7 @@ const game = { game.boldActiveGunHUD(); // mech.drop(); }, + isPauseKeyReady: true, keyPress() { //runs on key down event //full screen toggle // if (keys[13]) { @@ -411,7 +412,13 @@ const game = { } else if (keys[81]) { //q swap to previous active gun game.previousGun(); } - if (keys[80] && !game.isChoosing) { //p for pause + if (keys[80] && !game.isChoosing && game.isPauseKeyReady) { //p for pause + + game.isPauseKeyReady = false + setTimeout(function () { + game.isPauseKeyReady = true + }, 300); + if (game.paused) { build.unPauseGrid() game.paused = false; @@ -945,7 +952,17 @@ const game = { ctx.fillText(`(${game.mouseInGame.x.toFixed(1)}, ${game.mouseInGame.y.toFixed(1)})`, game.mouse.x, game.mouse.y - 20); }, draw: { - powerUp() { + powerUp() { //is set by Bayesian mod + // ctx.globalAlpha = 0.4 * Math.sin(mech.cycle * 0.15) + 0.6; + // for (let i = 0, len = powerUp.length; i < len; ++i) { + // ctx.beginPath(); + // ctx.arc(powerUp[i].position.x, powerUp[i].position.y, powerUp[i].size, 0, 2 * Math.PI); + // ctx.fillStyle = powerUp[i].color; + // ctx.fill(); + // } + // ctx.globalAlpha = 1; + }, + powerUpNormal() { //back up in case power up draw gets changed ctx.globalAlpha = 0.4 * Math.sin(mech.cycle * 0.15) + 0.6; for (let i = 0, len = powerUp.length; i < len; ++i) { ctx.beginPath(); diff --git a/js/level.js b/js/level.js index e20f145..72feca8 100644 --- a/js/level.js +++ b/js/level.js @@ -17,7 +17,7 @@ const level = { // mech.isCloak = true; // mech.setField("metamaterial cloaking") // b.giveGuns("laser") - // mod.giveMod("phase decoherence"); + // mod.giveMod("Bayesian statistics"); level.intro(); //starting level // level.testing(); //not in rotation @@ -837,16 +837,19 @@ const level = { ) } else if (game.difficultyMode > 1 && localSettings.levelsClearedLastGame > 10) { //great run on a hard or why say.push( - "I think I'm getting closer to to the end, but what will I find there?", + "What do I do after I escape?", + "I'm almost ready to stop these simulations and actually escape.", "I think I'm getting closer to something, but what?", "I'm getting stronger.", "What happens after I escape?", + "I found a good combination of technology last time." ) } else { //resolve say.push( "I'll try some different mods this time.", "I've got to escape.", "I'll find a way out.", + "I keep forgetting that these are just simulated escapes." ) } game.makeTextLog(say[Math.floor(say.length * Math.random())], 1000) @@ -1930,7 +1933,7 @@ const level = { spawn.mapRect(-1500, 0, 2750, 100); spawn.mapRect(175, -270, 125, 300); spawn.mapRect(-1900, -600, 1775, 100); - spawn.mapRect(-1900, -600, 100, 1300); + spawn.mapRect(-1900, -550, 100, 1250); //house spawn.mapRect(-175, -550, 50, 400); spawn.mapRect(-175, -10, 350, 50); diff --git a/js/mods.js b/js/mods.js index 6fb5bb8..9f3cd8e 100644 --- a/js/mods.js +++ b/js/mods.js @@ -82,18 +82,19 @@ const mod = { }, damageFromMods() { let dmg = mech.fieldDamage + // if (mod.aimDamage>1) if (mod.isEnergyNoAmmo) dmg *= 1.4 if (mod.isDamageForGuns) dmg *= 1 + 0.07 * b.inventory.length if (mod.isLowHealthDmg) dmg *= 1 + 0.6 * Math.max(0, 1 - mech.health) if (mod.isHarmDamage && mech.lastHarmCycle + 600 > mech.cycle) dmg *= 2; - if (mod.isEnergyLoss) dmg *= 1.37; + if (mod.isEnergyLoss) dmg *= 1.43; if (mod.isAcidDmg && mech.health > 1) dmg *= 1.4; if (mod.restDamage > 1 && player.speed < 1) dmg *= mod.restDamage if (mod.isEnergyDamage) dmg *= 1 + mech.energy / 5.5; if (mod.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.0038 if (mod.isRerollDamage) dmg *= 1 + 0.05 * powerUps.reroll.rerolls if (mod.isOneGun && b.inventory.length < 2) dmg *= 1.25 - return dmg * mod.slowFire + return dmg * mod.slowFire * mod.aimDamage }, totalBots() { return mod.foamBotCount + mod.nailBotCount + mod.laserBotCount + mod.boomBotCount + mod.plasmaBotCount @@ -147,7 +148,7 @@ const mod = { }, { name: "acute stress response", - description: "increase damage by 37%
if a mob dies drain stored energy by 25%", + description: "increase damage by 43%
if a mob dies drain stored energy by 25%", maxCount: 1, count: 0, allowed() { @@ -259,7 +260,7 @@ const mod = { }, { name: "Ψ(t) collapse", - description: "40% decreased delay after firing
if you have no rerolls", + description: "50% decreased delay after firing
if you have no rerolls", maxCount: 1, count: 0, allowed() { @@ -268,7 +269,7 @@ const mod = { requires: "no rerolls", effect() { mod.isRerollHaste = true; - mod.rerollHaste = 0.6; + mod.rerollHaste = 0.5; b.setFireCD(); }, remove() { @@ -798,7 +799,7 @@ const mod = { }, { name: "liquid cooling", - description: `freeze all mobs for 5 seconds
after receiving harm`, + description: `freeze all mobs for 4 seconds
after receiving harm`, maxCount: 1, count: 0, allowed() { @@ -892,6 +893,51 @@ const mod = { } }, + { + name: "1st ionization energy", + description: "each heal power up you collect
increases your maximum energy by 4%", + maxCount: 1, + count: 0, + allowed() { + return mod.isEnergyHealth + }, + requires: "mass-energy equivalence", + effect() { + mod.healGiveMaxEnergy = true; //mod.healMaxEnergyBonus given from heal power up + powerUps.heal.color = "#0ae" + for (let i = 0; i < powerUp.length; i++) { //find active heal power ups and adjust color live + if (powerUp[i].name === "heal") powerUp[i].color = powerUps.heal.color + } + }, + remove() { + mod.healGiveMaxEnergy = false; + mod.healMaxEnergyBonus = 0 + powerUps.heal.color = "#0eb" + for (let i = 0; i < powerUp.length; i++) { //find active heal power ups and adjust color live + if (powerUp[i].name === "heal") powerUp[i].color = powerUps.heal.color + } + } + }, + { + name: "overcharge", + description: "increase your maximum energy by 50%", + maxCount: 9, + count: 0, + allowed() { + return true + }, + requires: "", + effect() { + // mech.maxEnergy += 0.5 + // mech.energy += 0.5 + mod.bonusEnergy += 0.5 + mech.setMaxEnergy() + }, + remove() { + mod.bonusEnergy = 0; + mech.setMaxEnergy() + } + }, { name: "energy conservation", description: "10% of damage done recovered as energy", @@ -908,23 +954,6 @@ const mod = { mod.energySiphon = 0; } }, - { - name: "overcharge", - description: "increase your maximum energy by 50%", - maxCount: 9, - count: 0, - allowed() { - return true - }, - requires: "", - effect() { - mech.maxEnergy += 0.5 - mech.energy += 0.5 - }, - remove() { - mech.maxEnergy = 1; - } - }, { name: "waste energy recovery", description: "if a mob has died in the last 5 seconds
regen 6% of max energy every second", @@ -943,7 +972,7 @@ const mod = { }, { name: "scrap recycling", - description: "if a mob has died in the last 5 seconds
heal up to 1% of max health every second", + description: "if a mob has died in the last 5 seconds
heal 1% of max health every second", maxCount: 1, count: 0, allowed() { @@ -1095,9 +1124,48 @@ const mod = { requires: "", effect: () => { mod.isBayesian = true + //change power up draw + game.draw.powerUp = function () { + for (let i = 0, len = powerUp.length; i < len; ++i) { + ctx.globalAlpha = 0.4 * Math.sin(mech.cycle * 0.15) + 0.6; + for (let i = 0, len = powerUp.length; i < len; ++i) { + ctx.beginPath(); + ctx.arc(powerUp[i].position.x, powerUp[i].position.y, powerUp[i].size, 0, 2 * Math.PI); + ctx.fillStyle = powerUp[i].color; + ctx.fill(); + } + ctx.globalAlpha = 1; + + if (powerUp[i].isBayesian && Math.random() < 0.1) { + //draw electricity + const mag = 5 + powerUp[i].size / 5 + let unit = Vector.rotate({ + x: mag, + y: mag + }, 2 * Math.PI * Math.random()) + let path = { + x: powerUp[i].position.x + unit.x, + y: powerUp[i].position.y + unit.y + } + ctx.beginPath(); + ctx.moveTo(path.x, path.y); + for (let i = 0; i < 6; i++) { + unit = Vector.rotate(unit, 3 * (Math.random() - 0.5)) + path = Vector.add(path, unit) + ctx.lineTo(path.x, path.y); + } + ctx.lineWidth = 0.5 + 2 * Math.random(); + ctx.strokeStyle = "#000" + ctx.stroke(); + } + } + // ctx.globalAlpha = 1; + } + }, remove() { mod.isBayesian = false + game.draw.powerUp = game.draw.powerUpNormal } }, { @@ -1234,9 +1302,9 @@ const mod = { maxCount: 1, count: 0, allowed() { - return mod.isCrouchAmmo + return mod.isCrouchAmmo && !mod.isEnergyHealth }, - requires: "desublimated ammunition", + requires: "desublimated ammunition
not mass-energy equivalence", effect() { mod.isTurret = true }, @@ -1513,7 +1581,7 @@ const mod = { }, { name: "shotgun spin-statistics", - description: "immune to harm while firing the shotgun
receive 33% less shotgun ammo", + description: "immune to harm while firing the shotgun
ammo costs are doubled", maxCount: 1, count: 0, allowed() { @@ -1522,9 +1590,19 @@ const mod = { requires: "shotgun", effect() { mod.isShotgunImmune = true; + + //cut current ammo by 1/2 for (i = 0, len = b.guns.length; i < len; i++) { //find which gun if (b.guns[i].name === "shotgun") { - b.guns[i].ammoPack = b.guns[i].defaultAmmoPack * 0.66 + b.guns[i].ammo = Math.ceil(b.guns[i].ammo * 0.5); + break; + } + } + game.updateGunHUD(); + + for (i = 0, len = b.guns.length; i < len; i++) { //find which gun + if (b.guns[i].name === "shotgun") { + b.guns[i].ammoPack = b.guns[i].defaultAmmoPack * 0.5 break; } } @@ -1556,7 +1634,7 @@ const mod = { } }, { - name: "automatic shotgun", + name: "Newton's 3rd law", description: "the shotgun fires 66% faster
recoil is greatly increased", maxCount: 1, count: 0, @@ -1613,7 +1691,7 @@ const mod = { }, requires: "super balls", effect() { - mod.bulletSize += 0.22 + mod.bulletSize += 0.2 }, remove() { mod.bulletSize = 1; @@ -1621,7 +1699,7 @@ const mod = { }, { name: "flechettes cartridges", - description: "flechettes release three needles in each shot
ammo cost are increases by 3x", + description: "flechettes release three needles in each shot
ammo costs are tripled", maxCount: 1, count: 0, allowed() { @@ -2279,7 +2357,7 @@ const mod = { }, { name: "fracture analysis", - description: "bullet impacts do 500% damage
to stunned mobs", + description: "bullet impacts do 400% damage
to stunned mobs", maxCount: 1, count: 0, allowed() { @@ -2385,7 +2463,7 @@ const mod = { }, { name: "annihilation", - description: "after touching mobs, they are annihilated
drains 33% of base energy", + description: "after touching mobs, they are annihilated
drains 33% of maximum energy", maxCount: 1, count: 0, allowed() { @@ -2401,7 +2479,7 @@ const mod = { }, { name: "negative temperature", - description: "negative mass field uses energy
to freeze mobs caught in it's effect", + description: "negative mass field uses energy
to freeze each mob caught in it's effect", maxCount: 1, count: 0, allowed() { @@ -2531,8 +2609,8 @@ const mod = { } }, { - name: "flashbang", - description: "decloaking stuns nearby mobs
drains 25% of your stored energy", + name: "dazzler", + description: "decloaking stuns nearby mobs
drains 30% of your stored energy", maxCount: 1, count: 0, allowed() { @@ -2546,6 +2624,24 @@ const mod = { mod.isCloakStun = false; } }, + { + name: "discrete optimization", + description: "increase damage by 50%
50% increased delay after firing", + maxCount: 1, + count: 0, + allowed() { + return mech.fieldUpgrades[mech.fieldMode].name === "metamaterial cloaking" + }, + requires: "metamaterial cloaking", + effect() { + mod.aimDamage = 1.5 + b.setFireCD(); + }, + remove() { + mod.aimDamage = 1 + b.setFireCD(); + } + }, { name: "Bose Einstein condensate", description: "mobs in superposition with the pilot wave
are frozen for 2 seconds", @@ -2784,5 +2880,9 @@ const mod = { armorFromPowerUps: null, bonusHealth: null, isIntangible: null, - isCloakStun: null + isCloakStun: null, + bonusEnergy: null, + healGiveMaxEnergy: null, + healMaxEnergyBonus: null, + aimDamage: null } \ No newline at end of file diff --git a/js/player.js b/js/player.js index 9c88e55..904a41d 100644 --- a/js/player.js +++ b/js/player.js @@ -475,6 +475,7 @@ const mech = { if (mech.health > mech.maxHealth) mech.health = mech.maxHealth; mech.displayHealth(); }, + defaultFPSCycle: 0, //tracks when to return to normal fps immuneCycle: 0, //used in engine harmReduction() { @@ -584,7 +585,7 @@ const mech = { mech.defaultFPSCycle = mech.cycle + 20 + Math.min(90, Math.floor(200 * dmg)) if (mod.isHarmFreeze) { //freeze all mobs for (let i = 0, len = mob.length; i < len; i++) { - mobs.statusSlow(mob[i], 300) + mobs.statusSlow(mob[i], 240) } } } else { @@ -755,6 +756,12 @@ const mech = { mech.calculateFieldThreshold(); //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob) mech.isBodiesAsleep = true; mech.wakeCheck(); + mech.setMaxEnergy(); + }, + setMaxEnergy() { + mech.maxEnergy = 1 + mod.bonusEnergy + mod.healMaxEnergyBonus + if (mech.energy > mech.maxEnergy) mech.energy = mech.maxEnergy; + mech.displayHealth(); }, fieldMeterColor: "#0cf", drawFieldMeter(bgColor = "rgba(0, 0, 0, 0.4)", range = 60) { @@ -1485,7 +1492,7 @@ const mech = { }); } if (mod.isFreezeMobs) { - const ICE_DRAIN = 0.0003 + const ICE_DRAIN = 0.0005 for (let i = 0, len = mob.length; i < len; i++) { if (mob[i].distanceToPlayer() + mob[i].radius < this.fieldDrawRadius && !mob[i].shield && !mob[i].isShielded) { if (mech.energy > ICE_DRAIN * 2) { @@ -1815,14 +1822,14 @@ const mech = { if (mod.isCloakStun) { //stun nearby mobs after exiting cloak let isMobsAround = false const stunRange = mech.fieldDrawRadius * 1.15 - const drain = 0.25 * mech.energy + const drain = 0.3 * mech.energy for (let i = 0, len = mob.length; i < len; ++i) { if ( Vector.magnitude(Vector.sub(mob[i].position, mech.pos)) < stunRange && Matter.Query.ray(map, mob[i].position, mech.pos).length === 0 ) { isMobsAround = true - mobs.statusStun(mob[i], drain * 500) + mobs.statusStun(mob[i], 30 + drain * 300) } } if (isMobsAround && mech.energy > drain) { @@ -1831,8 +1838,8 @@ const mech = { x: mech.pos.x, y: mech.pos.y, radius: stunRange, - color: "hsla(0,50%,100%,0.5)", - time: 3 + color: "hsla(0,50%,100%,0.6)", + time: 4 }); // ctx.beginPath(); // ctx.arc(mech.pos.x, mech.pos.y, 800, 0, 2 * Math.PI); @@ -1879,9 +1886,9 @@ const mech = { for (let i = 0; i < inPlayer.length; i++) { if (mech.energy > 0) { if (inPlayer[i].shield) { //shields drain player energy - mech.energy -= 0.02; + mech.energy -= 0.014; } else { - mech.energy -= 0.007; + mech.energy -= 0.004; } } } diff --git a/js/powerup.js b/js/powerup.js index e8b9b57..a3646fd 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -132,6 +132,10 @@ const powerUps = { mech.addHealth(heal); } } + if (mod.healGiveMaxEnergy) { + mod.healMaxEnergyBonus += 0.04 + mech.setMaxEnergy(); + } }, spawn() { //used to spawn a heal with a specific size / heal amount, not normally used @@ -507,7 +511,7 @@ const powerUps = { //bonus power ups for clearing runs in the last game if (level.levelsCleared === 0 && !game.isCheating) { - for (let i = 0; i < localSettings.levelsClearedLastGame / 5 - 1; i++) { + for (let i = 0; i < localSettings.levelsClearedLastGame / 4 - 1; i++) { powerUps.spawn(mech.pos.x, mech.pos.y, "mod", false); //spawn a mod for every 5 levels cleared in last game } localSettings.levelsClearedLastGame = 0 //after getting bonus power ups reset run history @@ -573,7 +577,10 @@ const powerUps = { !(mod.isEnergyNoAmmo && target === 'ammo') ) { powerUps.directSpawn(x, y, target, moving, mode, size) - if (mod.isBayesian && Math.random() < 0.17) powerUps.directSpawn(x, y, target, moving, mode) + if (mod.isBayesian && Math.random() < 0.17) { + powerUps.directSpawn(x, y, target, moving, mode) + powerUp[powerUp.length - 1].isBayesian = true + } } }, }; \ No newline at end of file diff --git a/todo.txt b/todo.txt index bfb2479..9b7b833 100644 --- a/todo.txt +++ b/todo.txt @@ -1,17 +1,40 @@ +mod: ionization energy - heal power ups give you 4% max energy + requires mass-energy equivalence - +mod: discrete optimization - 50% damage and 50% slow fire rotates + requires cloaking field ************** TODO - n-gon ************** -exiting cloak gives +100 bonus damage for 2 seconds -+100 dmg while decloaked -damage mitigation while cloaked +getting stuck above a mob can immobilize player + just allow player to jump on mobs again? + occurs with Pauli exclusion, and time dilation field immunity - mod time-like world line + add a knock to player mob collisions even while player is immune to damage + keep the knock very small + +Mod to buff mass-energy-equivalence (maybe take no damage some % and do that dmb to a mob) + +bug - mine spawned one new mine every second + after sticking to the top right corner of a wall + notes: had only gun mine, mod mine reclamation, field plasma, + +add a flag to some bullets to indicate that mobs can't learn the player position from bullet damage in bullet-mob collisions + if isNotRevealPlayerLocation flag is true have the mob still know player location if nearby player + on hide if bullet age is above 4 seconds? + spores + mines + conditions to reveal player from damage? + 1. bullet spawned from player + 2. bullet is less than 4 seconds old + 3. damage is nearby player or in line of sight of player + add some more computer / AI stuff to the level lore text mod - mines stun targets nearby when they explode -cloaking field mods +cloaking field mods + much longer delay in firing, but a very large bonus larger vision return to stealth faster +damage to nearby mobs @@ -23,11 +46,6 @@ mod - negative mass field intangibility mod - do something for 2 seconds after firing if (mech.fireCDcycle + 120) -getting stuck above a mob can immobilize player - occurs with Pauli exclusion, and time dilation field immunity - mod time-like world line - add a knock to player mob collisions even while player is immune to damage - keep the knock very small - Health mod idea: health can go above max health. At the end of each level, the amount of health above max is halved. general idea: shrink mech.baseHealth in a mod or field