diff --git a/js/bullets.js b/js/bullets.js
index 0b1bfc1..1928669 100644
--- a/js/bullets.js
+++ b/js/bullets.js
@@ -926,7 +926,7 @@ const b = {
},
{
name: "super ball",
- description: "fire one large super ball
that stuns mobs for 2 second",
+ description: "fire one large super ball
that stuns mobs for 3 second",
maxCount: 1,
count: 0,
allowed() {
@@ -1338,7 +1338,7 @@ const b = {
},
{
name: "renormalization",
- description: "phase decoherence field has 3x visibility
and 1/3 energy drain when firing",
+ description: "phase decoherence field has 3x visibility
and 3x less energy drain when firing",
maxCount: 1,
count: 0,
allowed() {
@@ -1353,8 +1353,9 @@ const b = {
}
},
{
- name: "quantum dissipation",
- description: "phase decoherence field uses energy to
damage unshielded mobs that you overlap",
+ name: "superposition",
+ // description: "phase decoherence field applies a stun
to unshielded mobs for 2 seconds",
+ description: "apply a 4 second stun to unshielded mobs
that overlap with phase decoherence field",
maxCount: 1,
count: 0,
allowed() {
@@ -1362,10 +1363,10 @@ const b = {
},
requires: "phase decoherence field",
effect() {
- b.isModPhaseFieldDamage = true;
+ b.superposition = true;
},
remove() {
- b.isModPhaseFieldDamage = false;
+ b.superposition = false;
}
},
],
@@ -2478,7 +2479,7 @@ const b = {
this.force.y += this.mass * 0.001;
};
bullet[me].onDmg = function (who) {
- mobs.statusStun(who, 120) // (2.3) * 2 / 14 ticks (2x damage over 7 seconds)
+ mobs.statusStun(who, 180) // (2.3) * 2 / 14 ticks (2x damage over 7 seconds)
};
} else {
b.muzzleFlash(20);
diff --git a/js/game.js b/js/game.js
index b773138..f14563d 100644
--- a/js/game.js
+++ b/js/game.js
@@ -601,7 +601,7 @@ const game = {
if (game.isCommunityMaps) level.levels.push("stronghold");
level.levels = shuffle(level.levels); //shuffles order of maps
level.levels.unshift("bosses"); //add bosses level to the end of the randomized levels list
- console.log(level.levels)
+ // console.log(level.levels)
}
game.reset();
game.firstRun = false;
diff --git a/js/index.js b/js/index.js
index a40ab83..2ae60fa 100644
--- a/js/index.js
+++ b/js/index.js
@@ -1,6 +1,6 @@
"use strict";
//collision groups
-// cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet | cat.mobShield
+// cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet | cat.mobShield | cat.phased
const cat = {
player: 0x1,
map: 0x10,
@@ -10,6 +10,7 @@ const cat = {
mob: 0x100000,
mobBullet: 0x1000000,
mobShield: 0x10000000,
+ phased: 0x100000000,
}
//example https://landgreen.github.io/sidescroller/index.html?
diff --git a/js/level.js b/js/level.js
index 85083a1..7c2f692 100644
--- a/js/level.js
+++ b/js/level.js
@@ -147,8 +147,8 @@ const level = {
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump
// spawn.laserBoss(2900, -500)
- // spawn.exploder(3200, -500)
- spawn.timeSkipBoss(2900, -500)
+ spawn.springer(3200, -500)
+ // spawn.timeSkipBoss(2900, -500)
// spawn.randomMob(3200, -500)
},
diff --git a/js/mobs.js b/js/mobs.js
index a73e967..ee16ba8 100644
--- a/js/mobs.js
+++ b/js/mobs.js
@@ -485,10 +485,10 @@ const mobs = {
}
},
searchSpring() {
+ //draw the two dots on the end of the springs
ctx.beginPath();
ctx.arc(this.cons.pointA.x, this.cons.pointA.y, 6, 0, 2 * Math.PI);
ctx.arc(this.cons2.pointA.x, this.cons2.pointA.y, 6, 0, 2 * Math.PI);
- // ctx.arc(this.cons.bodyB.position.x, this.cons.bodyB.position.y,6,0,2*Math.PI);
ctx.fillStyle = "#222";
ctx.fill();
@@ -501,25 +501,28 @@ const mobs = {
!mech.isStealth
) {
this.foundPlayer();
- if (!(game.cycle % (this.seePlayerFreq * 2))) {
- this.springTarget.x = this.seePlayer.position.x;
- this.springTarget.y = this.seePlayer.position.y;
- this.cons.length = -200;
- this.cons2.length = 100 + 1.5 * this.radius;
- } else {
- this.springTarget2.x = this.seePlayer.position.x;
- this.springTarget2.y = this.seePlayer.position.y;
- this.cons.length = 100 + 1.5 * this.radius;
- this.cons2.length = -200;
- }
} else if (this.seePlayer.recall) {
this.lostPlayer();
}
}
- //if you don't recall player location rotate and draw to show where you are looking
- if (!this.seePlayer.recall) {
+ },
+ springAttack() {
+ // set new values of the ends of the spring constraints
+ if (this.seePlayer.recall) {
+ if (!(game.cycle % (this.seePlayerFreq * 2))) {
+ this.springTarget.x = this.seePlayer.position.x;
+ this.springTarget.y = this.seePlayer.position.y;
+ this.cons.length = -200;
+ this.cons2.length = 100 + 1.5 * this.radius;
+ } else {
+ this.springTarget2.x = this.seePlayer.position.x;
+ this.springTarget2.y = this.seePlayer.position.y;
+ this.cons.length = 100 + 1.5 * this.radius;
+ this.cons2.length = -200;
+ }
+ } else {
this.torque = this.lookTorque * this.inertia;
- //draw
+ //draw looking around arcs
const range = Math.PI * this.lookRange;
ctx.beginPath();
ctx.arc(this.position.x, this.position.y, this.radius * 2.5, this.angle - range, this.angle + range);
@@ -567,8 +570,8 @@ const mobs = {
}
}
};
- const seeRange = 3000;
- if (!(game.cycle % (this.seePlayerFreq * 10))) {
+ //move to a random location
+ if (!(game.cycle % (this.seePlayerFreq * 5))) {
best = {
x: null,
y: null,
@@ -577,6 +580,7 @@ const mobs = {
v1: null,
v2: null
};
+ const seeRange = 3000;
const look = {
x: this.position.x + seeRange * Math.cos(this.angle),
y: this.position.y + seeRange * Math.sin(this.angle)
@@ -589,27 +593,6 @@ const mobs = {
this.cons2.length = 100 + 1.5 * this.radius;
}
}
- if (!((game.cycle + this.seePlayerFreq * 5) % (this.seePlayerFreq * 10))) {
- best = {
- x: null,
- y: null,
- dist2: Infinity,
- who: null,
- v1: null,
- v2: null
- };
- const look = {
- x: this.position.x + seeRange * Math.cos(this.angle),
- y: this.position.y + seeRange * Math.sin(this.angle)
- };
- vertexCollision(this.position, look, map);
- if (best.dist2 != Infinity) {
- this.springTarget2.x = best.x;
- this.springTarget2.y = best.y;
- this.cons.length = 100 + 1.5 * this.radius;
- this.cons2.length = 100 + 1.5 * this.radius;
- }
- }
}
},
alertNearByMobs() {
@@ -805,6 +788,7 @@ const mobs = {
if (this.seePlayer.recall && this.cd < game.cycle) {
const dist = Vector.sub(this.seePlayer.position, this.position);
const distMag = Vector.magnitude(dist);
+ console.log(this.seePlayer.recall)
if (distMag < 400) {
this.cd = game.cycle + this.delay;
ctx.beginPath();
diff --git a/js/player.js b/js/player.js
index ccef669..b129cf4 100644
--- a/js/player.js
+++ b/js/player.js
@@ -1787,7 +1787,7 @@ const mech = {
mech.grabPowerUp();
mech.lookForPickUp();
- const DRAIN = (0.0005 + 0.0001 * player.speed) * (mech.fireCDcycle > mech.cycle ? 10 / b.modRenormalization : 1) //game.mouseDown
+ const DRAIN = (0.0005 + 0.0001 * player.speed) * (mech.fireCDcycle > mech.cycle ? 9 / b.modRenormalization : 1) //game.mouseDown
if (mech.energy > DRAIN) {
mech.energy -= DRAIN;
if (mech.energy < 0.001) {
@@ -1805,14 +1805,15 @@ const mech = {
if (inPlayer.length > 0) {
for (let i = 0; i < inPlayer.length; i++) {
if (inPlayer[i].shield) {
- mech.energy -= 0.005; //shields drain player energy
+ mech.energy -= 0.01; //shields drain player energy
//draw outline of shield
ctx.fillStyle = `rgba(0, 204, 255,0.6)`
ctx.fill()
- } else if (b.isModPhaseFieldDamage && mech.energy > 0.006 && inPlayer[i].dropPowerUp && !inPlayer[i].isShielded) {
- inPlayer[i].damage(0.4 * b.dmgScale); //damage mobs inside the player
- mech.energy -= 0.002;
+ } else if (b.superposition && inPlayer[i].dropPowerUp) {
+ // inPlayer[i].damage(0.4 * b.dmgScale); //damage mobs inside the player
+ // mech.energy += 0.005;
+ mobs.statusStun(inPlayer[i], 240)
//draw outline of mob in a few random locations to show blurriness
const vertices = inPlayer[i].vertices;
const off = 30
@@ -1825,11 +1826,8 @@ const mech = {
ctx.lineTo(xOff + vertices[j].x, yOff + vertices[j].y);
}
ctx.lineTo(xOff + vertices[0].x, yOff + vertices[0].y);
- ctx.fillStyle = "rgba(0,0,0,0.3)"
+ ctx.fillStyle = "rgba(0,0,0,0.1)"
ctx.fill()
- // ctx.strokeStyle = "#000"
- // ctx.lineWidth = 1
- // ctx.stroke()
}
break;
}
diff --git a/js/spawn.js b/js/spawn.js
index 7a92ac5..d5a3af9 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -182,6 +182,7 @@ const spawn = {
me.do = function () {
if (!mech.isBodiesAsleep) {
this.seePlayerByDistOrLOS();
+ this.checkStatus();
this.attraction();
if (this.seePlayer.recall && this.mass < this.cellMassMax) { //grow cell radius
@@ -205,7 +206,6 @@ const spawn = {
}
}
}
- this.checkStatus()
};
me.onDeath = function () {
let count = 0 //count other cells
@@ -318,8 +318,8 @@ const spawn = {
me.do = function () {
this.gravity();
this.seePlayerCheck();
- this.attraction();
this.checkStatus();
+ this.attraction();
};
},
grower(x, y, radius = 15) {
@@ -329,9 +329,9 @@ const spawn = {
me.accelMag = 0.00045 * game.accelScale;
me.do = function () {
this.seePlayerByLookingAt();
+ this.checkStatus();
this.attraction();
this.grow();
- this.checkStatus();
};
},
springer(x, y, radius = 20 + Math.ceil(Math.random() * 35)) {
@@ -381,6 +381,8 @@ const spawn = {
this.gravity();
this.searchSpring();
this.checkStatus();
+ this.springAttack();
+ //not properly effected by stun, if looking at player while stun will still attack...
};
},
hopper(x, y, radius = 30 + Math.ceil(Math.random() * 30)) {
@@ -397,6 +399,7 @@ const spawn = {
me.do = function () {
this.gravity();
this.seePlayerCheck();
+ this.checkStatus();
this.hop();
//randomly hob if not aware of player
if (this.randomHopCD < game.cycle && this.speed < 1 && !this.seePlayer.recall) {
@@ -408,7 +411,6 @@ const spawn = {
this.force.x += forceMag * Math.cos(angle);
this.force.y += forceMag * Math.sin(angle) - 0.04 * this.mass; //antigravity
}
- this.checkStatus();
};
},
spinner(x, y, radius = 30 + Math.ceil(Math.random() * 35)) {
@@ -430,6 +432,7 @@ const spawn = {
spawn.shield(me, x, y);
me.do = 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) {
@@ -463,7 +466,6 @@ const spawn = {
} else {
this.cdBurst2 = 0;
}
- this.checkStatus();
};
},
sucker(x, y, radius = 30 + Math.ceil(Math.random() * 70)) {
@@ -486,6 +488,7 @@ const spawn = {
});
}
this.seePlayerByDistOrLOS();
+ this.checkStatus();
if (this.seePlayer.recall) {
//eventHorizon waves in and out
eventHorizon = this.eventHorizon * (0.93 + 0.17 * Math.sin(game.cycle * 0.011))
@@ -533,7 +536,6 @@ const spawn = {
ctx.fill();
}
}
- this.checkStatus();
}
},
suckerBoss(x, y, radius = 25) {
@@ -575,6 +577,7 @@ const spawn = {
});
}
this.seePlayerByDistOrLOS();
+ this.checkStatus();
if (this.seePlayer.recall) {
//accelerate towards the player
const forceMag = this.accelMag * this.mass;
@@ -633,7 +636,6 @@ const spawn = {
}
this.curl(eventHorizon);
}
- this.checkStatus();
}
},
timeSkipBoss(x, y, radius = 80) {
@@ -654,6 +656,7 @@ const spawn = {
me.do = function () {
//keep it slow, to stop issues from explosion knock backs
this.seePlayerCheck();
+ this.checkStatus();
this.attraction()
if (!game.isTimeSkipping) {
const compress = 3
@@ -704,8 +707,6 @@ const spawn = {
ctx.fill();
}
}
-
- this.checkStatus();
}
},
beamer(x, y, radius = 15 + Math.ceil(Math.random() * 15)) {
@@ -719,11 +720,11 @@ const spawn = {
spawn.shield(me, x, y);
me.do = function () {
this.seePlayerByLookingAt();
+ this.checkStatus();
this.attraction();
this.repulsion();
//laser beam
this.laserBeam();
- this.checkStatus();
};
},
focuser(x, y, radius = 30 + Math.ceil(Math.random() * 10)) {
@@ -744,6 +745,7 @@ const spawn = {
me.do = function () {
if (!mech.isBodiesAsleep) {
this.seePlayerByLookingAt();
+ this.checkStatus();
const dist2 = this.distanceToPlayer2();
//laser Tracking
if (this.seePlayer.yes && dist2 < 4000000 && !mech.isStealth) {
@@ -787,7 +789,6 @@ const spawn = {
this.laserPos = this.position;
}
};
- this.checkStatus();
}
},
laser(x, y, radius = 30) {
@@ -802,9 +803,9 @@ const spawn = {
};
me.do = function () {
this.seePlayerByLookingAt();
+ this.checkStatus();
this.attraction();
this.laser();
- this.checkStatus();
};
},
laserBoss(x, y, radius = 30) {
@@ -937,11 +938,11 @@ const spawn = {
this.cd = game.cycle + this.delay;
};
me.do = function () {
- this.seePlayerCheck();
- this.attraction();
this.gravity();
- this.strike();
+ this.seePlayerCheck();
this.checkStatus();
+ this.attraction();
+ this.strike();
};
},
sneaker(x, y, radius = 15 + Math.ceil(Math.random() * 25)) {
@@ -958,9 +959,10 @@ const spawn = {
me.showHealthBar = false;
// me.memory = 420;
me.do = function () {
- this.seePlayerCheck();
- this.attraction();
this.gravity();
+ this.seePlayerCheck();
+ this.checkStatus();
+ this.attraction();
//draw
if (!mech.isBodiesAsleep) {
if (this.seePlayer.yes) {
@@ -991,7 +993,6 @@ const spawn = {
this.canTouchPlayer = false;
this.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob //can't touch player
}
- this.checkStatus();
};
},
ghoster(x, y, radius = 40 + Math.ceil(Math.random() * 100)) {
@@ -1018,6 +1019,7 @@ const spawn = {
});
}
this.seePlayerCheckByDistance();
+ this.checkStatus();
this.attraction();
this.search();
//draw
@@ -1049,7 +1051,6 @@ const spawn = {
this.canTouchPlayer = false;
this.collisionFilter.mask = cat.bullet; //can't touch player or walls
}
- this.checkStatus();
};
},
// blinker(x, y, radius = 45 + Math.ceil(Math.random() * 70)) {
@@ -1122,10 +1123,12 @@ const spawn = {
};
me.do = function () {
this.seePlayerCheckByDistance();
- this.hoverOverPlayer();
- this.bomb();
- this.search();
this.checkStatus();
+ if (this.seePlayer.recall) {
+ this.hoverOverPlayer();
+ this.bomb();
+ this.search();
+ }
};
},
shooter(x, y, radius = 25 + Math.ceil(Math.random() * 50)) {
@@ -1146,8 +1149,8 @@ const spawn = {
// spawn.shield(me, x, y);
me.do = function () {
this.seePlayerByLookingAt();
- this.fire();
this.checkStatus();
+ this.fire();
};
},
shooterBoss(x, y, radius = 130) {
@@ -1176,12 +1179,12 @@ const spawn = {
};
me.do = function () {
this.seePlayerByLookingAt();
+ this.checkStatus();
this.fire();
//gently return to starting location
const sub = Vector.sub(this.homePosition, this.position)
const dist = Vector.magnitude(sub)
if (dist > 50) this.force = Vector.mult(Vector.normalise(sub), this.mass * 0.0002)
- this.checkStatus();
};
},
bullet(x, y, radius = 6, sides = 0) {
@@ -1226,8 +1229,8 @@ const spawn = {
me.do = function () {
this.gravity();
this.seePlayerCheck();
- this.attraction();
this.checkStatus();
+ this.attraction();
};
},
spawns(x, y, radius = 15 + Math.ceil(Math.random() * 5)) {
@@ -1246,8 +1249,8 @@ const spawn = {
me.do = function () {
this.gravity();
this.seePlayerCheck();
- this.attraction();
this.checkStatus();
+ this.attraction();
};
},
exploder(x, y, radius = 25 + Math.ceil(Math.random() * 50)) {
@@ -1261,8 +1264,8 @@ const spawn = {
me.do = function () {
this.gravity();
this.seePlayerCheck();
- this.attraction();
this.checkStatus();
+ this.attraction();
};
},
snakeBoss(x, y, radius = 80) {
@@ -1279,9 +1282,9 @@ const spawn = {
};
me.do = function () {
this.seePlayerCheck();
+ this.checkStatus();
this.attraction();
this.laserBeam();
- this.checkStatus();
};
//snake tail
@@ -1322,8 +1325,8 @@ const spawn = {
me.do = function () {
this.gravity();
this.seePlayerCheck();
- this.attraction();
this.checkStatus();
+ this.attraction();
};
},
shield(target, x, y, chance = Math.min(0.02 + game.difficulty * 0.005, 0.2)) {
diff --git a/todo.txt b/todo.txt
index ee0d005..f23f278 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,5 +1,10 @@
************** TODO - n-gon **************
+boss mob - just a faster and larger version of a springer mob
+ could have a more frequent random walk
+ always shielded
+ consider combining with time skipper field?
+
pulse and time dilation only ones left with no dedicated mod
lore - a robot (the player) gains self awareness