diff --git a/js/bullets.js b/js/bullets.js
index 9e0a635..73ca1b0 100644
--- a/js/bullets.js
+++ b/js/bullets.js
@@ -78,6 +78,7 @@ const b = {
modWaveHelix: null,
isModSporeFollow: null,
isModNailPoison: null,
+ isModEnergyHealth: null,
modOnHealthChange() { //used with acid mod
if (b.isModAcidDmg && mech.health > 0.8) {
b.modAcidDmg = 0.5
@@ -557,15 +558,35 @@ const b = {
b.isModEntanglement = false;
}
},
+ {
+ name: "mass-energy equivalence",
+ description: "your energy replaces your health
you can't die if your energy is above zero",
+ maxCount: 1,
+ count: 0,
+ allowed() {
+ return !b.isModPiezo
+ },
+ requires: "not piezoelectricity",
+ effect: () => {
+ mech.health = 0
+ b.modOnHealthChange();
+ mech.displayHealth();
+ b.isModEnergyHealth = true;
+ },
+ remove() {
+ b.isModEnergyHealth = false;
+ mech.health = mech.energy;
+ }
+ },
{
name: "piezoelectricity",
description: "colliding with mobs fills your energy
15% less harm from mob collisions",
maxCount: 1,
count: 0,
allowed() {
- return true
+ return !b.isModEnergyHealth
},
- requires: "",
+ requires: "not mass-energy equivalence",
effect() {
b.isModPiezo = true;
mech.energy = mech.fieldEnergyMax;
@@ -678,7 +699,7 @@ const b = {
}
},
{
- name: "mass-energy equivalence",
+ name: "pair production",
description: "power ups overfill your energy
temporarily gain twice your maximum",
maxCount: 1,
count: 0,
@@ -822,7 +843,7 @@ const b = {
},
{
name: "depleted uranium rounds",
- description: `your bullets are +13% larger
increased mass and physical damage`,
+ description: `your bullets are +16% larger
increased mass and physical damage`,
count: 0,
maxCount: 9,
allowed() {
@@ -830,7 +851,7 @@ const b = {
},
requires: "minigun, shotgun, super balls",
effect() {
- b.modBulletSize += 0.13
+ b.modBulletSize += 0.16
},
remove() {
b.modBulletSize = 1;
@@ -2042,8 +2063,7 @@ const b = {
},
onEnd() {},
do() {
- //find mob targets
- if (!(game.cycle % this.lookFrequency)) {
+ if (!(game.cycle % this.lookFrequency)) { //find mob targets
this.closestTarget = null;
this.lockedOn = null;
let closeDist = Infinity;
@@ -2061,8 +2081,8 @@ const b = {
}
}
}
- //accelerate towards mobs
- if (this.lockedOn && this.lockedOn.alive) {
+
+ if (this.lockedOn && this.lockedOn.alive) { //accelerate towards mobs
this.force = Vector.mult(Vector.normalise(Vector.sub(this.lockedOn.position, this.position)), this.mass * this.thrust)
} else if (b.isModSporeFollow && this.lockedOn !== undefined) { //move towards player
//checking for undefined means that the spores don't go after the player until it has looked and not found a target
@@ -2097,7 +2117,7 @@ const b = {
friction: 0,
frictionAir: 0.10,
restitution: 0.3,
- dmg: 0.2, //damage done in addition to the damage from momentum
+ dmg: 0.18, //damage done in addition to the damage from momentum
lookFrequency: 10 + Math.floor(7 * Math.random()),
endCycle: game.cycle + 120 * b.isModBulletsLastLonger, //Math.floor((1200 + 420 * Math.random()) * b.isModBulletsLastLonger),
classType: "bullet",
diff --git a/js/game.js b/js/game.js
index 6394034..a3c8c0f 100644
--- a/js/game.js
+++ b/js/game.js
@@ -686,31 +686,30 @@ const game = {
}
},
checks() {
- if (mech.pos.y > game.fallHeight) { // if 4000px deep
- if (game.difficultyMode > 2) {
- mech.death();
- } else {
- Matter.Body.setVelocity(player, {
- x: 0,
- y: 0
- });
- Matter.Body.setPosition(player, {
- x: level.enter.x + 50,
- y: level.enter.y - 20
- });
- // Matter.Body.setPosition(player, {
- // x: player.position.x,
- // y: -7000
- // });
- // game.noCameraScroll()
-
- mech.energy = 0;
- if (game.difficultyMode === 2) mech.damage(0.3);
- if (game.difficultyMode === 1) mech.damage(0.1);
- }
- }
-
if (!(mech.cycle % 60)) { //once a second
+ if (mech.pos.y > game.fallHeight) { // if 4000px deep
+ if (game.difficultyMode > 2) {
+ mech.death();
+ } else {
+ Matter.Body.setVelocity(player, {
+ x: 0,
+ y: 0
+ });
+ Matter.Body.setPosition(player, {
+ x: level.enter.x + 50,
+ y: level.enter.y - 20
+ });
+ // Matter.Body.setPosition(player, {
+ // x: player.position.x,
+ // y: -7000
+ // });
+ // game.noCameraScroll()
+
+ if (game.difficultyMode === 2) mech.damage(0.3);
+ if (game.difficultyMode === 1) mech.damage(0.1);
+ mech.energy = 0;
+ }
+ }
if (b.isModEnergyDamage) {
document.getElementById("mod-capacitor").innerHTML = `(+${(mech.energy/0.05).toFixed(0)}%)`
diff --git a/js/index.js b/js/index.js
index 3b52c3d..187cbca 100644
--- a/js/index.js
+++ b/js/index.js
@@ -458,6 +458,35 @@ document.body.addEventListener("mousedown", (e) => {
}
});
+document.body.addEventListener("mouseenter", (e) => { //prevents mouse getting stuck when leaving the window
+ // console.log(e)
+ if (e.which === 1) {
+ game.mouseDown = true;
+ } else {
+ game.mouseDown = false;
+ }
+
+ if (e.which === 3) {
+ game.mouseDownRight = true;
+ } else {
+ game.mouseDownRight = false;
+ }
+});
+document.body.addEventListener("mouseleave", (e) => { //prevents mouse getting stuck when leaving the window
+ // console.log(e)
+ if (e.which === 1) {
+ game.mouseDown = true;
+ } else {
+ game.mouseDown = false;
+ }
+
+ if (e.which === 3) {
+ game.mouseDownRight = true;
+ } else {
+ game.mouseDownRight = false;
+ }
+});
+
//keyboard input
const keys = [];
document.body.addEventListener("keydown", (e) => {
@@ -537,14 +566,14 @@ function cycle() {
}
game.loop();
- if (isNaN(mech.health)) {
- console.log(`mech.health = ${mech.health}`)
- game.paused = true;
- game.replaceTextLog = true;
- build.pauseGrid()
- document.body.style.cursor = "auto";
- alert("health is NaN, please report this bug to the discord \n https://discordapp.com/invite/2eC9pgJ")
- }
+ // if (isNaN(mech.health) || isNaN(mech.energy)) {
+ // console.log(`mech.health = ${mech.health}`)
+ // game.paused = true;
+ // game.replaceTextLog = true;
+ // build.pauseGrid()
+ // document.body.style.cursor = "auto";
+ // alert("health is NaN, please report this bug to the discord \n https://discordapp.com/invite/2eC9pgJ")
+ // }
// for (let i = 0, len = loop.length; i < len; i++) {
// loop[i]()
// }
diff --git a/js/level.js b/js/level.js
index b8a32ac..1df4d51 100644
--- a/js/level.js
+++ b/js/level.js
@@ -16,10 +16,9 @@ const level = {
if (level.levelsCleared === 0) { //this code only runs on the first level
// level.difficultyIncrease(9)
// b.giveGuns("vacuum bomb")
- // mech.setField("pilot wave")
- // mech.energy = 0.1;
- // b.giveMod("negative feedback");
- // b.giveMod("photovoltaics");
+ mech.setField("pilot wave")
+ // b.giveMod("energy");
+ // b.giveMod("Born rule");
level.intro(); //starting level
// level.testing();
diff --git a/js/player.js b/js/player.js
index adb2689..c71cbd0 100644
--- a/js/player.js
+++ b/js/player.js
@@ -494,10 +494,12 @@ const mech = {
}
},
addHealth(heal) {
- mech.health += heal * game.healScale;
- if (mech.health > mech.maxHealth) mech.health = mech.maxHealth;
- b.modOnHealthChange();
- mech.displayHealth();
+ if (!b.isModEnergyHealth) {
+ mech.health += heal * game.healScale;
+ if (mech.health > mech.maxHealth) mech.health = mech.maxHealth;
+ b.modOnHealthChange();
+ mech.displayHealth();
+ }
},
defaultFPSCycle: 0, //tracks when to return to normal fps
collisionImmuneCycle: 0, //used in engine
@@ -522,41 +524,73 @@ const mech = {
}
dmg *= mech.fieldDamageResistance
- if (!b.modEnergyRegen) dmg *= 0.5 //0.22 + 0.78 * mech.energy //77% damage reduction at zero energy
+ 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)) {
+ if (b.isModDeathAvoid && !b.isModDeathAvoidOnCD) { //&& Math.random() < 0.5
+ b.isModDeathAvoidOnCD = true;
+ mech.energy += dmg //undo the damage
+ if (mech.energy < 0.05) mech.energy = 0.05
+ mech.collisionImmuneCycle = mech.cycle + 30 //disable this.collisionImmuneCycle bonus seconds
- mech.health -= dmg;
- if (mech.health < 0) {
- if (b.isModDeathAvoid && !b.isModDeathAvoidOnCD) { //&& Math.random() < 0.5
- b.isModDeathAvoidOnCD = true;
- mech.health += dmg //undo the damage
- if (mech.health < 0.05) mech.health = 0.05
- mech.collisionImmuneCycle = mech.cycle + 30 //disable this.collisionImmuneCycle bonus seconds
-
- game.wipe = function () { //set wipe to have trails
- ctx.fillStyle = "rgba(255,255,255,0.02)";
- ctx.fillRect(0, 0, canvas.width, canvas.height);
- }
- setTimeout(function () {
- game.wipe = function () { //set wipe to normal
- ctx.clearRect(0, 0, canvas.width, canvas.height);
+ game.wipe = function () { //set wipe to have trails
+ ctx.fillStyle = "rgba(255,255,255,0.02)";
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
}
- // game.replaceTextLog = true;
- // game.makeTextLog("death avoided", 360);
- b.isModDeathAvoidOnCD = false;
- }, 3000);
+ setTimeout(function () {
+ game.wipe = function () { //set wipe to normal
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ }
+ // game.replaceTextLog = true;
+ // game.makeTextLog("death avoided", 360);
+ b.isModDeathAvoidOnCD = false;
+ }, 3000);
- return;
- } else {
- mech.health = 0;
- mech.death();
- return;
+ return;
+ } else {
+ mech.health = 0;
+ mech.energy = 0;
+ mech.death();
+ return;
+ }
+ }
+ } else {
+ mech.health -= dmg;
+ if (mech.health < 0 || isNaN(mech.health)) {
+ if (b.isModDeathAvoid && !b.isModDeathAvoidOnCD) { //&& Math.random() < 0.5
+ b.isModDeathAvoidOnCD = true;
+ mech.health += dmg //undo the damage
+ if (mech.health < 0.05) mech.health = 0.05
+ mech.collisionImmuneCycle = mech.cycle + 30 //disable this.collisionImmuneCycle bonus seconds
+
+ game.wipe = function () { //set wipe to have trails
+ ctx.fillStyle = "rgba(255,255,255,0.02)";
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
+ }
+ setTimeout(function () {
+ game.wipe = function () { //set wipe to normal
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ }
+ // game.replaceTextLog = true;
+ // game.makeTextLog("death avoided", 360);
+ b.isModDeathAvoidOnCD = false;
+ }, 3000);
+
+ return;
+ } else {
+ mech.health = 0;
+ mech.death();
+ return;
+ }
}
}
+
b.modOnHealthChange();
mech.displayHealth();
document.getElementById("dmg").style.transition = "opacity 0s";
@@ -1891,63 +1925,130 @@ const mech = {
}
}
},
- // {
- // name: "pilot wave",
- // description: "push stuff",
- // isEasyToAim: false,
- // effect: () => {
- // game.replaceTextLog = true; //allow text over write
- // mech.lastMouseInGame = {
- // x: game.mouseInGame.x,
- // y: game.mouseInGame.y
- // }
- // mech.drop();
- // mech.fieldPhase = 0;
- // mech.hold = function () {
- // if ((keys[32] || game.mouseDownRight && mech.fieldCDcycle < mech.cycle)) { //not hold but field button is pressed
- // mech.grabPowerUp();
- // //disable if player is inside field
+ {
+ name: "pilot wave",
+ description: "use energy to push blocks with your mouse
energy drain is lower in your line of sight",
+ isEasyToAim: false,
+ effect: () => {
+ game.replaceTextLog = true; //allow text over write
+ mech.fieldPhase = 0;
+ mech.fieldPosition = {
+ x: game.mouseInGame.x,
+ y: game.mouseInGame.y
+ }
+ mech.lastFieldPosition = {
+ x: game.mouseInGame.x,
+ y: game.mouseInGame.y
+ }
+ mech.fieldOn = false;
+ mech.fieldRadius = 0;
+ mech.drop();
+ mech.hold = function () {
+ if ((keys[32] || game.mouseDownRight && mech.fieldCDcycle < mech.cycle)) { //not hold but field button is pressed
- // const radius = 100
- // if (mech.energy > 0.05) {
- // // && Vector.magnitude(Vector.sub(game.mouseInGame, player.position)) > radius * 1.5
- // //find mouse velocity
- // const diff = Vector.sub(game.mouseInGame, mech.lastMouseInGame)
- // const velocity = Vector.mult(Vector.normalise(diff), Math.min(Vector.magnitude(diff), 60)) //limit velocity
- // //find nearby blocks
- // for (let i = 0, len = body.length; i < len; ++i) {
- // if (Vector.magnitude(Vector.sub(body[i].position, game.mouseInGame)) < radius) {
- // // Matter.Query.collides(body, bodies)
- // Matter.Body.setVelocity(body[i], velocity); //give block mouse velocity
- // body[i].force.y -= body[i].mass * game.g; //antigravity
- // //maybe give blocks some weak attraction to mouse
- // }
- // }
- // ctx.beginPath();
- // const rotate = mech.cycle * 0.008;
- // mech.fieldPhase += 0.2 // - 0.5 * Math.sqrt(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(game.mouseInGame.x, game.mouseInGame.y, radius * off1, radius * off2, rotate, 0, 2 * Math.PI);
- // // ctx.arc(game.mouseInGame.x, game.mouseInGame.y, this.fieldRange, 0, 2 * Math.PI);
- // ctx.fillStyle = "#eef";
- // ctx.globalCompositeOperation = "difference";
- // ctx.fill();
- // ctx.strokeStyle = "#000";
- // ctx.lineWidth = 1;
- // ctx.stroke();
- // ctx.globalCompositeOperation = "source-over";
- // }
- // }
- // mech.lastMouseInGame = { //constantly log last mouse position so you can calc mouse velocity
- // x: game.mouseInGame.x,
- // y: game.mouseInGame.y
- // }
- // mech.drawFieldMeter()
- // }
- // }
- // },
+ // if (Matter.Query.ray(map, game.mouseInGame, player.position).length === 0){
+
+ // } else {
+ // mech.fieldOn = false;
+ // }
+
+ if (!mech.fieldOn) {
+ mech.fieldOn = true;
+ mech.fieldPosition = { //smooth the mouse position
+ x: game.mouseInGame.x,
+ y: game.mouseInGame.y
+ }
+ mech.lastFieldPosition = { //used to find velocity of field changes
+ x: mech.fieldPosition.x,
+ y: mech.fieldPosition.y
+ }
+ } else {
+ mech.lastFieldPosition = { //used to find velocity of field changes
+ x: mech.fieldPosition.x,
+ y: mech.fieldPosition.y
+ }
+ const smooth = 0.97
+ mech.fieldPosition = { //smooth the mouse position
+ x: mech.fieldPosition.x * smooth + game.mouseInGame.x * (1 - smooth),
+ y: mech.fieldPosition.y * smooth + game.mouseInGame.y * (1 - smooth),
+ }
+ }
+ // Matter.Query.ray(map, game.mouseInGame, player.position).length === 0
+ //make it so the field only works in line of sight
+ // make the field not get stuck on map when there in no line of site
+ // maybe track the last mouse position, and revert to smooting towards it when mouse leaves line of site
+ // if (Matter.Query.ray(map, mech.fieldPosition, player.position).length === 0)
+
+
+
+ mech.grabPowerUp();
+ //disable if player is inside field
+
+ if (mech.energy > 0.01) {
+ // && Vector.magnitude(Vector.sub(game.mouseInGame, player.position)) > radius * 1.5 //disable effect when near player
+ //find mouse velocity
+ const diff = Vector.sub(mech.fieldPosition, mech.lastFieldPosition)
+ const speed = Vector.magnitude(diff)
+ const velocity = Vector.mult(Vector.normalise(diff), Math.min(speed, 60)) //limit velocity
+ let radius = Math.max(50, 250 - 1.5 * speed) //change radius proportional to mouse speed //run a smoothing function?
+ let isVisible = true
+ if (Matter.Query.ray(map, mech.fieldPosition, player.position).length !== 0) {
+ isVisible = false
+ radius *= 0.2
+ }
+ smooth = 0.9
+ mech.fieldRadius = mech.fieldRadius * smooth + radius * (1 - smooth)
+
+ //find nearby blocks
+ for (let i = 0, len = body.length; i < len; ++i) {
+ if (Vector.magnitude(Vector.sub(body[i].position, mech.fieldPosition)) < mech.fieldRadius) {
+ // Matter.Query.collides(player, [body[i]]).length === 0) { //block is not touching player, for no flying
+ // (Matter.Query.ray(map, game.mouseInGame, player.position).length === 0 ? 1 : 4)
+ const DRAIN = speed * body[i].mass * 0.00002 * (isVisible ? 1 : 4)
+ if (mech.energy > DRAIN) {
+ mech.energy -= DRAIN;
+ Matter.Body.setVelocity(body[i], velocity); //give block mouse velocity
+ body[i].force.y -= body[i].mass * game.g; //remove gravity effects
+ } else {
+ mech.fieldOn = false
+ mech.fieldCDcycle = mech.cycle + 120;
+ mech.fieldRadius = 0
+ break
+ }
+ }
+ }
+ ctx.beginPath();
+ const rotate = mech.cycle * 0.008;
+ mech.fieldPhase += 0.2 // - 0.5 * Math.sqrt(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.fieldPosition.x, mech.fieldPosition.y, 1.2 * mech.fieldRadius * off1, 1.2 * mech.fieldRadius * off2, rotate, 0, 2 * Math.PI);
+ // ctx.ellipse(game.mouseInGame.x, game.mouseInGame.y, radius * off1, radius * off2, -rotate, 0, 2 * Math.PI);
+ // ctx.arc(game.mouseInGame.x, game.mouseInGame.y, this.fieldRange, 0, 2 * Math.PI);
+ ctx.fillStyle = "#fff"; //"#eef";
+ ctx.globalCompositeOperation = "exclusion"; //"exclusion" "difference";
+ ctx.fill();
+ ctx.globalCompositeOperation = "source-over";
+
+ ctx.beginPath();
+ ctx.ellipse(mech.fieldPosition.x, mech.fieldPosition.y, 1.2 * mech.fieldRadius * off1, 1.2 * mech.fieldRadius * off2, rotate, 0, mech.energy * 2 * Math.PI);
+ ctx.strokeStyle = "#000";
+ ctx.lineWidth = 4;
+ ctx.stroke();
+ } else {
+ mech.fieldOn = false
+ mech.fieldCDcycle = mech.cycle + 120;
+ mech.fieldRadius = 0
+ }
+ } else {
+ mech.fieldOn = false
+ mech.fieldRadius = 0
+ }
+ mech.drawFieldMeter()
+ }
+ }
+ },
],
};
\ No newline at end of file
diff --git a/js/powerups.js b/js/powerups.js
index 2ffa226..9d655a8 100644
--- a/js/powerups.js
+++ b/js/powerups.js
@@ -47,10 +47,14 @@ const powerUps = {
return 40 * Math.sqrt(0.1 + Math.random() * 0.5);
},
effect() {
- let heal = 0
- for (let i = 0; i < b.modRecursiveHealing; i++) heal += ((this.size / 40) ** 2)
- if (heal > 0) game.makeTextLog("