mod superposition stuns mobs in phase field, stun bug fixes

This commit is contained in:
landgreen
2020-04-05 10:35:09 -07:00
parent e66538820e
commit 51cf02f6d5
8 changed files with 79 additions and 87 deletions

View File

@@ -926,7 +926,7 @@ const b = {
},
{
name: "super ball",
description: "fire one <strong>large</strong> super <strong>ball</strong><br>that <strong>stuns</strong> mobs for <strong>2</strong> second",
description: "fire one <strong>large</strong> super <strong>ball</strong><br>that <strong>stuns</strong> mobs for <strong>3</strong> second",
maxCount: 1,
count: 0,
allowed() {
@@ -1338,7 +1338,7 @@ const b = {
},
{
name: "renormalization",
description: "<strong>phase decoherence field</strong> has <strong>3x visibility</strong><br>and <strong>1/3</strong> <strong class='color-f'>energy</strong> drain when <strong>firing</strong>",
description: "<strong>phase decoherence field</strong> has <strong>3x visibility</strong><br>and <strong>3x</strong> less <strong class='color-f'>energy</strong> drain when <strong>firing</strong>",
maxCount: 1,
count: 0,
allowed() {
@@ -1353,8 +1353,9 @@ const b = {
}
},
{
name: "quantum dissipation",
description: "<strong>phase decoherence field</strong> uses <strong class='color-f'>energy</strong> to <br><strong class='color-d'>damage</strong> unshielded <strong>mobs</strong> that you <strong>overlap</strong>",
name: "superposition",
// description: "<strong>phase decoherence field</strong> applies a <strong>stun</strong><br> to unshielded <strong>mobs</strong> for <strong>2</strong> seconds",
description: "apply a <strong>4</strong> second <strong>stun</strong> to unshielded <strong>mobs</strong><br>that <strong>overlap</strong> with <strong>phase decoherence field</strong>",
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);

View File

@@ -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;

View File

@@ -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?

View File

@@ -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)
},

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -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)) {

View File

@@ -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