diff --git a/js/bullets.js b/js/bullets.js
index c1441db..1ec48a0 100644
--- a/js/bullets.js
+++ b/js/bullets.js
@@ -36,7 +36,7 @@ const b = {
modCollisionImmuneCycles: null,
modBlockDmg: null,
isModPiezo: null,
- isModDroneCollide: null,
+ isModFastDrones: null,
isModFastSpores: null,
modSuperBallNumber: null,
modOneSuperBall: null,
@@ -49,7 +49,6 @@ const b = {
isModHealthRecovery: null,
isModEnergyLoss: null,
isModDeathAvoid: null,
- isModDeathAvoidOnCD: null,
modWaveSpeedMap: null,
modWaveSpeedBody: null,
isModSporeField: null,
@@ -531,7 +530,7 @@ const b = {
},
{
name: "Pauli exclusion",
- description: `unable to collide with mobs for +2 seconds
activates after being harmed from a collision`,
+ description: `immune to harm for +1 seconds
activates after being harmed from a collision`,
maxCount: 9,
count: 0,
allowed() {
@@ -539,8 +538,8 @@ const b = {
},
requires: "",
effect() {
- b.modCollisionImmuneCycles += 120;
- mech.collisionImmuneCycle = mech.cycle + b.modCollisionImmuneCycles; //player is immune to collision damage for 30 cycles
+ b.modCollisionImmuneCycles += 60;
+ mech.immuneCycle = mech.cycle + b.modCollisionImmuneCycles; //player is immune to collision damage for 30 cycles
},
remove() {
b.modCollisionImmuneCycles = 30;
@@ -562,40 +561,6 @@ const b = {
b.isModSlowFPS = false;
}
},
- {
- name: "quantum immortality",
- description: "after dying, continue in an alternate reality
guns, ammo, field, and mods are randomized",
- maxCount: 1,
- count: 0,
- allowed() {
- return true
- },
- requires: "",
- effect() {
- b.isModImmortal = true;
- },
- remove() {
- b.isModImmortal = false;
- }
- },
- {
- name: "anthropic principle",
- description: "fatal harm can't happen
saves you up to once every 3 seconds",
- maxCount: 1,
- count: 0,
- allowed() {
- return true
- },
- requires: "",
- effect() {
- b.isModDeathAvoid = true;
- b.isModDeathAvoidOnCD = false;
- },
- remove() {
- b.isModDeathAvoid = false;
- b.isModDeathAvoidOnCD = false;
- }
- },
{
name: "entanglement",
nameInfo: "",
@@ -780,7 +745,7 @@ const b = {
},
{
name: "Bayesian inference",
- description: "33% chance for double power ups to drop
remove all future ammo power ups",
+ description: "37% chance for double power ups to drop
remove all future ammo power ups",
maxCount: 1,
count: 0,
allowed() {
@@ -788,7 +753,7 @@ const b = {
},
requires: "",
effect: () => {
- b.modBayesian = 0.33;
+ b.modBayesian = 0.37;
},
remove() {
b.modBayesian = 0;
@@ -828,7 +793,7 @@ const b = {
},
{
name: "determinism",
- description: "spawn 4 mods and 2 heal power ups
future power ups are limited to one choice",
+ description: "spawn 5 mods and 2 heal power ups
future power ups are limited to one choice",
maxCount: 1,
count: 0,
allowed() {
@@ -837,7 +802,7 @@ const b = {
requires: "not cardinality",
effect: () => {
b.isModDeterminism = true;
- for (let i = 0; i < 4; i++) { //if you change the six also change it in Born rule
+ for (let i = 0; i < 5; i++) { //if you change the six also change it in Born rule
powerUps.spawn(mech.pos.x, mech.pos.y, "mod");
if (Math.random() < b.modBayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "mod");
}
@@ -852,7 +817,7 @@ const b = {
},
{
name: "many worlds",
- description: "spawn a reroll after choosing a power up",
+ description: "after choosing a gun, field, or mod
66% chance to spawn a reroll",
maxCount: 1,
count: 0,
allowed() {
@@ -870,6 +835,45 @@ const b = {
b.manyWorlds = false;
}
},
+ {
+ name: "anthropic principle",
+ nameInfo: "",
+ description: "heal to 50% health instead of dying
consumes 1 reroll",
+ maxCount: 1,
+ count: 0,
+ allowed() {
+ return powerUps.reroll.rerolls > 0 || build.isCustomSelection
+ },
+ requires: "at least 1 reroll",
+ effect() {
+ b.isModDeathAvoid = true;
+ setTimeout(function () {
+ powerUps.reroll.changeRerolls(0)
+ }, 1000);
+ },
+ remove() {
+ b.isModDeathAvoid = false;
+ }
+ },
+ {
+ name: "quantum immortality",
+ description: "after dying, continue in an alternate reality
spawn 3 rerolls",
+ maxCount: 1,
+ count: 0,
+ allowed() {
+ return true
+ },
+ requires: "",
+ effect() {
+ b.isModImmortal = true;
+ powerUps.spawn(mech.pos.x, mech.pos.y, "reroll", false);
+ powerUps.spawn(mech.pos.x, mech.pos.y, "reroll", false);
+ powerUps.spawn(mech.pos.x, mech.pos.y, "reroll", false);
+ },
+ remove() {
+ b.isModImmortal = false;
+ }
+ },
{
name: "Born rule",
description: "remove all current mods
spawn new mods to replace them",
@@ -991,7 +995,7 @@ const b = {
},
{
name: "shotgun spin-statistics",
- description: "firing the shotgun makes you
immune to collisions for 1 second",
+ description: "firing the shotgun makes you
immune to harm for 1 second",
maxCount: 1,
count: 0,
allowed() {
@@ -1364,8 +1368,8 @@ const b = {
}
},
{
- name: "redundant systems",
- description: "drone collisions no longer reduce their lifespan",
+ name: "brushless motor",
+ description: "drones accelerate 50% faster",
maxCount: 1,
count: 0,
allowed() {
@@ -1373,10 +1377,10 @@ const b = {
},
requires: "drones",
effect() {
- b.isModDroneCollide = true
+ b.isModFastDrones = true
},
remove() {
- b.isModDroneCollide = true;
+ b.isModFastDrones = false
}
},
{
@@ -2133,7 +2137,7 @@ const b = {
let collide = Matter.Query.collides(this, map) //check if collides with map
if (collide.length > 0) {
for (let i = 0; i < collide.length; i++) {
- if (collide[i].bodyA.collisionFilter.category === cat.map || collide[i].bodyB.collisionFilter.category === cat.map) {
+ if (collide[i].bodyA.collisionFilter.category === cat.map) { // || collide[i].bodyB.collisionFilter.category === cat.map) {
const angle = Matter.Vector.angle(collide[i].normal, {
x: 1,
y: 0
@@ -2141,7 +2145,7 @@ const b = {
Matter.Body.setAngle(this, Math.atan2(collide[i].tangent.y, collide[i].tangent.x))
//move until touching map again after rotation
for (let j = 0; j < 10; j++) {
- if (Matter.Query.collides(this, map).length > 0) {
+ if (Matter.Query.collides(this, map).length > 0) { //touching map
if (angle > -0.2 || angle < -1.5) { //don't stick to level ground
Matter.Body.setStatic(this, true) //don't set to static if not touching map
} else {
@@ -2156,7 +2160,8 @@ const b = {
//sometimes the mine can't attach to map and it just needs to be reset
const that = this
setTimeout(function () {
- if (Matter.Query.collides(that, map).length === 0) {
+ if (Matter.Query.collides(that, map).length === 0 || Matter.Query.point(map, that.position).length > 0) {
+ console.log(that)
that.endCycle = 0 // if not touching map explode
that.isArmed = false
b.mine(that.position, that.velocity, that.angle)
@@ -2366,17 +2371,18 @@ const b = {
},
drone(speed = 1) {
const me = bullet.length;
- const THRUST = 0.0015
- const dir = mech.angle + 0.2 * (Math.random() - 0.5);
+ const THRUST = b.isModFastDrones ? 0.0025 : 0.0015
+ const FRICTION = b.isModFastDrones ? 0.008 : 0.0005
+ const dir = mech.angle + 0.4 * (Math.random() - 0.5);
const RADIUS = (4.5 + 3 * Math.random())
bullet[me] = Bodies.polygon(mech.pos.x + 30 * Math.cos(mech.angle), mech.pos.y + 30 * Math.sin(mech.angle), 8, RADIUS, {
angle: dir,
inertia: Infinity,
friction: 0.05,
- frictionAir: 0.0005,
+ frictionAir: FRICTION,
restitution: 1,
dmg: 0.23, //damage done in addition to the damage from momentum
- lookFrequency: 107 + Math.floor(47 * Math.random()),
+ lookFrequency: 100 + Math.floor(23 * Math.random()),
endCycle: game.cycle + Math.floor((1200 + 420 * Math.random()) * b.isModBulletsLastLonger),
classType: "bullet",
collisionFilter: {
@@ -2396,7 +2402,7 @@ const b = {
});
this.lockedOn = null
- if (this.endCycle > game.cycle + this.deathCycles && b.isModDroneCollide) {
+ if (this.endCycle > game.cycle + this.deathCycles) {
this.endCycle -= 60
if (game.cycle + this.deathCycles > this.endCycle) this.endCycle = game.cycle + this.deathCycles
}
@@ -2966,7 +2972,7 @@ const b = {
}
player.force.x -= knock * Math.cos(mech.angle)
player.force.y -= knock * Math.sin(mech.angle) * 0.3 //reduce knock back in vertical direction to stop super jumps
- if (b.isModShotgunImmune) mech.collisionImmuneCycle = mech.cycle + 60; //player is immune to collision damage for 30 cycles
+ if (b.isModShotgunImmune) mech.immuneCycle = mech.cycle + 60; //player is immune to collision damage for 30 cycles
b.muzzleFlash(35);
const side = 19 * b.modBulletSize
for (let i = 0; i < 15; i++) {
@@ -3687,11 +3693,15 @@ const b = {
isStarterGun: false,
isEasyToAim: true,
fire() {
- const speed = mech.crouch ? 36 : 22
- b.mine({
+ const pos = {
x: mech.pos.x + 30 * Math.cos(mech.angle),
y: mech.pos.y + 30 * Math.sin(mech.angle)
- }, {
+ }
+ let speed = mech.crouch ? 36 : 22
+ if (Matter.Query.point(map, pos).length > 0) { //don't fire if mine will spawn inside map
+ speed = -2
+ }
+ b.mine(pos, {
x: speed * Math.cos(mech.angle),
y: speed * Math.sin(mech.angle)
}, 0, b.isModMineAmmoBack)
@@ -3820,13 +3830,13 @@ const b = {
name: "drones",
description: "deploy drones that crash into mobs
collisions reduce their lifespan by 1 second",
ammo: 0,
- ammoPack: 14,
+ ammoPack: 15,
have: false,
isStarterGun: true,
isEasyToAim: true,
fire() {
b.drone(mech.crouch ? 45 : 1)
- mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 25 : 5) * b.modFireRate); // cool down
+ mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 13 : 5) * b.modFireRate); // cool down
}
},
{
diff --git a/js/engine.js b/js/engine.js
index 34b1d0e..9cf2e23 100644
--- a/js/engine.js
+++ b/js/engine.js
@@ -97,8 +97,7 @@ function collisionChecks(event) {
function collidePlayer(obj) {
//player dmg from hitting a body
- // if ( mech.collisionImmuneCycle < mech.cycle) {
- if (obj.classType === "body" && obj.speed > 10 && mech.collisionImmuneCycle < mech.cycle) {
+ if (obj.classType === "body" && obj.speed > 10 && mech.immuneCycle < mech.cycle) {
const velocityThreshold = 30 //keep this lines up with player.enterLand numbers (130/5 = 26)
if (player.position.y > obj.position.y) { //block is above the player look at total momentum difference
const velocityDiffMag = Vector.magnitude(Vector.sub(player.velocity, obj.velocity))
@@ -109,7 +108,7 @@ function collisionChecks(event) {
}
function hit(dmg) {
- mech.collisionImmuneCycle = mech.cycle + b.modCollisionImmuneCycles; //player is immune to collision damage for 30 cycles
+ mech.immuneCycle = mech.cycle + b.modCollisionImmuneCycles; //player is immune to collision damage for 30 cycles
dmg = Math.min(Math.max(Math.sqrt(dmg) * obj.mass * 0.01, 0.02), 0.15);
mech.damage(dmg);
game.drawList.push({ //add dmg to draw queue
@@ -123,27 +122,6 @@ function collisionChecks(event) {
}
}
- // function collidePlayer(obj, speedThreshold = 12, massThreshold = 2) {
- // //player dmg from hitting a body
- // if (obj.classType === "body" && mech.collisionImmuneCycle < mech.cycle && obj.speed > speedThreshold && obj.mass > massThreshold) {
- // const v = Vector.magnitude(Vector.sub(player.velocity, obj.velocity));
- // if ((Math.abs(obj.velocity.x - player.velocity.x) > speedThreshold) || (player.position.y > obj.position.y && v > speedThreshold)) {
- // mech.collisionImmuneCycle = mech.cycle + b.modCollisionImmuneCycles; //player is immune to collision damage for 30 cycles
- // let dmg = Math.sqrt((v - speedThreshold + 0.1) * (obj.mass - massThreshold)) * 0.01;
- // dmg = Math.min(Math.max(dmg, 0.02), 0.15);
- // mech.damage(dmg);
- // game.drawList.push({ //add dmg to draw queue
- // x: pairs[i].activeContacts[0].vertex.x,
- // y: pairs[i].activeContacts[0].vertex.y,
- // radius: dmg * 500,
- // color: game.mobDmgColor,
- // time: game.drawTime
- // });
- // return;
- // }
- // }
- // }
-
//mob + (player,bullet,body) collisions
for (let k = 0; k < mob.length; k++) {
if (mob[k].alive && mech.alive) {
@@ -157,8 +135,8 @@ function collisionChecks(event) {
function collideMob(obj) {
//player + mob collision
- if (mech.collisionImmuneCycle < mech.cycle && (obj === playerBody || obj === playerHead)) {
- mech.collisionImmuneCycle = mech.cycle + b.modCollisionImmuneCycles; //player is immune to collision damage for 30 cycles
+ if (mech.immuneCycle < mech.cycle && (obj === playerBody || obj === playerHead)) {
+ mech.immuneCycle = mech.cycle + b.modCollisionImmuneCycles; //player is immune to collision damage for 30 cycles
mob[k].foundPlayer();
let dmg = Math.min(Math.max(0.025 * Math.sqrt(mob[k].mass), 0.05), 0.3) * game.dmgScale; //player damage is capped at 0.3*dmgScale of 1.0
if (b.isModPiezo) {
diff --git a/js/level.js b/js/level.js
index 79126b2..76cdee6 100644
--- a/js/level.js
+++ b/js/level.js
@@ -17,9 +17,9 @@ const level = {
// game.enableConstructMode() //used to build maps in testing mode
// level.difficultyIncrease(9)
// mech.setField("time dilation field")
- // b.giveMod("many worlds");
- // b.giveGuns("neutron bomb")
- // b.giveGuns("foam")
+ // b.giveMod("brushless motor");
+ // b.giveGuns("drones")
+ // b.giveGuns("mine")
// mech.setField("pilot wave")
// mech.setField("phase decoherence field")
@@ -135,7 +135,7 @@ const level = {
spawn.mapRect(-250, -700, 1000, 900); // shelf
spawn.mapRect(-250, -1200, 1000, 250); // shelf roof
powerUps.spawnStartingPowerUps(600, -800);
- powerUps.spawn(550, -800, "reroll", false); //starting gun
+ powerUps.spawn(550, -800, "reroll", false);
function blockDoor(x, y, blockSize = 58) {
spawn.mapRect(x, y - 290, 40, 60); // door lip
diff --git a/js/mobs.js b/js/mobs.js
index 9c1736b..4beba84 100644
--- a/js/mobs.js
+++ b/js/mobs.js
@@ -373,7 +373,7 @@ const mobs = {
ctx.setLineDash([125 * Math.random(), 125 * Math.random()]);
// ctx.lineDashOffset = 6*(game.cycle % 215);
if (this.distanceToPlayer() < this.laserRange && !mech.isStealth) {
- if (mech.collisionImmuneCycle < mech.cycle) mech.damage(0.0003 * game.dmgScale);
+ if (mech.immuneCycle < mech.cycle) mech.damage(0.0003 * game.dmgScale);
if (mech.energy > 0.1) mech.energy -= 0.003
ctx.beginPath();
ctx.moveTo(this.position.x, this.position.y);
@@ -461,13 +461,15 @@ const mobs = {
if (!mech.isStealth) vertexCollision(this.position, look, [player]);
// hitting player
if (best.who === player) {
- if (mech.collisionImmuneCycle < mech.cycle) dmg = 0.0012 * game.dmgScale;
- mech.damage(dmg);
- //draw damage
- ctx.fillStyle = "#f00";
- ctx.beginPath();
- ctx.arc(best.x, best.y, dmg * 2000, 0, 2 * Math.PI);
- ctx.fill();
+ if (mech.immuneCycle < mech.cycle) {
+ const dmg = 0.0012 * game.dmgScale;
+ mech.damage(dmg);
+ //draw damage
+ ctx.fillStyle = "#f00";
+ ctx.beginPath();
+ ctx.arc(best.x, best.y, dmg * 2000, 0, 2 * Math.PI);
+ ctx.fill();
+ }
}
//draw beam
if (best.dist2 === Infinity) {
diff --git a/js/player.js b/js/player.js
index 60a195d..dcb3390 100644
--- a/js/player.js
+++ b/js/player.js
@@ -215,9 +215,6 @@ const mech = {
mech.yOff = mech.yOffWhen.jump;
mech.hardLandCD = mech.cycle + Math.min(momentum / 6.5 - 6, 40)
- // if (b.isModStompPauli) {
- // mech.collisionImmuneCycle = mech.cycle + b.modCollisionImmuneCycles; //player is immune to collision damage for 30 cycles
- // }
if (b.isModStomp) {
const len = Math.min(25, (momentum - 120) * 0.1)
for (let i = 0; i < len; i++) {
@@ -363,7 +360,7 @@ const mech = {
if (b.isModImmortal) { //if player has the immortality buff, spawn on the same level with randomized stats
spawn.setSpawnList(); //new mob types
game.clearNow = true; //triggers a map reset
- powerUps.reroll.rerolls = Math.floor(Math.random() * Math.random() * 8)
+ powerUps.reroll.rerolls = Math.floor(Math.random() * Math.random() * 12)
//count mods
let totalMods = 0;
@@ -511,7 +508,7 @@ const mech = {
}
},
defaultFPSCycle: 0, //tracks when to return to normal fps
- collisionImmuneCycle: 0, //used in engine
+ immuneCycle: 0, //used in engine
harmReduction() {
let dmg = 1
dmg *= mech.fieldDamageResistance
@@ -548,24 +545,23 @@ const mech = {
if (b.isModEnergyHealth) {
mech.energy -= dmg;
if (mech.energy < 0 || isNaN(mech.energy)) {
- if (b.isModDeathAvoid && !b.isModDeathAvoidOnCD) { //&& Math.random() < 0.5
- b.isModDeathAvoidOnCD = true;
- mech.energy += dmg //undo the damage
- if (mech.energy < 0.05) mech.energy = 0.05
- mech.collisionImmuneCycle = mech.cycle + 30 //disable this.collisionImmuneCycle bonus seconds
+ if (b.isModDeathAvoid && powerUps.reroll.rerolls) { //&& Math.random() < 0.5
+ powerUps.reroll.changeRerolls(-1)
+
+ mech.energy = mech.maxEnergy * 0.5
+ // if (mech.energy < 0.05) mech.energy = 0.05
+ mech.immuneCycle = mech.cycle + 120 //disable this.immuneCycle bonus seconds
+ game.makeTextLog(" death avoided
1 reroll consumed", 300)
game.wipe = function () { //set wipe to have trails
- ctx.fillStyle = "rgba(255,255,255,0.02)";
+ ctx.fillStyle = "rgba(255,255,255,0.03)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
setTimeout(function () {
game.wipe = function () { //set wipe to normal
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
- // game.replaceTextLog = true;
- // game.makeTextLog("death avoided", 360);
- b.isModDeathAvoidOnCD = false;
- }, 3000);
+ }, 2000);
return;
} else {
@@ -578,24 +574,22 @@ const mech = {
} else {
mech.health -= dmg;
if (mech.health < 0 || isNaN(mech.health)) {
- if (b.isModDeathAvoid && !b.isModDeathAvoidOnCD) { //&& Math.random() < 0.5
- b.isModDeathAvoidOnCD = true;
- mech.health += dmg //undo the damage
- if (mech.health < 0.05) mech.health = 0.05
- mech.collisionImmuneCycle = mech.cycle + 30 //disable this.collisionImmuneCycle bonus seconds
+ if (b.isModDeathAvoid && powerUps.reroll.rerolls > 0) { //&& Math.random() < 0.5
+ powerUps.reroll.changeRerolls(-1)
+ mech.health = mech.maxHealth * 0.5
+ // if (mech.health < 0.05) mech.health = 0.05
+ mech.immuneCycle = mech.cycle + 120 //disable this.immuneCycle bonus seconds
+ game.makeTextLog(" death avoided
1 reroll consumed", 300)
game.wipe = function () { //set wipe to have trails
- ctx.fillStyle = "rgba(255,255,255,0.02)";
+ ctx.fillStyle = "rgba(255,255,255,0.03)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
setTimeout(function () {
game.wipe = function () { //set wipe to normal
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
- // game.replaceTextLog = true;
- // game.makeTextLog("death avoided", 360);
- b.isModDeathAvoidOnCD = false;
- }, 3000);
+ }, 2000);
} else {
mech.health = 0;
mech.death();
@@ -711,19 +705,12 @@ const mech = {
// },
draw() {
- // mech.fillColor = (mech.collisionImmuneCycle < mech.cycle) ? "#fff" : "rgba(255,255,255,0.1)" //"#cff"
ctx.fillStyle = mech.fillColor;
mech.walk_cycle += mech.flipLegs * mech.Vx;
//draw body
ctx.save();
- // if (mech.collisionImmuneCycle < mech.cycle) {
- // ctx.globalAlpha = 1
- // if (mech.collisionImmune) mech.collisionImmune = false;
- // } else {
- // ctx.globalAlpha = 0.7
- // }
- ctx.globalAlpha = (mech.collisionImmuneCycle < mech.cycle) ? 1 : 0.7
+ ctx.globalAlpha = (mech.immuneCycle < mech.cycle) ? 1 : 0.7
ctx.translate(mech.pos.x, mech.pos.y);
mech.calcLeg(Math.PI, -3);
mech.drawLeg("#4a4a4a");
@@ -1672,8 +1659,8 @@ const mech = {
const force = Vector.mult(Vector.normalise(Vector.sub(mech.pos, path[1])), -0.01 * Math.min(5, best.who.mass))
Matter.Body.applyForce(best.who, path[1], force)
Matter.Body.setVelocity(best.who, { //friction
- x: best.who.velocity.x * 0.6,
- y: best.who.velocity.y * 0.6
+ x: best.who.velocity.x * 0.7,
+ y: best.who.velocity.y * 0.7
});
// const angle = Math.atan2(player.position.y - best.who.position.y, player.position.x - best.who.position.x);
// const mass = Math.min(Math.sqrt(best.who.mass), 6);
diff --git a/js/powerups.js b/js/powerups.js
index e0b0b9e..a6b0cd1 100644
--- a/js/powerups.js
+++ b/js/powerups.js
@@ -21,7 +21,7 @@ const powerUps = {
powerUps.endDraft();
},
endDraft() {
- if (b.manyWorlds) {
+ if (b.manyWorlds && Math.random() < 0.66) {
powerUps.spawn(mech.pos.x, mech.pos.y, "reroll");
if (Math.random() < b.modBayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "reroll");
}
@@ -47,9 +47,16 @@ const powerUps = {
return 20;
},
effect() {
- powerUps.reroll.rerolls++
+ powerUps.reroll.changeRerolls(1)
game.makeTextLog("