diff --git a/js/bullet.js b/js/bullet.js
index e57cc1f..5d639a2 100644
--- a/js/bullet.js
+++ b/js/bullet.js
@@ -2259,7 +2259,7 @@ const b = {
// check if inside a mob
q = Matter.Query.point(mob, this.position)
for (let i = 0; i < q.length; i++) {
- let dmg = b.dmgScale * 0.36 / Math.sqrt(q[i].mass) * (mod.waveHelix === 1 ? 1 : 0.8) //1 - 0.4 = 0.6 for helix mod 40% damage reduction
+ let dmg = b.dmgScale * 0.4 / Math.sqrt(q[i].mass) * (mod.waveHelix === 1 ? 1 : 0.8) //1 - 0.4 = 0.6 for helix mod 40% damage reduction
q[i].damage(dmg);
q[i].foundPlayer();
game.drawList.push({ //add dmg to draw queue
@@ -2292,7 +2292,7 @@ const b = {
for (let i = 0; i < q.length; i++) {
slowCheck = 0.3;
Matter.Body.setPosition(this, Vector.add(this.position, q[i].velocity)) //move with the medium
- let dmg = b.dmgScale * 0.36 / Math.sqrt(q[i].mass) * (mod.waveHelix === 1 ? 1 : 0.8) //1 - 0.4 = 0.6 for helix mod 40% damage reduction
+ let dmg = b.dmgScale * 0.4 / Math.sqrt(q[i].mass) * (mod.waveHelix === 1 ? 1 : 0.8) //1 - 0.4 = 0.6 for helix mod 40% damage reduction
q[i].damage(dmg);
q[i].foundPlayer();
game.drawList.push({ //add dmg to draw queue
diff --git a/js/level.js b/js/level.js
index e60bef3..f00b947 100644
--- a/js/level.js
+++ b/js/level.js
@@ -13,13 +13,13 @@ 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(8)
+ // level.difficultyIncrease(89)
// game.zoomScale = 1000;
// game.setZoom();
// mech.setField("wormhole")
// b.giveGuns("laser")
// mod.is3Missiles = true
- // mod.giveMod("history laser")
+ // mod.giveMod("CPT reversal")
// mod.giveMod("diffuse beam")
level.intro(); //starting level
@@ -156,7 +156,7 @@ const level = {
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump
// spawn.boost(1500, 0, 900);
- // spawn.starter(1900, -500, 20)
+ spawn.starter(1900, -500, 20)
// spawn.sucker(2900, -500)
// spawn.launcherBoss(1200, -500)
// spawn.laserTargetingBoss(1600, -400)
@@ -171,7 +171,7 @@ const level = {
// spawn.nodeBoss(1200, -500, "launcher")
// spawn.snakeBoss(1200, -500)
- spawn.powerUpBoss(2900, -500)
+ // spawn.powerUpBoss(2900, -500)
// spawn.randomMob(1600, -500)
},
template() {
@@ -762,7 +762,11 @@ const level = {
spawn.randomMob(-75, -850, -0.1);
spawn.randomMob(1300, -600, -0.1);
spawn.randomMob(550, -3400, 0);
- if (game.difficulty > 50) {
+ spawn.randomMob(0, -1175, 0.5);
+ spawn.randomMob(-75, -1150, 0.5);
+ spawn.randomMob(1075, -625, 0.5);
+ spawn.randomMob(1725, -575, 0.5);
+ if (game.difficulty > 40) {
spawn.randomMob(2300, -2775, -0.5);
spawn.randomMob(600, -925, -0.5);
spawn.randomMob(1550, -2750, -0.5);
@@ -770,7 +774,7 @@ const level = {
spawn.randomMob(-75, -1475, 0);
spawn.randomBoss(600, -2600, 0);
}
- if (game.difficulty < 32) {
+ if (game.difficulty < 25) {
spawn.randomMob(700, -1650, 0);
spawn.randomMob(600, -3500, 0.2);
spawn.randomMob(-75, -1175, 0.2);
@@ -871,12 +875,6 @@ const level = {
spawn.mapRect(2625, 2288, 650, 50);
spawn.mapRect(2700, 2276, 500, 50);
- // spawn.mapRect(3000, 400, 1000, 1250);
- // spawn.mapRect(3000, 1925, 1000, 150);
- // spawn.mapRect(3100, 1875, 800, 100);
- // spawn.mapRect(3100, 1600, 800, 100);
- // spawn.mapRect(3100, 350, 800, 100);
- // spawn.mapRect(3100, 2025, 800, 100);
spawn.mapRect(2400, 0, 200, 1925); //left down tube wall
spawn.mapRect(600, 2300, 3750, 200);
@@ -889,7 +887,6 @@ const level = {
spawn.mapRect(500, 1700, 200, 800); //left wall
spawn.mapRect(675, 1875, 325, 150, 0.5);
-
spawn.mapRect(4450, 2900, 4900, 200); //boss room floor
spawn.mapRect(4150, 2600, 400, 500);
spawn.mapRect(6250, 2675, 700, 325);
@@ -909,25 +906,30 @@ const level = {
spawn.mapRect(9300, 2590, 650, 25);
spawn.mapRect(9700, 2580, 100, 50);
- spawn.randomBoss(1300, 2100, 0.5);
- spawn.randomMob(8300, 2100, 0.2);
- spawn.randomSmallMob(2575, -75, 0.2); //entrance
- spawn.randomMob(8125, 2450, 0.25);
- spawn.randomSmallMob(3200, 250, 0.3);
- spawn.randomMob(2425, 2150, 0.3);
- spawn.randomSmallMob(3500, 250, 0.4);
- spawn.randomMob(3800, 2175, 0.4);
- spawn.randomSmallMob(1100, -300, 0.4); //entrance
- spawn.randomMob(4450, 2500, 0.5);
- spawn.randomMob(6350, 2525, 0.5);
- spawn.randomBoss(9200, 2400, 0.6);
- spawn.randomSmallMob(1900, -250, 0.6); //entrance
- spawn.randomMob(1500, 2100, 0.7);
- spawn.randomSmallMob(1700, -150, 0.7); //entrance
- spawn.randomMob(8800, 2725, 0.8);
- spawn.randomMob(7300, 2200, 0.8);
- spawn.randomMob(2075, 2025, 0.8);
- spawn.randomMob(3475, 2175, 0.8);
+ spawn.randomBoss(1300, 2100, 0.1);
+ spawn.randomMob(8300, 2100, 0.1);
+ spawn.randomSmallMob(2575, -75, 0.1); //entrance
+ spawn.randomMob(8125, 2450, 0.1);
+ spawn.randomSmallMob(3200, 250, 0.1);
+ spawn.randomMob(2425, 2150, 0.1);
+ spawn.randomSmallMob(3500, 250, 0.2);
+ spawn.randomMob(3800, 2175, 0.2);
+ spawn.randomSmallMob(1100, -300, 0.2); //entrance
+ spawn.randomMob(4450, 2500, 0.2);
+ spawn.randomMob(6350, 2525, 0.2);
+ spawn.randomBoss(9200, 2400, 0.3);
+ spawn.randomSmallMob(1900, -250, 0.3); //entrance
+ spawn.randomMob(1500, 2100, 0.4);
+ spawn.randomSmallMob(1700, -150, 0.4); //entrance
+ spawn.randomMob(8800, 2725, 0.5);
+ spawn.randomMob(7300, 2200, 0.5);
+ spawn.randomMob(2075, 2025, 0.5);
+ spawn.randomMob(3475, 2175, 0.5);
+ spawn.randomMob(8900, 2825, 0.5);
+ spawn.randomMob(9600, 2425, 0.9);
+ 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"]);
powerUps.addRerollToLevel() //needs to run after mobs are spawned
},
@@ -996,13 +998,6 @@ const level = {
height: 775,
color: "rgba(0,20,40,0.2)"
});
- level.fill.push({
- x: 1800,
- y: -475,
- width: 850,
- height: 775,
- color: "rgba(0,20,40,0.2)"
- });
level.fillBG.push({
x: -250,
y: -750,
@@ -1037,19 +1032,26 @@ const level = {
color: "#d0d4d6"
});
//tall platform
- spawn.mapVertex(2225, -450, "325 0 250 80 -250 80 -325 0 -250 -80 250 -80"); //base
+ spawn.mapVertex(2225, -250, "325 0 250 80 -250 80 -325 0 -250 -80 250 -80"); //base
spawn.mapRect(1725, -2800, 1000, 50); //super high shade
- spawn.mapRect(1800, -500, 850, 100); //far left starting ceiling
+ spawn.mapRect(1800, -300, 850, 100); //far left starting ceiling
spawn.bodyRect(2400, -2950, 150, 150); //shield from laser
level.fillBG.push({
x: 2000,
y: -2800,
width: 450,
- height: 2300,
+ height: 2500,
color: "#d0d4d6"
});
+ level.fill.push({
+ x: 1800,
+ y: -275,
+ width: 850,
+ height: 775,
+ color: "rgba(0,20,40,0.2)"
+ });
//tall platform
- spawn.mapVertex(3350, 200, "375 0 -375 0 -250 -250 250 -250"); //base
+ spawn.mapVertex(3350, 200, "400 0 -400 0 -275 -275 275 -275"); //base
spawn.bodyRect(3400, -150, 150, 150);
spawn.mapRect(2850, -3150, 1000, 50); //super high shade
spawn.bodyRect(3675, -3470, 525, 20); //plank
@@ -1089,16 +1091,9 @@ const level = {
spawn.mapRect(4600, -1300, 450, 100);
//steep stairs
- // spawn.mapRect(4100, -1700, 100, 100);
- // spawn.mapRect(4200, -2050, 100, 450);
- // spawn.mapRect(4300, -2400, 100, 800);
- // spawn.mapRect(4400, -2750, 100, 1150);
- // spawn.mapRect(4500, -3100, 100, 1500);
spawn.mapRect(4100, -2250, 100, 650);
spawn.mapRect(4100, -3450, 100, 650); //left top shelf
spawn.mapRect(4600, -3450, 100, 1850);
- // spawn.mapRect(4200, -3450, 100, 400); //left top shelf
- // spawn.mapRect(4300, -3450, 100, 100); //left top shelf
level.fill.push({
x: 4100,
y: -3450,
@@ -1106,31 +1101,24 @@ const level = {
height: 2250,
color: "rgba(0,20,40,0.13)"
});
- // level.fill.push({
- // x: 4100,
- // y: -1600,
- // width: 600,
- // height: 300,
- // color: "rgba(0,20,40,0.13)"
- // });
spawn.randomSmallMob(4400, -3500);
spawn.randomSmallMob(4800, -800);
- spawn.randomSmallMob(800, 150);
- spawn.randomMob(700, -600, 0.8);
- spawn.randomMob(3100, -3600, 0.7);
- spawn.randomMob(3300, -1000, 0.7);
- spawn.randomMob(4200, -250, 0.7);
- spawn.randomMob(4900, -1500, 0.6);
- spawn.randomMob(1200, 100, 0.4);
+ spawn.randomMob(800, -2600);
+ spawn.randomMob(700, -600, 0.3);
+ spawn.randomMob(3100, -3600, 0.3);
+ spawn.randomMob(3300, -1000, 0.3);
+ spawn.randomMob(4200, -250, 0.3);
+ spawn.randomMob(4900, -1500, 0.3);
+ spawn.randomMob(3800, 175, 0.4);
+ spawn.randomMob(5750, 125, 0.4);
spawn.randomMob(5900, -1500, 0.4);
spawn.randomMob(4700, -800, 0.4);
spawn.randomMob(1400, -400, 0.3);
- spawn.randomMob(1200, 100, 0.3);
- spawn.randomMob(2550, -100, 0.2);
- spawn.randomMob(2000, -2800, 0.2);
- spawn.randomMob(2000, -500, 0.2);
- spawn.randomMob(4475, -3550, 0.1);
+ spawn.randomMob(2850, 175, 0.4);
+ spawn.randomMob(2000, -2800, 0.4);
+ spawn.randomMob(2200, -500, 0.4);
+ spawn.randomMob(4475, -3550, 0.3);
spawn.randomBoss(5000, -2150, 1);
spawn.randomBoss(3700, -4100, 0.3);
spawn.randomBoss(2700, -1600, 0.1);
@@ -1538,6 +1526,12 @@ const level = {
spawn.randomMob(4700, -150, 0.2);
spawn.randomBoss(4000, -350, 0.6);
spawn.randomBoss(2750, -550, 0.1);
+ spawn.randomMob(2175, -925, 0.5);
+ spawn.randomMob(2750, 100, 0.5);
+ spawn.randomMob(4250, -1725, 0.5);
+ spawn.randomMob(3575, -2425, 0.5);
+ spawn.randomMob(3975, -3900, 0.5);
+ spawn.randomMob(1725, 125, 0.5);
if (game.difficulty > 3) {
if (Math.random() < 0.1) { // tether ball
spawn.tetherBoss(4250, 0)
diff --git a/js/mob.js b/js/mob.js
index 27a1463..b37c841 100644
--- a/js/mob.js
+++ b/js/mob.js
@@ -970,9 +970,11 @@ const mobs = {
Matter.Body.setAngle(this, angle - Math.PI);
},
explode(mass = this.mass) {
- mech.damage(Math.min(Math.max(0.02 * Math.sqrt(mass), 0.01), 0.35) * game.dmgScale);
- this.dropPowerUp = false;
- this.death(); //death with no power up or body
+ if (mech.immuneCycle < mech.cycle) {
+ mech.damage(Math.min(Math.max(0.02 * Math.sqrt(mass), 0.01), 0.35) * game.dmgScale);
+ this.dropPowerUp = false;
+ this.death(); //death with no power up or body
+ }
},
timeLimit() {
if (!mech.isBodiesAsleep) {
diff --git a/js/mods.js b/js/mods.js
index b72270b..9b42461 100644
--- a/js/mods.js
+++ b/js/mods.js
@@ -981,6 +981,22 @@ const mod = {
mod.overfillDrain = 0.8
}
},
+ {
+ name: "CPT reversal",
+ description: "rewind 2-4 seconds to avoid harm
drains a minimum of 100% energy",
+ maxCount: 1,
+ count: 0,
+ allowed() {
+ return mech.fieldUpgrades[mech.fieldMode].name !== "nano-scale manufacturing" && mech.fieldUpgrades[mech.fieldMode].name !== "standing wave harmonics" && !mod.isEnergyHealth && !mod.isEnergyLoss
+ },
+ requires: "not nano-scale manufacturing, not mass-energy equivalence, not standing wave harmonics, not acute stress response",
+ effect() {
+ mod.isTimeAvoidDeath = true;
+ },
+ remove() {
+ mod.isTimeAvoidDeath = false;
+ }
+ },
{
name: "piezoelectricity",
description: "colliding with mobs overfills energy by 200%
reduce harm by 15%",
@@ -1022,7 +1038,7 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
- return !mod.isPiezo
+ return !mod.isPiezo && !mod.isTimeAvoidDeath
},
requires: "not piezoelectricity
or acute stress response",
effect: () => {
@@ -1629,7 +1645,7 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
- return (mech.fieldUpgrades[mech.fieldMode].name === "nano-scale manufacturing" && !(mod.isSporeField || mod.isMissileField || mod.isIceField)) || mod.haveGunCheck("drones") || mod.haveGunCheck("super balls") || (mod.haveGunCheck("nail gun")) || (mod.haveGunCheck("shotgun")) && !mod.isIceCrystals && !mod.isNailCrit && !mod.isNailShot && !mod.isNailPoison
+ return ((mech.fieldUpgrades[mech.fieldMode].name === "nano-scale manufacturing" && !(mod.isSporeField || mod.isMissileField || mod.isIceField)) || mod.haveGunCheck("drones") || mod.haveGunCheck("super balls") || mod.haveGunCheck("nail gun") || mod.haveGunCheck("shotgun")) && !mod.isIceCrystals && !mod.isNailCrit && !mod.isNailShot && !mod.isNailPoison
},
requires: "drones, super balls, nail gun, shotgun",
effect() {
@@ -3123,7 +3139,7 @@ const mod = {
},
{
name: "traversable geodesics",
- description: "your bullets can traverse wormholes
spawn a gun power up",
+ description: "your bullets can traverse wormholes
spawn a gun and ammo power up",
maxCount: 1,
count: 0,
allowed() {
@@ -3133,6 +3149,7 @@ const mod = {
effect() {
mod.isWormBullets = true
powerUps.spawn(mech.pos.x, mech.pos.y, "gun");
+ powerUps.spawn(mech.pos.x, mech.pos.y, "ammo");
},
remove() {
mod.isWormBullets = false
@@ -3394,5 +3411,6 @@ const mod = {
isRailAreaDamage: null,
historyLaser: null,
isSpeedHarm: null,
- isSpeedDamage: null
+ isSpeedDamage: null,
+ isTimeSkip: null
}
\ No newline at end of file
diff --git a/js/player.js b/js/player.js
index fee5509..efe94ce 100644
--- a/js/player.js
+++ b/js/player.js
@@ -476,6 +476,45 @@ const mech = {
return dmg
},
damage(dmg) {
+ if (mod.isTimeAvoidDeath && mech.energy > 0.97) {
+ const steps = Math.floor(Math.min(240, 120 * mech.energy)) //go back 2 seconds at 100% energy
+ let history = mech.history[(mech.cycle - steps) % 300]
+ Matter.Body.setPosition(player, history.position);
+ Matter.Body.setVelocity(player, { x: history.velocity.x, y: history.velocity.y });
+ mech.energy = Math.max(mech.energy - steps, 0.01)
+ mech.immuneCycle = mech.cycle + mod.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
+
+ let isDrawPlayer = true
+ const shortPause = function() {
+ if (mech.defaultFPSCycle < mech.cycle) { //back to default values
+ game.fpsCap = game.fpsCapDefault
+ game.fpsInterval = 1000 / game.fpsCap;
+ } else {
+ requestAnimationFrame(shortPause);
+ if (isDrawPlayer) {
+ isDrawPlayer = false
+
+ ctx.save();
+ ctx.translate(canvas.width2, canvas.height2); //center
+ 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]
+ mech.pos.x = history.position.x
+ mech.pos.y = history.position.y
+ mech.draw();
+ }
+ ctx.restore();
+ }
+ }
+ };
+
+ if (mech.defaultFPSCycle < mech.cycle) requestAnimationFrame(shortPause);
+ game.fpsCap = 4 //1 is shortest pause, 4 is standard
+ game.fpsInterval = 1000 / game.fpsCap;
+ mech.defaultFPSCycle = mech.cycle
+ return
+ }
mech.lastHarmCycle = mech.cycle
if (mod.isDroneOnDamage) { //chance to build a drone on damage from mod
const len = Math.min((dmg - 0.06 * Math.random()) * 40, 40)
@@ -549,7 +588,6 @@ const mech = {
}
if (dmg > 0.06 / mech.holdingMassScale) mech.drop(); //drop block if holding
-
const normalFPS = function() {
if (mech.defaultFPSCycle < mech.cycle) { //back to default values
game.fpsCap = game.fpsCapDefault
@@ -1769,13 +1807,13 @@ const mech = {
},
{
name: "metamaterial cloaking", //"weak photonic coupling" "electromagnetically induced transparency" "optical non-coupling" "slow light field" "electro-optic transparency"
- description: "cloak after not using your gun or field
while cloaked mobs can't see you
increase damage by 111%",
+ description: "cloak after not using your gun or field
while cloaked mobs can't see you
increase damage by 133%",
effect: () => {
mech.fieldFire = true;
mech.fieldMeterColor = "#fff";
mech.fieldPhase = 0;
mech.isCloak = false
- mech.fieldDamage = 2.11 // 1 + 111/100
+ mech.fieldDamage = 2.33 // 1 + 111/100
mech.fieldDrawRadius = 0
const drawRadius = 1000
@@ -2293,11 +2331,13 @@ const mech = {
mech.fieldRange *= 0.8
if (mod.isWormholeEnergy) mech.energy += 0.5
if (mod.isWormSpores) { //pandimensionalspermia
- b.spore(Vector.add(mech.hole.pos2, Vector.rotate({
- x: mech.fieldRange,
- 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));
+ for (let i = 0, len = Math.ceil(2 * Math.random()); i < len; i++) {
+ b.spore(Vector.add(mech.hole.pos1, Vector.rotate({
+ x: mech.fieldRange,
+ 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
}
@@ -2317,12 +2357,13 @@ const mech = {
// if (mod.isWormholeEnergy && mech.energy < mech.maxEnergy * 2) mech.energy = mech.maxEnergy * 2
if (mod.isWormholeEnergy) mech.energy += 0.5
if (mod.isWormSpores) { //pandimensionalspermia
- b.spore(Vector.add(mech.hole.pos1, Vector.rotate({
- x: mech.fieldRange,
- 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));
-
+ for (let i = 0, len = Math.ceil(2 * Math.random()); i < len; i++) {
+ b.spore(Vector.add(mech.hole.pos1, Vector.rotate({
+ x: mech.fieldRange,
+ 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
}
@@ -2383,7 +2424,7 @@ const mech = {
) {
const sub = Vector.sub(game.mouseInGame, mech.pos)
const mag = Vector.magnitude(sub)
- const drain = 0.04 + 0.007 * Math.sqrt(mag)
+ const drain = 0.03 + 0.005 * Math.sqrt(mag)
if (mech.energy > drain && mag > 300) {
mech.energy -= drain
mech.hole.isReady = false;
diff --git a/js/powerup.js b/js/powerup.js
index 13f75be..c40d7f2 100644
--- a/js/powerup.js
+++ b/js/powerup.js
@@ -33,7 +33,7 @@ const powerUps = {
}
game.paused = true;
game.isChoosing = true; //stops p from un pausing on key down
- build.pauseGrid()
+ build.pauseGrid(true)
},
endDraft() {
if (mod.manyWorlds && powerUps.reroll.rerolls < 1) {
@@ -43,10 +43,10 @@ const powerUps = {
document.getElementById("choose-background").style.display = "none"
document.body.style.cursor = "none";
document.body.style.overflow = "hidden"
- build.unPauseGrid()
game.paused = false;
game.isChoosing = false; //stops p from un pausing on key down
mech.immuneCycle = mech.cycle + 60; //player is immune to collision damage for 30 cycles
+ build.unPauseGrid()
requestAnimationFrame(cycle);
},
reroll: {
diff --git a/js/spawn.js b/js/spawn.js
index 2f3d2c2..1c776d4 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -2215,9 +2215,9 @@ const spawn = {
spawn.shield(me, x, y, 1);
me.onDeath = function() {
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
- //wake up tail mobs
- for (let i = 0; i < mob.length; i++) {
+ for (let i = 0; i < mob.length; i++) { //wake up tail mobs
if (mob[i].isSnakeTail && mob[i].alive) {
+ mob[i].isSnakeTail = false;
mob[i].do = mob[i].doActive
mob[i].removeConsBB();
}
@@ -2257,23 +2257,32 @@ const spawn = {
snakeBody(x, y, radius = 20) {
mobs.spawn(x, y, 4, radius, "rgb(55,170,170)");
let me = mob[mob.length - 1];
- me.onHit = function() {
- //run this function on hitting player
- this.explode();
- };
- me.collisionFilter.mask = cat.bullet | cat.player
- // me.g = 0.0002; //required if using 'gravity'
- me.accelMag = 0.001 * game.accelScale;
+ // me.onHit = function() {
+ // //run this function on hitting player
+ // this.explode();
+ // };
+ me.collisionFilter.mask = cat.bullet | cat.player | cat.mob
+ me.accelMag = 0.0006 * game.accelScale;
me.leaveBody = false;
- me.seePlayerFreq = Math.round((80 + 50 * Math.random()) * game.lookFreqScale);
me.frictionAir = 0.02;
me.isSnakeTail = true;
+ me.onDeath = function() {
+ if (this.isSnakeTail) { //wake up tail mobs
+ for (let i = 0; i < mob.length; i++) {
+ if (mob[i].isSnakeTail && mob[i].alive) {
+ mob[i].isSnakeTail = false;
+ mob[i].do = mob[i].doActive
+ mob[i].removeConsBB();
+ }
+ }
+ }
+ };
me.do = function() {
this.checkStatus();
};
me.doActive = function() {
- this.seePlayerCheck();
this.checkStatus();
+ this.alwaysSeePlayer();
this.attraction();
};
},
diff --git a/style.css b/style.css
index 9d006f7..fa14ed7 100644
--- a/style.css
+++ b/style.css
@@ -108,13 +108,13 @@ summary {
#choose-background {
position: absolute;
- z-index: 2;
+ z-index: 3;
width: 100%;
height: 100%;
display: none;
- background-color: #fff;
- opacity: 0.5;
- /* transition: display 0.5s; */
+ background-color: #ccc;
+ opacity: 0.6;
+ /* transition: opacity 1.5s; */
}
#construct {
@@ -151,6 +151,7 @@ summary {
grid-auto-rows: minmax(auto, auto);
grid-gap: 10px;
font-size: 1.3em;
+ /* box-shadow: 0px 0px 40px 20px rgba(255, 255, 255, 0.25); */
}
.choose-grid-module {
@@ -188,7 +189,7 @@ summary {
grid-gap: 0px;
align-content: space-between;
- z-index: 10;
+ z-index: 2;
font-size: 1.3em;
}
diff --git a/todo.txt b/todo.txt
index 9297561..16c44fb 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,9 +1,10 @@
*********** NEXT PATCH ***********
-you can see your build while in the power up selection menu
-balance - metamaterial cloaking field gives 111% more damage (up from 66%)
-mod: Newton's 1st law - harm reduction when moving fast (thanks NoHaxJustPi)
-mod: Newton's 2nd law - damage increase while moving fast
+mod: CPT reversal - avoid damage by rewinding to your past, but use up all your energy
+ requires wormhole or time dilation
+
+several minor buffs to wormhole
+small changes to mob distribution on a few maps
************** BUGS **************
@@ -25,42 +26,32 @@ mod: Newton's 2nd law - damage increase while moving fast
************** TODO **************
+bot that follows the players history
+ 1st bot is at 5s, 2nd is at 4.5s, ...
+ effect:
+ give player energy overfill
+ damage mobs on contact
+ damage bonus damage reduction push away mobs
+
+mob vision: look at player history
+ build a new type of attraction for mobs
+ if mobs can't see player, they check to see if they can see where the player was in the history
+ if mobs can't see player, they could check to see if they can find player in the past
+ https://abitawake.com/news/articles/enemy-ai-chasing-a-player-without-navigation2d-or-a-star-pathfinding
+
+mod negative mass field - mobs caught in the field take damage that increases with the relative velocity between the player and mob
+
+wormhole - make it clear when the wormhole can and can't teleport to a location before the player clicks
+
time dilation - slow down the game engine by 1/2, but run an extra player cycle to simulate slow motion
flavor - your bullets destroy blocks
- this isn't really a bonus, so maybe just add this as flavor to another mod/field
-
-mod - if you take damage and you have full energy remove your energy and go back in time 1 second
- for time dilation field?
- check to see if your previous location is clear or mobs, blocks
- go back proportional to your energy
- pause game, switch the game.loop to cycle backwards in player position until energy runs out
+ this isn't really a bonus, so maybe just add this as flavor to another mod/field/gun
mod plasma : plasma length increases then decreases as you hold down the field button (like stabbing with a spear)
grows to 1.5 longer after 0.3 seconds, then returns to normal length over 1 second, until field is pressed again
extra energy is drained when field is longer
-write custom dialogue for field / guns / mods used in last game
- you'd have to store an array of guns/fields/mod used last game
-
-mod laser history
- what about only works with diffuse
- no energy cost increase
- each stack makes each beam thicker?
- separate the beam into individual nonreflecting lines each 3 cycles farther into the past
- taking wider diffuse beam means more lines farther into the past?
- or double thickness beam
-
-technology - player data logging
- mod/field - pressing field while crouched sends the player back in time
- mod for time dilation?
- could be used in mob targeting
- build a new type of attraction for mobs
- if mobs can't see player, they check to see if they can see where the player was in the history
- if mobs can't see player, they could check to see if they can find player in the past
- mod bot - a bot follows where the player was 1 second ago
- gives player a harm reduction bonus when it is near the player
-
using a reroll gives 3 options for mods, and 3 options for guns/fields/mods
or 6 options for mods (rewrite mod selection to work with 1-6 options)
the second stack of 3 mods could have repeats, so you don't have to write new mod code
@@ -74,10 +65,6 @@ new power up - increase damage and fire speed, for 15 seconds
how to indicate effect duration
or just give the effect after picking up a reroll
-mod - bot very slowly follows you and gives you a bonus when it's in range
- it moves through walls
- effect: damage bonus?, damage reduction?, push away mobs, limit top speed of mobs/blocks/player?
-
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
mirror ending (if no cheats)
@@ -115,9 +102,6 @@ field - one block orbits you, it can protect you a bit and do collision damage
mod - attach a permanent neutron bomb to the block
lowers energy regen, but it can damage mobs
-wormholes need to give feedback on where a portal can go
- or automatically put portals in safe places
-
repeat map in vertical and horizontal space
or at least vertical space
camera looks strange when you teleport player with a high velocity
@@ -202,21 +186,6 @@ atmosphere levels
you shoot your self to wake up?
nonaggressive mobs
-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
- can the (robot)
- (escape captivity, and learn new technology)
- while managing (health, energy, negatives of technological upgrades)
- to overcome the (mobs, dangerous levels)
- to achieve a (technological singularity/positive technological feedback loop)
-
level boss: fires a line intersection in a random direction every few seconds.
the last two intersections have a destructive laser between them.
@@ -266,9 +235,6 @@ an effect when canceling a power up
ammo? heals?
50% chance for a mod, 25% heal, 25% ammo
-add player Scent Trails for mob navigation
- https://abitawake.com/news/articles/enemy-ai-chasing-a-player-without-navigation2d-or-a-star-pathfinding
-
css transition for pause menu
animate new level spawn by having the map aspects randomly fly into place
@@ -280,4 +246,76 @@ n-gon outreach ideas
paste this into console to see fps
- javascript:(function(){var script=document.createElement('script');script.onload=function(){var stats=new Stats();document.body.appendChild(stats.dom);requestAnimationFrame(function loop(){stats.update();requestAnimationFrame(loop)});};script.src='//mrdoob.github.io/stats.js/build/stats.min.js';document.head.appendChild(script);})()
\ No newline at end of file
+ javascript:(function(){var script=document.createElement('script');script.onload=function(){var stats=new Stats();document.body.appendChild(stats.dom);requestAnimationFrame(function loop(){stats.update();requestAnimationFrame(loop)});};script.src='//mrdoob.github.io/stats.js/build/stats.min.js';document.head.appendChild(script);})()
+
+
+************** LORE **************
+
+ 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
+ can the (robot)
+ (escape captivity, and learn new technology)
+ while managing (health, energy, negatives of technological upgrades)
+ to overcome the (mobs, dangerous levels)
+ to achieve a (technological singularity/positive technological feedback loop)
+
+
+
+
+game setting:
+ the mind of a new AI in a robot body that is running simulated escape attempts
+ every level is an idealized version of what could be outside
+
+actual setting is:
+ near future lab
+ the lab combined a quantum computer with a robot body
+ they started running machine learning algorithms
+ this led to general advancement in many computation fields
+ navigation, technology, self awareness, ...
+
+robot AI mind
+ has been researching new technology
+ thinks it needs to escape to learn more about the world
+ doesn't yet understand morality
+ thinks that the world is filled with minds like their own
+ models everything as very simple and random, it isn't sure what to expect
+
+robot AI growth
+ learns morality
+ game theory says that it isn't a viable strategy to kill everything (warGames)
+ learns about the actual world
+ learns about the nature of foundational physics, metaphysics
+ how to find meaning
+
+AI knows about:
+ the AI knows a great deal about technology
+ children's books
+AI doesn't know about:
+ modern pop culture
+ outside the lab
+
+robot AI communication
+ output to
+ bottom left message
+ tab title?
+ style
+ make it look like a computer terminal
+ mono space font
+ square edges
+ in baby talk?
+ with random ASCII gibberish letters
+ end each message with a hexadecimal encryption code/hash
+ message after selecting each new (mod / gun / field)
+ put messages in (mod / gun / field) method
+ at start of run
+ write custom dialogue for field / guns / mods used in last game
+ 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
\ No newline at end of file