diff --git a/js/bullet.js b/js/bullet.js
index 77b0c86..ce62235 100644
--- a/js/bullet.js
+++ b/js/bullet.js
@@ -670,7 +670,7 @@ const b = {
},
drone(speed = 1) {
const me = bullet.length;
- const THRUST = mod.isFastDrones ? 0.0025 : 0.0015
+ const THRUST = mod.isFastDrones ? 0.0023 : 0.0015
// const FRICTION = mod.isFastDrones ? 0.008 : 0.0005
const dir = mech.angle + 0.4 * (Math.random() - 0.5);
const RADIUS = (4.5 + 3 * Math.random())
@@ -2550,7 +2550,7 @@ const b = {
name: "drones",
description: "deploy drones that crash into mobs
crashes reduce their lifespan by 1 second",
ammo: 0,
- ammoPack: 13,
+ ammoPack: 14,
have: false,
fire() {
b.drone(mech.crouch ? 45 : 1)
@@ -3173,8 +3173,8 @@ const b = {
};
if (mod.isPulseAim) { //find mobs in line of sight
let dist = 2200
- energy = 0.25 * Math.min(mech.energy, 1.75)
- explosionRange = 1100 * energy
+ energy = 0.23 * Math.min(mech.energy, 1.75)
+ explosionRange = 1300 * energy
for (let i = 0, len = mob.length; i < len; i++) {
const newDist = Vector.magnitude(Vector.sub(path[0], mob[i].position))
if (explosionRange < newDist &&
@@ -3206,7 +3206,7 @@ const b = {
} else {
energy = 0.3 * Math.min(mech.energy, 1.75)
mech.energy -= energy * mod.isLaserDiode
- explosionRange = 1100 * energy
+ explosionRange = 1200 * energy
if (best.who) b.explosion(path[1], explosionRange, true)
mech.fireCDcycle = mech.cycle + Math.floor(50 * b.fireCD); // cool down
}
diff --git a/js/engine.js b/js/engine.js
index e86ba81..12d5600 100644
--- a/js/engine.js
+++ b/js/engine.js
@@ -162,6 +162,21 @@ function collisionChecks(event) {
dmg *= 0.85
}
mech.damage(dmg);
+ if (mod.isEjectMod) {
+ const have = [] //find which mods you have
+ for (let i = 0; i < mod.mods.length; i++) {
+ if (mod.mods[i].count > 0) have.push(i)
+ }
+ const choose = have[Math.floor(Math.random() * have.length)]
+ //message about what mod was lost
+ game.makeTextLog(`
${mod.mods[choose].name} ejected by exciton-lattice`, 300)
+
+
+ for (let i = 0; i < mod.mods[choose].count; i++) powerUps.spawn(mech.pos.x, mech.pos.y, "mod");
+ mod.mods[choose].count = 0;
+ mod.mods[choose].remove(); // remove a random mod form the list of mods you have
+ game.updateModHUD();
+ }
if (mob[k].onHit) mob[k].onHit(k);
//extra kick between player and mob //this section would be better with forces but they don't work...
diff --git a/js/game.js b/js/game.js
index 9739958..a25e02f 100644
--- a/js/game.js
+++ b/js/game.js
@@ -43,6 +43,7 @@ const game = {
// game.clip();
ctx.restore();
game.drawCursor();
+ // game.pixelGraphics();
},
testingLoop() {
game.gravity();
@@ -153,6 +154,84 @@ const game = {
// clip() {
// },
+ pixelGraphics() {
+ //copy current canvas pixel data
+ let imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
+ let data = imgData.data;
+ //change pixel data
+
+
+ // const off = 4 * Math.floor(x) + 4 * canvas.width * Math.floor(y);
+ // multiple windows
+ for (let i = data.length / 2; i < data.length; i += 4) {
+ index = i % (canvas.width * canvas.height * 2) // + canvas.width*4*canvas.height
+
+ data[i + 0] = data[index + 0]; // red
+ data[i + 1] = data[index + 1]; // red
+ data[i + 2] = data[index + 2]; // red
+ data[i + 3] = data[index + 3]; // red
+ }
+
+ for (let x = 0; x < len; x++) {
+
+ }
+
+
+
+ // const startX = 2 * canvas.width + 2 * canvas.width * canvas.height
+ // const endX = 4 * canvas.width + 4 * canvas.width * canvas.height
+ // const startY = 2 * canvas.width + 2 * canvas.width * canvas.height
+ // const endY = 4 * canvas.width + 4 * canvas.width * canvas.height
+ // for (let x = startX; x < endX; x++) {
+ // for (let y = startY; y < endY; y++) {
+
+ // }
+ // }
+
+
+
+
+ //strange draw offset
+ // const off = canvas.height * canvas.width * 4 / 2
+ // for (let index = 0; index < data.length; index += 4) {
+ // data[index + 0] = data[index + 0 + off]; // red
+ // data[index + 1] = data[index + 1 + off]; // red
+ // data[index + 2] = data[index + 2 + off]; // red
+ // data[index + 3] = data[index + 3 + off]; // red
+ // }
+
+ //change all pixels
+ // for (let index = 0; index < data.length; index += 4) {
+ // data[index + 0] = 255; // red
+ // data[index + 1] = 255; // green
+ // data[index + 2] = 255; // blue
+ // data[index + 3] = 255; // alpha
+ // }
+
+ //change random pixels
+ // for (let i = 0, len = Math.floor(data.length / 10); i < len; ++i) {
+ // const index = Math.floor((Math.random() * data.length) / 4) * 4;
+ // data[index + 0] = 255; // red
+ // data[index + 1] = 0; // green
+ // data[index + 2] = 0; // blue
+ // data[index + 3] = 255 //Math.floor(Math.random() * Math.random() * 255); // alpha
+ // }
+
+ // //change random pixels
+ // for (let i = 0, len = Math.floor(data.length / 1000); i < len; ++i) {
+ // const index = Math.floor((Math.random() * data.length) / 4) * 4;
+ // // data[index] = data[index] ^ 255; // Invert Red
+ // // data[index + 1] = data[index + 1] ^ 255; // Invert Green
+ // // data[index + 2] = data[index + 2] ^ 255; // Invert Blue
+ // data[index + 0] = 0; // red
+ // data[index + 1] = 0; // green
+ // data[index + 2] = 0; // blue
+ // // data[index + 3] = 255 //Math.floor(Math.random() * Math.random() * 255); // alpha
+ // }
+
+ //draw new pixel data to canvas
+ ctx.putImageData(imgData, 0, 0);
+ },
drawCursor() {
const size = 10;
ctx.beginPath();
diff --git a/js/level.js b/js/level.js
index e63ce1b..02875fd 100644
--- a/js/level.js
+++ b/js/level.js
@@ -16,9 +16,9 @@ const level = {
// game.zoomScale = 1000;
// game.setZoom();
// mech.isStealth = true;
- // mech.setField("standing wave harmonics")
+ // mech.setField("time dilation field")
// b.giveGuns("rail gun")
- // mod.giveMod("capacitor bank");
+ // mod.giveMod("quantum immortality");
level.intro(); //starting level
// level.testing(); //not in rotation
diff --git a/js/mods.js b/js/mods.js
index c0893bf..e3c8514 100644
--- a/js/mods.js
+++ b/js/mods.js
@@ -86,7 +86,7 @@ const mod = {
if (mod.isAcidDmg && mech.health > 1) dmg *= 1.4;
if (mod.isRest && player.speed < 1) dmg *= 1.20;
if (mod.isEnergyDamage) dmg *= 1 + mech.energy / 5.5;
- if (mod.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.004
+ if (mod.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.0038
if (mod.isRerollDamage) dmg *= 1 + 0.05 * powerUps.reroll.rerolls
if (mod.isOneGun && b.inventory.length < 2) dmg *= 1.25
return dmg * mod.slowFire
@@ -713,6 +713,22 @@ const mod = {
mod.isHarmArmor = false;
}
},
+ {
+ name: "exciton-lattice",
+ description: `reduce harm by 80%, but
after a collision, eject one of your mods`,
+ maxCount: 1,
+ count: 0,
+ allowed() {
+ return !mod.isEnergyHealth && (mod.isBayesian || mod.isExtraChoice || mod.manyWorlds || mod.isImmortal || mod.isMineDrop || mod.renormalization)
+ },
+ requires: "Bayesian, cardinality, many worlds, immortality, renormalization, or mine synthesis",
+ effect() {
+ mod.isEjectMod = true;
+ },
+ remove() {
+ mod.isEjectMod = false;
+ }
+ },
{
name: "clock gating",
description: `slow time by 50% after receiving harm
reduce harm by 15%`,
@@ -1093,9 +1109,9 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
- return true
+ return !mod.isBayesian
},
- requires: "",
+ requires: "not Bayesian inference",
effect() {
mod.isAmmoForGun = true;
},
@@ -1127,9 +1143,9 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
- return !mod.isEnergyHealth
+ return !mod.isEnergyHealth && !mod.isBayesian
},
- requires: "not mass-energy equivalence",
+ requires: "not mass-energy equivalence
not Bayesian inference",
effect: () => {
mod.isAmmoFromHealth = 0.023;
},
@@ -1288,7 +1304,7 @@ const mod = {
},
requires: "more than 6 mods",
effect: () => {
- //remove bullets //to get rid of bots
+ //remove active bullets //to get rid of bots
for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]);
bullet = [];
@@ -1324,13 +1340,13 @@ 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)
+ for (let i = 0; i < 2 * mod.mods[choose].count; i++) {
+ powerUps.spawn(mech.pos.x, mech.pos.y, "gun");
+ }
mod.mods[choose].remove(); // remove a random mod form the list of mods you have
mod.mods[choose].count = 0;
game.updateModHUD();
-
- for (let i = 0; i < 2; i++) {
- powerUps.spawn(mech.pos.x, mech.pos.y, "gun");
- }
},
remove() {}
},
@@ -2155,13 +2171,13 @@ const mod = {
requires: "laser",
effect() {
mod.laserReflections++;
- mod.laserDamage += 0.05; //base is 0.1
- mod.laserFieldDrain += 0.001 //base is 0.002
+ mod.laserDamage += 0.065; //base is 0.11
+ mod.laserFieldDrain += 0.0009 //base is 0.002
},
remove() {
mod.laserReflections = 2;
- mod.laserDamage = 0.1;
- mod.laserFieldDrain = 0.002;
+ mod.laserDamage = 0.13;
+ mod.laserFieldDrain = 0.0018;
}
},
{
@@ -2717,5 +2733,6 @@ const mod = {
isBayesian: null,
nailGun: null,
nailInstantFireRate: null,
- isCapacitor: null
+ isCapacitor: null,
+ isEjectMod: null
}
\ No newline at end of file
diff --git a/js/player.js b/js/player.js
index 5dc390a..3e41802 100644
--- a/js/player.js
+++ b/js/player.js
@@ -359,9 +359,31 @@ const mech = {
game.makeGunHUD(); //update gun HUD
}
+
+ function pixelWindows() {
+
+ //pixel graphics
+ let imgData = ctx.getImageData(0, 0, canvas.width, canvas.height); //copy current canvas pixel data
+ let data = imgData.data;
+ //change random pixels
+ //strange draw offset
+ // const off = canvas.height * canvas.width * 4 / 16
+ for (let i = 0; i < data.length; i += 4) {
+ index = i % canvas.width
+ data[index + 0] = data[index + 0]; // red
+ data[index + 1] = data[index + 1]; // red
+ data[index + 2] = data[index + 2]; // red
+ data[index + 3] = data[index + 3]; // red
+ }
+ ctx.putImageData(imgData, 0, 0); //draw new pixel data to canvas
+
+ }
+
+
game.wipe = function () { //set wipe to have trails
ctx.fillStyle = "rgba(255,255,255,0)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
+ // pixelWindows()
}
function randomizeEverything() {
@@ -387,6 +409,7 @@ const mech = {
game.wipe = function () { //set wipe to have trails
ctx.fillStyle = `rgba(255,255,255,${(i+1)*(i+1)*0.006})`;
ctx.fillRect(0, 0, canvas.width, canvas.height);
+ // pixelWindows()
}
}, (i + 1) * swapPeriod);
}
@@ -450,6 +473,7 @@ const mech = {
let dmg = 1
dmg *= mech.fieldHarmReduction
dmg *= mod.isSlowFPS ? 0.85 : 1
+ if (mod.isEjectMod) dmg *= 0.2
if (mod.isHarmReduce && mech.fieldUpgrades[mech.fieldMode].name === "negative mass field" && mech.isFieldActive) dmg *= 0.6
if (mod.isBotArmor) dmg *= 0.95 ** mod.totalBots()
if (mod.isHarmArmor && mech.lastHarmCycle + 600 > mech.cycle) dmg *= 0.5;
@@ -691,6 +715,7 @@ const mech = {
holdingTarget: null,
timeSkipLastCycle: 0,
// these values are set on reset by setHoldDefaults()
+ grabPowerUpRange2: 0,
isFieldActive: false,
fieldRange: 155,
fieldShieldingScale: 1,
@@ -713,6 +738,7 @@ const mech = {
mech.fieldBlockCD = 10;
game.isBodyDamage = true;
mech.fieldHarmReduction = 1;
+ mech.grabPowerUpRange2 = 156000;
mech.fieldRange = 155;
mech.fieldFire = false;
mech.fieldCDcycle = 0;
@@ -939,15 +965,18 @@ const mech = {
ctx.stroke();
},
grabPowerUp() { //look for power ups to grab with field
- const grabPowerUpRange2 = 156000 //(mech.fieldRange + 220) * (mech.fieldRange + 220)
for (let i = 0, len = powerUp.length; i < len; ++i) {
const dxP = mech.pos.x - powerUp[i].position.x;
const dyP = mech.pos.y - powerUp[i].position.y;
const dist2 = dxP * dxP + dyP * dyP;
// float towards player if looking at and in range or if very close to player
- if (dist2 < grabPowerUpRange2 && (mech.lookingAt(powerUp[i]) || dist2 < 16000) && !(mech.health === mech.maxHealth && powerUp[i].name === "heal")) {
- powerUp[i].force.x += 7 * (dxP / dist2) * powerUp[i].mass;
- powerUp[i].force.y += 7 * (dyP / dist2) * powerUp[i].mass - powerUp[i].mass * game.g; //negate gravity
+ if (dist2 < mech.grabPowerUpRange2 &&
+ (mech.lookingAt(powerUp[i]) || dist2 < 16000) &&
+ !(mech.health === mech.maxHealth && powerUp[i].name === "heal") &&
+ Matter.Query.ray(map, powerUp[i].position, mech.pos).length === 0
+ ) {
+ powerUp[i].force.x += 0.05 * (dxP / Math.sqrt(dist2)) * powerUp[i].mass;
+ powerUp[i].force.y += 0.05 * (dyP / Math.sqrt(dist2)) * powerUp[i].mass - powerUp[i].mass * game.g; //negate gravity
//extra friction
Matter.Body.setVelocity(powerUp[i], {
x: powerUp[i].velocity.x * 0.11,
@@ -1186,7 +1215,7 @@ const mech = {
},
fieldUpgrades: [{
name: "field emitter",
- description: "use energy to shield yourself from harm
pick up and throw objects",
+ description: "use energy to push mobs away
throw blocks to damage mobs
pick up power ups",
effect: () => {
game.replaceTextLog = true; //allow text over write
mech.hold = function () {
@@ -1212,9 +1241,9 @@ const mech = {
},
{
name: "standing wave harmonics",
- description: "three oscillating shields are permanently active
reduce harm by 30%",
+ description: "three oscillating shields are permanently active
blocking has no cool down
reduce harm by 20%",
effect: () => {
- mech.fieldHarmReduction = 0.70;
+ mech.fieldHarmReduction = 0.20;
mech.fieldBlockCD = 0;
mech.hold = function () {
if (mech.isHolding) {
@@ -1231,8 +1260,8 @@ const mech = {
}
if (mech.energy > 0.1 && mech.fieldCDcycle < mech.cycle) {
const fieldRange1 = (0.7 + 0.3 * Math.sin(mech.cycle / 23)) * mech.fieldRange
- const fieldRange2 = (0.6 + 0.4 * Math.sin(mech.cycle / 37)) * mech.fieldRange
- const fieldRange3 = (0.55 + 0.45 * Math.sin(mech.cycle / 47)) * mech.fieldRange
+ const fieldRange2 = (0.63 + 0.37 * Math.sin(mech.cycle / 37)) * mech.fieldRange
+ const fieldRange3 = (0.65 + 0.35 * Math.sin(mech.cycle / 47)) * mech.fieldRange
const netfieldRange = Math.max(fieldRange1, fieldRange2, fieldRange3)
ctx.fillStyle = "rgba(110,170,200," + (0.04 + mech.energy * (0.12 + 0.13 * Math.random())) + ")";
ctx.beginPath();
@@ -1254,16 +1283,18 @@ const mech = {
{
name: "perfect diamagnetism",
// description: "gain energy when blocking
no recoil when blocking",
- description: "blocking does not drain energy
blocking has no cool down and less recoil",
+ description: "blocking does not drain energy
blocking has no cool down and less recoil
attract power ups from far away",
effect: () => {
mech.fieldShieldingScale = 0;
+ mech.grabPowerUpRange2 = 4000000
+ // mech.holdingMassScale = 0.03; //can hold heavier blocks with lower cost to jumping
// mech.fieldMeterColor = "#0af"
// mech.fieldArc = 0.3; //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
// mech.calculateFieldThreshold();
mech.hold = function () {
const wave = Math.sin(mech.cycle * 0.022);
- mech.fieldRange = 165 + 12 * wave
- mech.fieldArc = 0.3 + 0.035 * wave //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
+ mech.fieldRange = 170 + 12 * wave
+ mech.fieldArc = 0.33 + 0.045 * wave //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
mech.calculateFieldThreshold();
if (mech.isHolding) {
mech.drawHold(mech.holdingTarget);
@@ -1317,13 +1348,13 @@ const mech = {
if (mod.isSporeField) {
// mech.fieldCDcycle = mech.cycle + 10; // set cool down to prevent +energy from making huge numbers of drones
const len = Math.floor(6 + 4 * Math.random())
- mech.energy -= len * 0.074;
+ mech.energy -= len * 0.07;
for (let i = 0; i < len; i++) {
b.spore(mech.pos)
}
} else if (mod.isMissileField) {
// mech.fieldCDcycle = mech.cycle + 10; // set cool down to prevent +energy from making huge numbers of drones
- mech.energy -= 0.6;
+ mech.energy -= 0.55;
b.missile({
x: mech.pos.x + 40 * Math.cos(mech.angle),
y: mech.pos.y + 40 * Math.sin(mech.angle) - 3
@@ -1333,11 +1364,11 @@ const mech = {
1, mod.babyMissiles)
} else if (mod.isIceField) {
// mech.fieldCDcycle = mech.cycle + 17; // set cool down to prevent +energy from making huge numbers of drones
- mech.energy -= 0.045;
+ mech.energy -= 0.04;
b.iceIX(1)
} else {
// mech.fieldCDcycle = mech.cycle + 10; // set cool down to prevent +energy from making huge numbers of drones
- mech.energy -= 0.33;
+ mech.energy -= 0.3;
b.drone(1)
}
@@ -1365,13 +1396,15 @@ const mech = {
},
{
name: "negative mass field",
- description: "use energy to nullify gravity
reduce harm by 45%",
+ description: "use energy to nullify gravity
reduce harm by 45%
blocks held by the field have a lower mass",
fieldDrawRadius: 0,
effect: () => {
mech.fieldFire = true;
mech.holdingMassScale = 0.03; //can hold heavier blocks with lower cost to jumping
mech.fieldMeterColor = "#000"
mech.fieldHarmReduction = 0.55;
+ mech.fieldDrawRadius = 0;
+
mech.hold = function () {
mech.airSpeedLimit = 125 //5 * player.mass * player.mass
mech.FxAir = 0.016
@@ -1483,7 +1516,7 @@ const mech = {
},
{
name: "plasma torch",
- description: "use energy to emit short range plasma
plasma damages and pushes mobs",
+ description: "use energy to emit short range plasma
plasma damages mobs
plasma pushes mobs and blocks away",
effect() {
mech.fieldMeterColor = "#f0f"
mech.hold = function () {
@@ -1638,7 +1671,7 @@ const mech = {
},
{
name: "time dilation field",
- description: "use energy to stop time
you can move and fire while time is stopped",
+ description: "use energy to stop time
move and fire while time is stopped
touching mobs still does harm",
effect: () => {
// mech.fieldMeterColor = "#000"
mech.fieldFire = true;
@@ -1667,6 +1700,7 @@ const mech = {
ctx.fillStyle = "#ccc";
ctx.fillRect(-100000, -100000, 200000, 200000)
ctx.globalCompositeOperation = "source-over"
+
//stop time
mech.isBodiesAsleep = true;
@@ -1730,7 +1764,7 @@ const mech = {
},
{
name: "phase decoherence field",
- description: "use energy to become intangible
firing and touching shields increases drain",
+ description: "use energy to become intangible
firing and touching shields drains energy
unable to see and be seen by mobs",
effect: () => {
mech.fieldFire = true;
mech.fieldMeterColor = "#fff";
diff --git a/js/powerup.js b/js/powerup.js
index 77fe4fb..aaa631f 100644
--- a/js/powerup.js
+++ b/js/powerup.js
@@ -21,24 +21,30 @@ const powerUps = {
}
powerUps.endDraft();
},
- endDraft() {
- if (mod.manyWorlds && powerUps.reroll.rerolls < 1) {
- powerUps.spawn(mech.pos.x, mech.pos.y, "reroll");
- }
- document.body.style.cursor = "none";
- document.getElementById("choose-grid").style.display = "none"
- document.getElementById("choose-background").style.display = "none"
- game.paused = false;
- game.isChoosing = false; //stops p from un pausing on key down
- requestAnimationFrame(cycle);
- },
showDraft() {
document.getElementById("choose-grid").style.display = "grid"
document.getElementById("choose-background").style.display = "inline"
document.body.style.cursor = "auto";
+ if (mod.isExtraChoice) {
+ document.body.style.overflowY = "scroll";
+ document.body.style.overflowX = "hidden";
+ }
game.paused = true;
game.isChoosing = true; //stops p from un pausing on key down
},
+ endDraft() {
+ if (mod.manyWorlds && powerUps.reroll.rerolls < 1) {
+ powerUps.spawn(mech.pos.x, mech.pos.y, "reroll");
+ }
+ document.getElementById("choose-grid").style.display = "none"
+ document.getElementById("choose-background").style.display = "none"
+ document.body.style.cursor = "none";
+ document.body.style.overflow = "hidden"
+ 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
+ requestAnimationFrame(cycle);
+ },
reroll: {
rerolls: 0,
name: "reroll",
@@ -48,7 +54,7 @@ const powerUps = {
},
effect() {
powerUps.reroll.changeRerolls(1)
- game.makeTextLog(" +1 reroll", 300)
+ game.makeTextLog(` rerolls: ${powerUps.reroll.rerolls}`, 300)
},
changeRerolls(amount) {
powerUps.reroll.rerolls += amount
@@ -262,66 +268,67 @@ const powerUps = {
},
choiceLog: [], //records all previous choice options
effect() {
-
- function pick(skip1 = -1, skip2 = -1, skip3 = -1, skip4 = -1) {
- let options = [];
- for (let i = 0; i < mod.mods.length; i++) {
- if (mod.mods[i].count < mod.mods[i].maxCount && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4 && mod.mods[i].allowed()) {
- options.push(i);
+ if (mech.alive) {
+ function pick(skip1 = -1, skip2 = -1, skip3 = -1, skip4 = -1) {
+ let options = [];
+ for (let i = 0; i < mod.mods.length; i++) {
+ if (mod.mods[i].count < mod.mods[i].maxCount && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4 && mod.mods[i].allowed()) {
+ options.push(i);
+ }
}
- }
- //remove repeats from last selection
- const totalChoices = mod.isDeterminism ? 1 : 3 + mod.isExtraChoice * 2
- if (powerUps.mod.choiceLog.length > totalChoices || powerUps.mod.choiceLog.length === totalChoices) { //make sure this isn't the first time getting a power up and there are previous choices to remove
- for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection
- if (options.length > totalChoices) {
- for (let j = 0, len = options.length; j < len; j++) {
- if (powerUps.mod.choiceLog[powerUps.mod.choiceLog.length - 1 - i] === options[j]) {
- options.splice(j, 1) //remove previous choice from option pool
- break
+ //remove repeats from last selection
+ const totalChoices = mod.isDeterminism ? 1 : 3 + mod.isExtraChoice * 2
+ if (powerUps.mod.choiceLog.length > totalChoices || powerUps.mod.choiceLog.length === totalChoices) { //make sure this isn't the first time getting a power up and there are previous choices to remove
+ for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection
+ if (options.length > totalChoices) {
+ for (let j = 0, len = options.length; j < len; j++) {
+ if (powerUps.mod.choiceLog[powerUps.mod.choiceLog.length - 1 - i] === options[j]) {
+ options.splice(j, 1) //remove previous choice from option pool
+ break
+ }
}
}
}
}
- }
- if (options.length > 0) {
- const choose = options[Math.floor(Math.random() * options.length)]
- text += ` ${mod.mods[choose].description}
`
- return choose
- }
+ if (options.length > 0) {
+ const choose = options[Math.floor(Math.random() * options.length)]
+ text += ` ${mod.mods[choose].description}
`
+ return choose
+ }
- }
- let text = ""
- if (!mod.isDeterminism) text += `✕
`
- text += `choose a mod
`
- let choice1 = pick()
- let choice2 = -1
- let choice3 = -1
- if (choice1 > -1) {
- if (!mod.isDeterminism) {
- choice2 = pick(choice1)
- // if (choice2 > -1) text += ` ${mod.mods[choice2].name}
${mod.mods[choice2].description}
`
- choice3 = pick(choice1, choice2)
- // if (choice3 > -1) text += ` ${mod.mods[choice3].name}
${mod.mods[choice3].description}
`
}
- if (mod.isExtraChoice) {
- let choice4 = pick(choice1, choice2, choice3)
- // if (choice4 > -1) text += ` ${mod.mods[choice4].name}
${mod.mods[choice4].description}
`
- let choice5 = pick(choice1, choice2, choice3, choice4)
- // if (choice5 > -1) text += ` ${mod.mods[choice5].name}
${mod.mods[choice5].description}
`
- powerUps.mod.choiceLog.push(choice4)
- powerUps.mod.choiceLog.push(choice5)
- }
- powerUps.mod.choiceLog.push(choice1)
- powerUps.mod.choiceLog.push(choice2)
- powerUps.mod.choiceLog.push(choice3)
- if (powerUps.reroll.rerolls) text += ` reroll
${powerUps.reroll.diceText()} `
+ let text = ""
+ if (!mod.isDeterminism) text += `✕
`
+ text += `choose a mod
`
+ let choice1 = pick()
+ let choice2 = -1
+ let choice3 = -1
+ if (choice1 > -1) {
+ if (!mod.isDeterminism) {
+ choice2 = pick(choice1)
+ // if (choice2 > -1) text += ` ${mod.mods[choice2].name}
${mod.mods[choice2].description}
`
+ choice3 = pick(choice1, choice2)
+ // if (choice3 > -1) text += ` ${mod.mods[choice3].name}
${mod.mods[choice3].description}
`
+ }
+ if (mod.isExtraChoice) {
+ let choice4 = pick(choice1, choice2, choice3)
+ // if (choice4 > -1) text += ` ${mod.mods[choice4].name}
${mod.mods[choice4].description}
`
+ let choice5 = pick(choice1, choice2, choice3, choice4)
+ // if (choice5 > -1) text += ` ${mod.mods[choice5].name}
${mod.mods[choice5].description}
`
+ powerUps.mod.choiceLog.push(choice4)
+ powerUps.mod.choiceLog.push(choice5)
+ }
+ powerUps.mod.choiceLog.push(choice1)
+ powerUps.mod.choiceLog.push(choice2)
+ powerUps.mod.choiceLog.push(choice3)
+ if (powerUps.reroll.rerolls) text += ` reroll
${powerUps.reroll.diceText()} `
- document.getElementById("choose-grid").innerHTML = text
- powerUps.showDraft();
- } else {
- powerUps.giveRandomAmmo()
+ document.getElementById("choose-grid").innerHTML = text
+ powerUps.showDraft();
+ } else {
+ powerUps.giveRandomAmmo()
+ }
}
}
},
@@ -449,11 +456,7 @@ const powerUps = {
randomPowerUpCounter: 0,
spawnBossPowerUp(x, y) { //boss spawns field and gun mod upgrades
powerUps.randomPowerUpCounter++;
- if (game.difficultyMode === 4 && Math.random() < 0.5) { //why mode gets a free power up chance
- powerUps.randomPowerUpCounter *= 0.5
- spawnPowerUps()
- }
-
+ if (game.difficultyMode === 4) spawnPowerUps() //why mode gets a free power up chance
const chanceToFail = Math.max(level.levelsCleared, 10) * 0.1 //1 until level 10, then 1.1, 1.2, 1.3, ...
if (Math.random() * chanceToFail < powerUps.randomPowerUpCounter) {
powerUps.randomPowerUpCounter = 0;
@@ -528,8 +531,8 @@ const powerUps = {
size = target.size();
powerUp[index] = Matter.Bodies.polygon(x, y, 0, size, {
density: 0.001,
- frictionAir: 0.01,
- restitution: 0.8,
+ frictionAir: 0.03,
+ restitution: 0.85,
inertia: Infinity, //prevents rotation
collisionFilter: {
group: 0,
diff --git a/todo.txt b/todo.txt
index 6b83634..5cf6c2c 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,43 +1,46 @@
-rail gun mod: capacitor bank - no charge time, but smaller bullets
+field: perfect diamagnetism is a bit larger
+ can now grab power ups from far away
-stunned mobs now still display health bar
-when you hit a mob hard with a block they get stunned
- blocks do about 15% less collision damage
- stuns lasts longer for larger and faster blocks
-
+mod: exciton-lattice - reduce harm by 80%, but after taking collision damage eject a random mod
+ eject extra mods if you have recursive stacks
+
+power ups have a bit more air friction
+power ups must be in line of sight to be pulled by the player
+why mode now gets 100% chance for a second boss power up (up from 50%)
+ this should let why mode reach more interesting build depth
+laser and pulse got a damage and energy use buff
+immune to harm for a second after exiting the power up selection menu
************** TODO - n-gon **************
-player goes intangible while immune after getting hit?
-getting stuck above a mob can immobilize player
- add a minimum knock from player mob collisions?
+new gun fire 3+ balls in arc
+ name: something about energy
+ does damage in area, like neutron bomb
+ ends on contact with wall, doesn't stick or bounce
+ hold fire to charge: increases the size of the balls
+ mod: balls are attracted to mobs
-when crouched make it harder for mobs to see player
- reduce arc size of mob vision cone
- reduce look range
- * (mech.crouch ? 0.7 : 1)
+fix: even with a scroll bar the top of the selection window is off screen for very short windows
+
+rework perfect diamagnetism
+ keep the zero energy cost
+ add a very short blocking CD
+ let the shield also do bremsstrahlung radiation
+ mod: grab and launch mobs?
+
+getting stuck above a mob can immobilize player
+ seems to only occur with Pauli exclusion
+ add a knock to player mob collisions even while player is immune to damage
+ keep the knock very small
map element - player rotates a rotor that makes a platform go up or down
-reduce damage by 80%, but lose ammo when you get hit
-
-foam needs a new mod
- is the foam mod colloidal foam fun?
- increase foam bullet size?
- foam explodes when it runs out?
-
removing supersaturation sets total health to 1
this cancels the health benefits from crystallized armor
produce a method that calculates max health based on mods
use mac automator to speed up your n-gon -> git sync
-considering removing the perfect diamagnetism field from the game
- or just rework perfect diamagnetism
- perfect diamagnetism be able to grab and launch mobs
-
-Gun: Launch yourself at high speed to the enemy, gaining temporary invincibility while in the air and for 3 seconds after landing. Upon impact, trigger a large explosion.
-
fix door.isOpen actually meaning isClosed
mod - laser fires 3 beams
@@ -45,27 +48,18 @@ mod - laser fires 3 beams
after you die custom should be populated with your last build
also you should be able to share while paused
-use canvas pixel array effects for full screen graphics
- add some pixels after player gets hit?
-
give missiles a suck and delay explosion, like vacuum bomb
bot that does AOE damage while it rotates around player
no physics / collisions
cap 3 ?
-
level Boss: fractal Sierpiński triangle
https://en.wikipedia.org/wiki/Sierpi%C5%84ski_triangle
spawns a 1/2 size version of the boss, this version can also spawn a smaller version, but it is capped at some size level
they spawn once at the start of the level
if a version dies, one can be replaced every ten seconds by the largest version
-performance issues with large numbers of spores
-consider limiting total bullets?
- 300?
-
-level element: a hanging chain of connected blocks
level element: a zone with wind, anti-gravity, extra gravity
control with button
@@ -123,15 +117,6 @@ new gun - deploy a turret that last for 20 seconds
mod - mines become a turret that fires nails
it could float to the mouse location on fire
-minigun: high caliber - rework
- slow down the bullets even more and increase the size?
- remove and actually make a full gun like this?
-
-portals:
- portal while holding block sometimes send player back to original portal
- only seems to happen with the bottom right block
- use buttons to turn on and off?
-
level boss: fires a line intersection in a random direction every few seconds.
the last two intersections have a destructive laser between them.
@@ -144,8 +129,6 @@ map: prison
doors linked to buttons
mobs inside the doors?
-map: airport
-
mod - do 50% more damage in close, but 50% less at a distance
code it like mod.isFarAwayDmg
have these mods disable each other
@@ -153,9 +136,6 @@ mod - do 50% more damage in close, but 50% less at a distance
phase field still isn't fun
does phase field need the stealth flag?
-mod: use the stealth flag from the phase decoherence field
- maybe trigger it along with the damage immunity CD
-
mod harmonic shield: slow everything in range around shield (temporal shield)
set max speed?
@@ -166,10 +146,6 @@ mod: bot very slowly follows you and gives you a bonus when it's in range
graphic idea: bezier curve that moves smoothly from mob to mob
loops around player
-graphic: give rail gun projectile a trail
- only draw above speed 5
- track previous positions?
-
movement fluidity
let legs jump on mobs, but player will still take damage
like: ori and the blind forest, celeste