diff --git a/js/bullets.js b/js/bullets.js
index 972cc66..3efddfd 100644
--- a/js/bullets.js
+++ b/js/bullets.js
@@ -296,7 +296,7 @@ const b = {
},
{
name: "scrap bots",
- description: "+16% chance to build a bot after killing a mob
the bot will follow you until you exit the map",
+ description: "+15% chance to build a bot after killing a mob
the bot will follow you until you exit the map",
maxCount: 6,
count: 0,
allowed() {
@@ -304,7 +304,7 @@ const b = {
},
requires: "",
effect() {
- b.isModBotSpawner += 0.16;
+ b.isModBotSpawner += 0.15;
},
remove() {
b.isModBotSpawner = 0;
@@ -441,9 +441,9 @@ const b = {
maxCount: 1,
count: 0,
allowed() {
- return true
+ return !b.isModEnergyHealth
},
- requires: "",
+ requires: "mass-energy equivalence",
effect() {
b.isModEnergyLoss = true;
},
@@ -549,9 +549,9 @@ const b = {
maxCount: 1,
count: 0,
allowed() {
- return !b.isModPiezo
+ return !b.isModPiezo && !b.isModEnergyLoss
},
- requires: "not piezoelectricity",
+ requires: "not piezoelectricity
or acute stress response",
effect: () => {
mech.health = 0
b.modOnHealthChange();
@@ -2148,7 +2148,7 @@ const b = {
friction: 0,
frictionAir: 0.10,
restitution: 0.3,
- dmg: 0.16, //damage done in addition to the damage from momentum
+ dmg: 0.15, //damage done in addition to the damage from momentum
lookFrequency: 10 + Math.floor(7 * Math.random()),
endCycle: game.cycle + 120 * b.isModBulletsLastLonger, //Math.floor((1200 + 420 * Math.random()) * b.isModBulletsLastLonger),
classType: "bullet",
@@ -2797,7 +2797,7 @@ const b = {
if (Vector.magnitude(sub) > range) {
// Matter.Body.setPosition(this, Vector.sub(this.position, Vector.mult(Vector.normalise(sub), 2 * range))) //teleport to opposite side
Matter.Body.setVelocity(this, Vector.mult(this.velocity, -1));
- // Matter.Body.setPosition(this, Vector.add(mech.pos, Vector.mult(Vector.normalise(sub), range)))
+ Matter.Body.setPosition(this, Vector.add(mech.pos, Vector.mult(Vector.normalise(sub), range))) //reflect
}
} else {
let slowCheck = 1
diff --git a/js/level.js b/js/level.js
index 1087efa..5f0c74e 100644
--- a/js/level.js
+++ b/js/level.js
@@ -151,8 +151,10 @@ const level = {
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump
// spawn.bomberBoss(2900, -500)
- spawn.hopper(1200, -500)
- spawn.hopper(1200, -500)
+ spawn.stabber(1200, -500)
+ spawn.chaser(1200, -500)
+ // spawn.nodeBoss(1200, -500, "spiker")
+ // spawn.hopper(1200, -500)
// spawn.timeSkipBoss(2900, -500)
// spawn.randomMob(1600, -500)
diff --git a/js/mobs.js b/js/mobs.js
index dc48002..bae4987 100644
--- a/js/mobs.js
+++ b/js/mobs.js
@@ -782,23 +782,6 @@ const mobs = {
}
}
},
- strike() {
- //teleport to player when close enough on CD
- if (this.seePlayer.recall && this.cd < game.cycle) {
- const dist = Vector.sub(this.seePlayer.position, this.position);
- const distMag = Vector.magnitude(dist);
- if (distMag < 400) {
- this.cd = game.cycle + this.delay;
- ctx.beginPath();
- ctx.moveTo(this.position.x, this.position.y);
- Matter.Body.translate(this, Vector.mult(Vector.normalise(dist), distMag - 20 - radius));
- ctx.lineTo(this.position.x, this.position.y);
- ctx.lineWidth = radius * 2;
- ctx.strokeStyle = this.fill; //"rgba(0,0,0,0.5)"; //'#000'
- ctx.stroke();
- }
- }
- },
blink() {
//teleport towards player as a way to move
if (this.seePlayer.recall && !(game.cycle % this.blinkRate)) {
diff --git a/js/spawn.js b/js/spawn.js
index f002e14..ae92a8c 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -2,23 +2,24 @@
const spawn = {
pickList: ["starter", "starter"],
fullPickList: [
+ "shooter", "shooter", "shooter", "shooter", "shooter",
+ "hopper", "hopper", "hopper", "hopper",
"chaser", "chaser", "chaser",
"striker", "striker",
+ "laser", "laser",
+ "exploder", "exploder",
+ "spiker", "spiker",
"spinner",
- "hopper", "hopper", "hopper", "hopper",
"grower",
"springer",
- "shooter", "shooter", "shooter", "shooter", "shooter",
"beamer",
"focuser",
- "laser", "laser",
"sucker",
- "exploder", "exploder", "exploder",
"spawner",
"ghoster",
"sneaker",
],
- allowedBossList: ["chaser", "spinner", "striker", "springer", "laser", "focuser", "beamer", "exploder", "spawner", "shooter"],
+ allowedBossList: ["chaser", "spinner", "striker", "springer", "laser", "focuser", "beamer", "exploder", "spawner", "shooter", "spiker"],
setSpawnList() { //this is run at the start of each new level to determine the possible mobs for the level
//each level has 2 mobs: one new mob and one from the last level
spawn.pickList.splice(0, 1);
@@ -935,6 +936,76 @@ const spawn = {
ctx.lineTo(best.x, best.y);
}
},
+ spiker(x, y, radius = 25 + Math.ceil(Math.random() * 15)) {
+ mobs.spawn(x, y, 10, radius, "rgb(220,50,205)");
+ let me = mob[mob.length - 1];
+ me.accelMag = 0.0005 * game.accelScale;
+ // me.g = 0.0002; //required if using 'gravity'
+ me.frictionStatic = 0;
+ me.friction = 0;
+ me.delay = 360 * game.CDScale;
+ me.cd = Infinity;
+ me.spikeVertex = 0;
+ me.spikeLength = 0;
+ me.isSpikeGrowing = false;
+ me.isSpikeReset = true;
+ Matter.Body.rotate(me, Math.PI * 0.1);
+ spawn.shield(me, x, y);
+ me.onDamage = function () {};
+ me.do = function () {
+ // this.gravity();
+ this.seePlayerByLookingAt();
+ this.checkStatus();
+ this.attraction();
+
+ const setNoseShape = () => {
+ const sub = Vector.sub(this.vertices[this.spikeVertex], this.position)
+ const spike = Vector.mult(Vector.normalise(sub), this.radius * this.spikeLength)
+ this.vertices[this.spikeVertex].x = this.position.x + spike.x
+ this.vertices[this.spikeVertex].y = this.position.y + spike.y
+ };
+
+
+ if (this.isSpikeReset) {
+ if (this.seePlayer.recall) {
+ const dist = Vector.sub(this.seePlayer.position, this.position);
+ const distMag = Vector.magnitude(dist);
+ if (distMag < this.radius * 7) {
+ //find nearest vertex
+ let nearestDistance = Infinity
+ for (let i = 0, len = this.vertices.length; i < len; i++) {
+ //find distance to player for each vertex
+ const dist = Vector.sub(this.seePlayer.position, this.vertices[i]);
+ const distMag = Vector.magnitude(dist);
+ //save the closest distance
+ if (distMag < nearestDistance) {
+ this.spikeVertex = i
+ nearestDistance = distMag
+ }
+ }
+ this.spikeLength = 1
+ this.isSpikeGrowing = true;
+ this.isSpikeReset = false;
+ Matter.Body.setAngularVelocity(this, 0)
+ }
+ }
+ } else {
+ if (this.isSpikeGrowing) {
+ this.spikeLength += 1
+ if (this.spikeLength > 9) {
+ this.isSpikeGrowing = false;
+ }
+ } else {
+ this.spikeLength -= 0.1
+ if (this.spikeLength < 1) {
+ this.spikeLength = 1
+ this.isSpikeReset = true
+ }
+ }
+ setNoseShape();
+ }
+ };
+ },
striker(x, y, radius = 14 + Math.ceil(Math.random() * 25)) {
mobs.spawn(x, y, 5, radius, "rgb(221,102,119)");
let me = mob[mob.length - 1];
@@ -967,7 +1038,20 @@ const spawn = {
}
this.checkStatus();
this.attraction();
- this.strike();
+ if (this.seePlayer.recall && this.cd < game.cycle) {
+ const dist = Vector.sub(this.seePlayer.position, this.position);
+ const distMag = Vector.magnitude(dist);
+ if (distMag < 400) {
+ this.cd = game.cycle + this.delay;
+ ctx.beginPath();
+ ctx.moveTo(this.position.x, this.position.y);
+ Matter.Body.translate(this, Vector.mult(Vector.normalise(dist), distMag - 20 - radius));
+ ctx.lineTo(this.position.x, this.position.y);
+ ctx.lineWidth = radius * 2;
+ ctx.strokeStyle = this.fill; //"rgba(0,0,0,0.5)"; //'#000'
+ ctx.stroke();
+ }
+ }
};
},
sneaker(x, y, radius = 15 + Math.ceil(Math.random() * 25)) {
diff --git a/todo.txt b/todo.txt
index b964be3..7f3bf37 100644
--- a/todo.txt
+++ b/todo.txt
@@ -3,6 +3,9 @@
************** TODO - n-gon **************
+bullets cost 5 life instead of ammo, but return 5 life when they hit a mob
+ replace life with energy or ammo?
+
an effect when canceling a power up
ammo? heals?
50% chance for a mod, 25% heal, 25% ammo