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:
52
js/bullet.js
52
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
|
||||
|
||||
12
js/engine.js
12
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,
|
||||
|
||||
@@ -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
|
||||
|
||||
94
js/level.js
94
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("<span style='font-size:115%;'> max health increased by " + (0.05 * powerUps.totalPowerUps * 100).toFixed(0) + "%</span>", 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]);
|
||||
}
|
||||
},
|
||||
};
|
||||
39
js/mob.js
39
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"
|
||||
|
||||
115
js/mods.js
115
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: "<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>",
|
||||
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: "<span id='mod-rest'></span>",
|
||||
description: "increase <strong class='color-d'>damage</strong> by <strong>20%</strong><br>when not <strong>moving</strong>",
|
||||
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: "<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,
|
||||
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 <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,
|
||||
count: 0,
|
||||
allowed() {
|
||||
@@ -2203,22 +2207,22 @@ const mod = {
|
||||
mod.laserFieldDrain = 0.0016;
|
||||
}
|
||||
},
|
||||
{
|
||||
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>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
allowed() {
|
||||
return mod.haveGunCheck("laser")
|
||||
},
|
||||
requires: "laser",
|
||||
effect() {
|
||||
mod.isLaserHealth = true;
|
||||
},
|
||||
remove() {
|
||||
mod.isLaserHealth = false
|
||||
}
|
||||
},
|
||||
// {
|
||||
// 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>",
|
||||
// maxCount: 1,
|
||||
// count: 0,
|
||||
// allowed() {
|
||||
// return mod.haveGunCheck("laser") && !mod.isEnergyHealth
|
||||
// },
|
||||
// requires: "laser<br>not mass-energy equivalence",
|
||||
// effect() {
|
||||
// mod.isLaserHealth = true;
|
||||
// },
|
||||
// remove() {
|
||||
// mod.isLaserHealth = false
|
||||
// }
|
||||
// },
|
||||
{
|
||||
name: "shock wave",
|
||||
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;
|
||||
}
|
||||
},
|
||||
{
|
||||
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",
|
||||
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,
|
||||
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 <strong>touch</strong> the <strong>phased</strong> player<br> are <strong>stunned</strong> for <strong>5</strong> seconds",
|
||||
name: "phase decoherence",
|
||||
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,
|
||||
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 <strong>500%</strong> <strong class='color-d'>damage</strong><br>to mobs that are <strong>unaware</strong> of you or <strong>stunned</strong>",
|
||||
name: "flashbang",
|
||||
description: "<strong class='color-cloaked'>decloaking</strong> <strong>stuns</strong> nearby mobs for <strong>2</strong> 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
|
||||
}
|
||||
304
js/player.js
304
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,11 +559,9 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
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 <strong class='color-f'>energy</strong> to nullify <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 <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,
|
||||
effect: () => {
|
||||
mech.fieldFire = true;
|
||||
@@ -1759,22 +1767,59 @@ const mech = {
|
||||
}
|
||||
},
|
||||
{
|
||||
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",
|
||||
name: "metamaterial cloaking", //"weak photonic coupling" "electromagnetically induced transparency" "optical non-coupling" "slow light field" "electro-optic transparency"
|
||||
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: () => {
|
||||
mech.fieldFire = true;
|
||||
mech.fieldMeterColor = "#fff";
|
||||
mech.fieldPhase = 0;
|
||||
mech.isCloak = false
|
||||
mech.fieldDamage = 1.33
|
||||
|
||||
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);
|
||||
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.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)) {
|
||||
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()
|
||||
}
|
||||
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 (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);
|
||||
if (mech.energy > 0) {
|
||||
if (inPlayer[i].shield) { //shields drain player energy
|
||||
mech.energy -= 0.02;
|
||||
} else {
|
||||
mech.energy -= 0.007;
|
||||
}
|
||||
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)
|
||||
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 <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",
|
||||
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>",
|
||||
|
||||
31
js/spawn.js
31
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 ******************************************************************************
|
||||
//**********************************************************************************************
|
||||
|
||||
@@ -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; */
|
||||
|
||||
53
todo.txt
53
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?
|
||||
|
||||
|
||||
Reference in New Issue
Block a user