diff --git a/js/bullet.js b/js/bullet.js
index 21c5c80..7aa8030 100644
--- a/js/bullet.js
+++ b/js/bullet.js
@@ -1853,7 +1853,7 @@ const b = {
bullet[me].endCycle = game.cycle + 60 + 18 * Math.random();
bullet[me].dmg = dmg
bullet[me].beforeDmg = function(who) { //beforeDmg is rewritten with ice crystal mod
- if (mod.isNailPoison) mobs.statusDoT(who, dmg * 0.22, 120) // one tick every 30 cycles
+ if (mod.isNailPoison) mobs.statusDoT(who, dmg * 0.24, 120) // one tick every 30 cycles
if (mod.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.99) this.dmg *= 5 //crit if hit near center
};
bullet[me].do = function() {};
@@ -2482,6 +2482,27 @@ const b = {
}
game.makeGunHUD();
},
+ removeGun(gun, isRemoveSelection = false) {
+ for (let i = 0; i < b.guns.length; i++) {
+ if (b.guns[i].name === gun) {
+ b.guns[i].have = false
+ 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();
+ if (isRemoveSelection) b.guns.splice(i, 1) //also remove gun from gun pool array
+ break
+ }
+ }
+ },
guns: [{
name: "nail gun",
description: "use compressed air to fire a stream of nails
delay after firing decreases as you shoot",
@@ -2550,7 +2571,7 @@ const b = {
if (mod.isIceCrystals) {
bullet[bullet.length - 1].beforeDmg = function(who) {
mobs.statusSlow(who, 30)
- if (mod.isNailPoison) mobs.statusDoT(who, dmg * 0.22, 120) // one tick every 30 cycles
+ if (mod.isNailPoison) mobs.statusDoT(who, dmg * 0.24, 120) // one tick every 30 cycles
if (mod.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.99) this.dmg *= 5 //crit if hit near center
};
@@ -3778,18 +3799,19 @@ const b = {
isRewinding: false,
lastFireCycle: 0,
holdCount: 0,
+ activeGunIndex: null,
fire() {
if (this.lastFireCycle === mech.cycle - 1) { //button has been held down
- this.rewindCount += 7;
+ this.rewindCount += 8;
const DRAIN = 0.01
- if (this.rewindCount > 599 || mech.energy < DRAIN) {
+ let history = mech.history[(mech.cycle - this.rewindCount) % 600]
+ if (this.rewindCount > 599 || mech.energy < DRAIN || history.activeGun !== this.activeGunIndex) {
this.rewindCount = 0;
mech.resetHistory();
- mech.fireCDcycle = mech.cycle + Math.floor(60 * b.fireCD); // cool down
+ mech.fireCDcycle = mech.cycle + Math.floor(120 * 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]
+ mech.immuneCycle = mech.cycle + 30; //player is immune to collision damage for 5 cycles
Matter.Body.setPosition(player, history.position);
Matter.Body.setVelocity(player, { x: history.velocity.x, y: history.velocity.y });
if (mech.health !== history.health) {
@@ -3799,6 +3821,7 @@ const b = {
}
} else { //button is held the first time
this.rewindCount = 0;
+ this.activeGunIndex = b.activeGun
}
this.lastFireCycle = mech.cycle;
}
diff --git a/js/index.js b/js/index.js
index 0695e53..156391c 100644
--- a/js/index.js
+++ b/js/index.js
@@ -203,19 +203,16 @@ const build = {
`;
- let countGuns = 0
- let countMods = 0
- for (let i = 0, len = b.guns.length; i < len; i++) {
- if (b.guns[i].have) {
- text += `
${b.guns[i].name} -
${b.guns[i].ammo} ${b.guns[i].description}
`
- countGuns++
- }
+ for (let i = 0, len = b.inventory.length; i < len; i++) {
+ text += ` ${b.guns[b.inventory[i]].name} -
${b.guns[b.inventory[i]].ammo} ${b.guns[b.inventory[i]].description}
`
}
+
let el = document.getElementById("pause-grid-left")
el.style.display = "grid"
el.innerHTML = text
text = "";
text += ` ${mech.fieldUpgrades[mech.fieldMode].name}
${mech.fieldUpgrades[mech.fieldMode].description}
`
+ let countMods = 0
for (let i = 0, len = mod.mods.length; i < len; i++) {
if (mod.mods[i].count > 0) {
const isCount = mod.mods[i].count > 1 ? `(${mod.mods[i].count}x)` : "";
@@ -248,7 +245,7 @@ const build = {
el = document.getElementById("pause-grid-right")
el.style.display = "grid"
el.innerHTML = text
- if (countMods > 5 || countGuns > 6) {
+ if (countMods > 5 || b.inventory.length > 6) {
document.body.style.overflowY = "scroll";
document.body.style.overflowX = "hidden";
}
diff --git a/js/level.js b/js/level.js
index 1b9af04..d33a354 100644
--- a/js/level.js
+++ b/js/level.js
@@ -3805,7 +3805,8 @@ const level = {
}
},
nextLevel() {
- if (level.bossKilled) level.levelsCleared++;
+ // if (level.bossKilled)
+ level.levelsCleared++;
// level.difficultyIncrease(game.difficultyMode) //increase difficulty based on modes
//difficulty is increased 5 times when finalBoss dies
diff --git a/js/mods.js b/js/mods.js
index 144c3ca..216c682 100644
--- a/js/mods.js
+++ b/js/mods.js
@@ -1054,7 +1054,7 @@ const mod = {
},
{
name: "CPT reversal",
- description: "rewind 1.5 - 5 seconds to avoid harm
drains 66 - 220 energy",
+ description: "charge, parity, and time invert to undo harm
rewind (1.5—5) seconds for (66—220) energy",
maxCount: 1,
count: 0,
allowed() { //&& (mech.fieldUpgrades[mech.fieldMode].name !== "nano-scale manufacturing" || mech.maxEnergy > 1)
@@ -1406,9 +1406,9 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
- return true
+ return mod.duplicationChance() < 1
},
- requires: "",
+ requires: "below 100% duplication chance",
effect: () => {
mod.isBayesian = true
game.draw.powerUp = game.draw.powerUpBonus //change power up draw
@@ -1424,9 +1424,9 @@ const mod = {
maxCount: 9,
count: 0,
allowed() {
- return true
+ return mod.duplicationChance() < 1
},
- requires: "",
+ requires: "below 100% duplication chance",
effect() {
mod.duplicateChance += 0.07
game.draw.powerUp = game.draw.powerUpBonus //change power up draw
@@ -1442,9 +1442,9 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
- return !mod.isDeterminism
+ return mod.duplicationChance() < 1 && !mod.isDeterminism
},
- requires: "not determinism",
+ requires: "below 100% duplication chance, not determinism",
effect() {
mod.isCancelDuplication = true
mod.cancelCount = 0
@@ -1927,7 +1927,7 @@ const mod = {
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
+ 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 //build.isCustomSelection ||
},
requires: "bots > 5, plasma torch, nano-scale, pilot wave, not mass-energy equivalence, CPT",
effect() {
@@ -1937,25 +1937,27 @@ const mod = {
},
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.removeGun("CPT gun", true)
+ // for (let i = 0; i < b.guns.length; i++) {
+ // if (b.guns[i].name === "CPT gun") {
+ // b.guns[i].have = false
+ // 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
- }
- }
+ // b.guns.splice(i, 1) //also remove CPT gun from gun pool array
+ // break
+ // }
+ // }
mod.isRewindGun = false
}
}
@@ -2619,7 +2621,7 @@ const mod = {
},
{
name: "railroad ties",
- description: "nails are 50% larger
increases physical damage by about 25%",
+ description: "nails are 40% larger
increases physical damage by about 20%",
isGunMod: true,
maxCount: 1,
count: 0,
@@ -2628,7 +2630,7 @@ const mod = {
},
requires: "nails",
effect() {
- mod.biggerNails += 0.5
+ mod.biggerNails += 0.33
},
remove() {
mod.biggerNails = 1
diff --git a/js/player.js b/js/player.js
index e7b4f9c..b4b4b59 100644
--- a/js/player.js
+++ b/js/player.js
@@ -7,14 +7,14 @@ const mech = {
//load player in matter.js physic engine
// let vector = Vertices.fromPath("0 40 50 40 50 115 0 115 30 130 20 130"); //player as a series of vertices
let vertices = Vertices.fromPath("0,40, 50,40, 50,115, 30,130, 20,130, 0,115, 0,40"); //player as a series of vertices
- playerBody = Matter.Bodies.fromVertices(0, 0, vertices);
+ playerBody = Bodies.fromVertices(0, 0, vertices);
jumpSensor = Bodies.rectangle(0, 46, 36, 6, {
//this sensor check if the player is on the ground to enable jumping
sleepThreshold: 99999999999,
isSensor: true
});
vertices = Vertices.fromPath("16 -82 2 -66 2 -37 43 -37 43 -66 30 -82");
- playerHead = Matter.Bodies.fromVertices(0, -55, vertices); //this part of the player lowers on crouch
+ playerHead = Bodies.fromVertices(0, -55, vertices); //this part of the player lowers on crouch
headSensor = Bodies.rectangle(0, -57, 48, 45, {
//senses if the player's head is empty and can return after crouching
sleepThreshold: 99999999999,
@@ -172,6 +172,7 @@ const mech = {
angle: mech.angle,
health: mech.health,
energy: mech.energy,
+ activeGun: b.activeGun
});
// const back = 59 // 59 looks at 1 second ago //29 looks at 1/2 a second ago
// historyIndex = (mech.cycle - back) % 60
@@ -198,20 +199,53 @@ const mech = {
if (!mech.crouch) {
mech.crouch = true;
mech.yOffGoal = mech.yOffWhen.crouch;
- Matter.Body.translate(playerHead, {
- x: 0,
- y: 40
- });
+ if ((playerHead.position.y - player.position.y) < 0) {
+
+ Matter.Body.setPosition(playerHead, {
+ x: player.position.x,
+ y: player.position.y + 9.1740767
+ })
+
+
+ // Matter.Body.translate(playerHead, {
+ // x: 0,
+ // y: 40
+ // });
+ }
+ // playerHead.collisionFilter.group = -1
+ // playerHead.collisionFilter.category = 0
+ // playerHead.collisionFilter.mask = -1
+ // playerHead.isSensor = true; //works, but has a 2 second lag...
+ // collisionFilter: {
+ // group: 0,
+ // category: cat.player,
+ // mask: cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield
+ // },
}
},
undoCrouch() {
if (mech.crouch) {
mech.crouch = false;
mech.yOffGoal = mech.yOffWhen.stand;
- Matter.Body.translate(playerHead, {
- x: 0,
- y: -40
- });
+ if ((playerHead.position.y - player.position.y) > 0) {
+ Matter.Body.setPosition(playerHead, {
+ x: player.position.x,
+ y: player.position.y - 30.28592321
+ })
+ // Matter.Body.translate(playerHead, {
+ // x: 0,
+ // y: -40
+ // });
+ }
+
+ // playerHead.collisionFilter = {
+ // group: 0,
+ // category: cat.player,
+ // mask: cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield
+ // }
+ // playerHead.isSensor = false;
+ // playerHead.collisionFilter.category = cat.player
+ // playerHead.collisionFilter.mask = cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield
}
},
hardLandCD: 0,
@@ -498,6 +532,12 @@ const mech = {
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 });
+ b.activeGun = history.activeGun
+ for (let i = 0; i < b.inventory.length; i++) {
+ if (b.inventory[i] === b.activeGun) b.inventoryGun = i
+ }
+ game.updateGunHUD();
+ game.boldActiveGunHUD();
// move bots to follow player
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType) {
diff --git a/todo.txt b/todo.txt
index 5c119d9..448008d 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,10 +1,7 @@
******************************************************** NEXT PATCH ********************************************************
-new level boss that fires 2 streams of small bullets that chase you
-
-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.
+added a crouch check to prevent move the head when it's already out of position
+also using setPosition to move player head instead of translate
******************************************************** BUGS ********************************************************
@@ -40,13 +37,13 @@ mod and mob are too similar
******************************************************** TODO ********************************************************
-mod: laser beams push like plasma torch pushes with directional force
+CPT gun seems a bit weak right now. How to buff the gun?
-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?
+mob ability bombs/bullets that suck in player
+
+mod where you can't stop firing, how to code?
+
+mod: laser beams push like plasma torch pushes with directional force
mechanic: technological dead end - add mods to the mod pool with a dumb effect
don't show up in custom?
@@ -67,6 +64,10 @@ mechanic: technological dead end - add mods to the mod pool with a dumb effect
remove your bots (requires you to have some bots)
your bots are changed to random bots
+Mod: "Expansion Formula": Permanently increase the size of Negative Mass field by 16%(Max 96%)
+
+Mod: "Circadian Rhythm": Become immune to harm for 1 second every 10 seconds while playing.
+
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
@@ -386,21 +387,17 @@ AI doesn't know about:
modern pop culture
outside the lab
-robot AI communication
- output to
- bottom left message
- tab title?
+in game console
+ output all console.log code //find starter code for this at the end of index.js
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
- black text on bottom right with no background?
- or white text, or yellow
- end each message with a hexadecimal encryption code/hash
+ messages about heal, ammo, mods, that just list internal computer code
+ example: a heal would be mech.health += 12
+ mono space font
+ square edges
+ black text on bottom right with no background?
+ or white text, or yellow
message after selecting each new (mod / gun / field)
put messages in (mod / gun / field) method
at start of run