diff --git a/js/bullet.js b/js/bullet.js
index 7bd9a00..21c5c80 100644
--- a/js/bullet.js
+++ b/js/bullet.js
@@ -274,6 +274,132 @@ const b = {
}
}
},
+ pulse(energy, angle = mech.angle) {
+ let best;
+ let explosionRange = 1560 * energy
+ let range = 3000
+ const path = [{
+ x: mech.pos.x + 20 * Math.cos(angle),
+ y: mech.pos.y + 20 * Math.sin(angle)
+ },
+ {
+ x: mech.pos.x + range * Math.cos(angle),
+ y: mech.pos.y + range * Math.sin(angle)
+ }
+ ];
+ const vertexCollision = function(v1, v1End, domain) {
+ for (let i = 0; i < domain.length; ++i) {
+ let vertices = domain[i].vertices;
+ const len = vertices.length - 1;
+ for (let j = 0; j < len; j++) {
+ results = game.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
+ if (results.onLine1 && results.onLine2) {
+ const dx = v1.x - results.x;
+ const dy = v1.y - results.y;
+ const dist2 = dx * dx + dy * dy;
+ if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
+ best = {
+ x: results.x,
+ y: results.y,
+ dist2: dist2,
+ who: domain[i],
+ v1: vertices[j],
+ v2: vertices[j + 1]
+ };
+ }
+ }
+ }
+ results = game.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
+ if (results.onLine1 && results.onLine2) {
+ const dx = v1.x - results.x;
+ const dy = v1.y - results.y;
+ const dist2 = dx * dx + dy * dy;
+ if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
+ best = {
+ x: results.x,
+ y: results.y,
+ dist2: dist2,
+ who: domain[i],
+ v1: vertices[0],
+ v2: vertices[len]
+ };
+ }
+ }
+ }
+ };
+ //check for collisions
+ best = {
+ x: null,
+ y: null,
+ dist2: Infinity,
+ who: null,
+ v1: null,
+ v2: null
+ };
+ if (mod.isPulseAim) { //find mobs in line of sight
+ let dist = 2200
+ for (let i = 0, len = mob.length; i < len; i++) {
+ const newDist = Vector.magnitude(Vector.sub(path[0], mob[i].position))
+ if (explosionRange < newDist &&
+ newDist < dist &&
+ Matter.Query.ray(map, path[0], mob[i].position).length === 0 &&
+ Matter.Query.ray(body, path[0], mob[i].position).length === 0) {
+ dist = newDist
+ best.who = mob[i]
+ path[path.length - 1] = mob[i].position
+ }
+ }
+ }
+ if (!best.who) {
+ vertexCollision(path[0], path[1], mob);
+ vertexCollision(path[0], path[1], map);
+ vertexCollision(path[0], path[1], body);
+ if (best.dist2 != Infinity) { //if hitting something
+ path[path.length - 1] = {
+ x: best.x,
+ y: best.y
+ };
+ }
+ }
+ if (best.who) b.explosion(path[1], explosionRange, true)
+
+ if (mod.isPulseStun) {
+ const range = 100 + 2000 * energy
+ for (let i = 0, len = mob.length; i < len; ++i) {
+ if (mob[i].alive && !mob[i].isShielded) {
+ dist = Vector.magnitude(Vector.sub(path[1], mob[i].position)) - mob[i].radius;
+ if (dist < range) mobs.statusStun(mob[i], 30 + Math.floor(energy * 60))
+ }
+ }
+ }
+ //draw laser beam
+ ctx.beginPath();
+ ctx.moveTo(path[0].x, path[0].y);
+ ctx.lineTo(path[1].x, path[1].y);
+ ctx.strokeStyle = "rgba(255,0,0,0.13)"
+ ctx.lineWidth = 60 * energy / 0.2
+ ctx.stroke();
+ ctx.strokeStyle = "rgba(255,0,0,0.2)"
+ ctx.lineWidth = 18
+ ctx.stroke();
+ ctx.strokeStyle = "#f00";
+ ctx.lineWidth = 4
+ ctx.stroke();
+
+ //draw little dots along the laser path
+ const sub = Vector.sub(path[1], path[0])
+ const mag = Vector.magnitude(sub)
+ for (let i = 0, len = Math.floor(mag * 0.03 * energy / 0.2); i < len; i++) {
+ const dist = Math.random()
+ game.drawList.push({
+ x: path[0].x + sub.x * dist + 13 * (Math.random() - 0.5),
+ y: path[0].y + sub.y * dist + 13 * (Math.random() - 0.5),
+ radius: 1 + 4 * Math.random(),
+ color: "rgba(255,0,0,0.5)",
+ time: Math.floor(2 + 33 * Math.random() * Math.random())
+ });
+ }
+ },
grenade() {
},
@@ -550,7 +676,7 @@ const b = {
}
}
slow(body, this.damageRadius)
- slow([player], this.damageRadius)
+ if (!mod.isNeutronImmune) slow([player], this.damageRadius)
}
}
}
@@ -591,6 +717,7 @@ const b = {
},
onEnd() {
b.explosion(this.position, this.explodeRad * size); //makes bullet do explosive damage at end
+ if (mod.fragments) b.targetedNail(this.position, mod.fragments * 5)
if (spawn) {
for (let i = 0; i < mod.recursiveMissiles; i++) {
if (0.2 - 0.02 * i > Math.random()) {
@@ -724,8 +851,8 @@ const b = {
const q = Matter.Query.point(mob, this.position)
for (let i = 0; i < q.length; i++) {
Matter.Body.setVelocity(q[i], {
- x: q[i].velocity.x * 0.7,
- y: q[i].velocity.y * 0.7
+ x: q[i].velocity.x * 0.6,
+ y: q[i].velocity.y * 0.6
});
Matter.Body.setPosition(this, Vector.add(this.position, q[i].velocity)) //move with the medium
let dmg = this.dmg / Math.min(10, q[i].mass)
@@ -743,9 +870,9 @@ const b = {
this.cycle++
const wiggleMag = (mech.crouch ? 6 : 12) * Math.cos(game.cycle * 0.09)
const wiggle = Vector.mult(transverse, wiggleMag * Math.cos(this.cycle * 0.36)) //+ wiggleMag * Math.cos(game.cycle * 0.3))
- // const velocity = Vector.mult(player.velocity, 0.25) //move with player
- // Matter.Body.setPosition(this, Vector.add(velocity, Vector.add(this.position, wiggle)))
- Matter.Body.setPosition(this, Vector.add(this.position, wiggle))
+ const velocity = Vector.mult(player.velocity, 0.3) //move with player
+ Matter.Body.setPosition(this, Vector.add(velocity, Vector.add(this.position, wiggle)))
+ // Matter.Body.setPosition(this, Vector.add(this.position, wiggle))
}
}
});
@@ -2089,11 +2216,11 @@ const b = {
const DIST = Vector.magnitude(sub);
const unit = Vector.normalise(sub)
if (DIST < mod.isPlasmaRange * 450 && mech.energy > this.drainThreshold) {
- mech.energy -= 0.0012;
- if (mech.energy < 0) {
- mech.fieldCDcycle = mech.cycle + 120;
- mech.energy = 0;
- }
+ mech.energy -= 0.005;
+ // if (mech.energy < 0) {
+ // mech.fieldCDcycle = mech.cycle + 120;
+ // mech.energy = 0;
+ // }
//calculate laser collision
let best;
let range = mod.isPlasmaRange * (120 + 300 * Math.sqrt(Math.random()))
@@ -2164,7 +2291,7 @@ const b = {
y: best.y
};
if (best.who.alive) {
- const dmg = 0.8 * b.dmgScale; //********** SCALE DAMAGE HERE *********************
+ const dmg = 0.6 * b.dmgScale; //********** SCALE DAMAGE HERE *********************
best.who.damage(dmg);
best.who.locatePlayer();
//push mobs away
@@ -3612,13 +3739,13 @@ const b = {
y: mech.pos.y + 3000 * Math.sin(mech.angle)
}, dmg, 0, true);
for (let i = 1; i < len; i++) {
- const history = mech.history[(mech.cycle - i * spacing) % 300]
+ const history = mech.history[(mech.cycle - i * spacing) % 600]
b.laser({
x: history.position.x + 20 * Math.cos(history.angle),
- y: history.position.y + 20 * Math.sin(history.angle)
+ y: history.position.y + 20 * Math.sin(history.angle) - mech.yPosDifference
}, {
x: history.position.x + 3000 * Math.cos(history.angle),
- y: history.position.y + 3000 * Math.sin(history.angle)
+ y: history.position.y + 3000 * Math.sin(history.angle) - mech.yPosDifference
}, dmg, 0, true);
}
ctx.stroke();
@@ -3642,130 +3769,38 @@ const b = {
},
},
],
- pulse(energy, angle = mech.angle) {
- let best;
- let explosionRange = 1560 * energy
- let range = 3000
- const path = [{
- x: mech.pos.x + 20 * Math.cos(angle),
- y: mech.pos.y + 20 * Math.sin(angle)
- },
- {
- x: mech.pos.x + range * Math.cos(angle),
- y: mech.pos.y + range * Math.sin(angle)
- }
- ];
- const vertexCollision = function(v1, v1End, domain) {
- for (let i = 0; i < domain.length; ++i) {
- let vertices = domain[i].vertices;
- const len = vertices.length - 1;
- for (let j = 0; j < len; j++) {
- results = game.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
- if (results.onLine1 && results.onLine2) {
- const dx = v1.x - results.x;
- const dy = v1.y - results.y;
- const dist2 = dx * dx + dy * dy;
- if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
- best = {
- x: results.x,
- y: results.y,
- dist2: dist2,
- who: domain[i],
- v1: vertices[j],
- v2: vertices[j + 1]
- };
- }
- }
- }
- results = game.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
- if (results.onLine1 && results.onLine2) {
- const dx = v1.x - results.x;
- const dy = v1.y - results.y;
- const dist2 = dx * dx + dy * dy;
- if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
- best = {
- x: results.x,
- y: results.y,
- dist2: dist2,
- who: domain[i],
- v1: vertices[0],
- v2: vertices[len]
- };
+ gunRewind: { //this gun is added with a mod
+ name: "CPT gun",
+ description: "use energy to rewind your health, velocity,
and position up to 10 seconds",
+ ammo: 0,
+ ammoPack: Infinity,
+ have: false,
+ isRewinding: false,
+ lastFireCycle: 0,
+ holdCount: 0,
+ fire() {
+ if (this.lastFireCycle === mech.cycle - 1) { //button has been held down
+ this.rewindCount += 7;
+ const DRAIN = 0.01
+ if (this.rewindCount > 599 || mech.energy < DRAIN) {
+ this.rewindCount = 0;
+ mech.resetHistory();
+ mech.fireCDcycle = mech.cycle + Math.floor(60 * b.fireCD); // cool down
+ } else {
+ mech.energy -= DRAIN
+ mech.immuneCycle = mech.cycle + 5; //player is immune to collision damage for 5 cycles
+ let history = mech.history[(mech.cycle - this.rewindCount) % 600]
+ Matter.Body.setPosition(player, history.position);
+ Matter.Body.setVelocity(player, { x: history.velocity.x, y: history.velocity.y });
+ if (mech.health !== history.health) {
+ mech.health = history.health
+ mech.displayHealth();
}
}
+ } else { //button is held the first time
+ this.rewindCount = 0;
}
- };
- //check for collisions
- best = {
- x: null,
- y: null,
- dist2: Infinity,
- who: null,
- v1: null,
- v2: null
- };
- if (mod.isPulseAim) { //find mobs in line of sight
- let dist = 2200
- for (let i = 0, len = mob.length; i < len; i++) {
- const newDist = Vector.magnitude(Vector.sub(path[0], mob[i].position))
- if (explosionRange < newDist &&
- newDist < dist &&
- Matter.Query.ray(map, path[0], mob[i].position).length === 0 &&
- Matter.Query.ray(body, path[0], mob[i].position).length === 0) {
- dist = newDist
- best.who = mob[i]
- path[path.length - 1] = mob[i].position
- }
- }
- }
- if (!best.who) {
- vertexCollision(path[0], path[1], mob);
- vertexCollision(path[0], path[1], map);
- vertexCollision(path[0], path[1], body);
- if (best.dist2 != Infinity) { //if hitting something
- path[path.length - 1] = {
- x: best.x,
- y: best.y
- };
- }
- }
- if (best.who) b.explosion(path[1], explosionRange, true)
-
- if (mod.isPulseStun) {
- const range = 100 + 2000 * energy
- for (let i = 0, len = mob.length; i < len; ++i) {
- if (mob[i].alive && !mob[i].isShielded) {
- dist = Vector.magnitude(Vector.sub(path[1], mob[i].position)) - mob[i].radius;
- if (dist < range) mobs.statusStun(mob[i], 30 + Math.floor(energy * 60))
- }
- }
- }
- //draw laser beam
- ctx.beginPath();
- ctx.moveTo(path[0].x, path[0].y);
- ctx.lineTo(path[1].x, path[1].y);
- ctx.strokeStyle = "rgba(255,0,0,0.13)"
- ctx.lineWidth = 60 * energy / 0.2
- ctx.stroke();
- ctx.strokeStyle = "rgba(255,0,0,0.2)"
- ctx.lineWidth = 18
- ctx.stroke();
- ctx.strokeStyle = "#f00";
- ctx.lineWidth = 4
- ctx.stroke();
-
- //draw little dots along the laser path
- const sub = Vector.sub(path[1], path[0])
- const mag = Vector.magnitude(sub)
- for (let i = 0, len = Math.floor(mag * 0.03 * energy / 0.2); i < len; i++) {
- const dist = Math.random()
- game.drawList.push({
- x: path[0].x + sub.x * dist + 13 * (Math.random() - 0.5),
- y: path[0].y + sub.y * dist + 13 * (Math.random() - 0.5),
- radius: 1 + 4 * Math.random(),
- color: "rgba(255,0,0,0.5)",
- time: Math.floor(2 + 33 * Math.random() * Math.random())
- });
+ this.lastFireCycle = mech.cycle;
}
}
};
\ No newline at end of file
diff --git a/js/game.js b/js/game.js
index d9b7938..2b2abf7 100644
--- a/js/game.js
+++ b/js/game.js
@@ -596,7 +596,17 @@ const game = {
}
if (mod.isEndLevelPowerUp) {
- for (let i = 0; i < powerUp.length; i++) powerUp[i].effect();
+ for (let i = 0; i < powerUp.length; i++) {
+ if (powerUp[i].name === "mod") {
+ mod.giveMod()
+ } else if (powerUp[i].name === "gun") {
+ if (!mod.isOneGun) b.giveGuns("random")
+ } else if (powerUp[i].name === "field") {
+ if (mech.fieldMode === 0) mech.setField(Math.ceil(Math.random() * (mech.fieldUpgrades.length - 1))) //pick a random field, but not field 0
+ } else {
+ powerUp[i].effect();
+ }
+ }
}
powerUps.totalPowerUps = powerUp.length
@@ -761,24 +771,24 @@ const game = {
x: 0,
y: 40
});
- if ((playerHead.position.y - player.position.y) > 0) {
- Matter.Body.translate(playerHead, {
- x: 0,
- y: 40
- });
- if ((playerHead.position.y - player.position.y) > 0) {
- Matter.Body.translate(playerHead, {
- x: 0,
- y: 40
- });
- if ((playerHead.position.y - player.position.y) > 0) {
- Matter.Body.translate(playerHead, {
- x: 0,
- y: 40
- });
- }
- }
- }
+ // if ((playerHead.position.y - player.position.y) > 0) {
+ // Matter.Body.translate(playerHead, {
+ // x: 0,
+ // y: 40
+ // });
+ // if ((playerHead.position.y - player.position.y) > 0) {
+ // Matter.Body.translate(playerHead, {
+ // x: 0,
+ // y: 40
+ // });
+ // if ((playerHead.position.y - player.position.y) > 0) {
+ // Matter.Body.translate(playerHead, {
+ // x: 0,
+ // y: 40
+ // });
+ // }
+ // }
+ // }
} else if (mech.crouch && ((playerHead.position.y - player.position.y) > 10)) {
Matter.Body.translate(playerHead, {
x: 0,
diff --git a/js/index.js b/js/index.js
index aefdc73..0695e53 100644
--- a/js/index.js
+++ b/js/index.js
@@ -787,7 +787,7 @@ window.addEventListener("keydown", function(event) {
break
}
if (game.testing) {
- switch (event.key) {
+ switch (event.key.toLowerCase()) {
case "o":
game.isAutoZoom = false;
game.zoomScale /= 0.9;
@@ -1081,4 +1081,24 @@ function cycle() {
// loop[i]()
// }
}
-}
\ No newline at end of file
+}
+
+
+
+//display console logs in game
+
+// function proxy(context, method, message) {
+// return function() {
+// // method.apply(context, [message].concat(Array.prototype.slice.apply(arguments)))
+// game.makeTextLog(arguments[0], 300)
+// }
+// }
+
+// console.log = proxy(console, console.log, 'n-gon: ')
+// console.error = proxy(console, console.error, 'Error:')
+// console.warn = proxy(console, console.warn, 'Warning:')
+
+// let's test
+// console.log('im from console.log', level, 2, 3);
+// console.error('im from console.error', 1, 2, 3);
+// console.warn('im from console.warn', 1, 2, 3);
\ No newline at end of file
diff --git a/js/level.js b/js/level.js
index caf4e5f..1b9af04 100644
--- a/js/level.js
+++ b/js/level.js
@@ -13,17 +13,15 @@ const level = {
start() {
if (level.levelsCleared === 0) { //this code only runs on the first level
// game.enableConstructMode() //used to build maps in testing mode
- // level.difficultyIncrease(19)
+ // level.difficultyIncrease(1)
// game.zoomScale = 1000;
// game.setZoom();
// mech.setField("plasma torch")
// b.giveGuns("wave beam")
- // mod.giveMod("micro-extruder")
- // mod.giveMod("piezoelectricity")
+ // mod.giveMod("CPT reversal")
+ // mod.giveMod("CPT gun")
// for (let i = 0; i < 15; i++) mod.giveMod("plasma jet")
-
-
level.intro(); //starting level
// level.testing(); //not in rotation
// level.finalBoss() //final boss level
@@ -163,12 +161,12 @@ const level = {
// spawn.launcherBoss(1200, -500)
// spawn.laserTargetingBoss(1600, -400)
// spawn.striker(1600, -500)
- spawn.shooter(1700, -120)
+ // spawn.shooter(1700, -120)
// spawn.bomberBoss(1400, -500)
// spawn.sniper(1800, -120)
// spawn.cellBossCulture(1600, -500)
- // spawn.spiderBoss(1600, -500)
- // spawn.laser(1200, -500)
+ spawn.streamBoss(1600, -500)
+ // spawn.beamer(1200, -500)
// spawn.shield(mob[mob.length - 1], 1800, -120, 1);
// spawn.nodeBoss(1200, -500, "launcher")
@@ -793,9 +791,9 @@ const level = {
powerUps.spawnBossPowerUp(-125, -1760);
} else {
if (Math.random() < 0.5) {
- spawn.randomLevelBoss(700, -1550, ["shooterBoss", "launcherBoss", "laserTargetingBoss"]);
+ spawn.randomLevelBoss(700, -1550, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "streamBoss"]);
} else {
- spawn.randomLevelBoss(675, -2775, ["shooterBoss", "launcherBoss", "laserTargetingBoss"]);
+ spawn.randomLevelBoss(675, -2775, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "streamBoss"]);
}
}
powerUps.addRerollToLevel() //needs to run after mobs are spawned
@@ -942,7 +940,7 @@ const level = {
spawn.randomMob(3600, 1725, 0.9);
spawn.randomMob(4100, 1225, 0.9);
spawn.randomMob(2825, 400, 0.9);
- if (game.difficulty > 3) spawn.randomLevelBoss(6000, 2300, ["spiderBoss", "launcherBoss", "laserTargetingBoss"]);
+ if (game.difficulty > 3) spawn.randomLevelBoss(6000, 2300, ["spiderBoss", "launcherBoss", "laserTargetingBoss", "streamBoss"]);
powerUps.addRerollToLevel() //needs to run after mobs are spawned
},
satellite() {
diff --git a/js/mob.js b/js/mob.js
index d0680ae..57eed7f 100644
--- a/js/mob.js
+++ b/js/mob.js
@@ -481,7 +481,7 @@ const mobs = {
}
}
};
- if (this.seePlayer.recall) {
+ if (this.seePlayer.recall && !this.isSlowed) {
this.torque = this.lookTorque * this.inertia * 2;
const seeRange = 2500;
diff --git a/js/mods.js b/js/mods.js
index 7892503..144c3ca 100644
--- a/js/mods.js
+++ b/js/mods.js
@@ -386,22 +386,6 @@ const mod = {
mod.throwChargeRate = 1
}
},
- {
- name: "fragmentation",
- description: "detonation or collisions with mobs eject nails
blocks, rail gun, grenades, shotgun slugs",
- maxCount: 9,
- count: 0,
- allowed() {
- return (mod.haveGunCheck("grenades") && !mod.isNeutronBomb) || mod.haveGunCheck("rail gun") || (mod.haveGunCheck("shotgun") && mod.isSlugShot) || mod.throwChargeRate > 1
- },
- requires: "grenades, rail gun, shotgun slugs, or mass driver",
- effect() {
- mod.fragments++
- },
- remove() {
- mod.fragments = 0
- }
- },
{
name: "ammonium nitrate",
description: "increase explosive damage by 20%
increase explosive radius by 20%",
@@ -569,7 +553,7 @@ const mod = {
b.nailBot();
},
remove() {
- mod.nailBotCount = 0;
+ mod.nailBotCount -= this.count;
}
},
{
@@ -608,7 +592,7 @@ const mod = {
b.foamBot();
},
remove() {
- mod.foamBotCount = 0;
+ mod.foamBotCount -= this.count;
}
},
{
@@ -647,7 +631,7 @@ const mod = {
b.boomBot();
},
remove() {
- mod.boomBotCount = 0;
+ mod.boomBotCount -= this.count;
}
},
{
@@ -686,7 +670,7 @@ const mod = {
b.laserBot();
},
remove() {
- mod.laserBotCount = 0;
+ mod.laserBotCount -= this.count;
}
},
{
@@ -725,7 +709,7 @@ const mod = {
mod.orbitBotCount++;
},
remove() {
- mod.orbitBotCount = 0;
+ mod.orbitBotCount -= this.count;
}
},
{
@@ -1074,9 +1058,9 @@ const mod = {
maxCount: 1,
count: 0,
allowed() { //&& (mech.fieldUpgrades[mech.fieldMode].name !== "nano-scale manufacturing" || mech.maxEnergy > 1)
- return mech.maxEnergy > 0.99 && mech.fieldUpgrades[mech.fieldMode].name !== "standing wave harmonics" && !mod.isEnergyHealth
+ return mech.maxEnergy > 0.99 && mech.fieldUpgrades[mech.fieldMode].name !== "standing wave harmonics" && !mod.isEnergyHealth && !mod.isRewindGun
},
- requires: "standing wave, mass-energy, piezoelectricity, max energy reduction",
+ requires: "not standing wave, mass-energy, piezo, max energy reduction, CPT gun",
effect() {
mod.isRewindAvoidDeath = true;
},
@@ -1135,13 +1119,13 @@ const mod = {
},
{
name: "ground state",
- description: "reduce harm by 66%
you no longer passively regenerate energy",
+ description: "reduce harm by 60%
you no longer passively regenerate energy",
maxCount: 1,
count: 0,
allowed() {
- return mod.isPiezo && mod.energyRegen !== 0.004
+ return (mod.iceEnergy || mod.isWormholeEnergy || mod.isPiezo || mod.isRailEnergyGain) && mod.energyRegen !== 0.004
},
- requires: "piezoelectricity, not time crystals",
+ requires: "piezoelectricity, Penrose, half-wave, or thermoelectric, but not time crystals",
effect: () => {
mod.energyRegen = 0;
mech.fieldRegen = mod.energyRegen;
@@ -1157,7 +1141,7 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
- return !mod.isEnergyLoss && !mod.isPiezo && !mod.isRewindAvoidDeath && !mod.isSpeedHarm && mech.fieldUpgrades[mech.fieldMode].name !== "negative mass field"
+ return !mod.isEnergyLoss && !mod.isPiezo && !mod.isRewindAvoidDeath && !mod.isRewindGun && !mod.isSpeedHarm && mech.fieldUpgrades[mech.fieldMode].name !== "negative mass field"
},
requires: "not exothermic process, piezoelectricity, CPT, 1st law, negative mass",
effect: () => {
@@ -1328,13 +1312,13 @@ const mod = {
},
{
name: "transceiver chip",
- description: "at the end of each level
gain the full effect of unused power ups",
+ description: "unused power ups at the end of each level
are still activated (selections are random)",
maxCount: 1,
count: 0,
allowed() {
return mod.isArmorFromPowerUps
},
- requires: "crystallized armor",
+ requires: "inductive coupling",
effect() {
mod.isEndLevelPowerUp = true;
},
@@ -1535,7 +1519,7 @@ const mod = {
if (mod.mods[i].count > 0) have.push(i)
}
const choose = have[Math.floor(Math.random() * have.length)]
- game.makeTextLog(`
${mod.mods[choose].name} removed by reallocation`, 300)
+ game.makeTextLog(` ${mod.mods[choose].name} removed by monte carlo experiment`, 300)
for (let i = 0; i < mod.mods[choose].count; i++) {
powerUps.spawn(mech.pos.x, mech.pos.y, "mod");
}
@@ -1935,10 +1919,50 @@ const mod = {
//**************************************************
//************************************************** gun
//************************************************** mods
- //**************************************************
+ //**************************************************
+ {
+ name: "CPT gun",
+ description: "adds the CPT gun to your inventory
it rewinds your health, velocity, and position",
+ isGunMod: true,
+ maxCount: 1,
+ count: 0,
+ allowed() {
+ return (mod.totalBots() > 5 || mech.fieldUpgrades[mech.fieldMode].name === "nano-scale manufacturing" || mech.fieldUpgrades[mech.fieldMode].name === "plasma torch" || mech.fieldUpgrades[mech.fieldMode].name === "pilot wave") && !mod.isEnergyHealth && !mod.isRewindAvoidDeath
+ },
+ requires: "bots > 5, plasma torch, nano-scale, pilot wave, not mass-energy equivalence, CPT",
+ effect() {
+ mod.isRewindGun = true
+ b.guns.push(b.gunRewind)
+ b.giveGuns("CPT gun");
+ },
+ remove() {
+ if (mod.isRewindGun) {
+ for (let i = 0; i < b.guns.length; i++) {
+ if (b.guns[i].name === "CPT gun") {
+ for (let j = 0; j < b.inventory.length; j++) {
+ if (b.inventory[j] === i) {
+ b.inventory.splice(j, 1)
+ break
+ }
+ }
+ if (b.inventory.length) {
+ b.activeGun = b.inventory[0];
+ } else {
+ b.activeGun = null;
+ }
+ game.makeGunHUD();
+
+ b.guns.splice(i, 1) //also remove CPT gun from gun pool array
+ break
+ }
+ }
+ mod.isRewindGun = false
+ }
+ }
+ },
{
name: "incendiary ammunition",
- description: "bullets are loaded with explosives
nail gun, shotgun, super balls, drones",
+ description: "some bullets are loaded with explosives
nail gun, shotgun, super balls, drones",
isGunMod: true,
maxCount: 1,
count: 0,
@@ -1953,9 +1977,26 @@ const mod = {
mod.isIncendiary = false;
}
},
+ {
+ name: "fragmentation",
+ description: "some detonations and collisions eject nails
blocks, rail gun, grenades, missiles, shotgun slugs",
+ isGunMod: true,
+ maxCount: 9,
+ count: 0,
+ allowed() {
+ return (mod.haveGunCheck("grenades") && !mod.isNeutronBomb) || mod.haveGunCheck("missiles") || mod.haveGunCheck("rail gun") || (mod.haveGunCheck("shotgun") && mod.isSlugShot) || mod.throwChargeRate > 1
+ },
+ requires: "grenades, missiles, rail gun, shotgun slugs, or mass driver",
+ effect() {
+ mod.fragments++
+ },
+ remove() {
+ mod.fragments = 0
+ }
+ },
{
name: "Lorentzian topology",
- description: "bullets last 30% longer
drones, spores, missiles, foam, wave, ice IX, neutron",
+ description: "some bullets last 30% longer
drones, spores, missiles, foam, wave, ice IX, neutron",
isGunMod: true,
maxCount: 3,
count: 0,
@@ -2783,7 +2824,7 @@ const mod = {
},
{
name: "colloidal foam",
- description: "increase foam damage by 200%
foam dissipates 40% faster",
+ description: "increase foam damage by 366%
foam dissipates 40% faster",
isGunMod: true,
maxCount: 1,
count: 0,
@@ -3259,8 +3300,8 @@ const mod = {
mod.giveMod("orbital-bot upgrade")
mod.setModToNonRefundable("orbital-bot upgrade")
for (let i = 0; i < 2; i++) {
- b.orbitalBot()
- mod.orbitalBotCount++;
+ b.orbitBot()
+ mod.orbitBotCount++;
}
})
//choose random function from the array and run it
@@ -3370,6 +3411,23 @@ const mod = {
mod.isFreezeMobs = false
}
},
+ // {
+ // name: "thermal reservoir",
+ // description: "increase your plasma damage by 100%
plasma temporarily lowers health not energy",
+ // isFieldMod: true,
+ // maxCount: 1,
+ // count: 0,
+ // allowed() {
+ // return mech.fieldUpgrades[mech.fieldMode].name === "plasma torch" && !mod.isEnergyHealth
+ // },
+ // requires: "plasma torch, not mass-energy equivalence",
+ // effect() {
+ // mod.isPlasmaRange += 0.27;
+ // },
+ // remove() {
+ // mod.isPlasmaRange = 1;
+ // }
+ // },
{
name: "plasma jet",
description: "increase plasma torch's range by 27%",
@@ -3874,5 +3932,7 @@ const mod = {
isRewindBot: null,
isRewindGrenade: null,
isExtruder: null,
- isEndLevelPowerUp: null
+ isEndLevelPowerUp: null,
+ isRewindGun: null
+
}
\ No newline at end of file
diff --git a/js/player.js b/js/player.js
index b9be3b9..e7b4f9c 100644
--- a/js/player.js
+++ b/js/player.js
@@ -103,6 +103,7 @@ const mech = {
x: 0,
y: 0
},
+ yPosDifference: 24.285923217549026, //player.position.y - mech.pos.y
Sy: 0, //adds a smoothing effect to vertical only
Vx: 0,
Vy: 0,
@@ -135,11 +136,11 @@ const mech = {
transY: 0,
history: [], //tracks the last second of player position
resetHistory() {
- for (let i = 0; i < 300; i++) { //reset history
+ for (let i = 0; i < 600; i++) { //reset history
mech.history[i] = {
position: {
- x: mech.pos.x,
- y: mech.pos.y,
+ x: player.position.x,
+ y: player.position.y,
},
velocity: {
x: player.velocity.x,
@@ -159,10 +160,10 @@ const mech = {
//tracks the last second of player information
// console.log(mech.history)
- mech.history.splice(mech.cycle % 300, 1, {
+ mech.history.splice(mech.cycle % 600, 1, {
position: {
- x: mech.pos.x,
- y: mech.pos.y,
+ x: player.position.x,
+ y: player.position.y,
},
velocity: {
x: player.velocity.x,
@@ -461,14 +462,14 @@ const mech = {
if (mod.isBotArmor) dmg *= 0.97 ** mod.totalBots()
if (mod.isHarmArmor && mech.lastHarmCycle + 600 > mech.cycle) dmg *= 0.33;
if (mod.isNoFireDefense && mech.cycle > mech.fireCDcycle + 120) dmg *= 0.6
- if (mod.energyRegen === 0) dmg *= 0.33 //0.22 + 0.78 * mech.energy //77% damage reduction at zero energy
+ if (mod.energyRegen === 0) dmg *= 0.4
if (mod.isTurret && mech.crouch) dmg *= 0.5;
if (mod.isEntanglement && b.inventory[0] === b.activeGun) {
for (let i = 0, len = b.inventory.length; i < len; i++) dmg *= 0.87 // 1 - 0.15
}
return dmg
},
- rewind(steps) {
+ rewind(steps) { // mech.rewind(Math.floor(Math.min(599, 137 * mech.energy)))
if (mod.isRewindGrenade) {
for (let i = 1, len = Math.floor(2 + steps / 40); i < len; i++) {
b.grenade(Vector.add(mech.pos, { x: 10 * (Math.random() - 0.5), y: 10 * (Math.random() - 0.5) }), -i * Math.PI / len) //fire different angles for each grenade
@@ -494,7 +495,7 @@ const mech = {
}
}
}
- let history = mech.history[(mech.cycle - steps) % 300]
+ let history = mech.history[(mech.cycle - steps) % 600]
Matter.Body.setPosition(player, history.position);
Matter.Body.setVelocity(player, { x: history.velocity.x, y: history.velocity.y });
// move bots to follow player
@@ -529,7 +530,7 @@ const mech = {
ctx.scale(game.zoom / game.edgeZoomOutSmooth, game.zoom / game.edgeZoomOutSmooth); //zoom in once centered
ctx.translate(-canvas.width2 + mech.transX, -canvas.height2 + mech.transY); //translate
for (let i = 1; i < steps; i++) {
- history = mech.history[(mech.cycle - i) % 300]
+ history = mech.history[(mech.cycle - i) % 600]
mech.pos.x = history.position.x
mech.pos.y = history.position.y
mech.draw();
@@ -547,7 +548,7 @@ const mech = {
if (mod.isRewindBot) {
const len = steps * 0.042 * mod.isRewindBot
for (let i = 0; i < len; i++) {
- const where = mech.history[Math.abs(mech.cycle - i * 40) % 300].position //spread out spawn locations along past history
+ const where = mech.history[Math.abs(mech.cycle - i * 40) % 600].position //spread out spawn locations along past history
b.randomBot({
x: where.x + 100 * (Math.random() - 0.5),
y: where.y + 100 * (Math.random() - 0.5)
@@ -558,8 +559,7 @@ const mech = {
},
damage(dmg) {
if (mod.isRewindAvoidDeath && mech.energy > 0.66) {
- const steps = Math.floor(Math.min(299, 137 * mech.energy))
- mech.rewind(steps)
+ mech.rewind(Math.floor(Math.min(299, 137 * mech.energy)))
return
}
mech.lastHarmCycle = mech.cycle
@@ -764,7 +764,7 @@ const mech = {
ctx.stroke();
// ctx.beginPath();
// ctx.arc(15, 0, 3, 0, 2 * Math.PI);
- // ctx.fillStyle = '#9cf' //'#0cf';
+ // ctx.fillStyle = '#0cf';
// ctx.fill()
ctx.restore();
mech.yOff = mech.yOff * 0.85 + mech.yOffGoal * 0.15; //smoothly move leg height towards height goal
@@ -2194,11 +2194,104 @@ const mech = {
{
name: "wormhole",
description: "use energy to tunnel through a wormhole
wormholes attract blocks and power ups
10% chance to duplicate spawned power ups", //
bullets may also traverse wormholes
- effect: () => {
+ effect: function() {
game.replaceTextLog = true; //allow text over write
mech.drop();
mech.duplicateChance = 0.1
game.draw.powerUp = game.draw.powerUpBonus //change power up draw
+
+ // if (mod.isRewindGun) {
+ // mech.hold = this.rewind
+ // } else {
+ mech.hold = this.teleport
+ // }
+ },
+ rewindCount: 0,
+ // rewind: function() {
+ // if (input.down) {
+ // if (input.field && mech.fieldCDcycle < mech.cycle) { //not hold but field button is pressed
+ // const DRAIN = 0.01
+ // if (this.rewindCount < 289 && mech.energy > DRAIN) {
+ // mech.energy -= DRAIN
+
+
+ // if (this.rewindCount === 0) {
+ // const shortPause = function() {
+ // if (mech.defaultFPSCycle < mech.cycle) { //back to default values
+ // game.fpsCap = game.fpsCapDefault
+ // game.fpsInterval = 1000 / game.fpsCap;
+ // // document.getElementById("dmg").style.transition = "opacity 1s";
+ // // document.getElementById("dmg").style.opacity = "0";
+ // } else {
+ // requestAnimationFrame(shortPause);
+ // }
+ // };
+ // if (mech.defaultFPSCycle < mech.cycle) requestAnimationFrame(shortPause);
+ // game.fpsCap = 4 //1 is longest pause, 4 is standard
+ // game.fpsInterval = 1000 / game.fpsCap;
+ // mech.defaultFPSCycle = mech.cycle
+ // }
+
+
+ // this.rewindCount += 10;
+ // game.wipe = function() { //set wipe to have trails
+ // // ctx.fillStyle = "rgba(255,255,255,0)";
+ // ctx.fillStyle = `rgba(221,221,221,${0.004})`;
+ // ctx.fillRect(0, 0, canvas.width, canvas.height);
+ // }
+ // let history = mech.history[(mech.cycle - this.rewindCount) % 300]
+ // Matter.Body.setPosition(player, history.position);
+ // Matter.Body.setVelocity(player, { x: history.velocity.x, y: history.velocity.y });
+ // if (history.health > mech.health) {
+ // mech.health = history.health
+ // mech.displayHealth();
+ // }
+ // //grab power ups
+ // for (let i = 0, len = powerUp.length; i < len; ++i) {
+ // const dxP = player.position.x - powerUp[i].position.x;
+ // const dyP = player.position.y - powerUp[i].position.y;
+ // if (dxP * dxP + dyP * dyP < 50000 && !game.isChoosing && !(mech.health === mech.maxHealth && powerUp[i].name === "heal")) {
+ // powerUps.onPickUp(player.position);
+ // powerUp[i].effect();
+ // Matter.World.remove(engine.world, powerUp[i]);
+ // powerUp.splice(i, 1);
+ // const shortPause = function() {
+ // if (mech.defaultFPSCycle < mech.cycle) { //back to default values
+ // game.fpsCap = game.fpsCapDefault
+ // game.fpsInterval = 1000 / game.fpsCap;
+ // // document.getElementById("dmg").style.transition = "opacity 1s";
+ // // document.getElementById("dmg").style.opacity = "0";
+ // } else {
+ // requestAnimationFrame(shortPause);
+ // }
+ // };
+ // if (mech.defaultFPSCycle < mech.cycle) requestAnimationFrame(shortPause);
+ // game.fpsCap = 3 //1 is longest pause, 4 is standard
+ // game.fpsInterval = 1000 / game.fpsCap;
+ // mech.defaultFPSCycle = mech.cycle
+ // break; //because the array order is messed up after splice
+ // }
+ // }
+ // mech.immuneCycle = mech.cycle + 5; //player is immune to collision damage for 30 cycles
+ // } else {
+ // mech.fieldCDcycle = mech.cycle + 30;
+ // // mech.resetHistory();
+ // }
+ // } else {
+ // if (this.rewindCount !== 0) {
+ // mech.fieldCDcycle = mech.cycle + 30;
+ // mech.resetHistory();
+ // this.rewindCount = 0;
+ // game.wipe = function() { //set wipe to normal
+ // ctx.clearRect(0, 0, canvas.width, canvas.height);
+ // }
+ // }
+ // 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()
+ // },
+ teleport: function() {
// mech.hole = { //this is reset with each new field, but I'm leaving it here for reference
// isOn: false,
// isReady: true,
@@ -2207,237 +2300,235 @@ const mech = {
// angle: 0,
// unit:{x:0,y:0},
// }
- mech.hold = function() {
- if (mech.hole.isOn) {
- // draw holes
- mech.fieldRange = 0.97 * mech.fieldRange + 0.03 * (50 + 10 * Math.sin(game.cycle * 0.025))
- const semiMajorAxis = mech.fieldRange + 30
- const edge1a = Vector.add(Vector.mult(mech.hole.unit, semiMajorAxis), mech.hole.pos1)
- const edge1b = Vector.add(Vector.mult(mech.hole.unit, -semiMajorAxis), mech.hole.pos1)
- const edge2a = Vector.add(Vector.mult(mech.hole.unit, semiMajorAxis), mech.hole.pos2)
- const edge2b = Vector.add(Vector.mult(mech.hole.unit, -semiMajorAxis), mech.hole.pos2)
- ctx.beginPath();
- ctx.moveTo(edge1a.x, edge1a.y)
- ctx.bezierCurveTo(mech.hole.pos1.x, mech.hole.pos1.y, mech.hole.pos2.x, mech.hole.pos2.y, edge2a.x, edge2a.y);
- ctx.lineTo(edge2b.x, edge2b.y)
- ctx.bezierCurveTo(mech.hole.pos2.x, mech.hole.pos2.y, mech.hole.pos1.x, mech.hole.pos1.y, edge1b.x, edge1b.y);
- ctx.fillStyle = `rgba(255,255,255,${200 / mech.fieldRange / mech.fieldRange})` //"rgba(0,0,0,0.1)"
- ctx.fill();
- ctx.beginPath();
- ctx.ellipse(mech.hole.pos1.x, mech.hole.pos1.y, mech.fieldRange, semiMajorAxis, mech.hole.angle, 0, 2 * Math.PI)
- ctx.ellipse(mech.hole.pos2.x, mech.hole.pos2.y, mech.fieldRange, semiMajorAxis, mech.hole.angle, 0, 2 * Math.PI)
- ctx.fillStyle = `rgba(255,255,255,${32 / mech.fieldRange})`
- ctx.fill();
+ if (mech.hole.isOn) {
+ // draw holes
+ mech.fieldRange = 0.97 * mech.fieldRange + 0.03 * (50 + 10 * Math.sin(game.cycle * 0.025))
+ const semiMajorAxis = mech.fieldRange + 30
+ const edge1a = Vector.add(Vector.mult(mech.hole.unit, semiMajorAxis), mech.hole.pos1)
+ const edge1b = Vector.add(Vector.mult(mech.hole.unit, -semiMajorAxis), mech.hole.pos1)
+ const edge2a = Vector.add(Vector.mult(mech.hole.unit, semiMajorAxis), mech.hole.pos2)
+ const edge2b = Vector.add(Vector.mult(mech.hole.unit, -semiMajorAxis), mech.hole.pos2)
+ ctx.beginPath();
+ ctx.moveTo(edge1a.x, edge1a.y)
+ ctx.bezierCurveTo(mech.hole.pos1.x, mech.hole.pos1.y, mech.hole.pos2.x, mech.hole.pos2.y, edge2a.x, edge2a.y);
+ ctx.lineTo(edge2b.x, edge2b.y)
+ ctx.bezierCurveTo(mech.hole.pos2.x, mech.hole.pos2.y, mech.hole.pos1.x, mech.hole.pos1.y, edge1b.x, edge1b.y);
+ ctx.fillStyle = `rgba(255,255,255,${200 / mech.fieldRange / mech.fieldRange})` //"rgba(0,0,0,0.1)"
+ ctx.fill();
+ ctx.beginPath();
+ ctx.ellipse(mech.hole.pos1.x, mech.hole.pos1.y, mech.fieldRange, semiMajorAxis, mech.hole.angle, 0, 2 * Math.PI)
+ ctx.ellipse(mech.hole.pos2.x, mech.hole.pos2.y, mech.fieldRange, semiMajorAxis, mech.hole.angle, 0, 2 * Math.PI)
+ ctx.fillStyle = `rgba(255,255,255,${32 / mech.fieldRange})`
+ ctx.fill();
- //suck power ups
- for (let i = 0, len = powerUp.length; i < len; ++i) {
- //which hole is closer
- const dxP1 = mech.hole.pos1.x - powerUp[i].position.x;
- const dyP1 = mech.hole.pos1.y - powerUp[i].position.y;
- const dxP2 = mech.hole.pos2.x - powerUp[i].position.x;
- const dyP2 = mech.hole.pos2.y - powerUp[i].position.y;
- let dxP, dyP, dist2
- if (dxP1 * dxP1 + dyP1 * dyP1 < dxP2 * dxP2 + dyP2 * dyP2) {
- dxP = dxP1
- dyP = dyP1
- } else {
- dxP = dxP2
- dyP = dyP2
- }
- dist2 = dxP * dxP + dyP * dyP;
- if (dist2 < 600000 && !(mech.health === mech.maxHealth && powerUp[i].name === "heal")) {
- powerUp[i].force.x += 4 * (dxP / dist2) * powerUp[i].mass; // float towards hole
- powerUp[i].force.y += 4 * (dyP / dist2) * powerUp[i].mass - powerUp[i].mass * game.g; //negate gravity
- Matter.Body.setVelocity(powerUp[i], { //extra friction
- x: powerUp[i].velocity.x * 0.05,
- y: powerUp[i].velocity.y * 0.05
- });
- if (dist2 < 1000 && !game.isChoosing) { //use power up if it is close enough
- mech.fieldRange *= 0.8
- powerUps.onPickUp(powerUp[i].position);
- powerUp[i].effect();
- Matter.World.remove(engine.world, powerUp[i]);
- powerUp.splice(i, 1);
- break; //because the array order is messed up after splice
- }
+ //suck power ups
+ for (let i = 0, len = powerUp.length; i < len; ++i) {
+ //which hole is closer
+ const dxP1 = mech.hole.pos1.x - powerUp[i].position.x;
+ const dyP1 = mech.hole.pos1.y - powerUp[i].position.y;
+ const dxP2 = mech.hole.pos2.x - powerUp[i].position.x;
+ const dyP2 = mech.hole.pos2.y - powerUp[i].position.y;
+ let dxP, dyP, dist2
+ if (dxP1 * dxP1 + dyP1 * dyP1 < dxP2 * dxP2 + dyP2 * dyP2) {
+ dxP = dxP1
+ dyP = dyP1
+ } else {
+ dxP = dxP2
+ dyP = dyP2
+ }
+ dist2 = dxP * dxP + dyP * dyP;
+ if (dist2 < 600000 && !(mech.health === mech.maxHealth && powerUp[i].name === "heal")) {
+ powerUp[i].force.x += 4 * (dxP / dist2) * powerUp[i].mass; // float towards hole
+ powerUp[i].force.y += 4 * (dyP / dist2) * powerUp[i].mass - powerUp[i].mass * game.g; //negate gravity
+ Matter.Body.setVelocity(powerUp[i], { //extra friction
+ x: powerUp[i].velocity.x * 0.05,
+ y: powerUp[i].velocity.y * 0.05
+ });
+ if (dist2 < 1000 && !game.isChoosing) { //use power up if it is close enough
+ mech.fieldRange *= 0.8
+ powerUps.onPickUp(powerUp[i].position);
+ powerUp[i].effect();
+ Matter.World.remove(engine.world, powerUp[i]);
+ powerUp.splice(i, 1);
+ break; //because the array order is messed up after splice
}
}
- //suck and shrink blocks
- const suckRange = 500
- const shrinkRange = 100
- const shrinkScale = 0.97;
- const slowScale = 0.9
- for (let i = 0, len = body.length; i < len; i++) {
- if (!body[i].isNotHoldable) {
- const dist1 = Vector.magnitude(Vector.sub(mech.hole.pos1, body[i].position))
- const dist2 = Vector.magnitude(Vector.sub(mech.hole.pos2, body[i].position))
- if (dist1 < dist2) {
- if (dist1 < suckRange) {
- const pull = Vector.mult(Vector.normalise(Vector.sub(mech.hole.pos1, body[i].position)), 1)
- const slow = Vector.mult(body[i].velocity, slowScale)
- Matter.Body.setVelocity(body[i], Vector.add(slow, pull));
- //shrink
- if (Vector.magnitude(Vector.sub(mech.hole.pos1, body[i].position)) < shrinkRange) {
- Matter.Body.scale(body[i], shrinkScale, shrinkScale);
- if (body[i].mass < 0.05) {
- Matter.World.remove(engine.world, body[i]);
- body.splice(i, 1);
- mech.fieldRange *= 0.8
- if (mod.isWormholeEnergy) mech.energy += 0.5
- if (mod.isWormSpores) { //pandimensionalspermia
- for (let i = 0, len = Math.ceil(3 * Math.random()); i < len; i++) {
- b.spore(Vector.add(mech.hole.pos2, Vector.rotate({
- x: mech.fieldRange * 0.4,
- y: 0
- }, 2 * Math.PI * Math.random())))
- Matter.Body.setVelocity(bullet[bullet.length - 1], Vector.mult(Vector.rotate(mech.hole.unit, Math.PI / 2), -15));
- }
- }
- break
- }
- }
- }
- } else if (dist2 < suckRange) {
- const pull = Vector.mult(Vector.normalise(Vector.sub(mech.hole.pos2, body[i].position)), 1)
+ }
+ //suck and shrink blocks
+ const suckRange = 500
+ const shrinkRange = 100
+ const shrinkScale = 0.97;
+ const slowScale = 0.9
+ for (let i = 0, len = body.length; i < len; i++) {
+ if (!body[i].isNotHoldable) {
+ const dist1 = Vector.magnitude(Vector.sub(mech.hole.pos1, body[i].position))
+ const dist2 = Vector.magnitude(Vector.sub(mech.hole.pos2, body[i].position))
+ if (dist1 < dist2) {
+ if (dist1 < suckRange) {
+ const pull = Vector.mult(Vector.normalise(Vector.sub(mech.hole.pos1, body[i].position)), 1)
const slow = Vector.mult(body[i].velocity, slowScale)
Matter.Body.setVelocity(body[i], Vector.add(slow, pull));
//shrink
- if (Vector.magnitude(Vector.sub(mech.hole.pos2, body[i].position)) < shrinkRange) {
+ if (Vector.magnitude(Vector.sub(mech.hole.pos1, body[i].position)) < shrinkRange) {
Matter.Body.scale(body[i], shrinkScale, shrinkScale);
if (body[i].mass < 0.05) {
Matter.World.remove(engine.world, body[i]);
body.splice(i, 1);
mech.fieldRange *= 0.8
- // if (mod.isWormholeEnergy && mech.energy < mech.maxEnergy * 2) mech.energy = mech.maxEnergy * 2
if (mod.isWormholeEnergy) mech.energy += 0.5
if (mod.isWormSpores) { //pandimensionalspermia
for (let i = 0, len = Math.ceil(3 * Math.random()); i < len; i++) {
- b.spore(Vector.add(mech.hole.pos1, Vector.rotate({
+ b.spore(Vector.add(mech.hole.pos2, Vector.rotate({
x: mech.fieldRange * 0.4,
y: 0
}, 2 * Math.PI * Math.random())))
- Matter.Body.setVelocity(bullet[bullet.length - 1], Vector.mult(Vector.rotate(mech.hole.unit, Math.PI / 2), 15));
+ Matter.Body.setVelocity(bullet[bullet.length - 1], Vector.mult(Vector.rotate(mech.hole.unit, Math.PI / 2), -15));
}
}
break
}
}
}
- }
- }
- if (mod.isWormBullets) {
- //teleport bullets
- for (let i = 0, len = bullet.length; i < len; ++i) { //teleport bullets from hole1 to hole2
- if (!bullet[i].botType && !bullet[i].isInHole) { //don't teleport bots
- if (Vector.magnitude(Vector.sub(mech.hole.pos1, bullet[i].position)) < mech.fieldRange) { //find if bullet is touching hole1
- Matter.Body.setPosition(bullet[i], Vector.add(mech.hole.pos2, Vector.sub(mech.hole.pos1, bullet[i].position)));
- mech.fieldRange += 5
- bullet[i].isInHole = true
- } else if (Vector.magnitude(Vector.sub(mech.hole.pos2, bullet[i].position)) < mech.fieldRange) { //find if bullet is touching hole1
- Matter.Body.setPosition(bullet[i], Vector.add(mech.hole.pos1, Vector.sub(mech.hole.pos2, bullet[i].position)));
- mech.fieldRange += 5
- bullet[i].isInHole = true
+ } else if (dist2 < suckRange) {
+ const pull = Vector.mult(Vector.normalise(Vector.sub(mech.hole.pos2, body[i].position)), 1)
+ const slow = Vector.mult(body[i].velocity, slowScale)
+ Matter.Body.setVelocity(body[i], Vector.add(slow, pull));
+ //shrink
+ if (Vector.magnitude(Vector.sub(mech.hole.pos2, body[i].position)) < shrinkRange) {
+ Matter.Body.scale(body[i], shrinkScale, shrinkScale);
+ if (body[i].mass < 0.05) {
+ Matter.World.remove(engine.world, body[i]);
+ body.splice(i, 1);
+ mech.fieldRange *= 0.8
+ // if (mod.isWormholeEnergy && mech.energy < mech.maxEnergy * 2) mech.energy = mech.maxEnergy * 2
+ if (mod.isWormholeEnergy) mech.energy += 0.5
+ if (mod.isWormSpores) { //pandimensionalspermia
+ for (let i = 0, len = Math.ceil(3 * Math.random()); i < len; i++) {
+ b.spore(Vector.add(mech.hole.pos1, Vector.rotate({
+ x: mech.fieldRange * 0.4,
+ y: 0
+ }, 2 * Math.PI * Math.random())))
+ Matter.Body.setVelocity(bullet[bullet.length - 1], Vector.mult(Vector.rotate(mech.hole.unit, Math.PI / 2), 15));
+ }
+ }
+ break
}
}
}
- // mobs get pushed away
- for (let i = 0, len = mob.length; i < len; i++) {
- if (Vector.magnitude(Vector.sub(mech.hole.pos1, mob[i].position)) < 200) {
- const pull = Vector.mult(Vector.normalise(Vector.sub(mech.hole.pos1, mob[i].position)), -0.07)
- Matter.Body.setVelocity(mob[i], Vector.add(mob[i].velocity, pull));
- }
- if (Vector.magnitude(Vector.sub(mech.hole.pos2, mob[i].position)) < 200) {
- const pull = Vector.mult(Vector.normalise(Vector.sub(mech.hole.pos2, mob[i].position)), -0.07)
- Matter.Body.setVelocity(mob[i], Vector.add(mob[i].velocity, pull));
- }
- }
}
}
+ if (mod.isWormBullets) {
+ //teleport bullets
+ for (let i = 0, len = bullet.length; i < len; ++i) { //teleport bullets from hole1 to hole2
+ if (!bullet[i].botType && !bullet[i].isInHole) { //don't teleport bots
+ if (Vector.magnitude(Vector.sub(mech.hole.pos1, bullet[i].position)) < mech.fieldRange) { //find if bullet is touching hole1
+ Matter.Body.setPosition(bullet[i], Vector.add(mech.hole.pos2, Vector.sub(mech.hole.pos1, bullet[i].position)));
+ mech.fieldRange += 5
+ bullet[i].isInHole = true
+ } else if (Vector.magnitude(Vector.sub(mech.hole.pos2, bullet[i].position)) < mech.fieldRange) { //find if bullet is touching hole1
+ Matter.Body.setPosition(bullet[i], Vector.add(mech.hole.pos1, Vector.sub(mech.hole.pos2, bullet[i].position)));
+ mech.fieldRange += 5
+ bullet[i].isInHole = true
+ }
+ }
+ }
+ // mobs get pushed away
+ for (let i = 0, len = mob.length; i < len; i++) {
+ if (Vector.magnitude(Vector.sub(mech.hole.pos1, mob[i].position)) < 200) {
+ const pull = Vector.mult(Vector.normalise(Vector.sub(mech.hole.pos1, mob[i].position)), -0.07)
+ Matter.Body.setVelocity(mob[i], Vector.add(mob[i].velocity, pull));
+ }
+ if (Vector.magnitude(Vector.sub(mech.hole.pos2, mob[i].position)) < 200) {
+ const pull = Vector.mult(Vector.normalise(Vector.sub(mech.hole.pos2, mob[i].position)), -0.07)
+ Matter.Body.setVelocity(mob[i], Vector.add(mob[i].velocity, pull));
+ }
+ }
+ }
+ }
- if (input.field && mech.fieldCDcycle < mech.cycle) { //not hold but field button is pressed
- const justPastMouse = Vector.add(Vector.mult(Vector.normalise(Vector.sub(game.mouseInGame, mech.pos)), 50), game.mouseInGame)
- const scale = 60
- // console.log(Matter.Query.region(map, bounds))
- if (mech.hole.isReady &&
- (
- Matter.Query.region(map, {
- min: {
- x: game.mouseInGame.x - scale,
- y: game.mouseInGame.y - scale
- },
- max: {
- x: game.mouseInGame.x + scale,
- y: game.mouseInGame.y + scale
- }
- }).length === 0 &&
- Matter.Query.ray(map, mech.pos, justPastMouse).length === 0
- // Matter.Query.ray(map, mech.pos, game.mouseInGame).length === 0 &&
- // Matter.Query.ray(map, player.position, game.mouseInGame).length === 0 &&
- // Matter.Query.ray(map, player.position, justPastMouse).length === 0
- )
- ) {
- const sub = Vector.sub(game.mouseInGame, mech.pos)
- const mag = Vector.magnitude(sub)
- const drain = 0.03 + 0.005 * Math.sqrt(mag)
- if (mech.energy > drain && mag > 300) {
- mech.energy -= drain
- mech.hole.isReady = false;
- mech.fieldRange = 0
- Matter.Body.setPosition(player, game.mouseInGame);
- mech.buttonCD_jump = 0 //this might fix a bug with jumping
- const velocity = Vector.mult(Vector.normalise(sub), 18)
- Matter.Body.setVelocity(player, {
- x: velocity.x,
- y: velocity.y - 4 //an extra vertical kick so the player hangs in place longer
- });
- mech.immuneCycle = mech.cycle + 15; //player is immune to collision damage
- // move bots to follow player
- for (let i = 0; i < bullet.length; i++) {
- if (bullet[i].botType) {
- Matter.Body.setPosition(bullet[i], Vector.add(player.position, {
- x: 250 * (Math.random() - 0.5),
- y: 250 * (Math.random() - 0.5)
- }));
- Matter.Body.setVelocity(bullet[i], {
- x: 0,
- y: 0
- });
+ if (input.field && mech.fieldCDcycle < mech.cycle) { //not hold but field button is pressed
+ const justPastMouse = Vector.add(Vector.mult(Vector.normalise(Vector.sub(game.mouseInGame, mech.pos)), 50), game.mouseInGame)
+ const scale = 60
+ // console.log(Matter.Query.region(map, bounds))
+ if (mech.hole.isReady &&
+ (
+ Matter.Query.region(map, {
+ min: {
+ x: game.mouseInGame.x - scale,
+ y: game.mouseInGame.y - scale
+ },
+ max: {
+ x: game.mouseInGame.x + scale,
+ y: game.mouseInGame.y + scale
+ }
+ }).length === 0 &&
+ Matter.Query.ray(map, mech.pos, justPastMouse).length === 0
+ // Matter.Query.ray(map, mech.pos, game.mouseInGame).length === 0 &&
+ // Matter.Query.ray(map, player.position, game.mouseInGame).length === 0 &&
+ // Matter.Query.ray(map, player.position, justPastMouse).length === 0
+ )
+ ) {
+ const sub = Vector.sub(game.mouseInGame, mech.pos)
+ const mag = Vector.magnitude(sub)
+ const drain = 0.03 + 0.005 * Math.sqrt(mag)
+ if (mech.energy > drain && mag > 300) {
+ mech.energy -= drain
+ mech.hole.isReady = false;
+ mech.fieldRange = 0
+ Matter.Body.setPosition(player, game.mouseInGame);
+ mech.buttonCD_jump = 0 //this might fix a bug with jumping
+ const velocity = Vector.mult(Vector.normalise(sub), 18)
+ Matter.Body.setVelocity(player, {
+ x: velocity.x,
+ y: velocity.y - 4 //an extra vertical kick so the player hangs in place longer
+ });
+ mech.immuneCycle = mech.cycle + 15; //player is immune to collision damage
+ // move bots to follow player
+ for (let i = 0; i < bullet.length; i++) {
+ if (bullet[i].botType) {
+ Matter.Body.setPosition(bullet[i], Vector.add(player.position, {
+ x: 250 * (Math.random() - 0.5),
+ y: 250 * (Math.random() - 0.5)
+ }));
+ Matter.Body.setVelocity(bullet[i], {
+ x: 0,
+ y: 0
+ });
+ }
+ }
+
+ //set holes
+ mech.hole.isOn = true;
+ mech.hole.pos1.x = mech.pos.x
+ mech.hole.pos1.y = mech.pos.y
+ mech.hole.pos2.x = player.position.x
+ mech.hole.pos2.y = player.position.y
+ mech.hole.angle = Math.atan2(sub.y, sub.x)
+ mech.hole.unit = Vector.perp(Vector.normalise(sub))
+
+ if (mod.isWormholeDamage) {
+ who = Matter.Query.ray(mob, mech.pos, game.mouseInGame, 80)
+ for (let i = 0; i < who.length; i++) {
+ if (who[i].body.alive) {
+ mobs.statusDoT(who[i].body, 0.6, 420)
+ mobs.statusStun(who[i].body, 240)
}
}
-
- //set holes
- mech.hole.isOn = true;
- mech.hole.pos1.x = mech.pos.x
- mech.hole.pos1.y = mech.pos.y
- mech.hole.pos2.x = player.position.x
- mech.hole.pos2.y = player.position.y
- mech.hole.angle = Math.atan2(sub.y, sub.x)
- mech.hole.unit = Vector.perp(Vector.normalise(sub))
-
- if (mod.isWormholeDamage) {
- who = Matter.Query.ray(mob, mech.pos, game.mouseInGame, 80)
- for (let i = 0; i < who.length; i++) {
- if (who[i].body.alive) {
- mobs.statusDoT(who[i].body, 0.6, 420)
- mobs.statusStun(who[i].body, 240)
- }
- }
- }
- } else {
- mech.grabPowerUp();
}
} else {
mech.grabPowerUp();
}
- } else if (mech.holdingTarget && mech.fieldCDcycle < mech.cycle) { //holding, but field button is released
- 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)
- mech.hole.isReady = true;
+ mech.grabPowerUp();
}
- mech.drawFieldMeter()
+ } else if (mech.holdingTarget && mech.fieldCDcycle < mech.cycle) { //holding, but field button is released
+ 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)
+ mech.hole.isReady = true;
}
- }
+ mech.drawFieldMeter()
+ },
},
],
};
\ No newline at end of file
diff --git a/js/spawn.js b/js/spawn.js
index 801962f..349fe10 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -81,7 +81,7 @@ const spawn = {
}
}
},
- randomLevelBoss(x, y, options = ["shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "powerUpBoss", "snakeBoss"]) {
+ randomLevelBoss(x, y, options = ["shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "powerUpBoss", "snakeBoss", "streamBoss"]) {
// other bosses: suckerBoss, laserBoss, tetherBoss, //all need a particular level to work so they are not included
spawn[options[Math.floor(Math.random() * options.length)]](x, y)
},
@@ -101,15 +101,34 @@ const spawn = {
level.bossKilled = true;
level.exit.x = 5500;
level.exit.y = -330;
+ //ramp up damage
+ for (let i = 0; i < 4; i++) level.difficultyIncrease(game.difficultyMode)
+
//pull in particles
- for (let i = 0, len = body.length; i < len; ++i) { //push blocks away horizontally
+ for (let i = 0, len = body.length; i < len; ++i) {
const velocity = Vector.mult(Vector.normalise(Vector.sub(this.position, body[i].position)), 65)
- const pushUp = Vector.add(velocity, { x: 0, y: -0.3 })
+ const pushUp = Vector.add(velocity, { x: 0, y: -0.5 })
Matter.Body.setVelocity(body[i], Vector.add(body[i].velocity, pushUp));
}
- //ramp up damage
- for (let i = 0; i < 5; i++) level.difficultyIncrease(game.difficultyMode)
+ //push away mobs
+ for (let i = 0, len = mob.length; i < len; ++i) {
+ if (mob[i] !== this) {
+ const velocity = Vector.mult(Vector.normalise(Vector.sub(this.position, mob[i].position)), -65)
+ Matter.Body.setVelocity(mob[i], Vector.add(mob[i].velocity, velocity));
+ }
+ }
+
+ //draw stuff
+ for (let i = 0, len = 22; i < len; i++) {
+ game.drawList.push({ //add dmg to draw queue
+ x: this.position.x,
+ y: this.position.y,
+ radius: (i + 1) * 150,
+ color: `rgba(255,255,255,0.17)`,
+ time: 5 * (len - i + 1)
+ });
+ }
};
me.onDamage = function() {};
@@ -761,7 +780,7 @@ const spawn = {
let me = mob[mob.length - 1];
me.stroke = "transparent"; //used for drawSneaker
me.eventHorizon = radius * 23; //required for blackhole
- me.seeAtDistance2 = (me.eventHorizon + 300) * (me.eventHorizon + 300); //vision limit is event horizon
+ me.seeAtDistance2 = (me.eventHorizon + 400) * (me.eventHorizon + 400); //vision limit is event horizon
me.accelMag = 0.00009 * game.accelScale;
me.frictionAir = 0.025;
me.collisionFilter.mask = cat.player | cat.bullet
@@ -775,8 +794,15 @@ const spawn = {
y: this.velocity.y * 0.99
});
}
- // this.seePlayerByDistOrLOS();
- this.seePlayerCheckByDistance()
+ // this.seePlayerCheckByDistance()
+ if (!(game.cycle % this.seePlayerFreq)) {
+ if (this.distanceToPlayer2() < this.seeAtDistance2) { //&& !mech.isCloak ignore cloak for black holes
+ this.locatePlayer();
+ if (!this.seePlayer.yes) this.seePlayer.yes = true;
+ } else if (this.seePlayer.recall) {
+ this.lostPlayer();
+ }
+ }
this.checkStatus();
if (this.seePlayer.recall) {
//eventHorizon waves in and out
@@ -832,7 +858,7 @@ const spawn = {
me.isBoss = true;
me.stroke = "transparent"; //used for drawSneaker
me.eventHorizon = 1100; //required for black hole
- me.seeAtDistance2 = (me.eventHorizon + 1000) * (me.eventHorizon + 1000); //vision limit is event horizon
+ me.seeAtDistance2 = (me.eventHorizon + 1200) * (me.eventHorizon + 1200); //vision limit is event horizon
me.accelMag = 0.00003 * game.accelScale;
me.collisionFilter.mask = cat.player | cat.bullet
// me.frictionAir = 0.005;
@@ -865,7 +891,14 @@ const spawn = {
y: this.velocity.y * 0.95
});
}
- this.seePlayerByDistOrLOS();
+ if (!(game.cycle % this.seePlayerFreq)) {
+ if (this.distanceToPlayer2() < this.seeAtDistance2) { //&& !mech.isCloak ignore cloak for black holes
+ this.locatePlayer();
+ if (!this.seePlayer.yes) this.seePlayer.yes = true;
+ } else if (this.seePlayer.recall) {
+ this.lostPlayer();
+ }
+ }
this.checkStatus();
if (this.seePlayer.recall) {
//accelerate towards the player
@@ -1865,7 +1898,7 @@ const spawn = {
me.onHit = function() {
this.explode(this.mass * 20);
};
- Matter.Body.setDensity(me, 0.00005); //normal is 0.001
+ Matter.Body.setDensity(me, 0.00004); //normal is 0.001
me.timeLeft = 200;
me.g = 0.001; //required if using 'gravity'
me.frictionAir = 0;
@@ -2106,7 +2139,7 @@ const spawn = {
me.frictionStatic = 0;
me.friction = 0;
me.frictionAir = 0.02;
- me.memory = 420 * game.CDScale;
+ me.memory = 420;
me.repulsionRange = 1200000; //squared
spawn.shield(me, x, y, 1);
Matter.Body.setDensity(me, 0.004 + 0.0005 * Math.sqrt(game.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
@@ -2124,7 +2157,7 @@ const spawn = {
Matter.Body.setAngularVelocity(this, 0.11)
//fire a bullet from each vertex
for (let i = 0, len = this.vertices.length; i < len; i++) {
- spawn.seeker(this.vertices[i].x, this.vertices[i].y, 7)
+ spawn.seeker(this.vertices[i].x, this.vertices[i].y, 6)
//give the bullet a rotational velocity as if they were attached to a vertex
const velocity = Vector.mult(Vector.perp(Vector.normalise(Vector.sub(this.position, this.vertices[i]))), -10)
Matter.Body.setVelocity(mob[mob.length - 1], {
@@ -2135,7 +2168,84 @@ const spawn = {
}
};
},
- seeker(x, y, radius = 5, sides = 0) {
+ streamBoss(x, y, radius = 110) {
+ mobs.spawn(x, y, 5, radius, "rgb(245,180,255)");
+ let me = mob[mob.length - 1];
+ me.isBoss = true;
+ // me.accelMag = 0.00023 * game.accelScale;
+ me.accelMag = 0.00008 * game.accelScale;
+ // me.fireFreq = Math.floor(30 * game.CDScale)
+ me.canFire = false;
+ me.closestVertex1 = 0;
+ me.closestVertex2 = 1;
+ me.cycle = 0
+ me.frictionStatic = 0;
+ me.friction = 0;
+ me.frictionAir = 0.022;
+ me.memory = 240;
+ me.repulsionRange = 1200000; //squared
+ spawn.shield(me, x, y, 1);
+ Matter.Body.setDensity(me, 0.025); //extra dense //normal is 0.001 //makes effective life much larger
+ me.onDeath = function() {
+ powerUps.spawnBossPowerUp(this.position.x, this.position.y)
+ // this.vertices = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices)) //helps collisions functions work better after vertex have been changed
+ };
+ me.onDamage = function() {};
+ me.do = function() {
+ this.seePlayerCheck();
+ this.checkStatus();
+ this.attraction();
+ this.repulsion();
+
+ this.cycle++
+ if (this.seePlayer.recall && ((this.cycle % 15) === 0) && !mech.isBodiesAsleep) {
+ if (this.canFire) {
+ if (this.cycle > 120) {
+ this.cycle = 0
+ this.canFire = false
+ // Matter.Body.setAngularVelocity(this, 0.1)
+ // const forceMag = 0.01 * this.mass;
+ // const angle = Math.atan2(this.seePlayer.position.y - this.position.y, this.seePlayer.position.x - this.position.x);
+ // this.force.x -= 2 * forceMag * Math.cos(angle);
+ // this.force.y -= 2 * forceMag * Math.sin(angle); // - 0.0007 * this.mass; //antigravity
+ }
+ spawn.seeker(this.vertices[this.closestVertex1].x, this.vertices[this.closestVertex1].y, 4)
+ Matter.Body.setDensity(mob[mob.length - 1], 0.000001); //normal is 0.001
+ const velocity = Vector.mult(Vector.normalise(Vector.sub(this.position, this.vertices[this.closestVertex1])), -10)
+ Matter.Body.setVelocity(mob[mob.length - 1], {
+ x: this.velocity.x + velocity.x,
+ y: this.velocity.y + velocity.y
+ });
+ spawn.seeker(this.vertices[this.closestVertex2].x, this.vertices[this.closestVertex2].y, 4)
+ Matter.Body.setDensity(mob[mob.length - 1], 0.000001); //normal is 0.001
+ const velocity2 = Vector.mult(Vector.normalise(Vector.sub(this.position, this.vertices[this.closestVertex2])), -10)
+ Matter.Body.setVelocity(mob[mob.length - 1], {
+ x: this.velocity.x + velocity2.x,
+ y: this.velocity.y + velocity2.y
+ });
+ } else if (this.cycle > 210) {
+ this.cycle = 0
+ this.canFire = true
+
+ //find closest 2 vertexes
+ let distance2 = Infinity
+ for (let i = 0; i < this.vertices.length; i++) {
+ const d = Vector.magnitudeSquared(Vector.sub(this.vertices[i], player.position))
+ if (d < distance2) {
+ distance2 = d
+ this.closestVertex2 = this.closestVertex1
+ this.closestVertex1 = i
+ }
+ }
+ if (this.closestVertex2 === this.closestVertex1) {
+ this.closestVertex2++
+ if (this.closestVertex2 === this.vertices.length) this.closestVertex2 = 0
+ }
+ }
+ }
+ };
+ },
+ seeker(x, y, radius = 5, sides = 6) {
//bullets
mobs.spawn(x, y, sides, radius, "rgb(255,0,255)");
let me = mob[mob.length - 1];
@@ -2143,10 +2253,10 @@ const spawn = {
me.onHit = function() {
this.explode(this.mass * 20);
};
- Matter.Body.setDensity(me, 0.00002); //normal is 0.001
+ Matter.Body.setDensity(me, 0.000015); //normal is 0.001
me.timeLeft = 420 * (0.8 + 0.4 * Math.random());
- me.accelMag = 0.00017 * (0.8 + 0.4 * Math.random()) * game.accelScale;
- me.frictionAir = 0.01 * (0.8 + 0.4 * Math.random());
+ me.accelMag = 0.00017 * game.accelScale; //* (0.8 + 0.4 * Math.random())
+ me.frictionAir = 0.01 //* (0.8 + 0.4 * Math.random());
me.restitution = 0.5;
me.leaveBody = false;
me.dropPowerUp = false;
@@ -2190,6 +2300,7 @@ const spawn = {
//run this function on hitting player
this.explode();
};
+ Matter.Body.setDensity(me, 0.0005); //normal is 0.001
me.g = 0.0001; //required if using 'gravity'
me.accelMag = 0.0003 * game.accelScale;
me.memory = 30;
diff --git a/style.css b/style.css
index 754418a..4b84895 100644
--- a/style.css
+++ b/style.css
@@ -587,6 +587,7 @@ em {
/* background: rgb(116, 102, 238); */
/* background: hsl(253, 57%, 52%); */
background: hsl(255, 100%, 71%);
+ /* background: hsl(282, 100%, 64%); */
}
/* .grey {
diff --git a/todo.txt b/todo.txt
index 8db3d91..5c119d9 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,22 +1,16 @@
******************************************************** NEXT PATCH ********************************************************
-your build url can now be copied in the pause screen
+new level boss that fires 2 streams of small bullets that chase you
-mod: inductive coupling - 4 max health per power up, but limited to 44 max health per level (replaces crystalized armor)
-mod: transceiver chip - use all the power ups left over at the end of a level
-mod: catabolism - does a flat 5 damage to your health for 3 ammo (was 2% of max health for 1 ammo)
+mod: add a CPT gun to your inventory that rewinds your history, reverts your health, position, velocity for 10 seconds
+ I expect that spamming rewind has some overpowered combos.
+ Let me know what you find, and your ideas on balance.
+
******************************************************** BUGS ********************************************************
-give worm hole pair production?
-
-2nd mod for crystalized armor
- no cap for health power ups?
-
-(not able to reproduce, might be fixed) possible bug with neutron rewind
- status doesn't apply correctly for spawned neutron bombs that are stuck to a shield
- also saw neutron bombs bounce off shield, for normal bullets
- test this more
+check for crouch after rewind
+ CPT, tesseract
mod and mob are too similar
@@ -26,13 +20,15 @@ mod and mob are too similar
trigger a short term non-collide if that occurs
(12+ reports) bug - crouch and worm hole? -> crouch locked in
- doesn't occur on my computer?
+ ***try checking the date of the first bug, and then look at what patches came out right before that***
+ doesn't occur on my computer? but it does occur on fast computers
you can spoof it with mech.crouch = true in console
players have extra gravity
might be from the short jump code
add in a check every 7 seconds to try and fix it
this fix was added and it is working for some cases
maybe move the fix to once a second?
+ bug fix - rewrite crouch to not translate the player height, but instead switch between 2 sensors
(intermittent, but almost every time) bug - capping the fps causes random slow downs, that can be fixed with pause
@@ -44,7 +40,39 @@ mod and mob are too similar
******************************************************** TODO ********************************************************
-make a reset hit box function as a way to fix crouch bug
+mod: laser beams push like plasma torch pushes with directional force
+
+mod: worm hole - you move through time instead of space. (field click to rewind)
+ add support for eating blocks, and damaging mobs that are nearby when you rewind
+ allow those mods
+ mod might not work as is because player needs to be able to pick up and move blocks sometimes
+ what about as a gun that uses energy not bullets?
+
+mechanic: technological dead end - add mods to the mod pool with a dumb effect
+ don't show up in custom?
+ negative effect (one time effects are better to avoid code clutter)
+ make the player rainbow colors
+ mech.color = {
+ hue: 0,
+ sat: 100,
+ light: 50
+ }
+ setInterval(function(){
+ mech.color.hue++
+ mech.setFillColors()
+ }, 10);
+ remove all your energy
+ eject all your rerolls (not bad with dup)
+ teleport to the start of the level
+ remove your bots (requires you to have some bots)
+ your bots are changed to random bots
+
+Mod: "High Risk": Spawn two bosses per level.
+ maybe limit to just the power up boss and spawn it at the exit every time to keep it simple
+ also weaken the player
+ remove a mod up?
+ lower harm reduction?
+ increase game difficulty by one level
mod that requires integrated armament
@@ -75,15 +103,6 @@ make different move methods
mod: when mobs are at full health you do 40% to them
-mechanic: failed technology - add mods to the mod pool with a dumb effect
- don't show up in custom?
- negative effect (one time effects are better to avoid code clutter)
- remove all your energy
- eject all your rerolls (not bad with dup)
- teleport to the start of the level
- remove your bots (requires you to have some bots)
- your bots are changed to random bots
-
mod - move super fast, go intangible, drain energy very fast
this is like a dodge roll
mod for standing wave?, cloaking?
@@ -371,12 +390,16 @@ robot AI communication
output to
bottom left message
tab title?
- style
+ style
+ output console.log?
make it look like a computer terminal
+ track multiple lines, like your vocoder program
+ messages about heal, ammo, mods, that just list internal computer code
+ example: a heal would be mech.health += 12
mono space font
square edges
- in baby talk?
- with random ASCII gibberish letters
+ black text on bottom right with no background?
+ or white text, or yellow
end each message with a hexadecimal encryption code/hash
message after selecting each new (mod / gun / field)
put messages in (mod / gun / field) method
@@ -385,6 +408,14 @@ robot AI communication
you'd have to store an array of guns/fields/mod used last game
n-gon escape simulation ${random seed}
say something about what mobs types are queued up, and level order
+ **all communication should be from scientists watching the simulation; the robot shouldn't talk**
+ talking about the robot, watching
+ trying to communicate with the robot? but how
+ lines:
+ I think it's planing to escape
+ Why is it attacking those shapes?
+ Are those shapes supposed to be us?
+
add an ending to the game
maybe the game ending should ask you to open the console and type in some commands like in the end of doki doki