diff --git a/js/bullets.js b/js/bullets.js
index 7f20aad..922f550 100644
--- a/js/bullets.js
+++ b/js/bullets.js
@@ -80,6 +80,9 @@ const b = {
isModEnergyHealth: null,
isModPulseStun: null,
isModPilotFreeze: null,
+ isModRest: null,
+ isModRPG: null,
+ isMod3Missiles: null,
modOnHealthChange() { //used with acid mod
if (b.isModAcidDmg && mech.health > 0.8) {
b.modAcidDmg = 0.5
@@ -96,13 +99,13 @@ const b = {
}, 10);
}
}
- if (b.isModLowHealthDmg) {
- if (!build.isCustomSelection) {
- setTimeout(function () {
- if (document.getElementById("mod-low-health-damage")) document.getElementById("mod-low-health-damage").innerHTML = " +" + (((3 / (2 + Math.min(mech.health, 1))) - 1) * 100).toFixed(0) + "%"
- }, 10);
- }
- }
+ // if (b.isModLowHealthDmg) {
+ // if (!build.isCustomSelection) {
+ // setTimeout(function () {
+ // if (document.getElementById("mod-low-health-damage")) document.getElementById("mod-low-health-damage").innerHTML = " +" + (((3 / (2 + Math.min(mech.health, 1))) - 1) * 100).toFixed(0) + "%"
+ // }, 10);
+ // }
+ // }
},
resetModText() {
setTimeout(function () {
@@ -112,7 +115,7 @@ const b = {
},
mods: [{
name: "capacitor",
- nameInfo: "",
+ // nameInfo: "",
description: "increase damage based on stored energy
+1% damage for every 5% energy",
maxCount: 1,
count: 0,
@@ -127,6 +130,23 @@ const b = {
b.isModEnergyDamage = false;
}
},
+ {
+ name: "rest frame",
+ // nameInfo: "",
+ description: "increase damage by 20% when at rest",
+ maxCount: 1,
+ count: 0,
+ allowed() {
+ return true
+ },
+ requires: "",
+ effect: () => {
+ b.isModRest = true // used in mech.grabPowerUp
+ },
+ remove() {
+ b.isModRest = false;
+ }
+ },
{
name: "kinetic bombardment",
description: "do up to 33% more damage at a distance
increase maxes out at about 40 steps away",
@@ -181,7 +201,7 @@ const b = {
},
{
name: "negative feedback",
- nameInfo: "",
+ // nameInfo: "",
description: "do extra damage at low health
up to 50% increase when near death",
maxCount: 1,
count: 0,
@@ -1057,7 +1077,7 @@ const b = {
},
{
name: "self-replication",
- description: "when missiles explode
they fire +1 smaller missiles",
+ description: "after missiles explode
they launch +1 smaller missile",
maxCount: 9,
count: 0,
allowed() {
@@ -1071,6 +1091,22 @@ const b = {
b.modBabyMissiles = 0;
}
},
+ {
+ name: "MIRV",
+ description: "launch 3 small missiles instead of 1
2x increase in delay after firing",
+ maxCount: 1,
+ count: 0,
+ allowed() {
+ return b.haveGunCheck("missiles")
+ },
+ requires: "missiles",
+ effect() {
+ b.isMod3Missiles = true;
+ },
+ remove() {
+ b.isMod3Missiles = false;
+ }
+ },
{
name: "optimized shell packing",
description: "flak ammo drops contain 3x more shells",
@@ -1107,6 +1143,22 @@ const b = {
b.modGrenadeFragments = 0
}
},
+ {
+ name: "rocket-propelled grenade",
+ description: "grenades are rapidly accelerated forward
map collisions trigger an explosion",
+ maxCount: 1,
+ count: 0,
+ allowed() {
+ return b.haveGunCheck("grenades")
+ },
+ requires: "grenades",
+ effect() {
+ b.isModRPG = true;
+ },
+ remove() {
+ b.isModRPG = false;
+ }
+ },
{
name: "electromagnetic pulse",
description: "vacuum bomb's explosion destroys shields
and does 20% more damage",
@@ -1467,7 +1519,7 @@ const b = {
},
{
name: "renormalization",
- description: "phase decoherence field has increased visibility
and 3x less energy drain when firing",
+ description: "phase decoherence has increased visibility
and 3x less energy drain when firing",
maxCount: 1,
count: 0,
allowed() {
@@ -1613,6 +1665,15 @@ const b = {
}
}
},
+ damageFromMods() {
+ let dmg = 1
+ if (b.isModLowHealthDmg) dmg *= (3 / (2 + Math.min(mech.health, 1))) //up to 50% dmg at zero player health //if this changes all update display in modOnHealthChange()
+ if (b.isModHarmDamage && mech.lastHarmCycle + 300 > mech.cycle) dmg *= 2;
+ if (b.isModEnergyLoss) dmg *= 1.33;
+ if (b.isModRest && player.speed < 1) dmg *= 1.20;
+ if (b.isModEnergyDamage) dmg *= 1 + mech.energy / 5;
+ return dmg
+ },
bulletRemove() { //run in main loop
//remove bullet if at end cycle for that bullet
let i = bullet.length;
@@ -1842,12 +1903,12 @@ const b = {
bullet[me].onEnd = function () {
b.explosion(this.position, this.explodeRad * size); //makes bullet do explosive damage at end
for (let i = 0; i < spawn; i++) {
- b.missile(this.position, 2 * Math.PI * Math.random(), 0, 0.65)
+ b.missile(this.position, 2 * Math.PI * Math.random(), 0, 0.7 * size)
}
}
bullet[me].onDmg = function () {
this.tryToLockOn();
- // this.endCycle = 0; //bullet ends cycle after doing damage // also triggers explosion
+ this.endCycle = 0; //bullet ends cycle after doing damage // also triggers explosion
};
bullet[me].lockedOn = null;
bullet[me].tryToLockOn = function () {
@@ -1874,7 +1935,7 @@ const b = {
if (this.lockedOn && Vector.magnitude(Vector.sub(this.position, this.lockedOn.position)) < this.explodeRad) {
// console.log('hit')
this.endCycle = 0; //bullet ends cycle after doing damage //also triggers explosion
- this.lockedOn.damage(b.dmgScale * 5 * size); //does extra damage to target
+ this.lockedOn.damage(b.dmgScale * 4 * size); //does extra damage to target
}
};
bullet[me].do = function () {
@@ -2875,7 +2936,7 @@ const b = {
},
{
name: "missiles",
- description: "fire missiles that accelerate towards mobs
explodes when near target",
+ description: "launch missiles that accelerate towards mobs
explodes when near target",
ammo: 0,
ammoPack: 4,
have: false,
@@ -2884,15 +2945,51 @@ const b = {
fireCycle: 0,
ammoLoaded: 0,
fire() {
- mech.fireCDcycle = mech.cycle + Math.floor(mech.crouch ? 50 : 25); // cool down
- b.missile({
- x: mech.pos.x + 40 * Math.cos(mech.angle),
- y: mech.pos.y + 40 * Math.sin(mech.angle) - 3
- },
- mech.angle + (0.5 - Math.random()) * (mech.crouch ? 0 : 0.2),
- -3 * (0.5 - Math.random()) + (mech.crouch ? 25 : -8) * b.modFireRate,
- 1, b.modBabyMissiles)
- bullet[bullet.length - 1].force.y += 0.0006; //a small push down at first to make it seem like the missile is briefly falling
+ if (b.isMod3Missiles) {
+ if (mech.crouch) {
+ mech.fireCDcycle = mech.cycle + 80; // cool down
+ const direction = {
+ x: Math.cos(mech.angle),
+ y: Math.sin(mech.angle)
+ }
+ const push = Vector.mult(Vector.perp(direction), 0.0007)
+ for (let i = 0; i < 3; i++) {
+ //missile(where, dir, speed, size = 1, spawn = 0) {
+ b.missile({
+ x: mech.pos.x + 40 * direction.x,
+ y: mech.pos.y + 40 * direction.y
+ }, mech.angle + 0.06 * (1 - i), 0, 0.7, b.modBabyMissiles)
+ bullet[bullet.length - 1].force.x += push.x * (i - 1);
+ bullet[bullet.length - 1].force.y += push.y * (i - 1);
+ }
+ } else {
+ mech.fireCDcycle = mech.cycle + 60; // cool down
+ const direction = {
+ x: Math.cos(mech.angle),
+ y: Math.sin(mech.angle)
+ }
+ const push = Vector.mult(Vector.perp(direction), 0.0008)
+ for (let i = 0; i < 3; i++) {
+ //missile(where, dir, speed, size = 1, spawn = 0) {
+ b.missile({
+ x: mech.pos.x + 40 * direction.x,
+ y: mech.pos.y + 40 * direction.y
+ }, mech.angle, 0, 0.7, b.modBabyMissiles)
+ bullet[bullet.length - 1].force.x += push.x * (i - 1);
+ bullet[bullet.length - 1].force.y += push.y * (i - 1);
+ }
+ }
+ } else {
+ mech.fireCDcycle = mech.cycle + Math.floor(mech.crouch ? 50 : 30); // cool down
+ b.missile({
+ x: mech.pos.x + 40 * Math.cos(mech.angle),
+ y: mech.pos.y + 40 * Math.sin(mech.angle) - 3
+ },
+ mech.angle + (0.5 - Math.random()) * (mech.crouch ? 0 : 0.2),
+ -3 * (0.5 - Math.random()) + (mech.crouch ? 25 : -8) * b.modFireRate,
+ 1, b.modBabyMissiles)
+ bullet[bullet.length - 1].force.y += 0.0006; //a small push down at first to make it seem like the missile is briefly falling
+ }
}
},
{
@@ -2953,11 +3050,7 @@ const b = {
const me = bullet.length;
const dir = mech.angle; // + Math.random() * 0.05;
bullet[me] = Bodies.circle(mech.pos.x + 30 * Math.cos(mech.angle), mech.pos.y + 30 * Math.sin(mech.angle), 20, b.fireAttributes(dir, true));
- b.fireProps(mech.crouch ? 30 : 20, mech.crouch ? 43 : 32, dir, me); //cd , speed
Matter.Body.setDensity(bullet[me], 0.0005);
- bullet[me].totalCycles = 100;
- bullet[me].endCycle = game.cycle + Math.floor(mech.crouch ? 120 : 80);
- bullet[me].restitution = 0.2;
bullet[me].explodeRad = 275;
bullet[me].onEnd = function () {
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
@@ -2997,10 +3090,35 @@ const b = {
bullet[me].onDmg = function () {
this.endCycle = 0; //bullet ends cycle after doing damage //this also triggers explosion
};
- bullet[me].do = function () {
- //extra gravity for harder arcs
- this.force.y += this.mass * 0.0025;
- };
+
+ if (b.isModRPG) {
+ b.fireProps(25, mech.crouch ? 60 : -15, dir, me); //cd , speed
+ bullet[me].endCycle = game.cycle + 70;
+ bullet[me].frictionAir = 0.07;
+ const MAG = 0.015
+ bullet[me].thrust = {
+ x: bullet[me].mass * MAG * Math.cos(dir),
+ y: bullet[me].mass * MAG * Math.sin(dir)
+ }
+ bullet[me].do = function () {
+ this.force.x += this.thrust.x;
+ this.force.y += this.thrust.y;
+ if (Matter.Query.collides(this, map).length || Matter.Query.collides(this, body).length) {
+ this.endCycle = 0; //explode if touching map or blocks
+ }
+ };
+ } else {
+ b.fireProps(mech.crouch ? 40 : 30, mech.crouch ? 43 : 32, dir, me); //cd , speed
+ bullet[me].endCycle = game.cycle + Math.floor(mech.crouch ? 120 : 80);
+ bullet[me].restitution = 0.2;
+ bullet[me].explodeRad = 275;
+ bullet[me].do = function () {
+ //extra gravity for harder arcs
+ this.force.y += this.mass * 0.0025;
+ };
+ }
+
+
}
},
{
@@ -3195,7 +3313,7 @@ const b = {
name: "drones",
description: "deploy drones that crash into mobs
collisions reduce their lifespan by 1 second",
ammo: 0,
- ammoPack: 12,
+ ammoPack: 13,
have: false,
isStarterGun: true,
isEasyToAim: true,
diff --git a/js/engine.js b/js/engine.js
index f41da53..cb46a7f 100644
--- a/js/engine.js
+++ b/js/engine.js
@@ -87,40 +87,41 @@ function collisionChecks(event) {
//body + player collision
- // if (game.isBodyDamage) {
- // if (pairs[i].bodyA === playerBody || pairs[i].bodyA === playerHead) {
- // collidePlayer(pairs[i].bodyB)
- // } else if (pairs[i].bodyB === playerBody || pairs[i].bodyB === playerHead) {
- // collidePlayer(pairs[i].bodyA)
- // }
- // }
+ if (game.isBodyDamage) {
+ if (pairs[i].bodyA === playerBody || pairs[i].bodyA === playerHead) {
+ collidePlayer(pairs[i].bodyB)
+ } else if (pairs[i].bodyB === playerBody || pairs[i].bodyB === playerHead) {
+ collidePlayer(pairs[i].bodyA)
+ }
+ }
- // function collidePlayer(obj) {
- // //player dmg from hitting a body
- // if (obj.classType === "body" && mech.collisionImmuneCycle < mech.cycle) {
- // const velocityThreshold = 13
- // if (player.position.y > obj.position.y) { //block is above the player look at total momentum difference
- // const velocityDiffMag = Vector.magnitude(Vector.sub(player.velocity, obj.velocity))
- // if (velocityDiffMag > velocityThreshold) hit(velocityDiffMag - velocityThreshold)
- // } else { //block is below player only look at horizontal momentum difference
- // const velocityDiffMagX = Math.abs(obj.velocity.x - player.velocity.x)
- // if (velocityDiffMagX > velocityThreshold) hit(velocityDiffMagX - velocityThreshold)
- // }
+ function collidePlayer(obj) {
+ //player dmg from hitting a body
+ // if ( mech.collisionImmuneCycle < mech.cycle) {
+ if (obj.classType === "body" && obj.speed > 10 && mech.collisionImmuneCycle < mech.cycle) {
+ const velocityThreshold = 30 //keep this lines up with player.enterLand numbers (130/5 = 26)
+ if (player.position.y > obj.position.y) { //block is above the player look at total momentum difference
+ const velocityDiffMag = Vector.magnitude(Vector.sub(player.velocity, obj.velocity))
+ if (velocityDiffMag > velocityThreshold) hit(velocityDiffMag - velocityThreshold)
+ } else { //block is below player only look at horizontal momentum difference
+ const velocityDiffMagX = Math.abs(obj.velocity.x - player.velocity.x)
+ if (velocityDiffMagX > velocityThreshold) hit(velocityDiffMagX - velocityThreshold)
+ }
- // function hit(dmg) {
- // mech.collisionImmuneCycle = mech.cycle + b.modCollisionImmuneCycles; //player is immune to collision damage for 30 cycles
- // dmg = Math.min(Math.max(Math.sqrt(dmg) * obj.mass * 0.01, 0.02), 0.15);
- // mech.damage(dmg);
- // game.drawList.push({ //add dmg to draw queue
- // x: pairs[i].activeContacts[0].vertex.x,
- // y: pairs[i].activeContacts[0].vertex.y,
- // radius: dmg * 500,
- // color: game.mobDmgColor,
- // time: game.drawTime
- // });
- // }
- // }
- // }
+ function hit(dmg) {
+ mech.collisionImmuneCycle = mech.cycle + b.modCollisionImmuneCycles; //player is immune to collision damage for 30 cycles
+ dmg = Math.min(Math.max(Math.sqrt(dmg) * obj.mass * 0.01, 0.02), 0.15);
+ mech.damage(dmg);
+ game.drawList.push({ //add dmg to draw queue
+ x: pairs[i].activeContacts[0].vertex.x,
+ y: pairs[i].activeContacts[0].vertex.y,
+ radius: dmg * 500,
+ color: game.mobDmgColor,
+ time: game.drawTime
+ });
+ }
+ }
+ }
// function collidePlayer(obj, speedThreshold = 12, massThreshold = 2) {
// //player dmg from hitting a body
diff --git a/js/game.js b/js/game.js
index a3c8c0f..f4be07d 100644
--- a/js/game.js
+++ b/js/game.js
@@ -711,9 +711,16 @@ const game = {
}
}
- if (b.isModEnergyDamage) {
- document.getElementById("mod-capacitor").innerHTML = `(+${(mech.energy/0.05).toFixed(0)}%)`
- }
+ // if (b.isModEnergyDamage) {
+ // document.getElementById("mod-capacitor").innerHTML = `(+${(mech.energy/0.05).toFixed(0)}%)`
+ // }
+ // if (b.isModRest) {
+ // if (player.speed < 1) {
+ // document.getElementById("mod-rest").innerHTML = `(+20%)`
+ // } else {
+ // document.getElementById("mod-rest").innerHTML = `(+0%)`
+ // }
+ // }
if (mech.lastKillCycle + 300 > mech.cycle) { //effects active for 5 seconds after killing a mob
if (b.isModEnergyRecovery) {
diff --git a/js/index.js b/js/index.js
index bea7ae1..c7b3ea3 100644
--- a/js/index.js
+++ b/js/index.js
@@ -83,8 +83,11 @@ const build = {
health: ${(mech.health*100).toFixed(0)}% energy: ${(mech.energy*100).toFixed(0)}% mass: ${player.mass.toFixed(1)}
position: (${player.position.x.toFixed(1)}, ${player.position.y.toFixed(1)}) velocity: (${player.velocity.x.toFixed(1)}, ${player.velocity.y.toFixed(1)})
+
global damage increase: ${((b.damageFromMods()-1)*100).toFixed(0)}%
+
global harm reduction: ${((1-mech.harmReduction())*100).toFixed(0)}%
`;
+
let countGuns = 0
let countMods = 0
for (let i = 0, len = b.guns.length; i < len; i++) {
diff --git a/js/level.js b/js/level.js
index da21787..5a24b26 100644
--- a/js/level.js
+++ b/js/level.js
@@ -15,12 +15,12 @@ const level = {
if (build.isURLBuild && level.levelsCleared === 0) build.onLoadPowerUps();
if (level.levelsCleared === 0) { //this code only runs on the first level
// level.difficultyIncrease(9)
- // b.giveGuns("wave beam")
- // mech.setField("phase decoherence field")
+ // b.giveGuns("missiles")
+ // mech.setField("time dilation field")
// b.giveMod("renormalization");
// b.giveMod("pocket universe");
- // b.giveMod("wave packet");
- // b.giveGuns("laser")
+ // b.giveGuns("grenades")
+ // b.giveMod("rocket-propelled grenade");
// mech.setField("pilot wave")
level.intro(); //starting level
@@ -154,7 +154,7 @@ const level = {
// spawn.bomberBoss(2900, -500)
spawn.stabber(1200, -500)
- spawn.chaser(1200, -500)
+ // spawn.chaser(1200, -500)
// spawn.nodeBoss(1200, -500, "spiker")
// spawn.hopper(1200, -500)
// spawn.timeSkipBoss(2900, -500)
@@ -264,7 +264,7 @@ const level = {
y: -600,
width: 400,
height: 500,
- color: "#cee"
+ color: "#dee"
});
level.fill.push({
@@ -272,7 +272,7 @@ const level = {
y: -1000,
width: 2750,
height: 1000,
- color: "rgba(0,20,40,0.1)"
+ color: "rgba(0,10,30,0.04)"
});
const lineColor = "#ddd"
@@ -606,6 +606,7 @@ const level = {
level.exit.y = -300;
spawn.mapRect(3600, -285, 100, 50); //ground bump wall
//mobs that spawn in exit room
+ spawn.bodyRect(4850, -750, 300, 25, 0.6); //
spawn.randomSmallMob(4100, -100);
spawn.randomSmallMob(4600, -100);
spawn.randomMob(3765, -450, 0.3);
@@ -629,7 +630,7 @@ const level = {
level.exit.x = -550;
level.exit.y = -2030;
spawn.mapRect(-550, -2015, 100, 50); //ground bump wall
- spawn.boost(4950, 0, 1600);
+ spawn.boost(4950, 0, 1100);
level.fillBG.push({
x: -650,
y: -2300,
@@ -761,7 +762,6 @@ const level = {
spawn.mapRect(3450, -1000, 50, 580); //left building wall
spawn.bodyRect(3460, -420, 30, 144);
spawn.mapRect(5450, -775, 100, 875); //right building wall
- spawn.bodyRect(4850, -750, 300, 25, 0.8);
spawn.bodyRect(3925, -1400, 100, 150, 0.8);
spawn.mapRect(3450, -1250, 1090, 50);
// spawn.mapRect(3450, -1225, 50, 75);
diff --git a/js/mobs.js b/js/mobs.js
index bae4987..ae98f40 100644
--- a/js/mobs.js
+++ b/js/mobs.js
@@ -946,13 +946,13 @@ const mobs = {
},
damage(dmg, isBypassShield = false) {
if (!this.isShielded || isBypassShield) {
+ dmg *= b.damageFromMods()
+ //mobs specific damage changes
dmg /= Math.sqrt(this.mass)
if (this.shield) dmg *= 0.04
- if (b.isModLowHealthDmg) dmg *= (3 / (2 + Math.min(mech.health, 1))) //up to 50% dmg at zero player health //if this changes all update display in modOnHealthChange()
- if (b.isModHarmDamage && mech.lastHarmCycle + 300 > mech.cycle) dmg *= 2;
- if (b.isModEnergyLoss) dmg *= 1.33;
- if (b.isModEnergyDamage) dmg *= 1 + mech.energy / 5;
if (b.isModFarAwayDmg) dmg *= 1 + Math.sqrt(Math.max(500, Math.min(3000, this.distanceToPlayer())) - 500) * 0.0067 //up to 50% dmg at max range of 3500
+
+ //energy and heal drain should be calculated after damage boosts
if (b.modEnergySiphon && dmg !== Infinity) mech.energy += Math.min(this.health, dmg) * b.modEnergySiphon
if (b.modHealthDrain && dmg !== Infinity) mech.addHealth(Math.min(this.health, dmg) * b.modHealthDrain)
this.health -= dmg
diff --git a/js/player.js b/js/player.js
index 8fde508..10fba08 100644
--- a/js/player.js
+++ b/js/player.js
@@ -202,7 +202,7 @@ const mech = {
} else {
//sets a hard land where player stays in a crouch for a bit and can't jump
//crouch is forced in keyMove() on ground section below
- const momentum = player.velocity.y * player.mass //player mass is 5 so this triggers at 20 down velocity, unless the player is holding something
+ const momentum = player.velocity.y * player.mass //player mass is 5 so this triggers at 26 down velocity, unless the player is holding something
if (momentum > 130) {
mech.doCrouch();
mech.yOff = mech.yOffWhen.jump;
@@ -503,6 +503,17 @@ const mech = {
},
defaultFPSCycle: 0, //tracks when to return to normal fps
collisionImmuneCycle: 0, //used in engine
+ harmReduction() {
+ let dmg = 1
+ dmg *= mech.fieldDamageResistance
+ if (b.modEnergyRegen === 0) dmg *= 0.5 //0.22 + 0.78 * mech.energy //77% damage reduction at zero energy
+ if (b.isModEntanglement && b.inventory[0] === b.activeGun) {
+ for (let i = 0, len = b.inventory.length; i < len; i++) {
+ dmg *= 0.84 // 1 - 0.16
+ }
+ }
+ return dmg
+ },
damage(dmg) {
mech.lastHarmCycle = mech.cycle
@@ -522,14 +533,8 @@ const mech = {
y: 0
})
}
+ dmg *= mech.harmReduction()
- dmg *= mech.fieldDamageResistance
- if (b.modEnergyRegen === 0) dmg *= 0.5 //0.22 + 0.78 * mech.energy //77% damage reduction at zero energy
- if (b.isModEntanglement && b.inventory[0] === b.activeGun) {
- for (let i = 0, len = b.inventory.length; i < len; i++) {
- dmg *= 0.84 // 1 - 0.16
- }
- }
if (b.isModEnergyHealth) {
mech.energy -= dmg;
if (mech.energy < 0 || isNaN(mech.energy)) {
@@ -1820,7 +1825,7 @@ const mech = {
mech.hold = function () {
function drawField(radius) {
- radius *= 0.7 + 0.6 * mech.energy;
+ radius *= 0.8 + 0.7 * 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);
@@ -1858,13 +1863,14 @@ const mech = {
mech.lookForPickUp();
const DRAIN = 0.0004 + 0.0002 * player.speed + ((!b.modRenormalization && mech.fireCDcycle > mech.cycle) ? 0.005 : 0.0017)
+ mech.energy -= DRAIN;
if (mech.energy > DRAIN) {
- mech.energy -= DRAIN;
- if (mech.energy < 0.001) {
- mech.fieldCDcycle = mech.cycle + 120;
- mech.energy = 0;
- }
- this.fieldRange = this.fieldRange * 0.9 + 0.1 * 160
+ // 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.87 + 0.13 * 160
drawField(this.fieldRange)
mech.isStealth = true //isStealth disables most uses of foundPlayer()
@@ -1903,32 +1909,33 @@ const mech = {
}
}
}
+ } 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();
} else {
// this.fieldRange = 3000
if (this.fieldRange < 2000 && mech.holdingTarget === null) {
- this.fieldRange += 20
+ this.fieldRange += 40
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)
}
- // mech.drawFieldMeter()
+
if (mech.energy < mech.fieldEnergyMax) {
mech.energy += mech.fieldRegen;
const xOff = mech.pos.x - mech.radius * mech.fieldEnergyMax
const yOff = mech.pos.y - 50
-
ctx.fillStyle = "rgba(0, 0, 0, 0.3)";
ctx.fillRect(xOff, yOff, 60 * mech.fieldEnergyMax, 10);
-
ctx.fillStyle = mech.fieldMeterColor;
ctx.fillRect(xOff, yOff, 60 * mech.energy, 10);
-
ctx.beginPath()
ctx.rect(xOff, yOff, 60 * mech.fieldEnergyMax, 10);
- // ctx.fill();
ctx.strokeStyle = "rgb(0, 0, 0)";
ctx.lineWidth = 1;
ctx.stroke();
@@ -1992,7 +1999,31 @@ const mech = {
y: mech.fieldPosition.y * smooth + game.mouseInGame.y * (1 - smooth),
}
}
- mech.grabPowerUp();
+
+ for (let i = 0, len = powerUp.length; i < len; ++i) {
+ const dxP = mech.fieldPosition.x - powerUp[i].position.x;
+ const dyP = mech.fieldPosition.y - powerUp[i].position.y;
+ const dist2 = dxP * dxP + dyP * dyP;
+ // float towards field if looking at and in range or if very close to player
+ if (dist2 < mech.fieldRadius * mech.fieldRadius && (mech.lookingAt(powerUp[i]) || dist2 < 16000) && !(mech.health === mech.maxHealth && powerUp[i].name === "heal")) {
+ powerUp[i].force.x += 7 * (dxP / dist2) * powerUp[i].mass;
+ powerUp[i].force.y += 7 * (dyP / dist2) * powerUp[i].mass - powerUp[i].mass * game.g; //negate gravity
+ //extra friction
+ Matter.Body.setVelocity(powerUp[i], {
+ x: powerUp[i].velocity.x * 0.11,
+ y: powerUp[i].velocity.y * 0.11
+ });
+ if (dist2 < 5000 && !game.isChoosing) { //use power up if it is close enough
+ if (b.isModMassEnergy) mech.energy = mech.fieldEnergyMax * 2;
+ powerUp[i].effect();
+ Matter.World.remove(engine.world, powerUp[i]);
+ powerUp.splice(i, 1);
+ mech.fieldRadius += 50
+ break; //because the array order is messed up after splice
+ }
+ }
+ }
+
if (mech.energy > 0.01) {
//find mouse velocity
const diff = Vector.sub(mech.fieldPosition, mech.lastFieldPosition)
diff --git a/js/spawn.js b/js/spawn.js
index e524d58..184c02c 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -937,7 +937,7 @@ const spawn = {
}
},
stabber(x, y, radius = 25 + Math.ceil(Math.random() * 15)) {
- mobs.spawn(x, y, 4, radius, "rgb(220,50,205)"); //can't have sides above 6 or collision events don't work (probably because of a convex problem)
+ mobs.spawn(x, y, 6, radius, "rgb(220,50,205)"); //can't have sides above 6 or collision events don't work (probably because of a convex problem)
let me = mob[mob.length - 1];
me.accelMag = 0.0006 * game.accelScale;
// me.g = 0.0002; //required if using 'gravity'
@@ -948,54 +948,64 @@ const spawn = {
me.isSpikeReset = true;
Matter.Body.rotate(me, Math.PI * 0.1);
spawn.shield(me, x, y);
- me.onDamage = function () {};
- me.do = function () {
- // this.gravity();
- this.seePlayerByLookingAt();
- this.checkStatus();
- this.attraction();
-
- if (this.isSpikeReset) {
- if (this.seePlayer.recall) {
- const dist = Vector.sub(this.seePlayer.position, this.position);
- const distMag = Vector.magnitude(dist);
- if (distMag < this.radius * 7) {
- //find nearest vertex
- let nearestDistance = Infinity
- for (let i = 0, len = this.vertices.length; i < len; i++) {
- //find distance to player for each vertex
- const dist = Vector.sub(this.seePlayer.position, this.vertices[i]);
- const distMag = Vector.magnitude(dist);
- //save the closest distance
- if (distMag < nearestDistance) {
- this.spikeVertex = i
- nearestDistance = distMag
- }
- }
- this.spikeLength = 1
- this.isSpikeGrowing = true;
- this.isSpikeReset = false;
- Matter.Body.setAngularVelocity(this, 0)
- }
- }
- } else {
- if (this.isSpikeGrowing) {
- this.spikeLength += 1
- if (this.spikeLength > 9) {
- this.isSpikeGrowing = false;
- }
- } else {
- this.spikeLength -= 0.1
- if (this.spikeLength < 1) {
- this.spikeLength = 1
- this.isSpikeReset = true
- }
- }
+ // me.onDamage = function () {};
+ me.onDeath = function () {
+ if (this.spikeLength > 4) {
+ this.spikeLength = 4
const spike = Vector.mult(Vector.normalise(Vector.sub(this.vertices[this.spikeVertex], this.position)), this.radius * this.spikeLength)
this.vertices[this.spikeVertex].x = this.position.x + spike.x
this.vertices[this.spikeVertex].y = this.position.y + spike.y
}
};
+ me.do = function () {
+ if (!mech.isBodiesAsleep) {
+ // this.gravity();
+ this.seePlayerByLookingAt();
+ this.checkStatus();
+ this.attraction();
+
+ if (this.isSpikeReset) {
+ if (this.seePlayer.recall) {
+ const dist = Vector.sub(this.seePlayer.position, this.position);
+ const distMag = Vector.magnitude(dist);
+ if (distMag < this.radius * 7) {
+ //find nearest vertex
+ let nearestDistance = Infinity
+ for (let i = 0, len = this.vertices.length; i < len; i++) {
+ //find distance to player for each vertex
+ const dist = Vector.sub(this.seePlayer.position, this.vertices[i]);
+ const distMag = Vector.magnitude(dist);
+ //save the closest distance
+ if (distMag < nearestDistance) {
+ this.spikeVertex = i
+ nearestDistance = distMag
+ }
+ }
+ this.spikeLength = 1
+ this.isSpikeGrowing = true;
+ this.isSpikeReset = false;
+ Matter.Body.setAngularVelocity(this, 0)
+ }
+ }
+ } else {
+ if (this.isSpikeGrowing) {
+ this.spikeLength += 1
+ if (this.spikeLength > 9) {
+ this.isSpikeGrowing = false;
+ }
+ } else {
+ this.spikeLength -= 0.1
+ if (this.spikeLength < 1) {
+ this.spikeLength = 1
+ this.isSpikeReset = true
+ }
+ }
+ const spike = Vector.mult(Vector.normalise(Vector.sub(this.vertices[this.spikeVertex], this.position)), this.radius * this.spikeLength)
+ this.vertices[this.spikeVertex].x = this.position.x + spike.x
+ this.vertices[this.spikeVertex].y = this.position.y + spike.y
+ }
+ }
+ };
},
striker(x, y, radius = 14 + Math.ceil(Math.random() * 25)) {
mobs.spawn(x, y, 5, radius, "rgb(221,102,119)");
diff --git a/todo.txt b/todo.txt
index 7f3bf37..ce9d391 100644
--- a/todo.txt
+++ b/todo.txt
@@ -2,6 +2,38 @@
************** TODO - n-gon **************
+foam - check for touching map / blocks and slow foam down rather then bounce off walls
+quantum foam should just skip the shield
+
+red flashes when you take damage were replaced with the color of your energy bar
+ When you have mass energy equivalence
+
+mod - missiles: fire 3 small missiles
+ disables missile replication mod
+
+lore - a robot (the player) gains self awareness
+ each mod/gun/field is a new tech
+ all the technology leads to the singularity
+ each game run is actually the mech simulating a possible escape
+ this is why the graphics are so bad, its just a simulation
+ final mod is "this is just a simulation"
+ you get immortality and Infinity damage
+ the next level is the final level
+ when you die with Quantum Immortality there is a chance of lore text
+
+atmosphere levels: change the pace, give the user a rest between combat
+ low or no combat, but more graphics
+ explore lore
+ find power ups in "wrecked" mechs representing previous simulations
+ how you could leave something in one simulation that effects a different simulation
+ Maybe some strange quantum physics principle.
+ add text for player thoughts?
+ simple puzzles
+ cool looking stuff
+ large rotating fan that the player has to move through
+ nonaggressive mobs
+ in the final level you see your self at the starting level, with the wires
+ you shoot your self to wake up?
bullets cost 5 life instead of ammo, but return 5 life when they hit a mob
replace life with energy or ammo?
@@ -37,8 +69,6 @@ boss mob - just a faster and larger version of a springer mob
mob - time skipper: sends a pulse wave out that will cause time to jump forward 1 second.
-mob stabber - extends one vector like the shooter, but quickly in order to stab
-
mob sniper - targeting laser, then a high speed, no gravity bullet
mod - increase laser bot range, and reduce energy drain
@@ -50,35 +80,9 @@ mod - blocks stun mobs
settings - custom keys binding
-lore - a robot (the player) gains self awareness
- each mod/gun/field is a new tech
- all the technology leads to the singularity
- each game run is actually the mech simulating a possible escape
- this is why the graphics are so bad, its just a simulation
- final mod is "this is just a simulation"
- you get immortality and Infinity damage
- the next level is the final level
- when you die with Quantum Immortality there is a chance of lore text
-
-atmosphere levels: change the pace, give the user a rest between combat
- low or no combat, but more graphics
- explore lore
- find power ups in "wrecked" mechs representing previous simulations
- how you could leave something in one simulation that effects a different simulation
- Maybe some strange quantum physics principle.
- add text for player thoughts?
- simple puzzles
- cool looking stuff
- large rotating fan that the player has to move through
- nonaggressive mobs
- in the final level you see your self at the starting level, with the wires
- you shoot your self to wake up?
-
css transition for pause menu
-mod - do extra damage based on your speed
- do more damage when not moving?
- take less damage when not moving?
+mod - do more damage when not moving?
gun/field: portals
use the code from mines to get them to stick to walls