diff --git a/js/bullets.js b/js/bullets.js
index 1530335..8ac9824 100644
--- a/js/bullets.js
+++ b/js/bullets.js
@@ -83,6 +83,8 @@ const b = {
isModRPG: null,
isMod3Missiles: null,
isModDeterminism: null,
+ isModHarmReduce: null,
+ modNailsDeathMob: null,
modOnHealthChange() { //used with acid mod
if (b.isModAcidDmg && mech.health > 0.8) {
b.modAcidDmg = 0.5
@@ -407,6 +409,22 @@ const b = {
b.isModExplodeMob = false;
}
},
+ {
+ name: "impact shear",
+ description: "mobs release +2 nails when they die
nails target nearby mobs",
+ maxCount: 9,
+ count: 0,
+ allowed() {
+ return true
+ },
+ requires: "",
+ effect: () => {
+ b.modNailsDeathMob += 2
+ },
+ remove() {
+ b.modNailsDeathMob = 0;
+ }
+ },
{
name: "reaction inhibitor",
description: "mobs die if their life goes below 12%",
@@ -1405,6 +1423,22 @@ const b = {
b.isModPlasmaRange = 1;
}
},
+ {
+ name: "degenerate matter",
+ description: "2x energy drain for negative mass field
increase harm reduction to 90%",
+ maxCount: 1,
+ count: 0,
+ allowed() {
+ return mech.fieldUpgrades[mech.fieldMode].name === "negative mass field"
+ },
+ requires: "negative mass field",
+ effect() {
+ b.isModHarmReduce = true
+ },
+ remove() {
+ b.isModHarmReduce = false;
+ }
+ },
{
name: "annihilation",
description: "after touching mobs, they are annihilated",
@@ -2081,35 +2115,7 @@ const b = {
},
onEnd() {
if (this.isArmed) {
- const targets = [] //target nearby mobs
- for (let i = 0, len = mob.length; i < len; i++) {
- if (mob[i].dropPowerUp) {
- const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position));
- if (dist < 1440000 && //1200*1200
- Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
- Matter.Query.ray(body, this.position, mob[i].position).length === 0) {
- targets.push(Vector.add(mob[i].position, Vector.mult(mob[i].velocity, Math.sqrt(dist) / 60))) //predict where the mob will be in a few cycles
- }
- }
- }
- for (let i = 0; i < 14; i++) {
- const speed = 53 + 10 * Math.random()
- if (targets.length > 0) { // aim near a random target in array
- const index = Math.floor(Math.random() * targets.length)
- const SPREAD = 150 / targets.length
- const WHERE = {
- x: targets[index].x + SPREAD * (Math.random() - 0.5),
- y: targets[index].y + SPREAD * (Math.random() - 0.5)
- }
- b.nail(this.position, Vector.mult(Vector.normalise(Vector.sub(WHERE, this.position)), speed), 1.1)
- } else { // aim in random direction
- const ANGLE = 2 * Math.PI * Math.random()
- b.nail(this.position, {
- x: speed * Math.cos(ANGLE),
- y: speed * Math.sin(ANGLE)
- })
- }
- }
+ b.targetedNail(this.position, 14)
}
if (isAmmoBack) { //get ammo back from b.isModMineAmmoBack
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
@@ -2371,6 +2377,36 @@ const b = {
y: speed * Math.sin(dir)
});
},
+ targetedNail(position, num = 1, speed = 50 + 10 * Math.random(), range = 1200) {
+ const targets = [] //target nearby mobs
+ for (let i = 0, len = mob.length; i < len; i++) {
+ if (mob[i].dropPowerUp) {
+ const dist = Vector.magnitude(Vector.sub(position, mob[i].position));
+ if (dist < range &&
+ Matter.Query.ray(map, position, mob[i].position).length === 0 &&
+ Matter.Query.ray(body, position, mob[i].position).length === 0) {
+ targets.push(Vector.add(mob[i].position, Vector.mult(mob[i].velocity, dist / 60))) //predict where the mob will be in a few cycles
+ }
+ }
+ }
+ for (let i = 0; i < num; i++) {
+ if (targets.length > 0) { // aim near a random target in array
+ const index = Math.floor(Math.random() * targets.length)
+ const SPREAD = 150 / targets.length
+ const WHERE = {
+ x: targets[index].x + SPREAD * (Math.random() - 0.5),
+ y: targets[index].y + SPREAD * (Math.random() - 0.5)
+ }
+ b.nail(position, Vector.mult(Vector.normalise(Vector.sub(WHERE, position)), speed), 1.1)
+ } else { // aim in random direction
+ const ANGLE = 2 * Math.PI * Math.random()
+ b.nail(position, {
+ x: speed * Math.cos(ANGLE),
+ y: speed * Math.sin(ANGLE)
+ })
+ }
+ }
+ },
nail(pos, velocity, dmg = 0) {
const me = bullet.length;
bullet[me] = Bodies.rectangle(pos.x, pos.y, 25, 2, b.fireAttributes(Math.atan2(velocity.y, velocity.x)));
@@ -2939,7 +2975,7 @@ const b = {
fire() {
if (b.isMod3Missiles) {
if (mech.crouch) {
- mech.fireCDcycle = mech.cycle + 80; // cool down
+ mech.fireCDcycle = mech.cycle + 80 * b.modFireRate; // cool down
const direction = {
x: Math.cos(mech.angle),
y: Math.sin(mech.angle)
@@ -2955,7 +2991,7 @@ const b = {
bullet[bullet.length - 1].force.y += push.y * (i - 1);
}
} else {
- mech.fireCDcycle = mech.cycle + 60; // cool down
+ mech.fireCDcycle = mech.cycle + 60 * b.modFireRate; // cool down
const direction = {
x: Math.cos(mech.angle),
y: Math.sin(mech.angle)
@@ -2972,7 +3008,7 @@ const b = {
}
}
} else {
- mech.fireCDcycle = mech.cycle + Math.floor(mech.crouch ? 50 : 30); // cool down
+ mech.fireCDcycle = mech.cycle + Math.floor(mech.crouch ? 50 : 30) * b.modFireRate; // cool down
b.missile({
x: mech.pos.x + 40 * Math.cos(mech.angle),
y: mech.pos.y + 40 * Math.sin(mech.angle) - 3
@@ -3046,37 +3082,7 @@ const b = {
bullet[me].explodeRad = 275;
bullet[me].onEnd = function () {
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
- if (b.modGrenadeFragments) {
- const targets = [] //target nearby mobs
- for (let i = 0, len = mob.length; i < len; i++) {
- if (mob[i].dropPowerUp) {
- const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position));
- if (dist < 1440000 && //1200*1200
- Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
- Matter.Query.ray(body, this.position, mob[i].position).length === 0) {
- targets.push(Vector.add(mob[i].position, Vector.mult(mob[i].velocity, Math.sqrt(dist) / 60))) //predict where the mob will be in a few cycles
- }
- }
- }
- for (let i = 0; i < b.modGrenadeFragments; i++) {
- const speed = 53 + 10 * Math.random()
- if (targets.length > 0) { // aim near a random target in array
- const index = Math.floor(Math.random() * targets.length)
- const SPREAD = 150 / targets.length
- const WHERE = {
- x: targets[index].x + SPREAD * (Math.random() - 0.5),
- y: targets[index].y + SPREAD * (Math.random() - 0.5)
- }
- b.nail(this.position, Vector.mult(Vector.normalise(Vector.sub(WHERE, this.position)), speed), 1.1)
- } else { // aim in random direction
- const ANGLE = 2 * Math.PI * Math.random()
- b.nail(this.position, {
- x: speed * Math.cos(ANGLE),
- y: speed * Math.sin(ANGLE)
- })
- }
- }
- }
+ if (b.modGrenadeFragments) b.targetedNail(this.position, b.modGrenadeFragments)
}
bullet[me].minDmgSpeed = 1;
bullet[me].onDmg = function () {
@@ -3305,7 +3311,7 @@ const b = {
name: "drones",
description: "deploy drones that crash into mobs
collisions reduce their lifespan by 1 second",
ammo: 0,
- ammoPack: 13,
+ ammoPack: 14,
have: false,
isStarterGun: true,
isEasyToAim: true,
@@ -3476,13 +3482,7 @@ const b = {
if (who.shield) {
for (let i = 0, len = mob.length; i < len; i++) {
if (mob[i].id === who.shieldTargetID) { //apply some knock back to shield mob before shield breaks
-
Matter.Body.setVelocity(mob[i], Matter.Vector.mult(Matter.Vector.normalise(this.velocity), 10));
-
- // const force = Matter.Vector.mult(this.velocity, 4 / mob[i].mass)
- // const velocity = Matter.Vector.add(force, mob[i].velocity)
- // Matter.Body.setVelocity(mob[i], velocity);
-
break
}
}
@@ -3493,35 +3493,7 @@ const b = {
Matter.Body.setDensity(this, 0.001);
}
if (b.isModRailNails && this.speed > 10) {
- const targets = [] //target nearby mobs
- for (let i = 0, len = mob.length; i < len; i++) {
- if (mob[i].dropPowerUp) {
- const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position));
- if (dist < 1000000 && //1000*1000
- Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
- Matter.Query.ray(body, this.position, mob[i].position).length === 0) {
- targets.push(Vector.add(mob[i].position, Vector.mult(mob[i].velocity, Math.sqrt(dist) / 60))) //predict where the mob will be in a few cycles
- }
- }
- }
- for (let i = 0; i < this.speed - 10; i++) {
- const speed = 50 + 10 * Math.random()
- if (targets.length > 0) { // aim near a random target in array
- const index = Math.floor(Math.random() * targets.length)
- const SPREAD = 150 / targets.length
- const WHERE = {
- x: targets[index].x + SPREAD * (Math.random() - 0.5),
- y: targets[index].y + SPREAD * (Math.random() - 0.5)
- }
- b.nail(this.position, Vector.mult(Vector.normalise(Vector.sub(WHERE, this.position)), speed), 1.1)
- } else { // aim in random direction
- const ANGLE = 2 * Math.PI * Math.random()
- b.nail(this.position, {
- x: speed * Math.cos(ANGLE),
- y: speed * Math.sin(ANGLE)
- })
- }
- }
+ b.targetedNail(this.position, Math.min(40, this.speed) - 10)
this.endCycle = 0 //triggers despawn
}
},
diff --git a/js/game.js b/js/game.js
index 0b0a515..814a995 100644
--- a/js/game.js
+++ b/js/game.js
@@ -67,6 +67,8 @@ const game = {
mech.cycle++;
game.gravity();
Engine.update(engine, game.delta);
+ mech.keyMove();
+
level.checkZones();
level.checkQuery();
mech.move();
diff --git a/js/level.js b/js/level.js
index 1ff5b3d..0d88890 100644
--- a/js/level.js
+++ b/js/level.js
@@ -19,13 +19,14 @@ const level = {
// b.giveGuns("foam")
// mech.setField("time dilation field")
// b.giveMod("renormalization");
- // b.giveMod("quantum tunneling");
- // b.giveGuns("rail gun")
+ // b.giveMod("impact shear");
+ // b.giveMod("nail bot");
+ // b.giveGuns("mine")
// mech.setField("pilot wave")
// mech.setField("perfect diamagnetism")
- // level.intro(); //starting level
- level.testing();
+ level.intro(); //starting level
+ // level.testing();
// level.stronghold()
// level.bosses();
// level.satellite();
@@ -157,11 +158,11 @@ const level = {
// spawn.bomberBoss(2900, -500)
// spawn.suckerBoss(1200, -500)
// spawn.hopper(1200, -500, 70)
- // spawn.hopper(1200, -500, 100)
+ spawn.spinner(1200, -500)
// spawn.shield(mob[mob.length - 1], 1200, -500, 1);
// spawn.nodeBoss(1200, -500, "spiker")
- spawn.spiderBoss(1200, -500)
+ // spawn.spiderBoss(1200, -500)
// spawn.timeSkipBoss(2900, -500)
// spawn.randomMob(1600, -500)
},
@@ -987,8 +988,7 @@ const level = {
stiffness: 0.00007
});
if (game.difficulty > 4) spawn.nodeBoss(4250, 0, "spawns", 8, 20, 105); //chance to spawn a ring of exploding mobs around this boss
- }
- if (Math.random() < 0.08) {
+ } else if (Math.random() < 0.08) {
spawn.randomLevelBoss(4250, -250);
} else {
//floor below right tall tower
@@ -1721,7 +1721,7 @@ const level = {
}
}
},
- stronghold() { // player made level by Francois 👑 from discord
+ stronghold() { // player made level by Francois 👑 from discord
level.defaultZoom = 1400
game.zoomTransition(level.defaultZoom)
@@ -1768,6 +1768,13 @@ const level = {
height: 1700,
color: "rgba(0,0,0,0.1)"
});
+ level.fillBG.push({
+ x: 1100,
+ y: -1700,
+ width: 50,
+ height: 450,
+ color: "rgba(0,0,0,0.1)"
+ });
level.fillBG.push({
x: 1050,
y: -1200,
@@ -1792,7 +1799,7 @@ const level = {
level.fillBG.push({
x: 2530,
y: -550,
- width: 400,
+ width: 430,
height: -1450,
color: "rgba(0,0,0,0.1)"
});
@@ -1873,15 +1880,15 @@ const level = {
spawn.bodyRect(3400, -1470, 110, 70); //Moyen bloc dans la cuve
spawn.mapRect(3270, -1750, 80, 50); // Rebord gauche cuve
- spawn.mapRect(2530, -2000, 400, 50); //First Plateforme
+ spawn.mapRect(2530, -2000, 430, 50); //First Plateforme
spawn.mapRect(1600, -1750, 600, 50); // Middle plateforme
- spawn.mapRect(1150, -1750, 250, 50); //Derniere plateforme // Toit petite boite en [
+ spawn.mapRect(1100, -1750, 300, 50); //Derniere plateforme // Toit petite boite en [
spawn.bodyRect(1830, -1980, 190, 230); // Fat bloc plateforme middle
spawn.bodyRect(1380, -1770, 250, 20) // Pont last plateforme
spawn.mapRect(1000, -1250, 400, 50); //Sol de la petite boite en [
- spawn.mapRect(1100, -1750, 50, 380); //Mur gauche petite boite en [
- spawn.bodyRect(1100, -1380, 48, 119); //Bloc-porte petite boite en [
+ spawn.mapRect(1100, -1550, 50, 190); //Mur gauche petite boite en [
+ spawn.bodyRect(1100, -1380, 48, 109); //Bloc-porte petite boite en [
spawn.mapRect(-100, -750, 1100, 50); //Sol last salle
spawn.mapRect(1000, -1200, 50, 500) // Mur droit last salle
@@ -1897,7 +1904,9 @@ const level = {
spawn.bodyRect(-503, -1250, 30, 30); // Petit bloc exit room
spawn.mapRect(500, -700, 100, 590); //Bloc noir un dessous last salle
- spawn.mapRect(1400, -250, 200, 250); //Black Block left from the spawn
+ spawn.mapRect(1350, -250, 250, 250); //Black Block left from the spawn
+ spawn.boost(1470, -250, 1080);
+
spawn.boost(-370, 0, 800);
map[map.length] = Bodies.polygon(2325, -205, 0, 15); //circle above door
@@ -1920,12 +1929,19 @@ const level = {
spawn.bodyRect(2545, -50, 70, 50);
spawn.bodyRect(2550, 0, 100, 30);
+ spawn.randomSmallMob(200, -1300, 0.5);
+ spawn.randomSmallMob(300, -1300, 0.9);
+ spawn.randomSmallMob(470, -650, 1);
spawn.randomSmallMob(1000, -400, 1);
spawn.randomSmallMob(2550, -560, 1);
spawn.randomSmallMob(3350, -900, 1);
spawn.randomSmallMob(3600, -1210, 1);
spawn.randomSmallMob(700, -1950, 0.2);
spawn.randomSmallMob(5050, -550);
+ spawn.randomMob(-250, -250, 0.8);
+ spawn.randomMob(-300, -600, 0.6);
+ spawn.randomMob(350, -900, 0.5);
+ spawn.randomMob(770, -950, 0.8)
spawn.randomMob(900, -160, 1);
spawn.randomMob(2360, -820, 0.8);
spawn.randomMob(2700, -2020, 0.8);
@@ -1935,6 +1951,7 @@ const level = {
spawn.randomBoss(1500, -1900, 0.5);
spawn.randomBoss(2350, -850, 1);
spawn.randomBoss(100, -450, 0.9);
+
if (game.difficulty > 3) spawn.randomLevelBoss(1850, -1400, 1);
},
//*****************************************************************************************************************
diff --git a/js/mobs.js b/js/mobs.js
index 6c2a3f4..4054ff3 100644
--- a/js/mobs.js
+++ b/js/mobs.js
@@ -996,6 +996,7 @@ const mobs = {
if (mech.energy > 0.33) mech.energy -= 0.33
}
if (b.isModExplodeMob) b.explosion(this.position, Math.min(450, Math.sqrt(this.mass + 3) * 80))
+ if (b.modNailsDeathMob) b.targetedNail(this.position, b.modNailsDeathMob)
}
},
removeConsBB() {
diff --git a/js/player.js b/js/player.js
index 2ea2776..f885eb5 100644
--- a/js/player.js
+++ b/js/player.js
@@ -1461,9 +1461,16 @@ const mech = {
} else if ((keys[32] || game.mouseDownRight) && mech.fieldCDcycle < mech.cycle) { //push away
mech.grabPowerUp();
mech.lookForPickUp();
- const DRAIN = 0.00035
+ let DRAIN = 0.00105;
if (mech.energy > DRAIN) {
- mech.fieldDamageResistance = 0.2; // 1 - 0.8
+ if (b.isModHarmReduce) {
+ mech.fieldDamageResistance = 0.1; // 1 - 0.9
+ DRAIN = 0.0007 //2x energy drain
+ } else {
+ mech.fieldDamageResistance = 0.2; // 1 - 0.8
+ DRAIN = 0.00035
+ }
+
// mech.pushMobs360();
//repulse mobs
diff --git a/js/spawn.js b/js/spawn.js
index eb6aad6..76c0e39 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -81,8 +81,7 @@ const spawn = {
},
randomLevelBoss(x, y) {
// suckerBoss, laserBoss, tetherBoss, snakeBoss all need a particular level to work so they are not included
- const options = ["spiderBoss"] //, "timeSkipBoss" //"shooterBoss", "cellBossCulture", "bomberBoss",
- // const options = ["timeSkipBoss"]
+ const options = ["shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss"] // , "timeSkipBoss"
spawn[options[Math.floor(Math.random() * options.length)]](x, y)
},
//mob templates *********************************************************************************************
@@ -420,55 +419,49 @@ const spawn = {
let me = mob[mob.length - 1];
me.fill = "#28b";
me.rememberFill = me.fill;
- me.cdBurst1 = 0; //must add for burstAttraction
- me.cdBurst2 = 0; //must add for burstAttraction
- me.delay = 0;
+ me.cd = 0;
me.burstDir = {
x: 0,
y: 0
};
- me.accelMag = 0.16 * game.accelScale;
me.frictionAir = 0.022;
me.lookTorque = 0.0000014;
me.restitution = 0;
spawn.shield(me, x, y);
- me.do = function () {
+ me.look = function () {
this.seePlayerByLookingAt();
this.checkStatus();
- //accelerate towards the player after a delay
- if (this.seePlayer.recall) {
- if (this.cdBurst2 < game.cycle && this.angularSpeed < 0.01) {
- this.cdBurst2 = Infinity;
- this.cdBurst1 = game.cycle + 40;
- this.burstDir = Vector.normalise(Vector.sub(this.seePlayer.position, this.position));
- } else if (this.cdBurst1 < game.cycle) {
- this.cdBurst2 = game.cycle + this.delay;
- this.cdBurst1 = Infinity;
- this.force = Vector.mult(this.burstDir, this.mass * 0.25);
- this.fill = this.rememberFill;
- } else if (this.cdBurst1 != Infinity) {
- this.torque += 0.000035 * this.inertia;
- this.fill = randomColor({
- hue: "blue"
- });
- //draw attack vector
- const mag = this.radius * 2.5 + 50;
- ctx.strokeStyle = "rgba(0,0,0,0.2)";
- ctx.lineWidth = 3;
- ctx.setLineDash([10, 20]); //30
- const dir = Vector.add(this.position, Vector.mult(this.burstDir, mag));
- ctx.beginPath();
- ctx.moveTo(this.position.x, this.position.y);
- ctx.lineTo(dir.x, dir.y);
- ctx.stroke();
- ctx.setLineDash([]);
- } else {
- this.fill = this.rememberFill;
- }
- } else {
- this.cdBurst2 = 0;
+ if (this.seePlayer.recall && this.cd < game.cycle) {
+ this.burstDir = Vector.normalise(Vector.sub(this.seePlayer.position, this.position));
+ this.cd = game.cycle + 40;
+ this.do = this.spin
}
- };
+ }
+ me.do = me.look
+ me.spin = function () {
+ this.checkStatus();
+ this.torque += 0.000035 * this.inertia;
+ this.fill = randomColor({
+ hue: "blue"
+ });
+ //draw attack vector
+ const mag = this.radius * 2.5 + 50;
+ ctx.strokeStyle = "rgba(0,0,0,0.2)";
+ ctx.lineWidth = 3;
+ ctx.setLineDash([10, 20]); //30
+ const dir = Vector.add(this.position, Vector.mult(this.burstDir, mag));
+ ctx.beginPath();
+ ctx.moveTo(this.position.x, this.position.y);
+ ctx.lineTo(dir.x, dir.y);
+ ctx.stroke();
+ ctx.setLineDash([]);
+ if (this.cd < game.cycle) {
+ this.fill = this.rememberFill;
+ this.cd = game.cycle + 180 * game.CDScale
+ this.do = this.look
+ this.force = Vector.mult(this.burstDir, this.mass * 0.25);
+ }
+ }
},
sucker(x, y, radius = 30 + Math.ceil(Math.random() * 70)) {
radius = 9 + radius / 8; //extra small
@@ -714,18 +707,18 @@ const spawn = {
});
}
},
- timeSkipBoss(x, y, radius = 70) {
+ timeSkipBoss(x, y, radius = 55) {
mobs.spawn(x, y, 6, radius, '#000');
let me = mob[mob.length - 1];
// me.stroke = "transparent"; //used for drawSneaker
me.timeSkipLastCycle = 0
- me.eventHorizon = 1600; //required for black hole
+ me.eventHorizon = 1800; //required for black hole
me.seeAtDistance2 = (me.eventHorizon + 2000) * (me.eventHorizon + 2000); //vision limit is event horizon + 2000
me.accelMag = 0.0004 * game.accelScale;
// me.frictionAir = 0.005;
// me.memory = 1600;
// Matter.Body.setDensity(me, 0.02); //extra dense //normal is 0.001 //makes effective life much larger
- Matter.Body.setDensity(me, 0.0025 + 0.0007 * Math.sqrt(game.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
+ Matter.Body.setDensity(me, 0.0015 + 0.0005 * Math.sqrt(game.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
spawn.shield(me, x, y, 1);
diff --git a/todo.txt b/todo.txt
index be95822..9eeb0d2 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,16 +1,24 @@
-
-large mods shrink on death instead of disappearing
-new boss mob: spiderBoss
-mod - Bayesian interference -> determinism
- spawn 4 mods and 2 heals, future power ups are limited to one choice
-mod - Leveraged investments -> Bayesian interference
- 33% chance for double power ups to drop, remove all future ammo power ups
-
-(serious progress on my level construction tools, but it's not ready yet)
+mod - negative mass field: 80%->90% harm reduction while active, but 2x energy drain
+mod - mobs fire nails when they die (by Francois 👑 from discord)
************** TODO - n-gon **************
+possible names for mods
+ Hypergolic - A hypergolic propellant combination used in a rocket engine is one whose components spontaneously ignite when they come into contact with each other.
+
+have a mob apply a positive status effect on other mobs,
+ heal?
+ make it yellow
+ damage bonus, but how?
+ possible balance issues
+
+mobs that fire grenades
+mobs that fire bullets
+ bullets that chase the player a bit (blue color)
+ short lived bullets that fire in every direction
+ or fire in a spiral over time
+
construct
display outline of map to be draw while mouse is down
toggle between maps and bodies
@@ -18,25 +26,6 @@ construct
display current output text in a box
live update it
-
-mod - blocking with perfect diamagnetism fires your gun
- maybe doesn't trigger cooldown?
- does use ammo
-
-mod - annihilation might be unbalanced?
-
-boss mob - let it die multiple times and come back to life
- on death event spawns a new version of self, but with a decrementing counter
-
-foam - check for touching map / blocks and slow foam down rather then bounce off walls
-quantum foam should just skip the shield
-
-red flashes when you take damage were replaced with the color of your energy bar
- When you have mass energy equivalence
-
-mod - missiles: fire 3 small missiles
- disables missile replication mod
-
lore - a robot (the player) gains self awareness
each mod/gun/field is a new tech
all the technology leads to the singularity
@@ -57,9 +46,12 @@ atmosphere levels: change the pace, give the user a rest between combat
simple puzzles
cool looking stuff
large rotating fan that the player has to move through
- nonaggressive mobs
in the final level you see your self at the starting level, with the wires
you shoot your self to wake up?
+ nonaggressive mobs
+
+boss mob - let it die multiple times and come back to life
+ on death event spawns a new version of self, but with a decrementing counter
bullets cost 5 life instead of ammo, but return 5 life when they hit a mob
replace life with energy or ammo?