diff --git a/js/bullets.js b/js/bullets.js
index 1ba512f..ef0c900 100644
--- a/js/bullets.js
+++ b/js/bullets.js
@@ -61,6 +61,7 @@ const b = {
isModRailNails: null,
isModHawking: null,
modBabyMissiles: null,
+ isModIceCrystals: null,
modOnHealthChange() { //used with acid mod
if (b.isModAcidDmg && mech.health > 0.8) {
game.playerDmgColor = "rgba(0,80,80,0.9)"
@@ -422,22 +423,6 @@ const b = {
b.isModStomp = false;
}
},
- {
- name: "entanglement",
- description: "only when your first gun is equipped
reduce harm by 10% for each gun you have",
- maxCount: 1,
- count: 0,
- allowed() {
- return true
- },
- requires: "",
- effect() {
- b.isModEntanglement = true
- },
- remove() {
- b.isModEntanglement = false;
- }
- },
{
name: "Pauli exclusion",
description: `unable to collide with mobs for +1 second
activates after being harmed from a collision`,
@@ -505,9 +490,25 @@ const b = {
b.isModDeathAvoidOnCD = false;
}
},
+ {
+ name: "entanglement",
+ description: "10% less harm for each gun in your inventory
when your first gun is equipped",
+ maxCount: 1,
+ count: 0,
+ allowed() {
+ return true
+ },
+ requires: "",
+ effect() {
+ b.isModEntanglement = true
+ },
+ remove() {
+ b.isModEntanglement = false;
+ }
+ },
{
name: "piezoelectricity",
- description: "colliding with mobs charges your energy",
+ description: "colliding with mobs charges your energy
10% less harm from mob collisions",
maxCount: 1,
count: 0,
allowed() {
@@ -735,8 +736,8 @@ const b = {
{
- name: "crystal nucleation",
- description: "fire crystals formed from the air
your minigun no longer requires ammo",
+ name: "ice crystal nucleation",
+ description: "your minigun condenses unlimited ammo
ice bullets made from water vapor slow mobs",
maxCount: 1,
count: 0,
allowed() {
@@ -744,6 +745,7 @@ const b = {
},
requires: "minigun",
effect() {
+ b.isModIceCrystals = true;
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "minigun") {
b.guns[i].ammoPack = Infinity
@@ -755,6 +757,7 @@ const b = {
}
},
remove() {
+ b.isModIceCrystals = false;
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "minigun") {
b.guns[i].ammoPack = b.guns[i].defaultAmmoPack;
@@ -829,6 +832,22 @@ const b = {
game.updateGunHUD();
}
},
+ {
+ name: "irradiated needles",
+ description: "fléchette needles are exposed to radiation
needles do 3x damage over 6 seconds",
+ maxCount: 1,
+ count: 0,
+ allowed() {
+ return b.haveGunCheck("fléchettes")
+ },
+ requires: "fléchettes",
+ effect() {
+ b.isModDotFlechette = true;
+ },
+ remove() {
+ b.isModDotFlechette = false;
+ }
+ },
{
name: "wave phase velocity",
description: "the wave beam propagates faster in solids",
@@ -2062,19 +2081,11 @@ const b = {
bullet[me].endCycle = game.cycle + 70;
bullet[me].dmg = 0.07;
bullet[me].frictionAir = mech.crouch ? 0.007 : 0.01;
- bullet[me].onDmg = function (who) {
-
- who.status.push({ //slow
- endCycle: game.cycle + 60,
- effect() {
-
- Matter.Body.setVelocity(who, {
- x: who.velocity.x * 0.8,
- y: who.velocity.y * 0.8
- });
- },
- })
- };
+ if (b.isModIceCrystals) {
+ bullet[me].onDmg = function (who) {
+ if (!who.shield) mobs.statusSlow(who, 60)
+ };
+ }
bullet[me].do = function () {
this.force.y += this.mass * 0.0005;
};
@@ -2169,7 +2180,6 @@ const b = {
const CD = (mech.crouch) ? 45 : 25
if (this.lastFireCycle + CD < mech.cycle) this.count = 0 //reset count if it cycles past the CD
this.lastFireCycle = mech.cycle
-
if (this.count > ((mech.crouch) ? 6 : 1)) {
this.count = 0
mech.fireCDcycle = mech.cycle + Math.floor(CD * b.modFireRate); // cool down
@@ -2181,8 +2191,17 @@ const b = {
function makeFlechette(angle = mech.angle) {
const me = bullet.length;
bullet[me] = Bodies.rectangle(mech.pos.x + 40 * Math.cos(mech.angle), mech.pos.y + 40 * Math.sin(mech.angle), 45 * b.modBulletSize, 1.4 * b.modBulletSize, b.fireAttributes(angle));
+ Matter.Body.setDensity(bullet[me], 0.0001); //0.001 is normal
bullet[me].endCycle = game.cycle + 180;
- bullet[me].dmg = 1.3;
+ if (b.isModDotFlechette) {
+ bullet[me].dmg = 0;
+ bullet[me].onDmg = function (who) {
+ mobs.statusDot(who, 0.35, 360) // (1.4) * 3 / 12 ticks (6 seconds)
+ };
+ } else {
+ bullet[me].dmg = 1.4;
+ }
+
bullet[me].do = function () {
if (this.speed < 10) this.force.y += this.mass * 0.0003; //no gravity until it slows don to improve aiming
};
@@ -2245,7 +2264,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.5 / Math.sqrt(q[i].mass)
+ let dmg = b.dmgScale * 0.6 / Math.sqrt(q[i].mass)
q[i].damage(dmg);
q[i].foundPlayer();
game.drawList.push({ //add dmg to draw queue
diff --git a/js/engine.js b/js/engine.js
index 9e0e76d..514dcb0 100644
--- a/js/engine.js
+++ b/js/engine.js
@@ -138,9 +138,12 @@ function collisionChecks(event) {
mech.collisionImmuneCycle = 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) {
+ mech.energy = mech.fieldEnergyMax;
+ dmg *= 0.9
+ }
mech.damage(dmg);
if (mob[k].onHit) mob[k].onHit(k);
- if (b.isModPiezo) mech.energy = mech.fieldEnergyMax;
if (b.isModAnnihilation && mob[k].dropPowerUp && !mob[k].isShielded) {
mob[k].death();
game.drawList.push({
@@ -193,17 +196,19 @@ function collisionChecks(event) {
return;
}
//mob + body collisions
- if (obj.classType === "body" && obj.speed > 5) {
+ if (obj.classType === "body" && obj.speed > 6) {
const v = Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity));
- if (v > 8) {
- let dmg = b.dmgScale * (v * Math.sqrt(obj.mass) * 0.07);
+ if (v > 9) {
+ let dmg = b.dmgScale * (v * obj.mass * 0.07);
+ if (b.isModCrit && !mob[k].seePlayer.recall && !mob[k].shield) dmg *= 5
+ if (mob[k].isShielded) dmg *= 0.5
mob[k].damage(dmg, true);
if (mob[k].distanceToPlayer2() < 1000000) mob[k].foundPlayer();
game.drawList.push({
//add dmg to draw queue
x: pairs[i].activeContacts[0].vertex.x,
y: pairs[i].activeContacts[0].vertex.y,
- radius: Math.sqrt(dmg) * 40,
+ radius: Math.log(2 * dmg + 1.1) * 40,
color: game.playerDmgColor,
time: game.drawTime
});
diff --git a/js/level.js b/js/level.js
index d4cb228..2a44256 100644
--- a/js/level.js
+++ b/js/level.js
@@ -14,9 +14,9 @@ const level = {
start() {
if (level.levelsCleared === 0) {
// level.difficultyIncrease(9)
- b.giveGuns("minigun")
+ b.giveGuns("fléchettes")
// mech.setField("phase decoherence field")
- // b.giveMod("quantum dissipation");
+ b.giveMod("irradiated needles");
// b.giveMod("reflective cavity");
// level.intro(); //starting level
@@ -129,7 +129,7 @@ const level = {
// powerUps.spawn(950, -425, "gun", false);
// }
- // spawn.nodeBoss(-500, -600, spawn.allowedBossList[Math.floor(Math.random() * spawn.allowedBossList.length)]);
+ spawn.nodeBoss(-500, -600, spawn.allowedBossList[Math.floor(Math.random() * spawn.allowedBossList.length)]);
// spawn.lineBoss(-500, -600, spawn.allowedBossList[Math.floor(Math.random() * spawn.allowedBossList.length)]);
// spawn.bodyRect(-135, -50, 50, 50);
// spawn.bodyRect(-140, -100, 50, 50);
@@ -140,7 +140,7 @@ const level = {
// powerUps.spawn(450, -400, "mod", false, 6);
// powerUps.spawn(450, -400, "mod", false);
// spawn.bodyRect(-45, -100, 40, 50);
- spawn.starter(800, -450);
+ spawn.starter(800, -450, 150);
// spawn.cellBoss(400, -750);
// spawn.randomLevelBoss(400, -750)
diff --git a/js/mobs.js b/js/mobs.js
index b20083f..0816df9 100644
--- a/js/mobs.js
+++ b/js/mobs.js
@@ -48,20 +48,57 @@ const mobs = {
}
}
},
- // alert(range) {
- // range = range * range;
- // for (let i = 0; i < mob.length; i++) {
- // if (mob[i].distanceToPlayer2() < range) mob[i].locatePlayer();
- // }
- // },
- // startle(amount) {
- // for (let i = 0; i < mob.length; i++) {
- // if (!mob[i].seePlayer.yes) {
- // mob[i].force.x += amount * mob[i].mass * (Math.random() - 0.5);
- // mob[i].force.y += amount * mob[i].mass * (Math.random() - 0.5);
- // }
- // }
- // },
+ statusSlow(who, cycles = 60) {
+ //remove other "slow" effects on this mob
+ let i = who.status.length
+ while (i--) {
+ if (who.status[i].type === "slow") who.status.splice(i, 1);
+ }
+ //add a new slow effect
+ who.status.push({
+ effect() {
+ Matter.Body.setVelocity(who, {
+ x: 0,
+ y: 0
+ });
+ Matter.Body.setAngularVelocity(who, 0);
+ ctx.beginPath();
+ ctx.moveTo(who.vertices[0].x, who.vertices[0].y);
+ for (let j = 1, len = who.vertices.length; j < len; ++j) {
+ ctx.lineTo(who.vertices[j].x, who.vertices[j].y);
+ }
+ ctx.lineTo(who.vertices[0].x, who.vertices[0].y);
+ ctx.strokeStyle = "rgba(0,100,255,0.5)";
+ ctx.lineWidth = 30;
+ ctx.stroke();
+ ctx.fillStyle = who.fill
+ ctx.fill();
+ },
+ type: "slow",
+ endCycle: game.cycle + cycles,
+ })
+ },
+ statusDot(who, tickDamage, cycles = 180) {
+ who.status.push({
+ effect() {
+ if ((game.cycle - this.startCycle) % 30 === 0) {
+ let dmg = b.dmgScale * tickDamage
+ who.damage(dmg);
+ game.drawList.push({ //add dmg to draw queue
+ x: who.position.x,
+ y: who.position.y,
+ radius: Math.log(2 * dmg + 1.1) * 40,
+ color: game.playerDmgColor,
+ time: game.drawTime
+ });
+ }
+ },
+ type: "dot",
+ endCycle: game.cycle + cycles,
+ startCycle: game.cycle
+ })
+ },
+
//**********************************************************************************************
//**********************************************************************************************
spawn(xPos, yPos, sides, radius, color) {
diff --git a/js/player.js b/js/player.js
index 4bf9df8..6c46bf6 100644
--- a/js/player.js
+++ b/js/player.js
@@ -822,20 +822,20 @@ const mech = {
mech.fieldCDcycle = mech.cycle + 15;
mech.isHolding = false;
//bullet-like collisions
- mech.holdingTarget.collisionFilter.category = cat.bullet;
+ mech.holdingTarget.collisionFilter.category = cat.body; //cat.bullet;
mech.holdingTarget.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield;
//check every second to see if player is away from thrown body, and make solid
const solid = function (that) {
const dx = that.position.x - player.position.x;
const dy = that.position.y - player.position.y;
- if (dx * dx + dy * dy > 10000 && that.speed < 3 && that !== mech.holdingTarget) {
- that.collisionFilter.category = cat.body; //make solid
- that.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet;
+ if (dx * dx + dy * dy > 10000 && that !== mech.holdingTarget) {
+ // that.collisionFilter.category = cat.body; //make solid
+ that.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet; //can hit player now
} else {
- setTimeout(solid, 50, that);
+ setTimeout(solid, 25, that);
}
};
- setTimeout(solid, 200, mech.holdingTarget);
+ setTimeout(solid, 150, mech.holdingTarget);
//throw speed scales a bit with mass
const speed = Math.min(85, Math.min(54 / mech.holdingTarget.mass + 5, 48) * Math.min(mech.throwCharge, mech.throwChargeMax) / 50);
diff --git a/js/spawn.js b/js/spawn.js
index 44a7bdc..fbc603b 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -142,9 +142,9 @@ const spawn = {
Matter.Body.setDensity(me, 0.0005) // normal density is 0.001 // this reduces life by half and decreases knockback
me.do = function () {
- this.checkStatus()
this.seePlayerByLookingAt();
this.attraction();
+ this.checkStatus();
};
},
cellBossCulture(x, y, radius = 20, num = 5) {
@@ -204,6 +204,7 @@ const spawn = {
}
}
}
+ this.checkStatus()
};
me.onDeath = function () {
let count = 0 //count other cells
@@ -317,6 +318,7 @@ const spawn = {
this.gravity();
this.seePlayerCheck();
this.attraction();
+ this.checkStatus();
};
},
grower(x, y, radius = 15) {
@@ -328,6 +330,7 @@ const spawn = {
this.seePlayerByLookingAt();
this.attraction();
this.grow();
+ this.checkStatus();
};
},
springer(x, y, radius = 20 + Math.ceil(Math.random() * 35)) {
@@ -376,6 +379,7 @@ const spawn = {
me.do = function () {
this.gravity();
this.searchSpring();
+ this.checkStatus();
};
},
hopper(x, y, radius = 30 + Math.ceil(Math.random() * 30)) {
@@ -403,6 +407,7 @@ const spawn = {
this.force.x += forceMag * Math.cos(angle);
this.force.y += forceMag * Math.sin(angle) - 0.04 * this.mass; //antigravity
}
+ this.checkStatus();
};
},
spinner(x, y, radius = 30 + Math.ceil(Math.random() * 35)) {
@@ -457,6 +462,7 @@ const spawn = {
} else {
this.cdBurst2 = 0;
}
+ this.checkStatus();
};
},
sucker(x, y, radius = 30 + Math.ceil(Math.random() * 70)) {
@@ -526,6 +532,7 @@ const spawn = {
ctx.fill();
}
}
+ this.checkStatus();
}
},
suckerBoss(x, y, radius = 25) {
@@ -625,6 +632,7 @@ const spawn = {
}
this.curl(eventHorizon);
}
+ this.checkStatus();
}
},
beamer(x, y, radius = 15 + Math.ceil(Math.random() * 15)) {
@@ -642,6 +650,7 @@ const spawn = {
this.repulsion();
//laser beam
this.laserBeam();
+ this.checkStatus();
};
},
focuser(x, y, radius = 30 + Math.ceil(Math.random() * 10)) {
@@ -705,6 +714,7 @@ const spawn = {
this.laserPos = this.position;
}
};
+ this.checkStatus();
}
},
laser(x, y, radius = 30) {
@@ -721,6 +731,7 @@ const spawn = {
this.seePlayerByLookingAt();
this.attraction();
this.laser();
+ this.checkStatus();
};
},
laserBoss(x, y, radius = 30) {
@@ -762,6 +773,7 @@ const spawn = {
ctx.strokeStyle = "rgba(80,0,255,0.07)";
ctx.stroke(); // Draw it
// this.laser(this.vertices[2], this.angle + Math.PI / 3);
+ this.checkStatus();
};
me.laser = function (where, angle) {
const vertexCollision = function (v1, v1End, domain) {
@@ -869,6 +881,7 @@ const spawn = {
this.attraction();
this.gravity();
this.strike();
+ this.checkStatus();
};
},
sneaker(x, y, radius = 15 + Math.ceil(Math.random() * 25)) {
@@ -885,7 +898,6 @@ const spawn = {
me.showHealthBar = false;
// me.memory = 420;
me.do = function () {
-
this.seePlayerCheck();
this.attraction();
this.gravity();
@@ -919,6 +931,7 @@ const spawn = {
this.canTouchPlayer = false;
this.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob //can't touch player
}
+ this.checkStatus();
};
},
ghoster(x, y, radius = 40 + Math.ceil(Math.random() * 100)) {
@@ -976,6 +989,7 @@ const spawn = {
this.canTouchPlayer = false;
this.collisionFilter.mask = cat.bullet; //can't touch player or walls
}
+ this.checkStatus();
};
},
// blinker(x, y, radius = 45 + Math.ceil(Math.random() * 70)) {
@@ -1046,6 +1060,7 @@ const spawn = {
this.hoverOverPlayer();
this.bomb();
this.search();
+ this.checkStatus();
};
},
shooter(x, y, radius = 25 + Math.ceil(Math.random() * 50)) {
@@ -1067,6 +1082,7 @@ const spawn = {
me.do = function () {
this.seePlayerByLookingAt();
this.fire();
+ this.checkStatus();
};
},
shooterBoss(x, y, radius = 130) {
@@ -1100,6 +1116,7 @@ const spawn = {
const sub = Vector.sub(this.homePosition, this.position)
const dist = Vector.magnitude(sub)
if (dist > 50) this.force = Vector.mult(Vector.normalise(sub), this.mass * 0.0002)
+ this.checkStatus();
};
},
bullet(x, y, radius = 6, sides = 0) {
@@ -1145,6 +1162,7 @@ const spawn = {
this.gravity();
this.seePlayerCheck();
this.attraction();
+ this.checkStatus();
};
},
spawns(x, y, radius = 15 + Math.ceil(Math.random() * 5)) {
@@ -1164,6 +1182,7 @@ const spawn = {
this.gravity();
this.seePlayerCheck();
this.attraction();
+ this.checkStatus();
};
},
exploder(x, y, radius = 25 + Math.ceil(Math.random() * 50)) {
@@ -1178,6 +1197,7 @@ const spawn = {
this.gravity();
this.seePlayerCheck();
this.attraction();
+ this.checkStatus();
};
},
snakeBoss(x, y, radius = 80) {
@@ -1196,6 +1216,7 @@ const spawn = {
this.seePlayerCheck();
this.attraction();
this.laserBeam();
+ this.checkStatus();
};
//snake tail
@@ -1237,6 +1258,7 @@ const spawn = {
this.gravity();
this.seePlayerCheck();
this.attraction();
+ this.checkStatus();
};
},
shield(target, x, y, chance = Math.min(0.02 + game.difficulty * 0.005, 0.2)) {
@@ -1274,7 +1296,9 @@ const spawn = {
//swap order of shield and mob, so that mob is behind shield graphically
mob[mob.length - 1] = mob[mob.length - 2];
mob[mob.length - 2] = me;
- me.do = function () {};
+ me.do = function () {
+ this.checkStatus();
+ };
}
},
bossShield(targets, x, y, radius) {
@@ -1314,7 +1338,9 @@ const spawn = {
me.showHealthBar = false;
mob[mob.length - 1] = mob[mob.length - 1 - nodes];
mob[mob.length - 1 - nodes] = me;
- me.do = function () {};
+ me.do = function () {
+ this.checkStatus();
+ };
},
//complex constrained mob templates**********************************************************************
//*******************************************************************************************************
diff --git a/todo.txt b/todo.txt
index ca0b045..3efc9d2 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,7 +1,7 @@
************** TODO - n-gon **************
-mod - lose your field, gain a gun and some ammo
- gain two guns?
+mod - lose your field, gain two guns?
+ lose a random mod, gain a gun?
mod - time dilation - Quantum Recovery
Expending all your energy while using the field will
@@ -24,13 +24,8 @@ mobs - add in a function to the main loops that does injected code for each mob
stun - blind, slow, but increased gravity effects
mod - flechettes mod for DoT poison damage
mod - grenade explosions stun enemies
- mod - give crystal minigun a slowing effect and rename it ice crystals
mod - vacuum bomb does DoT damage after exploding
-mod - get your next recursive mod 3 times
- are players aware of what a recursive mod is?
- too much of a nova drift rip off?
-
settings - auto aim at nearest mob
settings - custom keys binding