From 7b620ca1f06e034aa647deb791638dfa3ef5062d Mon Sep 17 00:00:00 2001 From: landgreen Date: Wed, 28 Oct 2020 05:21:08 -0700 Subject: [PATCH] added no power up setting to custom --- js/bullet.js | 27 +++++++++--------- js/game.js | 75 ++++++++++++++++++++++++------------------------ js/index.js | 39 ++++++++++++++++++++----- js/level.js | 79 +++++++++++++++++++++++++-------------------------- js/mods.js | 8 +++--- js/player.js | 6 ++-- js/powerup.js | 7 +++-- js/spawn.js | 22 +++++++------- todo.txt | 45 +++++++++++++---------------- 9 files changed, 163 insertions(+), 145 deletions(-) diff --git a/js/bullet.js b/js/bullet.js index 49c8671..2086889 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -1237,7 +1237,7 @@ const b = { onEnd() {}, do() { if (this.lastLookCycle < game.cycle && !mech.isCloak) { - this.lastLookCycle = game.cycle + 80 - this.isUpgraded * 55 + this.lastLookCycle = game.cycle + 80 - this.isUpgraded * 65 let target for (let i = 0, len = mob.length; i < len; i++) { const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)); @@ -1302,7 +1302,7 @@ const b = { const radius = 6 + 7 * Math.random() const SPEED = 29 - radius * 0.5; //(mech.crouch ? 32 : 20) - radius * 0.7; const velocity = Vector.mult(Vector.normalise(Vector.sub(target, this.position)), SPEED) - b.foam(this.position, velocity, radius + 11 * this.isUpgraded) + b.foam(this.position, velocity, radius + 14 * this.isUpgraded) break; } } @@ -1389,7 +1389,7 @@ const b = { mech.energy -= 0.0012 * mod.isLaserDiode // const sub = Vector.sub(this.lockedOn.position, this.vertices[0]) // const angle = Math.atan2(sub.y, sub.x); - b.laser(this.vertices[0], this.lockedOn.position, b.dmgScale * (0.06 + 0.08 * this.isUpgraded)) + b.laser(this.vertices[0], this.lockedOn.position, b.dmgScale * (0.06 + 0.1 * this.isUpgraded)) // //make sure you can still see vertex // const DIST = Vector.magnitude(Vector.sub(this.vertices[0], this.lockedOn.position)); @@ -1458,7 +1458,7 @@ const b = { explode: 0, beforeDmg() { if (this.lockedOn) { - const explosionRadius = Math.min(170 + 140 * this.isUpgraded, Vector.magnitude(Vector.sub(this.position, mech.pos)) - 30) + const explosionRadius = Math.min(170 + 170 * this.isUpgraded, Vector.magnitude(Vector.sub(this.position, mech.pos)) - 30) if (explosionRadius > 60) { this.explode = explosionRadius // @@ -1564,7 +1564,7 @@ const b = { const DIST = Vector.magnitude(sub); const unit = Vector.normalise(sub) const DRAIN = 0.002 - if (DIST < mod.isPlasmaRange * 500 && mech.energy > DRAIN) { + if (DIST < mod.isPlasmaRange * 450 && mech.energy > DRAIN) { mech.energy -= DRAIN; if (mech.energy < 0) { mech.fieldCDcycle = mech.cycle + 120; @@ -2038,9 +2038,9 @@ const b = { } } else { this.endCycle = 0; - if (mod.isFlechetteExplode && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.98) { + if (mod.isFlechetteExplode && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.975) { // mobs.statusStun(who, 120) - this.explodeRad = 250 + 30 * Math.random(); + this.explodeRad = 300 + 60 * Math.random(); b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end } who.foundPlayer(); @@ -2383,7 +2383,7 @@ const b = { const dir = mech.angle; // + Math.random() * 0.05; bullet[me] = Bodies.circle(mech.pos.x + 30 * Math.cos(mech.angle), mech.pos.y + 30 * Math.sin(mech.angle), 20, b.fireAttributes(dir, false)); Matter.Body.setDensity(bullet[me], 0.0003); - bullet[me].explodeRad = 400 + Math.floor(Math.random() * 50);; + bullet[me].explodeRad = 350 + Math.floor(Math.random() * 50);; bullet[me].onEnd = function () { b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end if (mod.grenadeFragments) b.targetedNail(this.position, mod.grenadeFragments) @@ -2554,7 +2554,6 @@ const b = { } bullet[me].radiationMode = function () { this.stuck(); //runs different code based on what the bullet is stuck to - if (!mech.isBodiesAsleep) { this.damageRadius = this.damageRadius * 0.85 + 0.15 * this.maxDamageRadius //smooth radius towards max this.maxDamageRadius -= 0.8 / mod.isBulletsLastLonger //+ 0.5 * Math.sin(game.cycle * 0.1) //slowly shrink max radius @@ -2575,8 +2574,8 @@ const b = { //aoe damage to mobs for (let i = 0, len = mob.length; i < len; i++) { if (Vector.magnitude(Vector.sub(mob[i].position, this.position)) < this.damageRadius) { - let dmg = b.dmgScale * 0.025 - if (Matter.Query.ray(map, mob[i].position, this.position).length > 0) dmg *= 0.5 //reduce damage if a wall is in the way + let dmg = b.dmgScale * 0.035 + if (Matter.Query.ray(map, mob[i].position, this.position).length > 0) dmg *= 0.3 //reduce damage if a wall is in the way if (mob[i].shield) dmg *= 4 //x5 to make up for the /5 that shields normally take mob[i].damage(dmg); mob[i].locatePlayer(); @@ -3232,12 +3231,12 @@ const b = { mech.energy -= energy * mod.isLaserDiode if (mod.beamSplitter) { - energy *= 0.7 + energy *= 0.66 b.pulse(energy, mech.angle) for (let i = 1; i < 1 + mod.beamSplitter; i++) { energy *= 0.9 - b.pulse(energy, mech.angle - i * 0.35) - b.pulse(energy, mech.angle + i * 0.35) + b.pulse(energy, mech.angle - i * 0.27) + b.pulse(energy, mech.angle + i * 0.27) } } else { b.pulse(energy, mech.angle) diff --git a/js/game.js b/js/game.js index a4b1db0..4aab2b4 100644 --- a/js/game.js +++ b/js/game.js @@ -134,6 +134,7 @@ const game = { accelScale: null, //set in levels.setDifficulty CDScale: null, //set in levels.setDifficulty lookFreqScale: null, //set in levels.setDifficulty + isNoPowerUps: false, // dropFPS(cap = 40, time = 15) { // game.fpsCap = cap // game.fpsInterval = 1000 / game.fpsCap; @@ -461,6 +462,7 @@ const game = { reset() { //run on first run, and each later run after you die input.endKeySensing(); b.removeAllGuns(); + game.isNoPowerUps = false; mod.setupAllMods(); //sets mods to default values b.setFireCD(); game.updateModHUD(); @@ -684,48 +686,45 @@ const game = { if (mech.energy > mech.maxEnergy) mech.energy = mech.maxEnergy + (mech.energy - mech.maxEnergy) * 0.75 if (mech.pos.y > game.fallHeight) { // if 4000px deep - if (game.difficultyMode > 4) { - mech.death(); - } else { - // Matter.Body.setPosition(player, { - // x: player.position.x, - // y: level.enter.y - 5000 - // }); - // mech.pos.x = player.position.x; - // mech.pos.y = playerBody.position.y - mech.yOff; - // const scale = 0.8; - // const velocityScale = 12 - // mech.transSmoothX = canvas.width2 - mech.pos.x - (game.mouse.x - canvas.width2) * scale + player.velocity.x * velocityScale; - // mech.transSmoothY = canvas.height2 - mech.pos.y - (game.mouse.y - canvas.height2) * scale + player.velocity.y * velocityScale; - // mech.transX += (mech.transSmoothX - mech.transX) * 1; - // mech.transY += (mech.transSmoothY - mech.transY) * 1; + // Matter.Body.setPosition(player, { + // x: player.position.x, + // y: level.enter.y - 5000 + // }); - Matter.Body.setVelocity(player, { - x: 0, - y: 0 - }); - Matter.Body.setPosition(player, { - x: level.enter.x + 50, - y: level.enter.y - 20 - }); - // move bots - for (let i = 0; i < bullet.length; i++) { - if (bullet[i].botType) { - Matter.Body.setPosition(bullet[i], Vector.add(player.position, { - x: 250 * (Math.random() - 0.5), - y: 250 * (Math.random() - 0.5) - })); - Matter.Body.setVelocity(bullet[i], { - x: 0, - y: 0 - }); - } + // mech.pos.x = player.position.x; + // mech.pos.y = playerBody.position.y - mech.yOff; + // const scale = 0.8; + // const velocityScale = 12 + // mech.transSmoothX = canvas.width2 - mech.pos.x - (game.mouse.x - canvas.width2) * scale + player.velocity.x * velocityScale; + // mech.transSmoothY = canvas.height2 - mech.pos.y - (game.mouse.y - canvas.height2) * scale + player.velocity.y * velocityScale; + // mech.transX += (mech.transSmoothX - mech.transX) * 1; + // mech.transY += (mech.transSmoothY - mech.transY) * 1; + + Matter.Body.setVelocity(player, { + x: 0, + y: 0 + }); + Matter.Body.setPosition(player, { + x: level.enter.x + 50, + y: level.enter.y - 20 + }); + // move bots + for (let i = 0; i < bullet.length; i++) { + if (bullet[i].botType) { + Matter.Body.setPosition(bullet[i], Vector.add(player.position, { + x: 250 * (Math.random() - 0.5), + y: 250 * (Math.random() - 0.5) + })); + Matter.Body.setVelocity(bullet[i], { + x: 0, + y: 0 + }); } - mech.damage(0.1 * game.difficultyMode); - mech.energy = 0.01; } + mech.damage(0.1 * game.difficultyMode); + mech.energy -= 0.1 * game.difficultyMode } // if (mod.isEnergyDamage) { @@ -749,7 +748,7 @@ const game = { let i = who.length; while (i--) { if (who[i].position.y > game.fallHeight) { - if (save && game.difficultyMode < 5) { + if (save) { Matter.Body.setVelocity(who[i], { x: 0, y: 0 diff --git a/js/index.js b/js/index.js index 0c12c16..b7bc7cf 100644 --- a/js/index.js +++ b/js/index.js @@ -105,6 +105,9 @@ window.addEventListener('load', (event) => { if (property === "level") { document.getElementById("starting-level").value = Number(set[property]) } + if (property === "noPower") { + document.getElementById("no-power-ups").checked = Number(set[property]) + } } } }); @@ -314,15 +317,21 @@ const build = { -
+
starting level:
+
- + +
+
+ + +
` for (let i = 0, len = mech.fieldUpgrades.length; i < len; i++) { text += `
  ${mech.fieldUpgrades[i].name}
${mech.fieldUpgrades[i].description}
` @@ -390,6 +399,7 @@ const build = { url += `&field=${encodeURIComponent(mech.fieldUpgrades[mech.fieldMode].name.trim())}` url += `&difficulty=${game.difficultyMode}` url += `&level=${Math.abs(Number(document.getElementById("starting-level").value))}` + url += `&noPower=${Number(document.getElementById("no-power-ups").checked)}` console.log(url) game.copyToClipBoard(url) alert('n-gon build URL copied to clipboard.\nPaste into browser address bar.') @@ -407,6 +417,20 @@ const build = { const levelsCleared = Math.abs(Number(document.getElementById("starting-level").value)) level.difficultyIncrease(Math.min(99, levelsCleared * game.difficultyMode)) //increase difficulty based on modes level.levelsCleared += levelsCleared; + game.isNoPowerUps = document.getElementById("no-power-ups").checked + if (game.isNoPowerUps) { //remove mods, guns, and fields + function removeOne() { //recursive remove one at a time to avoid array problems + for (let i = 0; i < powerUp.length; i++) { + if (powerUp[i].name === "mod" || powerUp[i].name === "gun" || powerUp[i].name === "field") { + Matter.World.remove(engine.world, powerUp[i]); + powerUp.splice(i, 1); + removeOne(); + break + } + } + } + removeOne(); + } game.isCheating = true; document.body.style.cursor = "none"; document.body.style.overflow = "hidden" @@ -795,6 +819,7 @@ window.addEventListener("keydown", function (event) { } break case "u": + level.bossKilled = true; //if there is no boss this needs to be true to increase levels level.nextLevel(); break case "X": //capital X to make it hard to die diff --git a/js/level.js b/js/level.js index d8af4d5..6bb7b35 100644 --- a/js/level.js +++ b/js/level.js @@ -21,7 +21,7 @@ const level = { // for (let i = 0; i < 10; i++) { // mod.giveMod("laser-bot"); // } - // mod.giveMod("vacuum bomb") + // mod.giveMod("cardinality") level.intro(); //starting level @@ -149,11 +149,11 @@ const level = { // spawn.spawner(1600, -500) // spawn.sniper(1700, -120, 50) // spawn.bomberBoss(1400, -500) - // spawn.sniper(1800, -120) + spawn.launcher(1800, -120) // spawn.cellBossCulture(1600, -500) // spawn.powerUpBoss(1600, -500) - spawn.sniper(1200, -500) - spawn.shield(mob[mob.length - 1], 1200, -500, 1); + // spawn.sniper(1200, -500) + // spawn.shield(mob[mob.length - 1], 1200, -500, 1); // spawn.nodeBoss(1200, -500, "launcher") // spawn.snakeBoss(1200, -500) @@ -1817,7 +1817,7 @@ const level = { spawn.mapRect(-4450, -600, 2300, 750); spawn.mapRect(-2225, -500, 175, 550); // spawn.mapRect(-2600, -975, 450, 50); - spawn.boost(-2800, -600, 1150); + spawn.boost(-2800, -600, 1700); spawn.mapRect(-3450, -1325, 550, 50); spawn.mapRect(-3425, -2200, 525, 50); spawn.mapRect(-2600, -1700, 450, 50); @@ -2964,6 +2964,40 @@ const level = { spawn.randomMob(2450, 2030, 0.3) spawn.randomMob(3300, 1980, 0.3) levelCustom2(); + if (game.difficulty > 2) { + if (Math.random() < 0.2) { + // tether ball + spawn.tetherBoss(8000, 630) + let me = mob[mob.length - 1]; + me.onDeath = function () { + this.removeCons(); //remove constraint + spawnCouloirEnHaut() + }; + cons[cons.length] = Constraint.create({ + pointA: { + x: 8550, + y: 680 + }, + bodyB: mob[mob.length - 1], + stiffness: 0.00015 + }); + World.add(engine.world, cons[cons.length - 1]); + if (game.difficulty > 4) spawn.nodeBoss(8000, 630, "spawns", 8, 20, 105); + } else if (game.difficulty > 3) { + spawn.randomLevelBoss(8000, 630, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss", "bomberBoss"]); + let me = mob[mob.length - 1]; + me.onDeath = function () { + this.removeCons(); //remove constraint + spawnCouloirEnHaut() + }; + } + } else { + spawn.randomLevelBoss(8000, 630, ["shooterBoss"]); + let me = mob[mob.length - 1]; + me.onDeath = function () { + spawnCouloirEnHaut() + }; + } } function spawnCouloirEnHaut() { @@ -3227,41 +3261,6 @@ const level = { spawn.randomMob(1250, 55, 0.2); spawn.randomMob(8800, -45, 0.2); spawn.randomBoss(8025, -845, 0.2); - - if (game.difficulty > 2) { - if (Math.random() < 0.2) { - // tether ball - spawn.tetherBoss(8000, 630) - let me = mob[mob.length - 1]; - me.onDeath = function () { - this.removeCons(); //remove constraint - spawnCouloirEnHaut() - }; - cons[cons.length] = Constraint.create({ - pointA: { - x: 8550, - y: 680 - }, - bodyB: mob[mob.length - 1], - stiffness: 0.00015 - }); - World.add(engine.world, cons[cons.length - 1]); - if (game.difficulty > 4) spawn.nodeBoss(8000, 630, "spawns", 8, 20, 105); - } else if (game.difficulty > 3) { - spawn.randomLevelBoss(8000, 630, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss", "bomberBoss"]); - let me = mob[mob.length - 1]; - me.onDeath = function () { - this.removeCons(); //remove constraint - spawnCouloirEnHaut() - }; - } - } else { - spawn.randomLevelBoss(8000, 630, ["shooterBoss"]); - let me = mob[mob.length - 1]; - me.onDeath = function () { - spawnCouloirEnHaut() - }; - } }, house() { const rotor = level.rotor(4315, -315, -0.0002, 120, 20, 200); diff --git a/js/mods.js b/js/mods.js index 96340a9..9252f20 100644 --- a/js/mods.js +++ b/js/mods.js @@ -519,7 +519,7 @@ const mod = { }, { name: "nail-bot upgrade", - description: "125% increased fire rate
applies to all current and future nail-bots", + description: "300% increased fire rate
applies to all current and future nail-bots", maxCount: 1, count: 0, allowed() { @@ -558,7 +558,7 @@ const mod = { }, { name: "foam-bot upgrade", - description: "125% increased foam size
applies to all current and future foam-bots", + description: "200% increased foam size
applies to all current and future foam-bots", maxCount: 1, count: 0, allowed() { @@ -597,7 +597,7 @@ const mod = { }, { name: "boom-bot upgrade", - description: "125% increased explosion damage and size
applies to all current and future boom-bots", + description: "200% increased explosion damage and size
applies to all current and future boom-bots", maxCount: 1, count: 0, allowed() { @@ -636,7 +636,7 @@ const mod = { }, { name: "laser-bot upgrade", - description: "125% increased laser damage
applies to all current and future laser-bots", + description: "200% increased laser damage
applies to all current and future laser-bots", maxCount: 1, count: 0, allowed() { diff --git a/js/player.js b/js/player.js index f295858..82634d3 100644 --- a/js/player.js +++ b/js/player.js @@ -1374,7 +1374,7 @@ const mech = { for (let i = 0; i < mob.length; i++) { const distance = Vector.magnitude(Vector.sub(mech.pos, mob[i].position)) if (distance < range) { - const cap = mob[i].isShielded ? 7 : 3.5 + const cap = mob[i].isShielded ? 8 : 4 if (mob[i].speed > cap && Vector.dot(mob[i].velocity, Vector.sub(mech.pos, mob[i].position)) > 0) { // if velocity is directed towards player Matter.Body.setVelocity(mob[i], Vector.mult(Vector.normalise(mob[i].velocity), cap)); //set velocity to cap, but keep the direction } @@ -1734,7 +1734,7 @@ const mech = { mech.grabPowerUp(); mech.lookForPickUp(180); - const DRAIN = 0.0007 + const DRAIN = 0.0006 if (mech.energy > DRAIN) { mech.energy -= DRAIN; if (mech.energy < DRAIN) { @@ -2425,7 +2425,7 @@ const mech = { ) { const sub = Vector.sub(game.mouseInGame, mech.pos) const mag = Vector.magnitude(sub) - const drain = 0.07 + 0.008 * Math.sqrt(mag) + const drain = 0.04 + 0.007 * Math.sqrt(mag) if (mech.energy > drain && mag > 300) { mech.energy -= drain mech.hole.isReady = false; diff --git a/js/powerup.js b/js/powerup.js index e6e52a4..cd757a3 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -22,8 +22,10 @@ const powerUps = { powerUps.endDraft(); }, showDraft() { + // document.getElementById("choose-grid").style.gridTemplateColumns = "repeat(2, minmax(370px, 1fr))" document.getElementById("choose-grid").style.display = "grid" document.getElementById("choose-background").style.display = "inline" + document.body.style.cursor = "auto"; if (mod.isExtraChoice) { document.body.style.overflowY = "scroll"; @@ -591,8 +593,9 @@ const powerUps = { }, spawn(x, y, target, moving = true, mode = null, size = powerUps[target].size()) { if ( - !(mod.isSuperDeterminism && (target === 'gun' || target === 'field' || target === 'reroll')) && - !(mod.isEnergyNoAmmo && target === 'ammo') + (!mod.isSuperDeterminism || (target === 'mod' || target === 'heal' || target === 'ammo')) && + !(mod.isEnergyNoAmmo && target === 'ammo') && + (!game.isNoPowerUps || (target === 'reroll' || target === 'heal' || target === 'ammo')) ) { powerUps.directSpawn(x, y, target, moving, mode, size) if (mod.duplicateChance && Math.random() < mod.duplicateChance) { diff --git a/js/spawn.js b/js/spawn.js index 6cce754..af12b5f 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -232,8 +232,8 @@ const spawn = { let me = mob[mob.length - 1]; me.isBoss = true; me.frictionAir = 0.01 - me.seeAtDistance2 = 9000000; - me.accelMag = 0.00065 * game.accelScale; + me.seeAtDistance2 = 1000000; + me.accelMag = 0.0005 * game.accelScale; Matter.Body.setDensity(me, 0.0006); //normal is 0.001 me.collisionFilter.mask = cat.bullet | cat.player me.memory = Infinity; @@ -1682,9 +1682,9 @@ const spawn = { let me = mob[mob.length - 1]; me.stroke = "transparent"; me.onHit = function () { - this.explode(this.mass * 10); + this.explode(this.mass * 20); }; - Matter.Body.setDensity(me, 0.0001); //normal is 0.001 + Matter.Body.setDensity(me, 0.00005); //normal is 0.001 me.timeLeft = 200; me.g = 0.001; //required if using 'gravity' me.frictionAir = 0; @@ -1704,7 +1704,7 @@ const spawn = { let me = mob[mob.length - 1]; me.stroke = "transparent"; me.onHit = function () { - this.explode(this.mass * 10); + this.explode(this.mass * 120); }; me.onDeath = function () { if (game.difficulty > 4) { @@ -1736,7 +1736,7 @@ const spawn = { }); } } - Matter.Body.setDensity(me, 0.0001); //normal is 0.001 + Matter.Body.setDensity(me, 0.00005); //normal is 0.001 me.timeLeft = 140 + Math.floor(Math.random() * 30); me.g = 0.001; //required if using 'gravity' me.frictionAir = 0; @@ -1867,9 +1867,9 @@ const spawn = { let me = mob[mob.length - 1]; me.stroke = "transparent"; me.onHit = function () { - this.explode(this.mass * 10); + this.explode(this.mass * 20); }; - Matter.Body.setDensity(me, 0.0001); //normal is 0.001 + Matter.Body.setDensity(me, 0.00005); //normal is 0.001 me.timeLeft = 240; me.g = 0.001; //required if using 'gravity' me.frictionAir = 0; @@ -1956,13 +1956,13 @@ const spawn = { }, seeker(x, y, radius = 5, sides = 0) { //bullets - mobs.spawn(x, y, sides, radius, "rgb(100,100,255)"); + mobs.spawn(x, y, sides, radius, "rgb(150,150,255)"); let me = mob[mob.length - 1]; me.stroke = "transparent"; me.onHit = function () { - this.explode(this.mass * 10); + this.explode(this.mass * 20); }; - Matter.Body.setDensity(me, 0.00005); //normal is 0.001 + Matter.Body.setDensity(me, 0.00002); //normal is 0.001 me.timeLeft = 420 * (0.8 + 0.4 * Math.random()); me.accelMag = 0.00017 * (0.8 + 0.4 * Math.random()) * game.accelScale; me.frictionAir = 0.01 * (0.8 + 0.4 * Math.random()); diff --git a/todo.txt b/todo.txt index d8ef188..940a4b8 100644 --- a/todo.txt +++ b/todo.txt @@ -1,38 +1,31 @@ - -gun: pulse is now a mod for laser - mod: beam splitter applies to pulse - -difficulty balancing - (this needs to be done as more mods are added to the game to prevent power creep) - all modes are a bit harder - if you used to play why, try the new hard - if you used to play hard try the new normal - power ups drop more often from bosses on all modes +neutron bomb does 60% more damage +powerUpBoss has a shorter vision range, and accelerates slower +custom mode has the option to disable mod, guns, and fields ************** TODO - n-gon ************** +add setting to disable power ups spawns for custom mode + mod - explosions apply radiation damage over time - or spawn a neutron bomb with a timer + or spawn a neutron bomb with a short timer mod self destruct - drones explode when they die drones lose extra time on collisions -optional setting for people with desktops that want double mobs - -combine more stuff? - ____ mod for ____ - flak -> missiles - neutron bomb -> mines - iceIX -> foam - flechettes -> nail gun - -mod: stealth field - mark a mob, it you next kill is that mob get a bonus power up - run only at the start of a new level - add an ending to the game - revamp the boss level, or add a new final level - final level requires you to kill something - so skipping content is only smart if you are strong enough to beat the final boss + add a final boss battle level + final boss has elements of other bosses + alternate between black hole aura and laser beams + fire seeker bullets + drop bombs + tail of shielded mobs + shield + mirror ending (if no cheats) + level after final boss battle is the intro level, but flipped left right, with a fake player + damage the fake player to end the game? + no ending (if cheats) + game goes on forever + around level 15 game never ends if you have used cheats