diff --git a/js/bullet.js b/js/bullet.js
index 4519c0b..330d332 100644
--- a/js/bullet.js
+++ b/js/bullet.js
@@ -770,11 +770,11 @@ const b = {
powerUp.splice(i, 1);
if (mod.isDroneGrab) {
this.isImproved = true;
- const SCALE = 2
+ const SCALE = 3.5
Matter.Body.scale(this, SCALE, SCALE);
this.lookFrequency = 30;
- this.endCycle = Infinity
- this.dmg *= 1.5;
+ this.endCycle += 2000
+ // this.dmg *= 1.25;
this.frictionAir = 0
}
break;
@@ -1061,7 +1061,7 @@ const b = {
},
onEnd() {},
do() {
- if (this.lastLookCycle < game.cycle) {
+ if (this.lastLookCycle < game.cycle && !mech.isCloak) {
this.lastLookCycle = game.cycle + 80 - this.isUpgraded * 50
let target
for (let i = 0, len = mob.length; i < len; i++) {
@@ -1117,7 +1117,7 @@ const b = {
},
onEnd() {},
do() {
- if (this.cd < game.cycle && !(game.cycle % this.lookFrequency) && !mech.isStealth) {
+ if (this.cd < game.cycle && !(game.cycle % this.lookFrequency) && !mech.isCloak) {
let target
for (let i = 0, len = mob.length; i < len; i++) {
const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position));
@@ -1186,7 +1186,7 @@ const b = {
y: this.velocity.y * 0.95
});
//find targets
- if (!(game.cycle % this.lookFrequency) && !mech.isStealth) {
+ if (!(game.cycle % this.lookFrequency) && !mech.isCloak) {
this.lockedOn = null;
let closeDist = this.range;
for (let i = 0, len = mob.length; i < len; ++i) {
@@ -1301,7 +1301,7 @@ const b = {
} else if (distanceToPlayer < 250) { //close to player
Matter.Body.setVelocity(this, Vector.add(Vector.mult(this.velocity, 0.90), Vector.mult(player.velocity, 0.17))); //add player's velocity
//find targets
- if (!(game.cycle % this.lookFrequency) && !mech.isStealth) {
+ if (!(game.cycle % this.lookFrequency) && !mech.isCloak) {
this.lockedOn = null;
let closeDist = this.range;
for (let i = 0, len = mob.length; i < len; ++i) {
@@ -1382,7 +1382,6 @@ const b = {
const unit = Vector.normalise(sub)
const DRAIN = 0.002
if (DIST < mod.isPlasmaRange * 500 && mech.energy > DRAIN) {
- console.log('fire')
mech.energy -= DRAIN;
if (mech.energy < 0) {
mech.fieldCDcycle = mech.cycle + 120;
@@ -1788,7 +1787,7 @@ const b = {
}
if (!immune) {
this.immuneList.push(who.id)
- if (!mech.isStealth) who.foundPlayer();
+ who.foundPlayer();
if (mod.isFastDot) {
mobs.statusDoT(who, 3.9, 30)
} else {
@@ -1804,7 +1803,7 @@ const b = {
}
} else {
this.endCycle = 0;
- if (!mech.isStealth) who.foundPlayer();
+ who.foundPlayer();
if (mod.isFastDot) {
mobs.statusDoT(who, 3.78, 30)
} else {
@@ -1903,7 +1902,7 @@ const b = {
for (let i = 0; i < q.length; i++) {
let dmg = b.dmgScale * 0.36 / Math.sqrt(q[i].mass) * (mod.waveHelix === 1 ? 1 : 0.66) //1 - 0.4 = 0.6 for helix mod 40% damage reduction
q[i].damage(dmg);
- if (!mech.isStealth) q[i].foundPlayer();
+ q[i].foundPlayer();
game.drawList.push({ //add dmg to draw queue
x: this.position.x,
y: this.position.y,
@@ -1936,7 +1935,7 @@ const b = {
Matter.Body.setPosition(this, Vector.add(this.position, q[i].velocity)) //move with the medium
let dmg = b.dmgScale * 0.36 / Math.sqrt(q[i].mass) * (mod.waveHelix === 1 ? 1 : 0.66) //1 - 0.4 = 0.6 for helix mod 40% damage reduction
q[i].damage(dmg);
- if (!mech.isStealth) q[i].foundPlayer();
+ q[i].foundPlayer();
game.drawList.push({ //add dmg to draw queue
x: this.position.x,
y: this.position.y,
@@ -2973,34 +2972,9 @@ const b = {
nextFireCycle: 0, //use to remember how longs its been since last fire, used to reset count
holdDamage: 1,
holdCount: 0,
+ healthLost: 0,
fire() {
- if (mod.isLaserHealth) {
- if (this.nextFireCycle === mech.cycle) { //ramp up damage
- this.holdDamage += 0.01
- if (this.holdDamage > 4) this.holdDamage = 4
- this.holdCount += this.holdDamage
- if (this.holdCount > 180) {
- this.holdCount = 0;
- const size = 15
- let dmg = (mod.largerHeals * (size / 40 / Math.sqrt(mod.largerHeals) / (game.healScale ** 0.25)) ** 2) / mech.harmReduction() * game.healScale
- if (mech.health < 0.15) {
- mech.fireCDcycle = mech.cycle + 120; // fire cool down if about to die
- } else {
- const totalPowerUps = powerUp.length
- powerUps.spawn(mech.pos.x, mech.pos.y, "heal", true, false, size);
- mech.damage(dmg, false)
- if (powerUp.length > totalPowerUps + 1) {
- dmg = (mod.largerHeals * (powerUp[powerUp.length - 1].size / 40 / Math.sqrt(mod.largerHeals) / (game.healScale ** 0.25)) ** 2) / mech.harmReduction() * game.healScale
- mech.damage(dmg, false) //do bonus damage if you spawn bonus power ups
- }
- }
- }
- } else {
- this.holdDamage = 1
- this.holdCount = 0;
- }
- this.nextFireCycle = mech.cycle + 1
- }
+ mech.fireCDcycle = mech.cycle
const reflectivity = 1 - 1 / (mod.laserReflections * 1.5)
let damage = b.dmgScale * mod.laserDamage * this.holdDamage
diff --git a/js/engine.js b/js/engine.js
index 136e7fc..22bef37 100644
--- a/js/engine.js
+++ b/js/engine.js
@@ -143,10 +143,7 @@ function collisionChecks(event) {
mech.immuneCycle = mech.cycle + mod.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
mob[k].foundPlayer();
let dmg = Math.min(Math.max(0.025 * Math.sqrt(mob[k].mass), 0.05), 0.3) * game.dmgScale; //player damage is capped at 0.3*dmgScale of 1.0
- if (mod.isPiezo) {
- mech.energy = mech.maxEnergy;
- dmg *= 0.85
- }
+ if (mod.isPiezo) mech.energy = mech.maxEnergy;
mech.damage(dmg);
if (mod.isBayesian) {
const have = [] //find which mods you have
@@ -203,8 +200,9 @@ function collisionChecks(event) {
//mob + bullet collisions
if (obj.classType === "bullet" && obj.speed > obj.minDmgSpeed) {
let dmg = b.dmgScale * (obj.dmg + 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity)))
- if (mod.isCrit && !mob[k].seePlayer.recall && !mob[k].shield) dmg *= 5
- if (!mech.isStealth) mob[k].foundPlayer();
+ // console.log(mob[k].seePlayer.recall)
+ if (mod.isCrit && mob[k].isStunned) dmg *= 5
+ mob[k].foundPlayer();
mob[k].damage(dmg);
obj.onDmg(mob[k]); //some bullets do actions when they hits things, like despawn //forces don't seem to work here
game.drawList.push({ //add dmg to draw queue
@@ -225,7 +223,7 @@ function collisionChecks(event) {
mob[k].damage(dmg, true);
const stunTime = dmg / Math.sqrt(obj.mass)
if (stunTime > 0.5) mobs.statusStun(mob[k], 30 + 60 * Math.sqrt(stunTime))
- if (mob[k].distanceToPlayer2() < 1000000 && !mech.isStealth) mob[k].foundPlayer();
+ if (mob[k].distanceToPlayer2() < 1000000 && !mech.isCloak) mob[k].foundPlayer();
game.drawList.push({
x: pairs[i].activeContacts[0].vertex.x,
y: pairs[i].activeContacts[0].vertex.y,
diff --git a/js/game.js b/js/game.js
index 7f91ea0..3084b98 100644
--- a/js/game.js
+++ b/js/game.js
@@ -476,9 +476,7 @@ const game = {
powerUps.directSpawn(game.mouseInGame.x, game.mouseInGame.y, "mod");
} else if (keys[54]) { // 6 spawn mob
const pick = spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)];
- spawn.allowShields = false;
spawn[pick](game.mouseInGame.x, game.mouseInGame.y);
- spawn.allowShields = true;
} else if (keys[55]) { // 7 spawn body
index = body.length
spawn.bodyRect(game.mouseInGame.x, game.mouseInGame.y, 50, 50);
@@ -712,8 +710,8 @@ const game = {
if (game.isCommunityMaps) {
level.levels.push("stronghold");
level.levels.push("basement");
+ level.levels.push("newLevel");
level.levels.push("house");
- // level.levels.push("newLevel");
}
level.levels = shuffle(level.levels); //shuffles order of maps
level.levels.unshift("bosses"); //add bosses level to the end of the randomized levels list
diff --git a/js/level.js b/js/level.js
index af55bb1..e20f145 100644
--- a/js/level.js
+++ b/js/level.js
@@ -14,10 +14,10 @@ const level = {
// game.enableConstructMode() //used to build maps in testing mode
// game.zoomScale = 1000;
// game.setZoom();
- // mech.isStealth = true;
- // mech.setField("pilot wave")
- // b.giveGuns("ice IX")
- // mod.giveMod("quantum immortality");
+ // mech.isCloak = true;
+ // mech.setField("metamaterial cloaking")
+ // b.giveGuns("laser")
+ // mod.giveMod("phase decoherence");
level.intro(); //starting level
// level.testing(); //not in rotation
@@ -53,13 +53,14 @@ const level = {
game.draw.setPaths();
b.respawnBots();
if (mod.isArmorFromPowerUps) {
- mech.maxHealth += 0.05 * powerUps.totalPowerUps
+ mod.armorFromPowerUps += 0.05 * powerUps.totalPowerUps
+ mech.setMaxHealth();
if (powerUps.totalPowerUps) game.makeTextLog(" max health increased by " + (0.05 * powerUps.totalPowerUps * 100).toFixed(0) + "%", 300)
}
if (mod.isHealLowHealth) {
const len = Math.floor((mech.maxHealth - mech.health) / 0.5)
for (let i = 0; i < len; i++) {
- powerUps.spawn(mech.pos.x, mech.pos.y, "heal", false);
+ powerUps.spawn(mech.pos.x + 60 * (Math.random() - 0.5), mech.pos.y + 60 * (Math.random() - 0.5), "heal", false);
}
}
if (mod.isGunCycle) {
@@ -142,7 +143,7 @@ const level = {
// spawn.sniper(1800, -120)
// spawn.sniper(2200, -120)
// spawn.cellBossCulture(1600, -500)
- // spawn.starter(1600, -500, 60)
+ spawn.starter(1600, -500, 60)
// spawn.powerUpBoss(1600, -500)
// spawn.shield(mob[mob.length - 1], 1200, -500, 1);
@@ -221,8 +222,8 @@ const level = {
y: -600
}, -2 * Math.PI / 3) //up left
- const hazard = level.hazard(350, -2025, 700, 10, 0.4, "hsl(0, 100%, 50%)") //laser
- const hazard2 = level.hazard(1775, -2550, 150, 10, 0.4, "hsl(0, 100%, 50%)") //laser
+ const hazard = level.hazard(350, -2025, 700, 10, 0.4, "hsl(0, 100%, 50%)", true) //laser
+ const hazard2 = level.hazard(1775, -2550, 150, 10, 0.4, "hsl(0, 100%, 50%)", true) //laser
const button = level.button(2100, -2600)
@@ -1484,6 +1485,8 @@ const level = {
bodyB: mob[mob.length - 1],
stiffness: 0.00007
});
+ World.add(engine.world, cons[cons.length - 1]);
+
if (game.difficulty > 4) spawn.nodeBoss(4250, 0, "spawns", 8, 20, 105); //chance to spawn a ring of exploding mobs around this boss
} else if (Math.random() < 0.15) {
spawn.randomLevelBoss(4250, -250);
@@ -1699,6 +1702,37 @@ const level = {
height: 275,
color: "#cff"
});
+ level.fillBG.push({
+ x: -3375,
+ y: -2875,
+ width: 25,
+ height: 725,
+ color: "#d0d0d2"
+ });
+ level.fillBG.push({
+ x: -2975,
+ y: -2750,
+ width: 25,
+ height: 600,
+ color: "#d0d0d2"
+ });
+ level.fillBG.push({
+ x: -2475,
+ y: -2450,
+ width: 25,
+ height: 750,
+ color: "#d0d0d2"
+ });
+
+ //3 platforms that lead to exit
+ spawn.mapRect(-3440, -2875, 155, 25);
+ spawn.mapRect(-3025, -2775, 125, 25);
+ spawn.mapRect(-2525, -2475, 125, 25);
+ spawn.bodyRect(-2600, -2500, 225, 20, 0.7);
+ spawn.bodyRect(-3350, -2900, 25, 25, 0.5);
+ spawn.bodyRect(-3400, -2950, 50, 75, 0.5);
+
+
//foreground
level.fill.push({
x: -1650,
@@ -1709,11 +1743,12 @@ const level = {
});
level.fill.push({
x: -2600,
- y: -2400,
+ y: -1675,
width: 450,
- height: 1800,
+ height: 1125,
color: "rgba(0,0,0,0.12)"
});
+
level.fill.push({
x: -3425,
y: -2150,
@@ -1781,7 +1816,7 @@ const level = {
spawn.mapRect(-3450, -1325, 550, 50);
spawn.mapRect(-3425, -2200, 525, 50);
spawn.mapRect(-2600, -1700, 450, 50);
- spawn.mapRect(-2600, -2450, 450, 50);
+ // spawn.mapRect(-2600, -2450, 450, 50);
spawn.bodyRect(-2275, -2700, 50, 60);
spawn.bodyRect(-2600, -1925, 250, 225);
spawn.bodyRect(-3415, -1425, 100, 100);
@@ -1799,6 +1834,7 @@ const level = {
spawn.bodyRect(-3080, -2250, 40, 40);
spawn.bodyRect(-3420, -650, 50, 50);
+
//exit
spawn.mapRect(-4450, -3075, 25, 300);
spawn.mapRect(-4450, -3075, 450, 25);
@@ -1831,7 +1867,8 @@ const level = {
spawn.randomMob(-550, -100, -0.1);
spawn.randomBoss(-3250, -2700, 0.2);
spawn.randomBoss(-2450, -1100, 0);
- if (game.difficulty > 3) spawn.randomLevelBoss(-3400, -2800);
+
+ if (game.difficulty > 3) spawn.randomLevelBoss(-2400, -3000);
powerUps.addRerollToLevel() //needs to run after mobs are spawned
},
warehouse() {
@@ -1930,6 +1967,7 @@ const level = {
stiffness: 0.0001815,
length: 1
});
+ World.add(engine.world, cons[cons.length - 1]);
spawn.bodyRect(600, 525, 125, 125, 1, spawn.propsSlide); //weight
spawn.bodyRect(800, 600, 300, 100, 1, spawn.propsHoist); //hoist
@@ -1942,6 +1980,7 @@ const level = {
stiffness: 0.0001815,
length: 1
});
+ World.add(engine.world, cons[cons.length - 1]);
spawn.bodyRect(-2700, 1150, 100, 160, 1, spawn.propsSlide); //weight
spawn.bodyRect(-2550, 1150, 200, 100, 1, spawn.propsSlide); //weight
@@ -1955,6 +1994,7 @@ const level = {
stiffness: 0.0005,
length: 566
});
+ World.add(engine.world, cons[cons.length - 1]);
//blocks
spawn.bodyRect(-165, -150, 30, 35, 1);
@@ -2130,6 +2170,7 @@ const level = {
bodyB: map[map.length - 1],
stiffness: 1
});
+ World.add(engine.world, consBB[consBB.length - 1]);
spawn.mapRect(-600 + 300, -2000 * 0.75, 1900, 50); //3rd floor
spawn.mapRect(-600 + 2000 * 0.7, -2000 * 0.74, 50, 375); //center wall
spawn.bodyRect(-600 + 2000 * 0.7, -2000 * 0.5 - 106, 50, 106); //center block under wall
@@ -2194,6 +2235,7 @@ const level = {
bodyB: mob[mob.length - 1],
stiffness: 0.00012
});
+ World.add(engine.world, cons[cons.length - 1]);
//chance to spawn a ring of exploding mobs around this boss
if (game.difficulty > 6) spawn.nodeBoss(2850, -80, "spawns", 8, 20, 105);
} else {
@@ -2356,6 +2398,7 @@ const level = {
stiffness: 0.0002, //1217,
length: 200
});
+ World.add(engine.world, cons[cons.length - 1]);
spawn.bodyRect(2799, -870, 310, 290); //Gros bloc angle toit
spawn.mapRect(4000, -1750, 50, 400); //Right Wall Cuve
@@ -2406,7 +2449,7 @@ const level = {
bodyB: map[map.length - 1],
stiffness: 1
});
-
+ World.add(engine.world, consBB[consBB.length - 1]);
spawn.bodyRect(650, 50, 70, 50);
spawn.bodyRect(300, 0, 100, 60);
spawn.bodyRect(400, 0, 100, 150);
@@ -2587,6 +2630,7 @@ const level = {
stiffness: 0.00014,
length: 120
});
+ World.add(engine.world, cons[cons.length - 1]);
spawn.bodyRect(0, -1250, 240, 190) //Fat cube ascenseur
} else { /// Reversed spawn
spawn.bodyRect(0, -650, 225, 175);
@@ -2666,6 +2710,7 @@ const level = {
bodyB: mob[mob.length - 1],
stiffness: 0.00006
});
+ World.add(engine.world, cons[cons.length - 1]);
if (game.difficulty > 4) spawn.nodeBoss(7000, -3300, "spawns", 8, 20, 105);
} else if (game.difficulty > 3) {
spawn.randomLevelBoss(6100, -3600, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss"]);
@@ -2684,6 +2729,7 @@ const level = {
bodyB: mob[mob.length - 1],
stiffness: 0.00036
});
+ World.add(engine.world, cons[cons.length - 1]);
if (game.difficulty > 4) spawn.nodeBoss(2350, -1300, "spawns", 8, 20, 105);
} else if (game.difficulty > 3) {
spawn.randomLevelBoss(2300, -1400, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss", "snakeBoss"]);
@@ -2759,6 +2805,7 @@ const level = {
bodyB: mob[mob.length - 1],
stiffness: 0.00017
});
+ World.add(engine.world, cons[cons.length - 1]);
//chance to spawn a ring of exploding mobs around this boss
if (game.difficulty > 4) spawn.nodeBoss(2330, 1850, "spawns", 8, 20, 105);
powerUps.spawn(3010, 1630, "mod");
@@ -3193,6 +3240,7 @@ const level = {
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"]);
@@ -3768,6 +3816,7 @@ const level = {
bodyB: mob[mob.length - 1],
stiffness: 0.00018 + 0.000007 * level.levelsCleared
});
+ World.add(engine.world, cons[cons.length - 1]);
if (game.difficulty > 4) spawn.nodeBoss(3380, -1775, "spawns", 8, 20, 105); //chance to spawn a ring of exploding mobs around this boss
} else {
@@ -4003,12 +4052,10 @@ const level = {
Matter.Body.setStatic(map[i], true); //make static
World.add(engine.world, map[i]); //add to world
}
- for (let i = 0; i < cons.length; i++) {
- World.add(engine.world, cons[i]);
- }
- for (let i = 0; i < consBB.length; i++) {
- World.add(engine.world, consBB[i]);
- }
+ // for (let i = 0; i < cons.length; i++) {
+ // World.add(engine.world, cons[i]);
+ // }
+
},
spinner(x, y, width, height, density = 0.001) {
x = x + width / 2
@@ -4404,7 +4451,7 @@ const level = {
mapB.portalPair = mapA
return [portalA, portalB, mapA, mapB]
},
- hazard(x, y, width, height, damage = 0.0005, color = "hsla(160, 100%, 35%,0.75)") {
+ hazard(x, y, width, height, damage = 0.0005, color = "hsla(160, 100%, 35%,0.75)", isOptical = false) {
return {
min: {
x: x,
@@ -4419,7 +4466,7 @@ const level = {
maxHeight: height,
isOn: true,
query() {
- if (this.isOn && this.height > 0 && Matter.Query.region([player], this).length && !mech.isStealth) {
+ if (this.isOn && this.height > 0 && Matter.Query.region([player], this).length && !(mech.isCloak && isOptical)) {
if (damage < 0.02) {
mech.damage(damage)
} else if (mech.immuneCycle < mech.cycle) {
@@ -4480,6 +4527,7 @@ const level = {
stiffness: stiffness,
damping: damping
});
+ World.add(engine.world, consBB[consBB.length - 1]);
}
cons[cons.length] = Constraint.create({ //pin first block to a point in space
pointA: {
@@ -4490,6 +4538,7 @@ const level = {
stiffness: 1,
damping: damping
});
+ World.add(engine.world, cons[cons.length - 1]);
if (isAttached) {
cons[cons.length] = Constraint.create({ //pin last block to a point in space
pointA: {
@@ -4500,6 +4549,7 @@ const level = {
stiffness: 1,
damping: damping
});
+ World.add(engine.world, cons[cons.length - 1]);
}
},
};
\ No newline at end of file
diff --git a/js/mob.js b/js/mob.js
index 9d547b7..cabc1ea 100644
--- a/js/mob.js
+++ b/js/mob.js
@@ -292,13 +292,16 @@ const mobs = {
this.seePlayer.position.x = player.position.x;
this.seePlayer.position.y = player.position.y;
},
- // locatePlayerByDist() {
- // if (this.distanceToPlayer2() < this.locateRange) {
- // this.locatePlayer();
- // }
- // },
+ alertNearByMobs() {
+ //this.alertRange2 is set at the very bottom of this mobs, after mob is made
+ for (let i = 0; i < mob.length; i++) {
+ if (!mob[i].seePlayer.recall && Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)) < this.alertRange2) {
+ mob[i].locatePlayer();
+ }
+ }
+ },
alwaysSeePlayer() {
- if (!mech.isStealth) {
+ if (!mech.isCloak) {
this.seePlayer.recall = true;
this.seePlayer.position.x = player.position.x;
this.seePlayer.position.y = player.position.y;
@@ -310,7 +313,7 @@ const mobs = {
this.distanceToPlayer2() < this.seeAtDistance2 &&
Matter.Query.ray(map, this.position, this.mechPosRange()).length === 0 &&
Matter.Query.ray(body, this.position, this.mechPosRange()).length === 0 &&
- !mech.isStealth
+ !mech.isCloak
) {
this.foundPlayer();
} else if (this.seePlayer.recall) {
@@ -320,7 +323,7 @@ const mobs = {
},
seePlayerCheckByDistance() {
if (!(game.cycle % this.seePlayerFreq)) {
- if (this.distanceToPlayer2() < this.seeAtDistance2 && !mech.isStealth) {
+ if (this.distanceToPlayer2() < this.seeAtDistance2 && !mech.isCloak) {
this.foundPlayer();
} else if (this.seePlayer.recall) {
this.lostPlayer();
@@ -331,7 +334,7 @@ const mobs = {
if (!(game.cycle % this.seePlayerFreq)) {
if (
(this.distanceToPlayer2() < this.seeAtDistance2 || (Matter.Query.ray(map, this.position, this.mechPosRange()).length === 0 && Matter.Query.ray(body, this.position, this.mechPosRange()).length === 0)) &&
- !mech.isStealth
+ !mech.isCloak
) {
this.foundPlayer();
} else if (this.seePlayer.recall) {
@@ -363,7 +366,7 @@ const mobs = {
this.distanceToPlayer2() < this.seeAtDistance2 &&
Matter.Query.ray(map, this.position, this.mechPosRange()).length === 0 &&
Matter.Query.ray(body, this.position, this.mechPosRange()).length === 0 &&
- !mech.isStealth
+ !mech.isCloak
) {
this.foundPlayer();
} else if (this.seePlayer.recall) {
@@ -411,7 +414,7 @@ const mobs = {
if (game.cycle % 7 && this.seePlayer.yes) {
ctx.setLineDash([125 * Math.random(), 125 * Math.random()]);
// ctx.lineDashOffset = 6*(game.cycle % 215);
- if (this.distanceToPlayer() < this.laserRange && !mech.isStealth) {
+ if (this.distanceToPlayer() < this.laserRange) {
if (mech.immuneCycle < mech.cycle) mech.damage(0.0003 * game.dmgScale);
if (mech.energy > 0.1) mech.energy -= 0.003
ctx.beginPath();
@@ -497,7 +500,7 @@ const mobs = {
};
vertexCollision(this.position, look, map);
vertexCollision(this.position, look, body);
- if (!mech.isStealth) vertexCollision(this.position, look, [player]);
+ if (!mech.isCloak) vertexCollision(this.position, look, [player]);
// hitting player
if (best.who === player) {
if (mech.immuneCycle < mech.cycle) {
@@ -538,7 +541,7 @@ const mobs = {
this.distanceToPlayer2() < this.seeAtDistance2 &&
Matter.Query.ray(map, this.position, player.position).length === 0 &&
Matter.Query.ray(body, this.position, player.position).length === 0 &&
- !mech.isStealth
+ !mech.isCloak
) {
this.foundPlayer();
} else if (this.seePlayer.recall) {
@@ -644,14 +647,6 @@ const mobs = {
}
}
},
- alertNearByMobs() {
- //this.alertRange2 is set at the very bottom of this mobs, after mob is made
- for (let i = 0; i < mob.length; i++) {
- if (!mob[i].seePlayer.recall && Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)) < this.alertRange2) {
- mob[i].locatePlayer();
- }
- }
- },
curl(range = 1000, mag = -10) {
//cause all mobs, and bodies to rotate in a circle
applyCurl = function (center, array, isAntiGravity = true) {
@@ -1049,7 +1044,7 @@ const mobs = {
}
}
if (Math.random() < mod.isBotSpawner) b.randomBot(this.position, false)
- if (mod.isExplodeMob) b.explosion(this.position, Math.min(425, Math.sqrt(this.mass + 3) * 70))
+ if (mod.isExplodeMob) b.explosion(this.position, Math.min(550, Math.sqrt(this.mass + 2.5) * 50))
if (mod.nailsDeathMob) b.targetedNail(this.position, mod.nailsDeathMob, 40 + 7 * Math.random())
} else if (mod.isShieldAmmo && this.shield) {
let type = "ammo"
diff --git a/js/mods.js b/js/mods.js
index bb54395..816d333 100644
--- a/js/mods.js
+++ b/js/mods.js
@@ -5,6 +5,7 @@ const mod = {
mod.mods[i].remove();
mod.mods[i].count = 0
}
+ mod.armorFromPowerUps = 0;
mod.totalCount = 0;
game.updateModHUD();
},
@@ -37,6 +38,7 @@ const mod = {
}
if (!found) return //if name not found don't give any mod
}
+ if (mod.mods[index].isLost) mod.mods[index].isLost = false; //give specific mod
mod.mods[index].effect(); //give specific mod
mod.mods[index].count++
mod.totalCount++ //used in power up randomization
@@ -78,7 +80,7 @@ const mod = {
return false
},
damageFromMods() {
- let dmg = 1
+ let dmg = mech.fieldDamage
if (mod.isEnergyNoAmmo) dmg *= 1.4
if (mod.isDamageForGuns) dmg *= 1 + 0.07 * b.inventory.length
if (mod.isLowHealthDmg) dmg *= 1 + 0.6 * Math.max(0, 1 - mech.health)
@@ -112,7 +114,6 @@ const mod = {
}
}, {
name: "capacitor",
- // nameInfo: "",
description: "increase damage by 1%
for every 5.5% stored energy",
maxCount: 1,
count: 0,
@@ -121,7 +122,7 @@ const mod = {
},
requires: "increased energy regen or max energy",
effect: () => {
- mod.isEnergyDamage = true // used in mech.grabPowerUp
+ mod.isEnergyDamage = true
},
remove() {
mod.isEnergyDamage = false;
@@ -161,7 +162,6 @@ const mod = {
},
{
name: "rest frame",
- // nameInfo: "",
description: "increase damage by 20%
when not moving",
maxCount: 1,
count: 0,
@@ -170,7 +170,7 @@ const mod = {
},
requires: "",
effect: () => {
- mod.isRest = true // used in mech.grabPowerUp
+ mod.isRest = true
},
remove() {
mod.isRest = false;
@@ -756,7 +756,7 @@ const mod = {
},
requires: "",
effect() {
- mod.collisionImmuneCycles += 60;
+ mod.collisionImmuneCycles += 55;
mech.immuneCycle = mech.cycle + mod.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
},
remove() {
@@ -818,7 +818,7 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
- return mod.superposition || mod.isStunField || mod.isPulseStun || mod.isNeutronStun || mod.oneSuperBall || mod.isHarmFreeze || mod.isIceField || mod.isIceCrystals || mod.isSporeFreeze || mod.isAoESlow || mod.isFreezeMobs || mod.isPilotFreeze || mod.haveGunCheck("ice IX")
+ return mod.isStunField || mod.isPulseStun || mod.isNeutronStun || mod.oneSuperBall || mod.isHarmFreeze || mod.isIceField || mod.isIceCrystals || mod.isSporeFreeze || mod.isAoESlow || mod.isFreezeMobs || mod.isPilotFreeze || mod.haveGunCheck("ice IX")
},
requires: "a freezing or stunning effect",
effect() {
@@ -830,7 +830,7 @@ const mod = {
},
{
name: "piezoelectricity",
- description: "colliding with mobs fills your energy
15% less harm from mob collisions",
+ description: "colliding with mobs fills your energy
reduce harm by 15%",
maxCount: 1,
count: 0,
allowed() {
@@ -982,12 +982,14 @@ const mod = {
},
requires: "not mass-energy equivalence",
effect() {
- mech.maxHealth += 0.50
+ mod.bonusHealth += 0.5
mech.addHealth(0.50)
+ mech.setMaxHealth();
},
remove() {
- mech.maxHealth = 1;
- mech.displayHealth();
+ mod.bonusHealth = 0
+ mech.setMaxHealth();
+
}
},
{
@@ -996,14 +998,16 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
- return !mod.isEnergyHealth && !mod.isDroneGrab
+ return !mod.isEnergyHealth
},
requires: "not mass-energy equivalence",
effect() {
- mod.isArmorFromPowerUps = true;
+ mod.isArmorFromPowerUps = true; //tracked by mod.armorFromPowerUps
},
remove() {
mod.isArmorFromPowerUps = false;
+ // mod.armorFromPowerUps = 0; //this is now reset in mod.setupAllMods();
+ mech.setMaxHealth();
}
},
{
@@ -2023,7 +2027,7 @@ const mod = {
},
{
name: "harvester",
- description: "after a drone picks up a power up,
it's larger, faster, and infinitely durable",
+ description: "after a drone picks up a power up,
it's larger, faster, and very durable",
maxCount: 1,
count: 0,
allowed() {
@@ -2203,22 +2207,22 @@ const mod = {
mod.laserFieldDrain = 0.0016;
}
},
- {
- name: "waste heat recovery",
- description: "laser damage grows by 400% as you fire
but you periodically eject your health",
- maxCount: 1,
- count: 0,
- allowed() {
- return mod.haveGunCheck("laser")
- },
- requires: "laser",
- effect() {
- mod.isLaserHealth = true;
- },
- remove() {
- mod.isLaserHealth = false
- }
- },
+ // {
+ // name: "waste heat recovery",
+ // description: "laser damage grows by 400% as you fire
but you periodically eject your health",
+ // maxCount: 1,
+ // count: 0,
+ // allowed() {
+ // return mod.haveGunCheck("laser") && !mod.isEnergyHealth
+ // },
+ // requires: "laser
not mass-energy equivalence",
+ // effect() {
+ // mod.isLaserHealth = true;
+ // },
+ // remove() {
+ // mod.isLaserHealth = false
+ // }
+ // },
{
name: "shock wave",
description: "mobs caught in pulse's explosion are stunned
for up to 2 seconds",
@@ -2272,6 +2276,22 @@ const mod = {
mod.isStunField = 0;
}
},
+ {
+ name: "fracture analysis",
+ description: "bullet impacts do 500% damage
to stunned mobs",
+ maxCount: 1,
+ count: 0,
+ allowed() {
+ return mod.isStunField || mod.oneSuperBall || mod.isCloakStun
+ },
+ requires: "flux pinning or super ball
or flashbang",
+ effect() {
+ mod.isCrit = true;
+ },
+ remove() {
+ mod.isCrit = false;
+ }
+ },
{
name: "timelike world line",
description: "time dilation doubles your relative time rate
and makes you immune to harm",
@@ -2451,7 +2471,7 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
- return mech.fieldUpgrades[mech.fieldMode].name === "nano-scale manufacturing" && !(mod.isMissileField || mod.isIceField || mod.isFastDrones)
+ return mech.fieldUpgrades[mech.fieldMode].name === "nano-scale manufacturing" && !(mod.isMissileField || mod.isIceField || mod.isFastDrones || mod.isDroneGrab)
},
requires: "nano-scale manufacturing",
effect() {
@@ -2467,7 +2487,7 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
- return mech.fieldUpgrades[mech.fieldMode].name === "nano-scale manufacturing" && !(mod.isSporeField || mod.isIceField || mod.isFastDrones)
+ return mech.fieldUpgrades[mech.fieldMode].name === "nano-scale manufacturing" && !(mod.isSporeField || mod.isIceField || mod.isFastDrones || mod.isDroneGrab)
},
requires: "nano-scale manufacturing",
effect() {
@@ -2483,7 +2503,7 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
- return mech.fieldUpgrades[mech.fieldMode].name === "nano-scale manufacturing" && !(mod.isSporeField || mod.isMissileField || mod.isFastDrones)
+ return mech.fieldUpgrades[mech.fieldMode].name === "nano-scale manufacturing" && !(mod.isSporeField || mod.isMissileField || mod.isFastDrones || mod.isDroneGrab)
},
requires: "nano-scale manufacturing",
effect() {
@@ -2494,35 +2514,35 @@ const mod = {
}
},
{
- name: "superposition",
- description: "mobs that touch the phased player
are stunned for 5 seconds",
+ name: "phase decoherence",
+ description: "become intangible while cloaked
but, passing through mobs drains your energy",
maxCount: 1,
count: 0,
allowed() {
- return mech.fieldUpgrades[mech.fieldMode].name === "phase decoherence field"
+ return mech.fieldUpgrades[mech.fieldMode].name === "metamaterial cloaking"
},
- requires: "phase decoherence field",
+ requires: "metamaterial cloaking",
effect() {
- mod.superposition = true;
+ mod.isIntangible = true;
},
remove() {
- mod.superposition = false;
+ mod.isIntangible = false;
}
},
{
- name: "fracture analysis",
- description: "bullet impacts do 500% damage
to mobs that are unaware of you or stunned",
+ name: "flashbang",
+ description: "decloaking stuns nearby mobs for 2 second",
maxCount: 1,
count: 0,
allowed() {
- return mod.isStunField || mech.fieldUpgrades[mech.fieldMode].name === "phase decoherence field"
+ return mech.fieldUpgrades[mech.fieldMode].name === "metamaterial cloaking"
},
- requires: "phase decoherence field or flux pinning",
+ requires: "metamaterial cloaking",
effect() {
- mod.isCrit = true;
+ mod.isCloakStun = true;
},
remove() {
- mod.isCrit = false;
+ mod.isCloakStun = false;
}
},
{
@@ -2760,5 +2780,8 @@ const mod = {
isFreezeHarmImmune: null,
isSmallExplosion: null,
isExplosionHarm: null,
- isLaserHealth: null
+ armorFromPowerUps: null,
+ bonusHealth: null,
+ isIntangible: null,
+ isCloakStun: null
}
\ No newline at end of file
diff --git a/js/player.js b/js/player.js
index 70a1a5c..93eaf71 100644
--- a/js/player.js
+++ b/js/player.js
@@ -469,12 +469,19 @@ const mech = {
mech.displayHealth();
}
},
+ baseHealth: 1,
+ setMaxHealth() {
+ mech.maxHealth = mech.baseHealth + mod.bonusHealth + mod.armorFromPowerUps
+ if (mech.health > mech.maxHealth) mech.health = mech.maxHealth;
+ mech.displayHealth();
+ },
defaultFPSCycle: 0, //tracks when to return to normal fps
immuneCycle: 0, //used in engine
harmReduction() {
let dmg = 1
dmg *= mech.fieldHarmReduction
- dmg *= mod.isSlowFPS ? 0.85 : 1
+ if (mod.isSlowFPS) dmg *= 0.85
+ if (mod.isPiezo) dmg *= 0.85
if (mod.isHarmReduce && mech.fieldUpgrades[mech.fieldMode].name === "negative mass field" && mech.isFieldActive) dmg *= 0.6
if (mod.isBotArmor) dmg *= 0.95 ** mod.totalBots()
if (mod.isHarmArmor && mech.lastHarmCycle + 600 > mech.cycle) dmg *= 0.5;
@@ -487,7 +494,7 @@ const mech = {
}
return dmg
},
- damage(dmg, isShowRed = true) {
+ damage(dmg) {
mech.lastHarmCycle = mech.cycle
if (mod.isDroneOnDamage) { //chance to build a drone on damage from mod
const len = Math.min((dmg - 0.06 * Math.random()) * 40, 40)
@@ -552,10 +559,8 @@ const mech = {
}
}
mech.displayHealth();
- if (isShowRed) {
- document.getElementById("dmg").style.transition = "opacity 0s";
- document.getElementById("dmg").style.opacity = 0.1 + Math.min(0.6, dmg * 4);
- }
+ document.getElementById("dmg").style.transition = "opacity 0s";
+ document.getElementById("dmg").style.opacity = 0.1 + Math.min(0.6, dmg * 4);
}
if (dmg > 0.06 / mech.holdingMassScale) mech.drop(); //drop block if holding
@@ -583,7 +588,7 @@ const mech = {
}
}
} else {
- if (dmg > 0.05 && isShowRed) { // freeze game for high damage hits
+ if (dmg > 0.05) { // freeze game for high damage hits
game.fpsCap = 4 //40 - Math.min(25, 100 * dmg)
game.fpsInterval = 1000 / game.fpsCap;
} else {
@@ -702,7 +707,7 @@ const mech = {
index: 0
},
isHolding: false,
- isStealth: false,
+ isCloak: false,
throwCharge: 0,
fireCDcycle: 0,
fieldCDcycle: 0,
@@ -715,6 +720,7 @@ const mech = {
isFieldActive: false,
fieldRange: 155,
fieldShieldingScale: 1,
+ fieldDamage: 1,
energy: 0,
fieldRegen: 0,
fieldMode: 0,
@@ -734,11 +740,12 @@ const mech = {
mech.fieldBlockCD = 10;
game.isBodyDamage = true;
mech.fieldHarmReduction = 1;
+ mech.fieldDamage = 1
mech.grabPowerUpRange2 = 156000;
mech.fieldRange = 155;
mech.fieldFire = false;
mech.fieldCDcycle = 0;
- mech.isStealth = false;
+ mech.isCloak = false;
player.collisionFilter.mask = cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield
mech.airSpeedLimit = 125
mech.drop();
@@ -849,6 +856,7 @@ const mech = {
if (mech.holdingTarget) {
if (keys[32] || game.mouseDownRight) {
if (mech.energy > 0.001) {
+ mech.fireCDcycle = mech.cycle
mech.energy -= 0.001 / mod.throwChargeRate;
mech.throwCharge += 0.5 * mod.throwChargeRate / mech.holdingTarget.mass
//draw charge
@@ -1392,7 +1400,7 @@ const mech = {
},
{
name: "negative mass field",
- description: "use energy to nullify gravity
reduce harm by 45%
blocks held by the field have a lower mass",
+ description: "use energy to nullify gravity
reduce harm by 45%
blocks held by the field have a lower mass",
fieldDrawRadius: 0,
effect: () => {
mech.fieldFire = true;
@@ -1759,22 +1767,59 @@ const mech = {
}
},
{
- name: "phase decoherence field",
- description: "use energy to become intangible
firing and touching shields drains energy
unable to see and be seen by mobs",
+ name: "metamaterial cloaking", //"weak photonic coupling" "electromagnetically induced transparency" "optical non-coupling" "slow light field" "electro-optic transparency"
+ description: "cloak after not using your gun or field
while cloaked mobs can't see you
increase damage by 33%",
effect: () => {
mech.fieldFire = true;
mech.fieldMeterColor = "#fff";
mech.fieldPhase = 0;
+ mech.isCloak = false
+ mech.fieldDamage = 1.33
mech.hold = function () {
+ if (mech.isHolding) {
+ mech.drawHold(mech.holdingTarget);
+ mech.holding();
+ mech.throwBlock();
+ if (mech.fireCDcycle < mech.cycle) mech.fireCDcycle = mech.cycle //to disable cloak
+ } else if ((keys[32] || game.mouseDownRight && mech.fieldCDcycle < mech.cycle)) { //not hold and field button is pressed
+ mech.grabPowerUp();
+ mech.lookForPickUp();
+ if (mech.fireCDcycle < mech.cycle) mech.fireCDcycle = mech.cycle - 40 //to disable cloak
+ } else if (mech.holdingTarget && mech.fieldCDcycle < mech.cycle) { //holding target exists, and field button is not pressed
+ mech.pickUp();
+ } else {
+ mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
+ }
+
+ //120 cycles after shooting (or using field) enable cloak
+ if (mech.energy < 0.05 && mech.fireCDcycle < mech.cycle) mech.fireCDcycle = mech.cycle
+ if (mech.fireCDcycle + 50 < mech.cycle) {
+ if (!mech.isCloak) mech.isCloak = true
+ } else {
+ if (mech.isCloak) {
+ mech.isCloak = false
+ if (mod.isCloakStun) { //stun nearby mobs after exiting cloak
+ ctx.beginPath();
+ ctx.arc(mech.pos.x, mech.pos.y, 800, 0, 2 * Math.PI);
+ ctx.fillStyle = "#000"
+ ctx.fill();
+ for (let i = 0, len = mob.length; i < len; ++i) {
+ if (Vector.magnitude(Vector.sub(mob[i].position, mech.pos)) < 850) {
+ mobs.statusStun(mob[i], 120)
+ }
+ }
+ }
+ }
+ }
+
function drawField(radius) {
- radius *= Math.min(4, 0.9 + 2.2 * mech.energy * mech.energy);
- const rotate = mech.cycle * 0.005;
- mech.fieldPhase += 0.5 - 0.5 * Math.sqrt(Math.max(0.01, Math.min(mech.energy, 1)));
- const off1 = 1 + 0.06 * Math.sin(mech.fieldPhase);
- const off2 = 1 - 0.06 * Math.sin(mech.fieldPhase);
+ const energy = Math.max(0.01, Math.min(mech.energy, 1))
+ radius *= Math.min(1, 0.3 + 0.5 * Math.min(1, energy * energy));
+ mech.fieldPhase += 0.007 + 0.07 * (1 - energy)
+ const wiggle = 0.15 * Math.sin(mech.fieldPhase * 0.5)
ctx.beginPath();
- ctx.ellipse(mech.pos.x, mech.pos.y, radius * off1, radius * off2, rotate, 0, 2 * Math.PI);
+ ctx.ellipse(mech.pos.x, mech.pos.y, radius * (1 - wiggle), radius * (1 + wiggle), mech.fieldPhase, 0, 2 * Math.PI);
if (mech.fireCDcycle > mech.cycle && (keys[32] || game.mouseDownRight)) {
ctx.lineWidth = 5;
ctx.strokeStyle = `rgba(0, 204, 255,1)`
@@ -1787,94 +1832,36 @@ const mech = {
ctx.clip();
}
- mech.isStealth = false //isStealth disables most uses of foundPlayer()
- player.collisionFilter.mask = cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield //normal collisions
- if (mech.isHolding) {
- if (this.fieldRange < 2000) {
- this.fieldRange += 100
+ if (mech.isCloak) {
+ this.fieldRange = this.fieldRange * 0.9 + 0.1 * 800
+ drawField(this.fieldRange)
+ } else {
+ if (this.fieldRange < 3000) {
+ this.fieldRange += 200
drawField(this.fieldRange)
}
- mech.drawHold(mech.holdingTarget);
- mech.holding();
- mech.throwBlock();
- } else if (keys[32] || game.mouseDownRight) {
- mech.grabPowerUp();
- mech.lookForPickUp();
-
- if (mech.fieldCDcycle < mech.cycle) {
- // game.draw.bodyFill = "transparent"
- // game.draw.bodyStroke = "transparent"
-
- const DRAIN = 0.00013 + (mech.fireCDcycle > mech.cycle ? 0.005 : 0)
- if (mech.energy > DRAIN) {
- mech.energy -= DRAIN;
- // if (mech.energy < 0.001) {
- // mech.fieldCDcycle = mech.cycle + 120;
- // mech.energy = 0;
- // mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
- // }
- this.fieldRange = this.fieldRange * 0.8 + 0.2 * 160
- drawField(this.fieldRange)
-
- mech.isStealth = true //isStealth disables most uses of foundPlayer()
- player.collisionFilter.mask = cat.map
-
-
- let inPlayer = Matter.Query.region(mob, player.bounds)
- if (inPlayer.length > 0) {
- for (let i = 0; i < inPlayer.length; i++) {
- if (inPlayer[i].shield) {
- mech.energy -= 0.005; //shields drain player energy
- //draw outline of shield
- ctx.fillStyle = `rgba(140,217,255,0.5)`
- ctx.fill()
- } else if (mod.superposition && inPlayer[i].dropPowerUp) {
- // inPlayer[i].damage(0.4 * b.dmgScale); //damage mobs inside the player
- // mech.energy += 0.005;
-
- mobs.statusStun(inPlayer[i], 300)
- //draw outline of mob in a few random locations to show blurriness
- const vertices = inPlayer[i].vertices;
- const off = 30
- for (let k = 0; k < 3; k++) {
- const xOff = off * (Math.random() - 0.5)
- const yOff = off * (Math.random() - 0.5)
- ctx.beginPath();
- ctx.moveTo(xOff + vertices[0].x, yOff + vertices[0].y);
- for (let j = 1, len = vertices.length; j < len; ++j) {
- 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.1)"
- ctx.fill()
- }
- break;
+ }
+ if (mod.isIntangible) {
+ if (mech.isCloak) {
+ player.collisionFilter.mask = cat.map
+ let inPlayer = Matter.Query.region(mob, player.bounds)
+ if (inPlayer.length > 0) {
+ for (let i = 0; i < inPlayer.length; i++) {
+ if (mech.energy > 0) {
+ if (inPlayer[i].shield) { //shields drain player energy
+ mech.energy -= 0.02;
+ } else {
+ mech.energy -= 0.007;
}
}
}
- } else {
- mech.fieldCDcycle = mech.cycle + 120;
- mech.energy = 0;
- mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
- drawField(this.fieldRange)
}
+ } else {
+ player.collisionFilter.mask = cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield //normal collisions
}
- } else if (mech.holdingTarget && mech.fieldCDcycle < mech.cycle) { //holding, but field button is released
- mech.pickUp();
- if (this.fieldRange < 2000) {
- this.fieldRange += 100
- drawField(this.fieldRange)
- }
- } else {
- // this.fieldRange = 3000
- if (this.fieldRange < 2000 && mech.holdingTarget === null) {
- this.fieldRange += 100
- drawField(this.fieldRange)
- }
- mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
}
- if (mech.energy < mech.maxEnergy) {
+ if (mech.energy < mech.maxEnergy) { // replaces mech.drawFieldMeter() with custom code
mech.energy += mech.fieldRegen;
const xOff = mech.pos.x - mech.radius * mech.maxEnergy
const yOff = mech.pos.y - 50
@@ -1888,10 +1875,143 @@ const mech = {
ctx.lineWidth = 1;
ctx.stroke();
}
- if (mech.energy < 0) mech.energy = 0
}
}
},
+ // {
+ // name: "phase decoherence field",
+ // description: "use energy to become intangible
firing and touching shields drains energy
unable to see and be seen by mobs",
+ // effect: () => {
+ // mech.fieldFire = true;
+ // mech.fieldMeterColor = "#fff";
+ // mech.fieldPhase = 0;
+
+ // mech.hold = function () {
+ // function drawField(radius) {
+ // radius *= Math.min(4, 0.9 + 2.2 * mech.energy * mech.energy);
+ // const rotate = mech.cycle * 0.005;
+ // mech.fieldPhase += 0.5 - 0.5 * Math.sqrt(Math.max(0.01, Math.min(mech.energy, 1)));
+ // const off1 = 1 + 0.06 * Math.sin(mech.fieldPhase);
+ // const off2 = 1 - 0.06 * Math.sin(mech.fieldPhase);
+ // ctx.beginPath();
+ // ctx.ellipse(mech.pos.x, mech.pos.y, radius * off1, radius * off2, rotate, 0, 2 * Math.PI);
+ // if (mech.fireCDcycle > mech.cycle && (keys[32] || game.mouseDownRight)) {
+ // ctx.lineWidth = 5;
+ // ctx.strokeStyle = `rgba(0, 204, 255,1)`
+ // ctx.stroke()
+ // }
+ // ctx.fillStyle = "#fff" //`rgba(0,0,0,${0.5+0.5*mech.energy})`;
+ // ctx.globalCompositeOperation = "destination-in"; //in or atop
+ // ctx.fill();
+ // ctx.globalCompositeOperation = "source-over";
+ // ctx.clip();
+ // }
+
+ // mech.isCloak = false //isCloak disables most uses of foundPlayer()
+ // player.collisionFilter.mask = cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield //normal collisions
+ // if (mech.isHolding) {
+ // if (this.fieldRange < 2000) {
+ // this.fieldRange += 100
+ // drawField(this.fieldRange)
+ // }
+ // mech.drawHold(mech.holdingTarget);
+ // mech.holding();
+ // mech.throwBlock();
+ // } else if (keys[32] || game.mouseDownRight) {
+ // mech.grabPowerUp();
+ // mech.lookForPickUp();
+
+ // if (mech.fieldCDcycle < mech.cycle) {
+ // // game.draw.bodyFill = "transparent"
+ // // game.draw.bodyStroke = "transparent"
+
+ // const DRAIN = 0.00013 + (mech.fireCDcycle > mech.cycle ? 0.005 : 0)
+ // if (mech.energy > DRAIN) {
+ // mech.energy -= DRAIN;
+ // // if (mech.energy < 0.001) {
+ // // mech.fieldCDcycle = mech.cycle + 120;
+ // // mech.energy = 0;
+ // // mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
+ // // }
+ // this.fieldRange = this.fieldRange * 0.8 + 0.2 * 160
+ // drawField(this.fieldRange)
+
+ // mech.isCloak = true //isCloak disables most uses of foundPlayer()
+ // player.collisionFilter.mask = cat.map
+
+
+ // let inPlayer = Matter.Query.region(mob, player.bounds)
+ // if (inPlayer.length > 0) {
+ // for (let i = 0; i < inPlayer.length; i++) {
+ // if (inPlayer[i].shield) {
+ // mech.energy -= 0.005; //shields drain player energy
+ // //draw outline of shield
+ // ctx.fillStyle = `rgba(140,217,255,0.5)`
+ // ctx.fill()
+ // } else if (mod.superposition && inPlayer[i].dropPowerUp) {
+ // // inPlayer[i].damage(0.4 * b.dmgScale); //damage mobs inside the player
+ // // mech.energy += 0.005;
+
+ // mobs.statusStun(inPlayer[i], 300)
+ // //draw outline of mob in a few random locations to show blurriness
+ // const vertices = inPlayer[i].vertices;
+ // const off = 30
+ // for (let k = 0; k < 3; k++) {
+ // const xOff = off * (Math.random() - 0.5)
+ // const yOff = off * (Math.random() - 0.5)
+ // ctx.beginPath();
+ // ctx.moveTo(xOff + vertices[0].x, yOff + vertices[0].y);
+ // for (let j = 1, len = vertices.length; j < len; ++j) {
+ // 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.1)"
+ // ctx.fill()
+ // }
+ // break;
+ // }
+ // }
+ // }
+ // } else {
+ // mech.fieldCDcycle = mech.cycle + 120;
+ // mech.energy = 0;
+ // mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
+ // drawField(this.fieldRange)
+ // }
+ // }
+ // } else if (mech.holdingTarget && mech.fieldCDcycle < mech.cycle) { //holding, but field button is released
+ // mech.pickUp();
+ // if (this.fieldRange < 2000) {
+ // this.fieldRange += 100
+ // drawField(this.fieldRange)
+ // }
+ // } else {
+ // // this.fieldRange = 3000
+ // if (this.fieldRange < 2000 && mech.holdingTarget === null) {
+ // this.fieldRange += 100
+ // drawField(this.fieldRange)
+ // }
+ // mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
+ // }
+
+ // if (mech.energy < mech.maxEnergy) {
+ // mech.energy += mech.fieldRegen;
+ // const xOff = mech.pos.x - mech.radius * mech.maxEnergy
+ // const yOff = mech.pos.y - 50
+ // ctx.fillStyle = "rgba(0, 0, 0, 0.3)";
+ // ctx.fillRect(xOff, yOff, 60 * mech.maxEnergy, 10);
+ // ctx.fillStyle = mech.fieldMeterColor;
+ // ctx.fillRect(xOff, yOff, 60 * mech.energy, 10);
+ // ctx.beginPath()
+ // ctx.rect(xOff, yOff, 60 * mech.maxEnergy, 10);
+ // ctx.strokeStyle = "rgb(0, 0, 0)";
+ // ctx.lineWidth = 1;
+ // ctx.stroke();
+ // }
+ // if (mech.energy < 0) mech.energy = 0
+ // }
+ // }
+ // },
{
name: "pilot wave",
description: "use energy to push blocks with your mouse
field radius decreases out of line of sight",
diff --git a/js/spawn.js b/js/spawn.js
index e9faf2a..8d154d5 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -245,7 +245,7 @@ const spawn = {
powerUps.spawnBossPowerUp(me.position.x, me.position.y)
powerUps.spawn(me.position.x, me.position.y, "heal");
powerUps.spawn(me.position.x, me.position.y, "ammo");
- } else if (!mech.isStealth) {
+ } else if (!mech.isCloak) {
me.foundPlayer();
}
@@ -578,7 +578,7 @@ const spawn = {
//when player is inside event horizon
if (Vector.magnitude(Vector.sub(this.position, player.position)) < eventHorizon) {
- mech.energy -= 0.004
+ if (mech.energy > 0) mech.energy -= 0.004
if (mech.energy < 0.1) {
mech.damage(0.00015 * game.dmgScale);
}
@@ -677,7 +677,7 @@ const spawn = {
ctx.fill();
//when player is inside event horizon
if (Vector.magnitude(Vector.sub(this.position, player.position)) < eventHorizon) {
- mech.energy -= 0.006
+ if (mech.energy > 0) mech.energy -= 0.006
if (mech.energy < 0.1) {
mech.damage(0.0002 * game.dmgScale);
}
@@ -727,6 +727,7 @@ const spawn = {
damping: springDampening
});
cons[len].length = 100 + 1.5 * radius;
+
me.cons = cons[len];
me.springTarget2 = {
@@ -780,7 +781,7 @@ const spawn = {
stiffness: attachmentStiffness,
damping: 0.01
});
- // console.log(consBB[consBB.length - 1])
+ World.add(engine.world, consBB[consBB.length - 1]);
}
},
timeSkipBoss(x, y, radius = 55) {
@@ -1061,7 +1062,7 @@ const spawn = {
};
vertexCollision(this.position, look, map);
vertexCollision(this.position, look, body);
- if (!mech.isStealth) vertexCollision(this.position, look, [player]);
+ if (!mech.isCloak) vertexCollision(this.position, look, [player]);
// hitting player
if (best.who === player) {
if (mech.immuneCycle < mech.cycle) {
@@ -1217,7 +1218,7 @@ const spawn = {
// vertexCollision(where, look, mob);
vertexCollision(where, look, map);
vertexCollision(where, look, body);
- if (!mech.isStealth) vertexCollision(where, look, [player]);
+ if (!mech.isCloak) vertexCollision(where, look, [player]);
if (best.who && best.who === player && mech.immuneCycle < mech.cycle) {
mech.immuneCycle = mech.cycle + mod.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
const dmg = 0.14 * game.dmgScale;
@@ -1336,7 +1337,7 @@ const spawn = {
this.distanceToPlayer2() < this.seeAtDistance2 &&
Matter.Query.ray(map, this.position, this.mechPosRange()).length === 0 &&
Matter.Query.ray(body, this.position, this.mechPosRange()).length === 0 &&
- !mech.isStealth
+ !mech.isCloak
) {
this.foundPlayer();
if (this.cd === Infinity) this.cd = game.cycle + this.delay * 0.7;
@@ -1447,7 +1448,7 @@ const spawn = {
if (this.alpha > 0) this.alpha -= 0.03;
}
if (this.alpha > 0) {
- if (this.alpha > 0.9) {
+ if (this.alpha > 0.9 && this.seePlayer.recall) {
this.healthBar();
if (!this.canTouchPlayer) {
this.canTouchPlayer = true;
@@ -2008,16 +2009,19 @@ const spawn = {
bodyB: mob[mob.length - 1 - nodes],
stiffness: 0.05
});
+ World.add(engine.world, consBB[consBB.length - 1]);
consBB[consBB.length] = Constraint.create({
bodyA: mob[mob.length - nodes + 1],
bodyB: mob[mob.length - 1 - nodes],
stiffness: 0.05
});
+ World.add(engine.world, consBB[consBB.length - 1]);
consBB[consBB.length] = Constraint.create({
bodyA: mob[mob.length - nodes + 2],
bodyB: mob[mob.length - 1 - nodes],
stiffness: 0.05
});
+ World.add(engine.world, consBB[consBB.length - 1]);
},
tetherBoss(x, y, radius = 90) {
@@ -2057,6 +2061,8 @@ const spawn = {
stiffness: 0.4,
damping: 0.1
});
+ World.add(engine.world, consBB[consBB.length - 1]);
+
me.onDamage = function () {
//make sure the mob that owns the shield can tell when damage is done
this.alertNearByMobs();
@@ -2101,6 +2107,7 @@ const spawn = {
stiffness: stiffness,
damping: 0.1
});
+ World.add(engine.world, consBB[consBB.length - 1]);
}
me.onDamage = function () {
this.alertNearByMobs(); //makes sure the mob that owns the shield can tell when damage is done
@@ -2220,6 +2227,7 @@ const spawn = {
bodyB: mob[mob.length - j],
stiffness: stiffness
});
+ World.add(engine.world, consBB[consBB.length - 1]);
}
}
},
@@ -2231,6 +2239,7 @@ const spawn = {
bodyB: mob[mob.length - i - 2],
stiffness: stiffness
});
+ World.add(engine.world, consBB[consBB.length - 1]);
}
if (nodes > 2) {
for (let i = 0; i < nodes - 2; ++i) {
@@ -2239,6 +2248,7 @@ const spawn = {
bodyB: mob[mob.length - i - 3],
stiffness: stiffness
});
+ World.add(engine.world, consBB[consBB.length - 1]);
}
}
//optional connect the tail to head
@@ -2248,16 +2258,19 @@ const spawn = {
bodyB: mob[mob.length - nodes],
stiffness: stiffness
});
+ World.add(engine.world, consBB[consBB.length - 1]);
consBB[consBB.length] = Constraint.create({
bodyA: mob[mob.length - 2],
bodyB: mob[mob.length - nodes],
stiffness: stiffness
});
+ World.add(engine.world, consBB[consBB.length - 1]);
consBB[consBB.length] = Constraint.create({
bodyA: mob[mob.length - 1],
bodyB: mob[mob.length - nodes + 1],
stiffness: stiffness
});
+ World.add(engine.world, consBB[consBB.length - 1]);
}
},
constraintPB(x, y, bodyIndex, stiffness) {
@@ -2269,6 +2282,7 @@ const spawn = {
bodyB: body[bodyIndex],
stiffness: stiffness
});
+ World.add(engine.world, cons[cons.length - 1]);
},
constraintBB(bodyIndexA, bodyIndexB, stiffness) {
consBB[consBB.length] = Constraint.create({
@@ -2276,6 +2290,7 @@ const spawn = {
bodyB: body[bodyIndexB],
stiffness: stiffness
});
+ World.add(engine.world, consBB[consBB.length - 1]);
},
// body and map spawns ******************************************************************************
//**********************************************************************************************
diff --git a/style.css b/style.css
index 0047fd7..56f5f00 100644
--- a/style.css
+++ b/style.css
@@ -464,6 +464,11 @@ em {
letter-spacing: 1px;
}
+.color-cloaked {
+ opacity: 0.25;
+ letter-spacing: 1px;
+}
+
.color-harm {
/* color: */
/* text-shadow: #FC0 1px 0 10px; */
diff --git a/todo.txt b/todo.txt
index e9e297c..ae4be41 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,19 +1,47 @@
-mod: electric reactive armor - reduce harm from explosions by 6% for every 10 energy
-mod: waste heat recovery - laser damage grows to 400%, but you start to eject your health as a heal power up
-new community level by Francois: house
************** TODO - n-gon **************
+mod - mines stun targets nearby when they explode
+
+cloaking field mods
+ larger vision
+ return to stealth faster
+ +damage to nearby mobs
+ +damage to unaware mobs (code for this doesn't seem to work)
+
+mod - negative mass field intangibility
+ doesn't seem that interesting
+
+mod - do something for 2 seconds after firing
+ if (mech.fireCDcycle + 120)
+
+getting stuck above a mob can immobilize player
+ occurs with Pauli exclusion, and time dilation field immunity - mod time-like world line
+ add a knock to player mob collisions even while player is immune to damage
+ keep the knock very small
+
+Health mod idea: health can go above max health. At the end of each level, the amount of health above max is halved.
+
+general idea: shrink mech.baseHealth in a mod or field
+
+mod: some drones(or spores) have a chance to spawn as a more power full version
+ do electric damage to nearby mobs
+ stun effect?
+
a bot that eats up health and ammo, but poops a reroll after picking up 2 power ups
it passes through walls
moves slower then the player so you can get to it before the bot if you hurry
4 rerolls can convert to a bot, also 1 rerolls can convert to 5% damage
the mods that do those effects could be required before you see this bot
disable crystalized armor?
+ could convert rerolls, ammo, and health into mods instead
laser-bot orbits player
+bot that does AOE damage while it rotates around player
+ no physics / collisions
+ cap 3 ?
mod: radiation effects can spread to nearby mobs
@@ -43,23 +71,11 @@ new gun or field - fire 3+ balls in arc
hold fire to charge: increases the size of the balls
mod: balls are attracted to mobs
-fix: even with a scroll bar the top of the selection window is off screen for very short windows
-
rework perfect diamagnetism
let the shield also do bremsstrahlung radiation
- mod: grab and launch mobs?
-
-getting stuck above a mob can immobilize player
- seems to only occur with Pauli exclusion
- add a knock to player mob collisions even while player is immune to damage
- keep the knock very small
map element - player rotates a rotor that makes a platform go up or down
-removing supersaturation sets total health to 1
- this cancels the health benefits from crystallized armor
- produce a method that calculates max health based on mods
-
use mac automator to speed up your n-gon -> git sync
fix door.isOpen actually meaning isClosed
@@ -68,10 +84,6 @@ mod - laser fires 3 beams
give missiles a suck and delay explosion, like vacuum bomb
-bot that does AOE damage while it rotates around player
- no physics / collisions
- cap 3 ?
-
level Boss: fractal SierpiĆski triangle
https://en.wikipedia.org/wiki/Sierpi%C5%84ski_triangle
spawns a 1/2 size version of the boss, this version can also spawn a smaller version, but it is capped at some size level
@@ -151,9 +163,6 @@ mod - do 50% more damage in close, but 50% less at a distance
code it like mod.isFarAwayDmg
have these mods disable each other
-phase field still isn't fun
- does phase field need the stealth flag?
-
mod harmonic shield: slow everything in range around shield (temporal shield)
set max speed?