cloaking field

mod: waste heat recovery is removed
mod - fracture analysis only applies to stunned mobs (not unaware mobs)

phase field is removed
new field: metamaterial cloaking
mod: phase decoherence - intangible to mobs while cloaked, but passing through mobs drains energy
mod: flashbang - stun mobs as you exit cloak
This commit is contained in:
landgreen
2020-09-19 09:11:55 -07:00
parent 2e7016d3d6
commit f334372281
10 changed files with 454 additions and 267 deletions

View File

@@ -770,11 +770,11 @@ const b = {
powerUp.splice(i, 1); powerUp.splice(i, 1);
if (mod.isDroneGrab) { if (mod.isDroneGrab) {
this.isImproved = true; this.isImproved = true;
const SCALE = 2 const SCALE = 3.5
Matter.Body.scale(this, SCALE, SCALE); Matter.Body.scale(this, SCALE, SCALE);
this.lookFrequency = 30; this.lookFrequency = 30;
this.endCycle = Infinity this.endCycle += 2000
this.dmg *= 1.5; // this.dmg *= 1.25;
this.frictionAir = 0 this.frictionAir = 0
} }
break; break;
@@ -1061,7 +1061,7 @@ const b = {
}, },
onEnd() {}, onEnd() {},
do() { do() {
if (this.lastLookCycle < game.cycle) { if (this.lastLookCycle < game.cycle && !mech.isCloak) {
this.lastLookCycle = game.cycle + 80 - this.isUpgraded * 50 this.lastLookCycle = game.cycle + 80 - this.isUpgraded * 50
let target let target
for (let i = 0, len = mob.length; i < len; i++) { for (let i = 0, len = mob.length; i < len; i++) {
@@ -1117,7 +1117,7 @@ const b = {
}, },
onEnd() {}, onEnd() {},
do() { 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 let target
for (let i = 0, len = mob.length; i < len; i++) { for (let i = 0, len = mob.length; i < len; i++) {
const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)); const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position));
@@ -1186,7 +1186,7 @@ const b = {
y: this.velocity.y * 0.95 y: this.velocity.y * 0.95
}); });
//find targets //find targets
if (!(game.cycle % this.lookFrequency) && !mech.isStealth) { if (!(game.cycle % this.lookFrequency) && !mech.isCloak) {
this.lockedOn = null; this.lockedOn = null;
let closeDist = this.range; let closeDist = this.range;
for (let i = 0, len = mob.length; i < len; ++i) { for (let i = 0, len = mob.length; i < len; ++i) {
@@ -1301,7 +1301,7 @@ const b = {
} else if (distanceToPlayer < 250) { //close to player } 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 Matter.Body.setVelocity(this, Vector.add(Vector.mult(this.velocity, 0.90), Vector.mult(player.velocity, 0.17))); //add player's velocity
//find targets //find targets
if (!(game.cycle % this.lookFrequency) && !mech.isStealth) { if (!(game.cycle % this.lookFrequency) && !mech.isCloak) {
this.lockedOn = null; this.lockedOn = null;
let closeDist = this.range; let closeDist = this.range;
for (let i = 0, len = mob.length; i < len; ++i) { for (let i = 0, len = mob.length; i < len; ++i) {
@@ -1382,7 +1382,6 @@ const b = {
const unit = Vector.normalise(sub) const unit = Vector.normalise(sub)
const DRAIN = 0.002 const DRAIN = 0.002
if (DIST < mod.isPlasmaRange * 500 && mech.energy > DRAIN) { if (DIST < mod.isPlasmaRange * 500 && mech.energy > DRAIN) {
console.log('fire')
mech.energy -= DRAIN; mech.energy -= DRAIN;
if (mech.energy < 0) { if (mech.energy < 0) {
mech.fieldCDcycle = mech.cycle + 120; mech.fieldCDcycle = mech.cycle + 120;
@@ -1788,7 +1787,7 @@ const b = {
} }
if (!immune) { if (!immune) {
this.immuneList.push(who.id) this.immuneList.push(who.id)
if (!mech.isStealth) who.foundPlayer(); who.foundPlayer();
if (mod.isFastDot) { if (mod.isFastDot) {
mobs.statusDoT(who, 3.9, 30) mobs.statusDoT(who, 3.9, 30)
} else { } else {
@@ -1804,7 +1803,7 @@ const b = {
} }
} else { } else {
this.endCycle = 0; this.endCycle = 0;
if (!mech.isStealth) who.foundPlayer(); who.foundPlayer();
if (mod.isFastDot) { if (mod.isFastDot) {
mobs.statusDoT(who, 3.78, 30) mobs.statusDoT(who, 3.78, 30)
} else { } else {
@@ -1903,7 +1902,7 @@ const b = {
for (let i = 0; i < q.length; i++) { 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 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); q[i].damage(dmg);
if (!mech.isStealth) q[i].foundPlayer(); q[i].foundPlayer();
game.drawList.push({ //add dmg to draw queue game.drawList.push({ //add dmg to draw queue
x: this.position.x, x: this.position.x,
y: this.position.y, 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 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 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); q[i].damage(dmg);
if (!mech.isStealth) q[i].foundPlayer(); q[i].foundPlayer();
game.drawList.push({ //add dmg to draw queue game.drawList.push({ //add dmg to draw queue
x: this.position.x, x: this.position.x,
y: this.position.y, 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 nextFireCycle: 0, //use to remember how longs its been since last fire, used to reset count
holdDamage: 1, holdDamage: 1,
holdCount: 0, holdCount: 0,
healthLost: 0,
fire() { fire() {
if (mod.isLaserHealth) { mech.fireCDcycle = mech.cycle
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
}
const reflectivity = 1 - 1 / (mod.laserReflections * 1.5) const reflectivity = 1 - 1 / (mod.laserReflections * 1.5)
let damage = b.dmgScale * mod.laserDamage * this.holdDamage let damage = b.dmgScale * mod.laserDamage * this.holdDamage

View File

@@ -143,10 +143,7 @@ function collisionChecks(event) {
mech.immuneCycle = mech.cycle + mod.collisionImmuneCycles; //player is immune to collision damage for 30 cycles mech.immuneCycle = mech.cycle + mod.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
mob[k].foundPlayer(); 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 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) { if (mod.isPiezo) mech.energy = mech.maxEnergy;
mech.energy = mech.maxEnergy;
dmg *= 0.85
}
mech.damage(dmg); mech.damage(dmg);
if (mod.isBayesian) { if (mod.isBayesian) {
const have = [] //find which mods you have const have = [] //find which mods you have
@@ -203,8 +200,9 @@ function collisionChecks(event) {
//mob + bullet collisions //mob + bullet collisions
if (obj.classType === "bullet" && obj.speed > obj.minDmgSpeed) { 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))) 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 // console.log(mob[k].seePlayer.recall)
if (!mech.isStealth) mob[k].foundPlayer(); if (mod.isCrit && mob[k].isStunned) dmg *= 5
mob[k].foundPlayer();
mob[k].damage(dmg); 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 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 game.drawList.push({ //add dmg to draw queue
@@ -225,7 +223,7 @@ function collisionChecks(event) {
mob[k].damage(dmg, true); mob[k].damage(dmg, true);
const stunTime = dmg / Math.sqrt(obj.mass) const stunTime = dmg / Math.sqrt(obj.mass)
if (stunTime > 0.5) mobs.statusStun(mob[k], 30 + 60 * Math.sqrt(stunTime)) 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({ game.drawList.push({
x: pairs[i].activeContacts[0].vertex.x, x: pairs[i].activeContacts[0].vertex.x,
y: pairs[i].activeContacts[0].vertex.y, y: pairs[i].activeContacts[0].vertex.y,

View File

@@ -476,9 +476,7 @@ const game = {
powerUps.directSpawn(game.mouseInGame.x, game.mouseInGame.y, "mod"); powerUps.directSpawn(game.mouseInGame.x, game.mouseInGame.y, "mod");
} else if (keys[54]) { // 6 spawn mob } else if (keys[54]) { // 6 spawn mob
const pick = spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]; const pick = spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)];
spawn.allowShields = false;
spawn[pick](game.mouseInGame.x, game.mouseInGame.y); spawn[pick](game.mouseInGame.x, game.mouseInGame.y);
spawn.allowShields = true;
} else if (keys[55]) { // 7 spawn body } else if (keys[55]) { // 7 spawn body
index = body.length index = body.length
spawn.bodyRect(game.mouseInGame.x, game.mouseInGame.y, 50, 50); spawn.bodyRect(game.mouseInGame.x, game.mouseInGame.y, 50, 50);
@@ -712,8 +710,8 @@ const game = {
if (game.isCommunityMaps) { if (game.isCommunityMaps) {
level.levels.push("stronghold"); level.levels.push("stronghold");
level.levels.push("basement"); level.levels.push("basement");
level.levels.push("newLevel");
level.levels.push("house"); level.levels.push("house");
// level.levels.push("newLevel");
} }
level.levels = shuffle(level.levels); //shuffles order of maps level.levels = shuffle(level.levels); //shuffles order of maps
level.levels.unshift("bosses"); //add bosses level to the end of the randomized levels list level.levels.unshift("bosses"); //add bosses level to the end of the randomized levels list

View File

@@ -14,10 +14,10 @@ const level = {
// game.enableConstructMode() //used to build maps in testing mode // game.enableConstructMode() //used to build maps in testing mode
// game.zoomScale = 1000; // game.zoomScale = 1000;
// game.setZoom(); // game.setZoom();
// mech.isStealth = true; // mech.isCloak = true;
// mech.setField("pilot wave") // mech.setField("metamaterial cloaking")
// b.giveGuns("ice IX") // b.giveGuns("laser")
// mod.giveMod("quantum immortality"); // mod.giveMod("phase decoherence");
level.intro(); //starting level level.intro(); //starting level
// level.testing(); //not in rotation // level.testing(); //not in rotation
@@ -53,13 +53,14 @@ const level = {
game.draw.setPaths(); game.draw.setPaths();
b.respawnBots(); b.respawnBots();
if (mod.isArmorFromPowerUps) { if (mod.isArmorFromPowerUps) {
mech.maxHealth += 0.05 * powerUps.totalPowerUps mod.armorFromPowerUps += 0.05 * powerUps.totalPowerUps
mech.setMaxHealth();
if (powerUps.totalPowerUps) game.makeTextLog("<span style='font-size:115%;'> max health increased by " + (0.05 * powerUps.totalPowerUps * 100).toFixed(0) + "%</span>", 300) if (powerUps.totalPowerUps) game.makeTextLog("<span style='font-size:115%;'> max health increased by " + (0.05 * powerUps.totalPowerUps * 100).toFixed(0) + "%</span>", 300)
} }
if (mod.isHealLowHealth) { if (mod.isHealLowHealth) {
const len = Math.floor((mech.maxHealth - mech.health) / 0.5) const len = Math.floor((mech.maxHealth - mech.health) / 0.5)
for (let i = 0; i < len; i++) { 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) { if (mod.isGunCycle) {
@@ -142,7 +143,7 @@ const level = {
// spawn.sniper(1800, -120) // spawn.sniper(1800, -120)
// spawn.sniper(2200, -120) // spawn.sniper(2200, -120)
// spawn.cellBossCulture(1600, -500) // spawn.cellBossCulture(1600, -500)
// spawn.starter(1600, -500, 60) spawn.starter(1600, -500, 60)
// spawn.powerUpBoss(1600, -500) // spawn.powerUpBoss(1600, -500)
// spawn.shield(mob[mob.length - 1], 1200, -500, 1); // spawn.shield(mob[mob.length - 1], 1200, -500, 1);
@@ -221,8 +222,8 @@ const level = {
y: -600 y: -600
}, -2 * Math.PI / 3) //up left }, -2 * Math.PI / 3) //up left
const hazard = level.hazard(350, -2025, 700, 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%)") //laser const hazard2 = level.hazard(1775, -2550, 150, 10, 0.4, "hsl(0, 100%, 50%)", true) //laser
const button = level.button(2100, -2600) const button = level.button(2100, -2600)
@@ -1484,6 +1485,8 @@ const level = {
bodyB: mob[mob.length - 1], bodyB: mob[mob.length - 1],
stiffness: 0.00007 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 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) { } else if (Math.random() < 0.15) {
spawn.randomLevelBoss(4250, -250); spawn.randomLevelBoss(4250, -250);
@@ -1699,6 +1702,37 @@ const level = {
height: 275, height: 275,
color: "#cff" 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 //foreground
level.fill.push({ level.fill.push({
x: -1650, x: -1650,
@@ -1709,11 +1743,12 @@ const level = {
}); });
level.fill.push({ level.fill.push({
x: -2600, x: -2600,
y: -2400, y: -1675,
width: 450, width: 450,
height: 1800, height: 1125,
color: "rgba(0,0,0,0.12)" color: "rgba(0,0,0,0.12)"
}); });
level.fill.push({ level.fill.push({
x: -3425, x: -3425,
y: -2150, y: -2150,
@@ -1781,7 +1816,7 @@ const level = {
spawn.mapRect(-3450, -1325, 550, 50); spawn.mapRect(-3450, -1325, 550, 50);
spawn.mapRect(-3425, -2200, 525, 50); spawn.mapRect(-3425, -2200, 525, 50);
spawn.mapRect(-2600, -1700, 450, 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(-2275, -2700, 50, 60);
spawn.bodyRect(-2600, -1925, 250, 225); spawn.bodyRect(-2600, -1925, 250, 225);
spawn.bodyRect(-3415, -1425, 100, 100); spawn.bodyRect(-3415, -1425, 100, 100);
@@ -1799,6 +1834,7 @@ const level = {
spawn.bodyRect(-3080, -2250, 40, 40); spawn.bodyRect(-3080, -2250, 40, 40);
spawn.bodyRect(-3420, -650, 50, 50); spawn.bodyRect(-3420, -650, 50, 50);
//exit //exit
spawn.mapRect(-4450, -3075, 25, 300); spawn.mapRect(-4450, -3075, 25, 300);
spawn.mapRect(-4450, -3075, 450, 25); spawn.mapRect(-4450, -3075, 450, 25);
@@ -1831,7 +1867,8 @@ const level = {
spawn.randomMob(-550, -100, -0.1); spawn.randomMob(-550, -100, -0.1);
spawn.randomBoss(-3250, -2700, 0.2); spawn.randomBoss(-3250, -2700, 0.2);
spawn.randomBoss(-2450, -1100, 0); 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 powerUps.addRerollToLevel() //needs to run after mobs are spawned
}, },
warehouse() { warehouse() {
@@ -1930,6 +1967,7 @@ const level = {
stiffness: 0.0001815, stiffness: 0.0001815,
length: 1 length: 1
}); });
World.add(engine.world, cons[cons.length - 1]);
spawn.bodyRect(600, 525, 125, 125, 1, spawn.propsSlide); //weight spawn.bodyRect(600, 525, 125, 125, 1, spawn.propsSlide); //weight
spawn.bodyRect(800, 600, 300, 100, 1, spawn.propsHoist); //hoist spawn.bodyRect(800, 600, 300, 100, 1, spawn.propsHoist); //hoist
@@ -1942,6 +1980,7 @@ const level = {
stiffness: 0.0001815, stiffness: 0.0001815,
length: 1 length: 1
}); });
World.add(engine.world, cons[cons.length - 1]);
spawn.bodyRect(-2700, 1150, 100, 160, 1, spawn.propsSlide); //weight spawn.bodyRect(-2700, 1150, 100, 160, 1, spawn.propsSlide); //weight
spawn.bodyRect(-2550, 1150, 200, 100, 1, spawn.propsSlide); //weight spawn.bodyRect(-2550, 1150, 200, 100, 1, spawn.propsSlide); //weight
@@ -1955,6 +1994,7 @@ const level = {
stiffness: 0.0005, stiffness: 0.0005,
length: 566 length: 566
}); });
World.add(engine.world, cons[cons.length - 1]);
//blocks //blocks
spawn.bodyRect(-165, -150, 30, 35, 1); spawn.bodyRect(-165, -150, 30, 35, 1);
@@ -2130,6 +2170,7 @@ const level = {
bodyB: map[map.length - 1], bodyB: map[map.length - 1],
stiffness: 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 + 300, -2000 * 0.75, 1900, 50); //3rd floor
spawn.mapRect(-600 + 2000 * 0.7, -2000 * 0.74, 50, 375); //center wall 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 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], bodyB: mob[mob.length - 1],
stiffness: 0.00012 stiffness: 0.00012
}); });
World.add(engine.world, cons[cons.length - 1]);
//chance to spawn a ring of exploding mobs around this boss //chance to spawn a ring of exploding mobs around this boss
if (game.difficulty > 6) spawn.nodeBoss(2850, -80, "spawns", 8, 20, 105); if (game.difficulty > 6) spawn.nodeBoss(2850, -80, "spawns", 8, 20, 105);
} else { } else {
@@ -2356,6 +2398,7 @@ const level = {
stiffness: 0.0002, //1217, stiffness: 0.0002, //1217,
length: 200 length: 200
}); });
World.add(engine.world, cons[cons.length - 1]);
spawn.bodyRect(2799, -870, 310, 290); //Gros bloc angle toit spawn.bodyRect(2799, -870, 310, 290); //Gros bloc angle toit
spawn.mapRect(4000, -1750, 50, 400); //Right Wall Cuve spawn.mapRect(4000, -1750, 50, 400); //Right Wall Cuve
@@ -2406,7 +2449,7 @@ const level = {
bodyB: map[map.length - 1], bodyB: map[map.length - 1],
stiffness: 1 stiffness: 1
}); });
World.add(engine.world, consBB[consBB.length - 1]);
spawn.bodyRect(650, 50, 70, 50); spawn.bodyRect(650, 50, 70, 50);
spawn.bodyRect(300, 0, 100, 60); spawn.bodyRect(300, 0, 100, 60);
spawn.bodyRect(400, 0, 100, 150); spawn.bodyRect(400, 0, 100, 150);
@@ -2587,6 +2630,7 @@ const level = {
stiffness: 0.00014, stiffness: 0.00014,
length: 120 length: 120
}); });
World.add(engine.world, cons[cons.length - 1]);
spawn.bodyRect(0, -1250, 240, 190) //Fat cube ascenseur spawn.bodyRect(0, -1250, 240, 190) //Fat cube ascenseur
} else { /// Reversed spawn } else { /// Reversed spawn
spawn.bodyRect(0, -650, 225, 175); spawn.bodyRect(0, -650, 225, 175);
@@ -2666,6 +2710,7 @@ const level = {
bodyB: mob[mob.length - 1], bodyB: mob[mob.length - 1],
stiffness: 0.00006 stiffness: 0.00006
}); });
World.add(engine.world, cons[cons.length - 1]);
if (game.difficulty > 4) spawn.nodeBoss(7000, -3300, "spawns", 8, 20, 105); if (game.difficulty > 4) spawn.nodeBoss(7000, -3300, "spawns", 8, 20, 105);
} else if (game.difficulty > 3) { } else if (game.difficulty > 3) {
spawn.randomLevelBoss(6100, -3600, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss"]); spawn.randomLevelBoss(6100, -3600, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss"]);
@@ -2684,6 +2729,7 @@ const level = {
bodyB: mob[mob.length - 1], bodyB: mob[mob.length - 1],
stiffness: 0.00036 stiffness: 0.00036
}); });
World.add(engine.world, cons[cons.length - 1]);
if (game.difficulty > 4) spawn.nodeBoss(2350, -1300, "spawns", 8, 20, 105); if (game.difficulty > 4) spawn.nodeBoss(2350, -1300, "spawns", 8, 20, 105);
} else if (game.difficulty > 3) { } else if (game.difficulty > 3) {
spawn.randomLevelBoss(2300, -1400, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss", "snakeBoss"]); spawn.randomLevelBoss(2300, -1400, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss", "snakeBoss"]);
@@ -2759,6 +2805,7 @@ const level = {
bodyB: mob[mob.length - 1], bodyB: mob[mob.length - 1],
stiffness: 0.00017 stiffness: 0.00017
}); });
World.add(engine.world, cons[cons.length - 1]);
//chance to spawn a ring of exploding mobs around this boss //chance to spawn a ring of exploding mobs around this boss
if (game.difficulty > 4) spawn.nodeBoss(2330, 1850, "spawns", 8, 20, 105); if (game.difficulty > 4) spawn.nodeBoss(2330, 1850, "spawns", 8, 20, 105);
powerUps.spawn(3010, 1630, "mod"); powerUps.spawn(3010, 1630, "mod");
@@ -3193,6 +3240,7 @@ const level = {
bodyB: mob[mob.length - 1], bodyB: mob[mob.length - 1],
stiffness: 0.00015 stiffness: 0.00015
}); });
World.add(engine.world, cons[cons.length - 1]);
if (game.difficulty > 4) spawn.nodeBoss(8000, 630, "spawns", 8, 20, 105); if (game.difficulty > 4) spawn.nodeBoss(8000, 630, "spawns", 8, 20, 105);
} else if (game.difficulty > 3) { } else if (game.difficulty > 3) {
spawn.randomLevelBoss(8000, 630, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss", "bomberBoss"]); spawn.randomLevelBoss(8000, 630, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss", "bomberBoss"]);
@@ -3768,6 +3816,7 @@ const level = {
bodyB: mob[mob.length - 1], bodyB: mob[mob.length - 1],
stiffness: 0.00018 + 0.000007 * level.levelsCleared 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 if (game.difficulty > 4) spawn.nodeBoss(3380, -1775, "spawns", 8, 20, 105); //chance to spawn a ring of exploding mobs around this boss
} else { } else {
@@ -4003,12 +4052,10 @@ const level = {
Matter.Body.setStatic(map[i], true); //make static Matter.Body.setStatic(map[i], true); //make static
World.add(engine.world, map[i]); //add to world World.add(engine.world, map[i]); //add to world
} }
for (let i = 0; i < cons.length; i++) { // for (let i = 0; i < cons.length; i++) {
World.add(engine.world, cons[i]); // World.add(engine.world, cons[i]);
} // }
for (let i = 0; i < consBB.length; i++) {
World.add(engine.world, consBB[i]);
}
}, },
spinner(x, y, width, height, density = 0.001) { spinner(x, y, width, height, density = 0.001) {
x = x + width / 2 x = x + width / 2
@@ -4404,7 +4451,7 @@ const level = {
mapB.portalPair = mapA mapB.portalPair = mapA
return [portalA, portalB, mapA, mapB] 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 { return {
min: { min: {
x: x, x: x,
@@ -4419,7 +4466,7 @@ const level = {
maxHeight: height, maxHeight: height,
isOn: true, isOn: true,
query() { 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) { if (damage < 0.02) {
mech.damage(damage) mech.damage(damage)
} else if (mech.immuneCycle < mech.cycle) { } else if (mech.immuneCycle < mech.cycle) {
@@ -4480,6 +4527,7 @@ const level = {
stiffness: stiffness, stiffness: stiffness,
damping: damping damping: damping
}); });
World.add(engine.world, consBB[consBB.length - 1]);
} }
cons[cons.length] = Constraint.create({ //pin first block to a point in space cons[cons.length] = Constraint.create({ //pin first block to a point in space
pointA: { pointA: {
@@ -4490,6 +4538,7 @@ const level = {
stiffness: 1, stiffness: 1,
damping: damping damping: damping
}); });
World.add(engine.world, cons[cons.length - 1]);
if (isAttached) { if (isAttached) {
cons[cons.length] = Constraint.create({ //pin last block to a point in space cons[cons.length] = Constraint.create({ //pin last block to a point in space
pointA: { pointA: {
@@ -4500,6 +4549,7 @@ const level = {
stiffness: 1, stiffness: 1,
damping: damping damping: damping
}); });
World.add(engine.world, cons[cons.length - 1]);
} }
}, },
}; };

View File

@@ -292,13 +292,16 @@ const mobs = {
this.seePlayer.position.x = player.position.x; this.seePlayer.position.x = player.position.x;
this.seePlayer.position.y = player.position.y; this.seePlayer.position.y = player.position.y;
}, },
// locatePlayerByDist() { alertNearByMobs() {
// if (this.distanceToPlayer2() < this.locateRange) { //this.alertRange2 is set at the very bottom of this mobs, after mob is made
// this.locatePlayer(); 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() { alwaysSeePlayer() {
if (!mech.isStealth) { if (!mech.isCloak) {
this.seePlayer.recall = true; this.seePlayer.recall = true;
this.seePlayer.position.x = player.position.x; this.seePlayer.position.x = player.position.x;
this.seePlayer.position.y = player.position.y; this.seePlayer.position.y = player.position.y;
@@ -310,7 +313,7 @@ const mobs = {
this.distanceToPlayer2() < this.seeAtDistance2 && this.distanceToPlayer2() < this.seeAtDistance2 &&
Matter.Query.ray(map, this.position, this.mechPosRange()).length === 0 && Matter.Query.ray(map, this.position, this.mechPosRange()).length === 0 &&
Matter.Query.ray(body, this.position, this.mechPosRange()).length === 0 && Matter.Query.ray(body, this.position, this.mechPosRange()).length === 0 &&
!mech.isStealth !mech.isCloak
) { ) {
this.foundPlayer(); this.foundPlayer();
} else if (this.seePlayer.recall) { } else if (this.seePlayer.recall) {
@@ -320,7 +323,7 @@ const mobs = {
}, },
seePlayerCheckByDistance() { seePlayerCheckByDistance() {
if (!(game.cycle % this.seePlayerFreq)) { if (!(game.cycle % this.seePlayerFreq)) {
if (this.distanceToPlayer2() < this.seeAtDistance2 && !mech.isStealth) { if (this.distanceToPlayer2() < this.seeAtDistance2 && !mech.isCloak) {
this.foundPlayer(); this.foundPlayer();
} else if (this.seePlayer.recall) { } else if (this.seePlayer.recall) {
this.lostPlayer(); this.lostPlayer();
@@ -331,7 +334,7 @@ const mobs = {
if (!(game.cycle % this.seePlayerFreq)) { if (!(game.cycle % this.seePlayerFreq)) {
if ( 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)) && (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(); this.foundPlayer();
} else if (this.seePlayer.recall) { } else if (this.seePlayer.recall) {
@@ -363,7 +366,7 @@ const mobs = {
this.distanceToPlayer2() < this.seeAtDistance2 && this.distanceToPlayer2() < this.seeAtDistance2 &&
Matter.Query.ray(map, this.position, this.mechPosRange()).length === 0 && Matter.Query.ray(map, this.position, this.mechPosRange()).length === 0 &&
Matter.Query.ray(body, this.position, this.mechPosRange()).length === 0 && Matter.Query.ray(body, this.position, this.mechPosRange()).length === 0 &&
!mech.isStealth !mech.isCloak
) { ) {
this.foundPlayer(); this.foundPlayer();
} else if (this.seePlayer.recall) { } else if (this.seePlayer.recall) {
@@ -411,7 +414,7 @@ const mobs = {
if (game.cycle % 7 && this.seePlayer.yes) { if (game.cycle % 7 && this.seePlayer.yes) {
ctx.setLineDash([125 * Math.random(), 125 * Math.random()]); ctx.setLineDash([125 * Math.random(), 125 * Math.random()]);
// ctx.lineDashOffset = 6*(game.cycle % 215); // 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.immuneCycle < mech.cycle) mech.damage(0.0003 * game.dmgScale);
if (mech.energy > 0.1) mech.energy -= 0.003 if (mech.energy > 0.1) mech.energy -= 0.003
ctx.beginPath(); ctx.beginPath();
@@ -497,7 +500,7 @@ const mobs = {
}; };
vertexCollision(this.position, look, map); vertexCollision(this.position, look, map);
vertexCollision(this.position, look, body); vertexCollision(this.position, look, body);
if (!mech.isStealth) vertexCollision(this.position, look, [player]); if (!mech.isCloak) vertexCollision(this.position, look, [player]);
// hitting player // hitting player
if (best.who === player) { if (best.who === player) {
if (mech.immuneCycle < mech.cycle) { if (mech.immuneCycle < mech.cycle) {
@@ -538,7 +541,7 @@ const mobs = {
this.distanceToPlayer2() < this.seeAtDistance2 && this.distanceToPlayer2() < this.seeAtDistance2 &&
Matter.Query.ray(map, this.position, player.position).length === 0 && Matter.Query.ray(map, this.position, player.position).length === 0 &&
Matter.Query.ray(body, this.position, player.position).length === 0 && Matter.Query.ray(body, this.position, player.position).length === 0 &&
!mech.isStealth !mech.isCloak
) { ) {
this.foundPlayer(); this.foundPlayer();
} else if (this.seePlayer.recall) { } 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) { curl(range = 1000, mag = -10) {
//cause all mobs, and bodies to rotate in a circle //cause all mobs, and bodies to rotate in a circle
applyCurl = function (center, array, isAntiGravity = true) { applyCurl = function (center, array, isAntiGravity = true) {
@@ -1049,7 +1044,7 @@ const mobs = {
} }
} }
if (Math.random() < mod.isBotSpawner) b.randomBot(this.position, false) 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()) if (mod.nailsDeathMob) b.targetedNail(this.position, mod.nailsDeathMob, 40 + 7 * Math.random())
} else if (mod.isShieldAmmo && this.shield) { } else if (mod.isShieldAmmo && this.shield) {
let type = "ammo" let type = "ammo"

View File

@@ -5,6 +5,7 @@ const mod = {
mod.mods[i].remove(); mod.mods[i].remove();
mod.mods[i].count = 0 mod.mods[i].count = 0
} }
mod.armorFromPowerUps = 0;
mod.totalCount = 0; mod.totalCount = 0;
game.updateModHUD(); game.updateModHUD();
}, },
@@ -37,6 +38,7 @@ const mod = {
} }
if (!found) return //if name not found don't give any 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].effect(); //give specific mod
mod.mods[index].count++ mod.mods[index].count++
mod.totalCount++ //used in power up randomization mod.totalCount++ //used in power up randomization
@@ -78,7 +80,7 @@ const mod = {
return false return false
}, },
damageFromMods() { damageFromMods() {
let dmg = 1 let dmg = mech.fieldDamage
if (mod.isEnergyNoAmmo) dmg *= 1.4 if (mod.isEnergyNoAmmo) dmg *= 1.4
if (mod.isDamageForGuns) dmg *= 1 + 0.07 * b.inventory.length if (mod.isDamageForGuns) dmg *= 1 + 0.07 * b.inventory.length
if (mod.isLowHealthDmg) dmg *= 1 + 0.6 * Math.max(0, 1 - mech.health) if (mod.isLowHealthDmg) dmg *= 1 + 0.6 * Math.max(0, 1 - mech.health)
@@ -112,7 +114,6 @@ const mod = {
} }
}, { }, {
name: "capacitor", name: "capacitor",
// nameInfo: "<span id='mod-capacitor'></span>",
description: "increase <strong class='color-d'>damage</strong> by <strong>1%</strong><br>for every <strong>5.5%</strong> stored <strong class='color-f'>energy</strong>", description: "increase <strong class='color-d'>damage</strong> by <strong>1%</strong><br>for every <strong>5.5%</strong> stored <strong class='color-f'>energy</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -121,7 +122,7 @@ const mod = {
}, },
requires: "increased energy regen or max energy", requires: "increased energy regen or max energy",
effect: () => { effect: () => {
mod.isEnergyDamage = true // used in mech.grabPowerUp mod.isEnergyDamage = true
}, },
remove() { remove() {
mod.isEnergyDamage = false; mod.isEnergyDamage = false;
@@ -161,7 +162,6 @@ const mod = {
}, },
{ {
name: "rest frame", name: "rest frame",
// nameInfo: "<span id='mod-rest'></span>",
description: "increase <strong class='color-d'>damage</strong> by <strong>20%</strong><br>when not <strong>moving</strong>", description: "increase <strong class='color-d'>damage</strong> by <strong>20%</strong><br>when not <strong>moving</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -170,7 +170,7 @@ const mod = {
}, },
requires: "", requires: "",
effect: () => { effect: () => {
mod.isRest = true // used in mech.grabPowerUp mod.isRest = true
}, },
remove() { remove() {
mod.isRest = false; mod.isRest = false;
@@ -756,7 +756,7 @@ const mod = {
}, },
requires: "", requires: "",
effect() { effect() {
mod.collisionImmuneCycles += 60; mod.collisionImmuneCycles += 55;
mech.immuneCycle = mech.cycle + mod.collisionImmuneCycles; //player is immune to collision damage for 30 cycles mech.immuneCycle = mech.cycle + mod.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
}, },
remove() { remove() {
@@ -818,7 +818,7 @@ const mod = {
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { 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", requires: "a freezing or stunning effect",
effect() { effect() {
@@ -830,7 +830,7 @@ const mod = {
}, },
{ {
name: "piezoelectricity", name: "piezoelectricity",
description: "<strong>colliding</strong> with mobs fills your <strong class='color-f'>energy</strong><br><strong>15%</strong> less <strong class='color-harm'>harm</strong> from mob collisions", description: "<strong>colliding</strong> with mobs fills your <strong class='color-f'>energy</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>15%</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
@@ -982,12 +982,14 @@ const mod = {
}, },
requires: "not mass-energy equivalence", requires: "not mass-energy equivalence",
effect() { effect() {
mech.maxHealth += 0.50 mod.bonusHealth += 0.5
mech.addHealth(0.50) mech.addHealth(0.50)
mech.setMaxHealth();
}, },
remove() { remove() {
mech.maxHealth = 1; mod.bonusHealth = 0
mech.displayHealth(); mech.setMaxHealth();
} }
}, },
{ {
@@ -996,14 +998,16 @@ const mod = {
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
return !mod.isEnergyHealth && !mod.isDroneGrab return !mod.isEnergyHealth
}, },
requires: "not mass-energy equivalence", requires: "not mass-energy equivalence",
effect() { effect() {
mod.isArmorFromPowerUps = true; mod.isArmorFromPowerUps = true; //tracked by mod.armorFromPowerUps
}, },
remove() { remove() {
mod.isArmorFromPowerUps = false; mod.isArmorFromPowerUps = false;
// mod.armorFromPowerUps = 0; //this is now reset in mod.setupAllMods();
mech.setMaxHealth();
} }
}, },
{ {
@@ -2023,7 +2027,7 @@ const mod = {
}, },
{ {
name: "harvester", name: "harvester",
description: "after a <strong>drone</strong> picks up a <strong>power up</strong>,<br>it's <strong>larger</strong>, <strong>faster</strong>, and infinitely <strong>durable</strong>", description: "after a <strong>drone</strong> picks up a <strong>power up</strong>,<br>it's <strong>larger</strong>, <strong>faster</strong>, and very <strong>durable</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
@@ -2203,22 +2207,22 @@ const mod = {
mod.laserFieldDrain = 0.0016; mod.laserFieldDrain = 0.0016;
} }
}, },
{ // {
name: "waste heat recovery", // name: "waste heat recovery",
description: "<strong>laser</strong> <strong class='color-d'>damage</strong> grows by <strong>400%</strong> as you fire<br>but you periodically <strong>eject</strong> your <strong class='color-h'>health</strong>", // description: "<strong>laser</strong> <strong class='color-d'>damage</strong> grows by <strong>400%</strong> as you fire<br>but you periodically <strong>eject</strong> your <strong class='color-h'>health</strong>",
maxCount: 1, // maxCount: 1,
count: 0, // count: 0,
allowed() { // allowed() {
return mod.haveGunCheck("laser") // return mod.haveGunCheck("laser") && !mod.isEnergyHealth
}, // },
requires: "laser", // requires: "laser<br>not mass-energy equivalence",
effect() { // effect() {
mod.isLaserHealth = true; // mod.isLaserHealth = true;
}, // },
remove() { // remove() {
mod.isLaserHealth = false // mod.isLaserHealth = false
} // }
}, // },
{ {
name: "shock wave", name: "shock wave",
description: "mobs caught in <strong>pulse's</strong> explosion are <strong>stunned</strong><br>for up to <strong>2 seconds</strong>", description: "mobs caught in <strong>pulse's</strong> explosion are <strong>stunned</strong><br>for up to <strong>2 seconds</strong>",
@@ -2272,6 +2276,22 @@ const mod = {
mod.isStunField = 0; mod.isStunField = 0;
} }
}, },
{
name: "fracture analysis",
description: "bullet impacts do <strong>500%</strong> <strong class='color-d'>damage</strong><br>to <strong>stunned</strong> mobs",
maxCount: 1,
count: 0,
allowed() {
return mod.isStunField || mod.oneSuperBall || mod.isCloakStun
},
requires: "flux pinning or super ball<br>or flashbang",
effect() {
mod.isCrit = true;
},
remove() {
mod.isCrit = false;
}
},
{ {
name: "timelike world line", name: "timelike world line",
description: "<strong>time dilation</strong> doubles your relative time <strong>rate</strong><br>and makes you <strong>immune</strong> to <strong class='color-harm'>harm</strong>", description: "<strong>time dilation</strong> doubles your relative time <strong>rate</strong><br>and makes you <strong>immune</strong> to <strong class='color-harm'>harm</strong>",
@@ -2451,7 +2471,7 @@ const mod = {
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { 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", requires: "nano-scale manufacturing",
effect() { effect() {
@@ -2467,7 +2487,7 @@ const mod = {
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { 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", requires: "nano-scale manufacturing",
effect() { effect() {
@@ -2483,7 +2503,7 @@ const mod = {
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { 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", requires: "nano-scale manufacturing",
effect() { effect() {
@@ -2494,35 +2514,35 @@ const mod = {
} }
}, },
{ {
name: "superposition", name: "phase decoherence",
description: "mobs that <strong>touch</strong> the <strong>phased</strong> player<br> are <strong>stunned</strong> for <strong>5</strong> seconds", description: "become <strong>intangible</strong> while <strong class='color-cloaked'>cloaked</strong><br>but, passing through <strong>mobs</strong> drains your <strong class='color-f'>energy</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { 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() { effect() {
mod.superposition = true; mod.isIntangible = true;
}, },
remove() { remove() {
mod.superposition = false; mod.isIntangible = false;
} }
}, },
{ {
name: "fracture analysis", name: "flashbang",
description: "bullet impacts do <strong>500%</strong> <strong class='color-d'>damage</strong><br>to mobs that are <strong>unaware</strong> of you or <strong>stunned</strong>", description: "<strong class='color-cloaked'>decloaking</strong> <strong>stuns</strong> nearby mobs for <strong>2</strong> second",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { 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() { effect() {
mod.isCrit = true; mod.isCloakStun = true;
}, },
remove() { remove() {
mod.isCrit = false; mod.isCloakStun = false;
} }
}, },
{ {
@@ -2760,5 +2780,8 @@ const mod = {
isFreezeHarmImmune: null, isFreezeHarmImmune: null,
isSmallExplosion: null, isSmallExplosion: null,
isExplosionHarm: null, isExplosionHarm: null,
isLaserHealth: null armorFromPowerUps: null,
bonusHealth: null,
isIntangible: null,
isCloakStun: null
} }

View File

@@ -469,12 +469,19 @@ const mech = {
mech.displayHealth(); 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 defaultFPSCycle: 0, //tracks when to return to normal fps
immuneCycle: 0, //used in engine immuneCycle: 0, //used in engine
harmReduction() { harmReduction() {
let dmg = 1 let dmg = 1
dmg *= mech.fieldHarmReduction 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.isHarmReduce && mech.fieldUpgrades[mech.fieldMode].name === "negative mass field" && mech.isFieldActive) dmg *= 0.6
if (mod.isBotArmor) dmg *= 0.95 ** mod.totalBots() if (mod.isBotArmor) dmg *= 0.95 ** mod.totalBots()
if (mod.isHarmArmor && mech.lastHarmCycle + 600 > mech.cycle) dmg *= 0.5; if (mod.isHarmArmor && mech.lastHarmCycle + 600 > mech.cycle) dmg *= 0.5;
@@ -487,7 +494,7 @@ const mech = {
} }
return dmg return dmg
}, },
damage(dmg, isShowRed = true) { damage(dmg) {
mech.lastHarmCycle = mech.cycle mech.lastHarmCycle = mech.cycle
if (mod.isDroneOnDamage) { //chance to build a drone on damage from mod if (mod.isDroneOnDamage) { //chance to build a drone on damage from mod
const len = Math.min((dmg - 0.06 * Math.random()) * 40, 40) const len = Math.min((dmg - 0.06 * Math.random()) * 40, 40)
@@ -552,11 +559,9 @@ const mech = {
} }
} }
mech.displayHealth(); mech.displayHealth();
if (isShowRed) {
document.getElementById("dmg").style.transition = "opacity 0s"; document.getElementById("dmg").style.transition = "opacity 0s";
document.getElementById("dmg").style.opacity = 0.1 + Math.min(0.6, dmg * 4); 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 if (dmg > 0.06 / mech.holdingMassScale) mech.drop(); //drop block if holding
@@ -583,7 +588,7 @@ const mech = {
} }
} }
} else { } 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.fpsCap = 4 //40 - Math.min(25, 100 * dmg)
game.fpsInterval = 1000 / game.fpsCap; game.fpsInterval = 1000 / game.fpsCap;
} else { } else {
@@ -702,7 +707,7 @@ const mech = {
index: 0 index: 0
}, },
isHolding: false, isHolding: false,
isStealth: false, isCloak: false,
throwCharge: 0, throwCharge: 0,
fireCDcycle: 0, fireCDcycle: 0,
fieldCDcycle: 0, fieldCDcycle: 0,
@@ -715,6 +720,7 @@ const mech = {
isFieldActive: false, isFieldActive: false,
fieldRange: 155, fieldRange: 155,
fieldShieldingScale: 1, fieldShieldingScale: 1,
fieldDamage: 1,
energy: 0, energy: 0,
fieldRegen: 0, fieldRegen: 0,
fieldMode: 0, fieldMode: 0,
@@ -734,11 +740,12 @@ const mech = {
mech.fieldBlockCD = 10; mech.fieldBlockCD = 10;
game.isBodyDamage = true; game.isBodyDamage = true;
mech.fieldHarmReduction = 1; mech.fieldHarmReduction = 1;
mech.fieldDamage = 1
mech.grabPowerUpRange2 = 156000; mech.grabPowerUpRange2 = 156000;
mech.fieldRange = 155; mech.fieldRange = 155;
mech.fieldFire = false; mech.fieldFire = false;
mech.fieldCDcycle = 0; mech.fieldCDcycle = 0;
mech.isStealth = false; mech.isCloak = false;
player.collisionFilter.mask = cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield player.collisionFilter.mask = cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield
mech.airSpeedLimit = 125 mech.airSpeedLimit = 125
mech.drop(); mech.drop();
@@ -849,6 +856,7 @@ const mech = {
if (mech.holdingTarget) { if (mech.holdingTarget) {
if (keys[32] || game.mouseDownRight) { if (keys[32] || game.mouseDownRight) {
if (mech.energy > 0.001) { if (mech.energy > 0.001) {
mech.fireCDcycle = mech.cycle
mech.energy -= 0.001 / mod.throwChargeRate; mech.energy -= 0.001 / mod.throwChargeRate;
mech.throwCharge += 0.5 * mod.throwChargeRate / mech.holdingTarget.mass mech.throwCharge += 0.5 * mod.throwChargeRate / mech.holdingTarget.mass
//draw charge //draw charge
@@ -1392,7 +1400,7 @@ const mech = {
}, },
{ {
name: "negative mass field", name: "negative mass field",
description: "use <strong class='color-f'>energy</strong> to nullify &nbsp; <strong style='letter-spacing: 12px;'>gravity</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>45%</strong><br><strong>blocks</strong> held by the field have a lower <strong>mass</strong>", description: "use <strong class='color-f'>energy</strong> to nullify &nbsp;<strong style='letter-spacing: 7px;'>gravity</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>45%</strong><br><strong>blocks</strong> held by the field have a lower <strong>mass</strong>",
fieldDrawRadius: 0, fieldDrawRadius: 0,
effect: () => { effect: () => {
mech.fieldFire = true; mech.fieldFire = true;
@@ -1759,22 +1767,59 @@ const mech = {
} }
}, },
{ {
name: "phase decoherence field", name: "metamaterial cloaking", //"weak photonic coupling" "electromagnetically induced transparency" "optical non-coupling" "slow light field" "electro-optic transparency"
description: "use <strong class='color-f'>energy</strong> to become <strong>intangible</strong><br><strong>firing</strong> and touching <strong>shields</strong> <strong>drains</strong> <strong class='color-f'>energy</strong><br>unable to <strong>see</strong> and be <strong>seen</strong> by mobs", description: "<strong class='color-cloaked'>cloak</strong> after not using your gun or field<br>while <strong class='color-cloaked'>cloaked</strong> mobs can't see you<br>increase <strong class='color-d'>damage</strong> by <strong>33%</strong>",
effect: () => { effect: () => {
mech.fieldFire = true; mech.fieldFire = true;
mech.fieldMeterColor = "#fff"; mech.fieldMeterColor = "#fff";
mech.fieldPhase = 0; mech.fieldPhase = 0;
mech.isCloak = false
mech.fieldDamage = 1.33
mech.hold = function () { mech.hold = function () {
function drawField(radius) { if (mech.isHolding) {
radius *= Math.min(4, 0.9 + 2.2 * mech.energy * mech.energy); mech.drawHold(mech.holdingTarget);
const rotate = mech.cycle * 0.005; mech.holding();
mech.fieldPhase += 0.5 - 0.5 * Math.sqrt(Math.max(0.01, Math.min(mech.energy, 1))); mech.throwBlock();
const off1 = 1 + 0.06 * Math.sin(mech.fieldPhase); if (mech.fireCDcycle < mech.cycle) mech.fireCDcycle = mech.cycle //to disable cloak
const off2 = 1 - 0.06 * Math.sin(mech.fieldPhase); } 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.beginPath();
ctx.ellipse(mech.pos.x, mech.pos.y, radius * off1, radius * off2, rotate, 0, 2 * Math.PI); 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) {
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 * (1 - wiggle), radius * (1 + wiggle), mech.fieldPhase, 0, 2 * Math.PI);
if (mech.fireCDcycle > mech.cycle && (keys[32] || game.mouseDownRight)) { if (mech.fireCDcycle > mech.cycle && (keys[32] || game.mouseDownRight)) {
ctx.lineWidth = 5; ctx.lineWidth = 5;
ctx.strokeStyle = `rgba(0, 204, 255,1)` ctx.strokeStyle = `rgba(0, 204, 255,1)`
@@ -1787,94 +1832,36 @@ const mech = {
ctx.clip(); ctx.clip();
} }
mech.isStealth = false //isStealth disables most uses of foundPlayer() if (mech.isCloak) {
player.collisionFilter.mask = cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield //normal collisions this.fieldRange = this.fieldRange * 0.9 + 0.1 * 800
if (mech.isHolding) { drawField(this.fieldRange)
if (this.fieldRange < 2000) { } else {
this.fieldRange += 100 if (this.fieldRange < 3000) {
this.fieldRange += 200
drawField(this.fieldRange) drawField(this.fieldRange)
} }
mech.drawHold(mech.holdingTarget); }
mech.holding(); if (mod.isIntangible) {
mech.throwBlock(); if (mech.isCloak) {
} 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 player.collisionFilter.mask = cat.map
let inPlayer = Matter.Query.region(mob, player.bounds) let inPlayer = Matter.Query.region(mob, player.bounds)
if (inPlayer.length > 0) { if (inPlayer.length > 0) {
for (let i = 0; i < inPlayer.length; i++) { for (let i = 0; i < inPlayer.length; i++) {
if (inPlayer[i].shield) { if (mech.energy > 0) {
mech.energy -= 0.005; //shields drain player energy if (inPlayer[i].shield) { //shields drain player energy
//draw outline of shield mech.energy -= 0.02;
ctx.fillStyle = `rgba(140,217,255,0.5)` } else {
ctx.fill() mech.energy -= 0.007;
} 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 { } else {
mech.fieldCDcycle = mech.cycle + 120; player.collisionFilter.mask = cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield //normal collisions
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) { if (mech.energy < mech.maxEnergy) { // replaces mech.drawFieldMeter() with custom code
mech.energy += mech.fieldRegen; mech.energy += mech.fieldRegen;
const xOff = mech.pos.x - mech.radius * mech.maxEnergy const xOff = mech.pos.x - mech.radius * mech.maxEnergy
const yOff = mech.pos.y - 50 const yOff = mech.pos.y - 50
@@ -1888,10 +1875,143 @@ const mech = {
ctx.lineWidth = 1; ctx.lineWidth = 1;
ctx.stroke(); ctx.stroke();
} }
if (mech.energy < 0) mech.energy = 0
} }
} }
}, },
// {
// name: "phase decoherence field",
// description: "use <strong class='color-f'>energy</strong> to become <strong>intangible</strong><br><strong>firing</strong> and touching <strong>shields</strong> <strong>drains</strong> <strong class='color-f'>energy</strong><br>unable to <strong>see</strong> and be <strong>seen</strong> 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", name: "pilot wave",
description: "use <strong class='color-f'>energy</strong> to push <strong>blocks</strong> with your mouse<br>field <strong>radius</strong> decreases out of <strong>line of sight</strong>", description: "use <strong class='color-f'>energy</strong> to push <strong>blocks</strong> with your mouse<br>field <strong>radius</strong> decreases out of <strong>line of sight</strong>",

View File

@@ -245,7 +245,7 @@ const spawn = {
powerUps.spawnBossPowerUp(me.position.x, me.position.y) 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, "heal");
powerUps.spawn(me.position.x, me.position.y, "ammo"); powerUps.spawn(me.position.x, me.position.y, "ammo");
} else if (!mech.isStealth) { } else if (!mech.isCloak) {
me.foundPlayer(); me.foundPlayer();
} }
@@ -578,7 +578,7 @@ const spawn = {
//when player is inside event horizon //when player is inside event horizon
if (Vector.magnitude(Vector.sub(this.position, player.position)) < eventHorizon) { 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) { if (mech.energy < 0.1) {
mech.damage(0.00015 * game.dmgScale); mech.damage(0.00015 * game.dmgScale);
} }
@@ -677,7 +677,7 @@ const spawn = {
ctx.fill(); ctx.fill();
//when player is inside event horizon //when player is inside event horizon
if (Vector.magnitude(Vector.sub(this.position, player.position)) < eventHorizon) { 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) { if (mech.energy < 0.1) {
mech.damage(0.0002 * game.dmgScale); mech.damage(0.0002 * game.dmgScale);
} }
@@ -727,6 +727,7 @@ const spawn = {
damping: springDampening damping: springDampening
}); });
cons[len].length = 100 + 1.5 * radius; cons[len].length = 100 + 1.5 * radius;
me.cons = cons[len]; me.cons = cons[len];
me.springTarget2 = { me.springTarget2 = {
@@ -780,7 +781,7 @@ const spawn = {
stiffness: attachmentStiffness, stiffness: attachmentStiffness,
damping: 0.01 damping: 0.01
}); });
// console.log(consBB[consBB.length - 1]) World.add(engine.world, consBB[consBB.length - 1]);
} }
}, },
timeSkipBoss(x, y, radius = 55) { timeSkipBoss(x, y, radius = 55) {
@@ -1061,7 +1062,7 @@ const spawn = {
}; };
vertexCollision(this.position, look, map); vertexCollision(this.position, look, map);
vertexCollision(this.position, look, body); vertexCollision(this.position, look, body);
if (!mech.isStealth) vertexCollision(this.position, look, [player]); if (!mech.isCloak) vertexCollision(this.position, look, [player]);
// hitting player // hitting player
if (best.who === player) { if (best.who === player) {
if (mech.immuneCycle < mech.cycle) { if (mech.immuneCycle < mech.cycle) {
@@ -1217,7 +1218,7 @@ const spawn = {
// vertexCollision(where, look, mob); // vertexCollision(where, look, mob);
vertexCollision(where, look, map); vertexCollision(where, look, map);
vertexCollision(where, look, body); 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) { 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 mech.immuneCycle = mech.cycle + mod.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
const dmg = 0.14 * game.dmgScale; const dmg = 0.14 * game.dmgScale;
@@ -1336,7 +1337,7 @@ const spawn = {
this.distanceToPlayer2() < this.seeAtDistance2 && this.distanceToPlayer2() < this.seeAtDistance2 &&
Matter.Query.ray(map, this.position, this.mechPosRange()).length === 0 && Matter.Query.ray(map, this.position, this.mechPosRange()).length === 0 &&
Matter.Query.ray(body, this.position, this.mechPosRange()).length === 0 && Matter.Query.ray(body, this.position, this.mechPosRange()).length === 0 &&
!mech.isStealth !mech.isCloak
) { ) {
this.foundPlayer(); this.foundPlayer();
if (this.cd === Infinity) this.cd = game.cycle + this.delay * 0.7; 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) this.alpha -= 0.03;
} }
if (this.alpha > 0) { if (this.alpha > 0) {
if (this.alpha > 0.9) { if (this.alpha > 0.9 && this.seePlayer.recall) {
this.healthBar(); this.healthBar();
if (!this.canTouchPlayer) { if (!this.canTouchPlayer) {
this.canTouchPlayer = true; this.canTouchPlayer = true;
@@ -2008,16 +2009,19 @@ const spawn = {
bodyB: mob[mob.length - 1 - nodes], bodyB: mob[mob.length - 1 - nodes],
stiffness: 0.05 stiffness: 0.05
}); });
World.add(engine.world, consBB[consBB.length - 1]);
consBB[consBB.length] = Constraint.create({ consBB[consBB.length] = Constraint.create({
bodyA: mob[mob.length - nodes + 1], bodyA: mob[mob.length - nodes + 1],
bodyB: mob[mob.length - 1 - nodes], bodyB: mob[mob.length - 1 - nodes],
stiffness: 0.05 stiffness: 0.05
}); });
World.add(engine.world, consBB[consBB.length - 1]);
consBB[consBB.length] = Constraint.create({ consBB[consBB.length] = Constraint.create({
bodyA: mob[mob.length - nodes + 2], bodyA: mob[mob.length - nodes + 2],
bodyB: mob[mob.length - 1 - nodes], bodyB: mob[mob.length - 1 - nodes],
stiffness: 0.05 stiffness: 0.05
}); });
World.add(engine.world, consBB[consBB.length - 1]);
}, },
tetherBoss(x, y, radius = 90) { tetherBoss(x, y, radius = 90) {
@@ -2057,6 +2061,8 @@ const spawn = {
stiffness: 0.4, stiffness: 0.4,
damping: 0.1 damping: 0.1
}); });
World.add(engine.world, consBB[consBB.length - 1]);
me.onDamage = function () { me.onDamage = function () {
//make sure the mob that owns the shield can tell when damage is done //make sure the mob that owns the shield can tell when damage is done
this.alertNearByMobs(); this.alertNearByMobs();
@@ -2101,6 +2107,7 @@ const spawn = {
stiffness: stiffness, stiffness: stiffness,
damping: 0.1 damping: 0.1
}); });
World.add(engine.world, consBB[consBB.length - 1]);
} }
me.onDamage = function () { me.onDamage = function () {
this.alertNearByMobs(); //makes sure the mob that owns the shield can tell when damage is done 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], bodyB: mob[mob.length - j],
stiffness: stiffness stiffness: stiffness
}); });
World.add(engine.world, consBB[consBB.length - 1]);
} }
} }
}, },
@@ -2231,6 +2239,7 @@ const spawn = {
bodyB: mob[mob.length - i - 2], bodyB: mob[mob.length - i - 2],
stiffness: stiffness stiffness: stiffness
}); });
World.add(engine.world, consBB[consBB.length - 1]);
} }
if (nodes > 2) { if (nodes > 2) {
for (let i = 0; i < nodes - 2; ++i) { for (let i = 0; i < nodes - 2; ++i) {
@@ -2239,6 +2248,7 @@ const spawn = {
bodyB: mob[mob.length - i - 3], bodyB: mob[mob.length - i - 3],
stiffness: stiffness stiffness: stiffness
}); });
World.add(engine.world, consBB[consBB.length - 1]);
} }
} }
//optional connect the tail to head //optional connect the tail to head
@@ -2248,16 +2258,19 @@ const spawn = {
bodyB: mob[mob.length - nodes], bodyB: mob[mob.length - nodes],
stiffness: stiffness stiffness: stiffness
}); });
World.add(engine.world, consBB[consBB.length - 1]);
consBB[consBB.length] = Constraint.create({ consBB[consBB.length] = Constraint.create({
bodyA: mob[mob.length - 2], bodyA: mob[mob.length - 2],
bodyB: mob[mob.length - nodes], bodyB: mob[mob.length - nodes],
stiffness: stiffness stiffness: stiffness
}); });
World.add(engine.world, consBB[consBB.length - 1]);
consBB[consBB.length] = Constraint.create({ consBB[consBB.length] = Constraint.create({
bodyA: mob[mob.length - 1], bodyA: mob[mob.length - 1],
bodyB: mob[mob.length - nodes + 1], bodyB: mob[mob.length - nodes + 1],
stiffness: stiffness stiffness: stiffness
}); });
World.add(engine.world, consBB[consBB.length - 1]);
} }
}, },
constraintPB(x, y, bodyIndex, stiffness) { constraintPB(x, y, bodyIndex, stiffness) {
@@ -2269,6 +2282,7 @@ const spawn = {
bodyB: body[bodyIndex], bodyB: body[bodyIndex],
stiffness: stiffness stiffness: stiffness
}); });
World.add(engine.world, cons[cons.length - 1]);
}, },
constraintBB(bodyIndexA, bodyIndexB, stiffness) { constraintBB(bodyIndexA, bodyIndexB, stiffness) {
consBB[consBB.length] = Constraint.create({ consBB[consBB.length] = Constraint.create({
@@ -2276,6 +2290,7 @@ const spawn = {
bodyB: body[bodyIndexB], bodyB: body[bodyIndexB],
stiffness: stiffness stiffness: stiffness
}); });
World.add(engine.world, consBB[consBB.length - 1]);
}, },
// body and map spawns ****************************************************************************** // body and map spawns ******************************************************************************
//********************************************************************************************** //**********************************************************************************************

View File

@@ -464,6 +464,11 @@ em {
letter-spacing: 1px; letter-spacing: 1px;
} }
.color-cloaked {
opacity: 0.25;
letter-spacing: 1px;
}
.color-harm { .color-harm {
/* color: */ /* color: */
/* text-shadow: #FC0 1px 0 10px; */ /* text-shadow: #FC0 1px 0 10px; */

View File

@@ -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 ************** ************** 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 a bot that eats up health and ammo, but poops a reroll after picking up 2 power ups
it passes through walls it passes through walls
moves slower then the player so you can get to it before the bot if you hurry 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 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 the mods that do those effects could be required before you see this bot
disable crystalized armor? disable crystalized armor?
could convert rerolls, ammo, and health into mods instead
laser-bot orbits player 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 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 hold fire to charge: increases the size of the balls
mod: balls are attracted to mobs 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 rework perfect diamagnetism
let the shield also do bremsstrahlung radiation 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 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 use mac automator to speed up your n-gon -> git sync
fix door.isOpen actually meaning isClosed 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 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 level Boss: fractal Sierpiński triangle
https://en.wikipedia.org/wiki/Sierpi%C5%84ski_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 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 code it like mod.isFarAwayDmg
have these mods disable each other 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) mod harmonic shield: slow everything in range around shield (temporal shield)
set max speed? set max speed?