fragments
so many bug fixes around CPT mod: fragments - blocks, grenades, rail gun, shotgun slugs can all eject nails on collisions, or detonation
This commit is contained in:
188
js/bullet.js
188
js/bullet.js
@@ -24,7 +24,7 @@ const b = {
|
|||||||
if (mod.isAmmoFromHealth) {
|
if (mod.isAmmoFromHealth) {
|
||||||
if (mech.health > 2 * mod.isAmmoFromHealth * mech.maxHealth) {
|
if (mech.health > 2 * mod.isAmmoFromHealth * mech.maxHealth) {
|
||||||
mech.damage(mod.isAmmoFromHealth * mech.maxHealth / mech.harmReduction());
|
mech.damage(mod.isAmmoFromHealth * mech.maxHealth / mech.harmReduction());
|
||||||
powerUps.spawn(mech.pos.x, mech.pos.y, "ammo");
|
if (!(mod.isRewindAvoidDeath && mech.energy > 0.66)) powerUps.spawn(mech.pos.x, mech.pos.y, "ammo"); //don't give ammo if CPT triggered
|
||||||
} else {
|
} else {
|
||||||
game.replaceTextLog = true;
|
game.replaceTextLog = true;
|
||||||
game.makeTextLog("not enough health for catabolism to produce ammo", 120);
|
game.makeTextLog("not enough health for catabolism to produce ammo", 120);
|
||||||
@@ -285,7 +285,7 @@ const b = {
|
|||||||
bullet[me].explodeRad = 275;
|
bullet[me].explodeRad = 275;
|
||||||
bullet[me].onEnd = function() {
|
bullet[me].onEnd = function() {
|
||||||
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
|
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
|
||||||
if (mod.grenadeFragments) b.targetedNail(this.position, mod.grenadeFragments)
|
if (mod.fragments) b.targetedNail(this.position, mod.fragments * 5)
|
||||||
}
|
}
|
||||||
bullet[me].minDmgSpeed = 1;
|
bullet[me].minDmgSpeed = 1;
|
||||||
bullet[me].beforeDmg = function() {
|
bullet[me].beforeDmg = function() {
|
||||||
@@ -310,7 +310,7 @@ const b = {
|
|||||||
bullet[me].explodeRad = 275;
|
bullet[me].explodeRad = 275;
|
||||||
bullet[me].onEnd = function() {
|
bullet[me].onEnd = function() {
|
||||||
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
|
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
|
||||||
if (mod.grenadeFragments) b.targetedNail(this.position, mod.grenadeFragments)
|
if (mod.fragments) b.targetedNail(this.position, mod.fragments * 5)
|
||||||
}
|
}
|
||||||
bullet[me].minDmgSpeed = 1;
|
bullet[me].minDmgSpeed = 1;
|
||||||
bullet[me].beforeDmg = function() {
|
bullet[me].beforeDmg = function() {
|
||||||
@@ -345,7 +345,7 @@ const b = {
|
|||||||
bullet[me].explodeRad = 325 + Math.floor(Math.random() * 50);;
|
bullet[me].explodeRad = 325 + Math.floor(Math.random() * 50);;
|
||||||
bullet[me].onEnd = function() {
|
bullet[me].onEnd = function() {
|
||||||
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
|
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
|
||||||
if (mod.grenadeFragments) b.targetedNail(this.position, mod.grenadeFragments)
|
if (mod.fragments) b.targetedNail(this.position, mod.fragments * 7)
|
||||||
}
|
}
|
||||||
bullet[me].beforeDmg = function() {};
|
bullet[me].beforeDmg = function() {};
|
||||||
bullet[me].restitution = 0.4;
|
bullet[me].restitution = 0.4;
|
||||||
@@ -426,14 +426,6 @@ const b = {
|
|||||||
bullet[me].stuckTo = null;
|
bullet[me].stuckTo = null;
|
||||||
bullet[me].stuckToRelativePosition = null;
|
bullet[me].stuckToRelativePosition = null;
|
||||||
bullet[me].vacuumSlow = 0.97;
|
bullet[me].vacuumSlow = 0.97;
|
||||||
if (mod.isRewindGrenade && input.down) {
|
|
||||||
Matter.Body.setVelocity(bullet[me], {
|
|
||||||
x: 0,
|
|
||||||
y: 0
|
|
||||||
});
|
|
||||||
bullet[me].maxDamageRadius *= 1.3
|
|
||||||
mech.rewind(200, false)
|
|
||||||
}
|
|
||||||
bullet[me].beforeDmg = function() {};
|
bullet[me].beforeDmg = function() {};
|
||||||
bullet[me].stuck = function() {};
|
bullet[me].stuck = function() {};
|
||||||
bullet[me].do = function() {
|
bullet[me].do = function() {
|
||||||
@@ -2300,6 +2292,14 @@ const b = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
if (mod.fragments) {
|
||||||
|
bullet[me].beforeDmg = function() {
|
||||||
|
if (this.speed > 4) {
|
||||||
|
b.targetedNail(this.position, mod.fragments * 8)
|
||||||
|
this.endCycle = 0 //triggers despawn
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (mod.isIncendiary) {
|
} else if (mod.isIncendiary) {
|
||||||
const SPEED = mech.crouch ? 35 : 25
|
const SPEED = mech.crouch ? 35 : 25
|
||||||
const END = Math.floor(mech.crouch ? 9 : 6);
|
const END = Math.floor(mech.crouch ? 9 : 6);
|
||||||
@@ -2716,162 +2716,6 @@ const b = {
|
|||||||
mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 40 : 30) * b.fireCD); // cool down
|
mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 40 : 30) * b.fireCD); // cool down
|
||||||
b.grenade()
|
b.grenade()
|
||||||
},
|
},
|
||||||
fireNeutron() {
|
|
||||||
const me = bullet.length;
|
|
||||||
const dir = mech.angle;
|
|
||||||
bullet[me] = Bodies.polygon(mech.pos.x + 30 * Math.cos(mech.angle), mech.pos.y + 30 * Math.sin(mech.angle), 10, 4, b.fireAttributes(dir, false));
|
|
||||||
b.fireProps(mech.crouch ? 45 : 25, mech.crouch ? 35 : 20, dir, me); //cd , speed
|
|
||||||
Matter.Body.setDensity(bullet[me], 0.000001);
|
|
||||||
bullet[me].endCycle = Infinity;
|
|
||||||
bullet[me].frictionAir = 0;
|
|
||||||
bullet[me].friction = 1;
|
|
||||||
bullet[me].frictionStatic = 1;
|
|
||||||
bullet[me].restitution = 0;
|
|
||||||
bullet[me].minDmgSpeed = 0;
|
|
||||||
bullet[me].damageRadius = 100;
|
|
||||||
bullet[me].maxDamageRadius = 450 + 130 * mod.isNeutronSlow + 130 * mod.isNeutronImmune //+ 150 * Math.random()
|
|
||||||
bullet[me].radiusDecay = (0.81 + 0.15 * mod.isNeutronSlow + 0.15 * mod.isNeutronImmune) / mod.isBulletsLastLonger
|
|
||||||
bullet[me].stuckTo = null;
|
|
||||||
bullet[me].stuckToRelativePosition = null;
|
|
||||||
bullet[me].vacuumSlow = 0.97;
|
|
||||||
if (mod.isRewindGrenade && input.down) {
|
|
||||||
Matter.Body.setVelocity(bullet[me], {
|
|
||||||
x: 0,
|
|
||||||
y: 0
|
|
||||||
});
|
|
||||||
bullet[me].maxDamageRadius *= 1.3
|
|
||||||
mech.rewind(200, false)
|
|
||||||
}
|
|
||||||
bullet[me].beforeDmg = function() {};
|
|
||||||
bullet[me].stuck = function() {};
|
|
||||||
bullet[me].do = function() {
|
|
||||||
function onCollide(that) {
|
|
||||||
that.collisionFilter.mask = 0; //non collide with everything
|
|
||||||
Matter.Body.setVelocity(that, {
|
|
||||||
x: 0,
|
|
||||||
y: 0
|
|
||||||
});
|
|
||||||
that.do = that.radiationMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
const mobCollisions = Matter.Query.collides(this, mob)
|
|
||||||
if (mobCollisions.length) {
|
|
||||||
onCollide(this)
|
|
||||||
this.stuckTo = mobCollisions[0].bodyA
|
|
||||||
mobs.statusDoT(this.stuckTo, 0.5, 360) //apply radiation damage status effect on direct hits
|
|
||||||
|
|
||||||
if (this.stuckTo.isVerticesChange) {
|
|
||||||
this.stuckToRelativePosition = {
|
|
||||||
x: 0,
|
|
||||||
y: 0
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//find the relative position for when the mob is at angle zero by undoing the mobs rotation
|
|
||||||
this.stuckToRelativePosition = Vector.rotate(Vector.sub(this.position, this.stuckTo.position), -this.stuckTo.angle)
|
|
||||||
}
|
|
||||||
this.stuck = function() {
|
|
||||||
if (this.stuckTo && this.stuckTo.alive) {
|
|
||||||
const rotate = Vector.rotate(this.stuckToRelativePosition, this.stuckTo.angle) //add in the mob's new angle to the relative position vector
|
|
||||||
Matter.Body.setPosition(this, Vector.add(Vector.add(rotate, this.stuckTo.velocity), this.stuckTo.position))
|
|
||||||
Matter.Body.setVelocity(this, this.stuckTo.velocity); //so that it will move properly if it gets unstuck
|
|
||||||
} else {
|
|
||||||
this.collisionFilter.mask = cat.map | cat.body | cat.player | cat.mob; //non collide with everything but map
|
|
||||||
this.stuck = function() {
|
|
||||||
this.force.y += this.mass * 0.001;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const bodyCollisions = Matter.Query.collides(this, body)
|
|
||||||
if (bodyCollisions.length) {
|
|
||||||
if (!bodyCollisions[0].bodyA.isNotHoldable) {
|
|
||||||
onCollide(this)
|
|
||||||
this.stuckTo = bodyCollisions[0].bodyA
|
|
||||||
//find the relative position for when the mob is at angle zero by undoing the mobs rotation
|
|
||||||
this.stuckToRelativePosition = Vector.rotate(Vector.sub(this.position, this.stuckTo.position), -this.stuckTo.angle)
|
|
||||||
} else {
|
|
||||||
this.do = this.radiationMode;
|
|
||||||
}
|
|
||||||
this.stuck = function() {
|
|
||||||
if (this.stuckTo) {
|
|
||||||
const rotate = Vector.rotate(this.stuckToRelativePosition, this.stuckTo.angle) //add in the mob's new angle to the relative position vector
|
|
||||||
Matter.Body.setPosition(this, Vector.add(Vector.add(rotate, this.stuckTo.velocity), this.stuckTo.position))
|
|
||||||
// Matter.Body.setVelocity(this, this.stuckTo.velocity); //so that it will move properly if it gets unstuck
|
|
||||||
} else {
|
|
||||||
this.force.y += this.mass * 0.001;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (Matter.Query.collides(this, map).length) {
|
|
||||||
onCollide(this)
|
|
||||||
} else { //if colliding with nothing just fall
|
|
||||||
this.force.y += this.mass * 0.001;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bullet[me].radiationMode = function() { //the do code after the bullet is stuck on something, projects a damaging radiation field
|
|
||||||
this.stuck(); //runs different code based on what the bullet is stuck to
|
|
||||||
if (!mech.isBodiesAsleep) {
|
|
||||||
this.damageRadius = this.damageRadius * 0.85 + 0.15 * this.maxDamageRadius //smooth radius towards max
|
|
||||||
this.maxDamageRadius -= this.radiusDecay
|
|
||||||
if (this.damageRadius < 15) {
|
|
||||||
this.endCycle = 0;
|
|
||||||
} else {
|
|
||||||
//aoe damage to player
|
|
||||||
if (!mod.isNeutronImmune && Vector.magnitude(Vector.sub(player.position, this.position)) < this.damageRadius) {
|
|
||||||
const DRAIN = 0.0023
|
|
||||||
if (mech.energy > DRAIN) {
|
|
||||||
mech.energy -= DRAIN
|
|
||||||
} else {
|
|
||||||
mech.energy = 0;
|
|
||||||
mech.damage(0.00015)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//aoe damage to mobs
|
|
||||||
for (let i = 0, len = mob.length; i < len; i++) {
|
|
||||||
if (Vector.magnitude(Vector.sub(mob[i].position, this.position)) < this.damageRadius) {
|
|
||||||
let dmg = b.dmgScale * 0.082
|
|
||||||
if (Matter.Query.ray(map, mob[i].position, this.position).length > 0) dmg *= 0.25 //reduce damage if a wall is in the way
|
|
||||||
if (mob[i].shield) dmg *= 4 //x5 to make up for the /5 that shields normally take
|
|
||||||
mob[i].damage(dmg);
|
|
||||||
mob[i].locatePlayer();
|
|
||||||
if (mod.isNeutronSlow) {
|
|
||||||
Matter.Body.setVelocity(mob[i], {
|
|
||||||
x: mob[i].velocity.x * this.vacuumSlow,
|
|
||||||
y: mob[i].velocity.y * this.vacuumSlow
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.arc(this.position.x, this.position.y, this.damageRadius, 0, 2 * Math.PI);
|
|
||||||
ctx.globalCompositeOperation = "lighter"
|
|
||||||
ctx.fillStyle = `rgba(25,139,170,${0.2+0.06*Math.random()})`;
|
|
||||||
ctx.fill();
|
|
||||||
ctx.globalCompositeOperation = "source-over"
|
|
||||||
if (mod.isNeutronSlow) {
|
|
||||||
const that = this
|
|
||||||
|
|
||||||
function slow(who, radius = that.explodeRad * 3.2) {
|
|
||||||
for (i = 0, len = who.length; i < len; i++) {
|
|
||||||
const sub = Vector.sub(that.position, who[i].position);
|
|
||||||
const dist = Vector.magnitude(sub);
|
|
||||||
if (dist < radius) {
|
|
||||||
Matter.Body.setVelocity(who[i], {
|
|
||||||
x: who[i].velocity.x * that.vacuumSlow,
|
|
||||||
y: who[i].velocity.y * that.vacuumSlow
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
slow(body, this.damageRadius)
|
|
||||||
slow([player], this.damageRadius)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "mine",
|
name: "mine",
|
||||||
@@ -3156,8 +3000,8 @@ const b = {
|
|||||||
});
|
});
|
||||||
// Matter.Body.setDensity(this, 0.001);
|
// Matter.Body.setDensity(this, 0.001);
|
||||||
}
|
}
|
||||||
if (mod.isRailNails && this.speed > 10) {
|
if (mod.fragments && this.speed > 10) {
|
||||||
b.targetedNail(this.position, (Math.min(40, this.speed) - 10) * 0.6) // 0.6 as many nails as the normal rail gun
|
b.targetedNail(this.position, mod.fragments * 10)
|
||||||
this.endCycle = 0 //triggers despawn
|
this.endCycle = 0 //triggers despawn
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -3243,8 +3087,8 @@ const b = {
|
|||||||
});
|
});
|
||||||
// Matter.Body.setDensity(this, 0.001);
|
// Matter.Body.setDensity(this, 0.001);
|
||||||
}
|
}
|
||||||
if (mod.isRailNails && this.speed > 10) {
|
if (mod.fragments && this.speed > 10) {
|
||||||
b.targetedNail(this.position, Math.min(40, this.speed) - 10)
|
b.targetedNail(this.position, mod.fragments * 16)
|
||||||
this.endCycle = 0 //triggers despawn
|
this.endCycle = 0 //triggers despawn
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
10
js/engine.js
10
js/engine.js
@@ -103,8 +103,12 @@ function collisionChecks(event) {
|
|||||||
) {
|
) {
|
||||||
mob[k].foundPlayer();
|
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
|
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 (mod.isRewindAvoidDeath && mech.energy > 0.66) { //CPT reversal runs in mech.damage, but it stops the rest of the collision code here too
|
||||||
|
mech.damage(dmg);
|
||||||
|
return
|
||||||
|
}
|
||||||
mech.damage(dmg);
|
mech.damage(dmg);
|
||||||
if (mod.isPiezo) mech.energy += mech.maxEnergy * 2;
|
if (mod.isPiezo) mech.energy += 200;
|
||||||
if (mod.isBayesian) powerUps.ejectMod()
|
if (mod.isBayesian) powerUps.ejectMod()
|
||||||
if (mob[k].onHit) mob[k].onHit(k);
|
if (mob[k].onHit) mob[k].onHit(k);
|
||||||
mech.immuneCycle = mech.cycle + mod.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
|
mech.immuneCycle = mech.cycle + mod.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
|
||||||
@@ -168,6 +172,10 @@ function collisionChecks(event) {
|
|||||||
const stunTime = dmg / Math.sqrt(obj.mass)
|
const stunTime = dmg / Math.sqrt(obj.mass)
|
||||||
if (stunTime > 0.5) mobs.statusStun(mob[k], 30 + 60 * Math.sqrt(stunTime))
|
if (stunTime > 0.5) mobs.statusStun(mob[k], 30 + 60 * Math.sqrt(stunTime))
|
||||||
if (mob[k].distanceToPlayer2() < 1000000 && !mech.isCloak) mob[k].foundPlayer();
|
if (mob[k].distanceToPlayer2() < 1000000 && !mech.isCloak) mob[k].foundPlayer();
|
||||||
|
if (mod.fragments && obj.speed > 10 && !obj.hasFragmented) {
|
||||||
|
obj.hasFragmented = true;
|
||||||
|
b.targetedNail(obj.position, mod.fragments * 4)
|
||||||
|
}
|
||||||
game.drawList.push({
|
game.drawList.push({
|
||||||
x: pairs[i].activeContacts[0].vertex.x,
|
x: pairs[i].activeContacts[0].vertex.x,
|
||||||
y: pairs[i].activeContacts[0].vertex.y,
|
y: pairs[i].activeContacts[0].vertex.y,
|
||||||
|
|||||||
@@ -277,7 +277,7 @@ const game = {
|
|||||||
if (b.inventory[0] === b.activeGun) {
|
if (b.inventory[0] === b.activeGun) {
|
||||||
let lessDamage = 1
|
let lessDamage = 1
|
||||||
for (let i = 0, len = b.inventory.length; i < len; i++) {
|
for (let i = 0, len = b.inventory.length; i < len; i++) {
|
||||||
lessDamage *= 0.87 // 1 - 0.15
|
lessDamage *= 0.87 // 1 - 0.13
|
||||||
}
|
}
|
||||||
document.getElementById("mod-entanglement").innerHTML = " " + ((1 - lessDamage) * 100).toFixed(0) + "%"
|
document.getElementById("mod-entanglement").innerHTML = " " + ((1 - lessDamage) * 100).toFixed(0) + "%"
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
12
js/level.js
12
js/level.js
@@ -20,7 +20,7 @@ const level = {
|
|||||||
// b.giveGuns("grenades")
|
// b.giveGuns("grenades")
|
||||||
// mod.isIncendiary = true
|
// mod.isIncendiary = true
|
||||||
// mod.is3Missiles = true
|
// mod.is3Missiles = true
|
||||||
// mod.giveMod("CPT reversal")
|
// mod.giveMod("neutron bomb")
|
||||||
// mod.giveMod("causality bombs")
|
// mod.giveMod("causality bombs")
|
||||||
|
|
||||||
level.intro(); //starting level
|
level.intro(); //starting level
|
||||||
@@ -236,6 +236,16 @@ const level = {
|
|||||||
height: 350,
|
height: 350,
|
||||||
color: "rgba(0,255,255,0.1)"
|
color: "rgba(0,255,255,0.1)"
|
||||||
});
|
});
|
||||||
|
powerUps.spawn(1675, -50, "ammo");
|
||||||
|
powerUps.spawn(3350, -75, "ammo");
|
||||||
|
powerUps.spawn(3925, -50, "ammo");
|
||||||
|
powerUps.spawn(4550, -75, "ammo");
|
||||||
|
powerUps.spawn(5225, -50, "ammo");
|
||||||
|
powerUps.spawn(5475, -350, "ammo");
|
||||||
|
powerUps.spawn(5625, -350, "ammo");
|
||||||
|
powerUps.spawn(5575, -425, "ammo");
|
||||||
|
powerUps.spawn(5550, -400, "ammo");
|
||||||
|
powerUps.spawn(5575, -425, "ammo");
|
||||||
|
|
||||||
spawn.mapRect(-1950, 0, 8200, 1800); //ground
|
spawn.mapRect(-1950, 0, 8200, 1800); //ground
|
||||||
spawn.mapRect(-1950, -1500, 1800, 1900); //left wall
|
spawn.mapRect(-1950, -1500, 1800, 1900); //left wall
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ const mobs = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
statusDoT(who, tickDamage, cycles = 180) {
|
statusDoT(who, tickDamage, cycles = 180) {
|
||||||
if (!who.isShielded && !mech.isBodiesAsleep) {
|
if (!who.isShielded && !mech.isBodiesAsleep && who.alive) {
|
||||||
who.status.push({
|
who.status.push({
|
||||||
effect() {
|
effect() {
|
||||||
if ((game.cycle - this.startCycle) % 30 === 0) {
|
if ((game.cycle - this.startCycle) % 30 === 0) {
|
||||||
|
|||||||
71
js/mods.js
71
js/mods.js
@@ -372,6 +372,22 @@ const mod = {
|
|||||||
mod.throwChargeRate = 1
|
mod.throwChargeRate = 1
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "fragmentation",
|
||||||
|
description: "detonation or collision ejects <strong>nails</strong><br><em>rail gun, grenades, shotgun slugs, blocks</em>",
|
||||||
|
maxCount: 9,
|
||||||
|
count: 0,
|
||||||
|
allowed() {
|
||||||
|
return (mod.haveGunCheck("grenades") && !mod.isNeutronBomb) || mod.haveGunCheck("rail gun") || (mod.haveGunCheck("shotgun") && mod.isSlugShot) || mod.throwChargeRate > 1
|
||||||
|
},
|
||||||
|
requires: "grenades, rail gun, shotgun slugs, or mass driver",
|
||||||
|
effect() {
|
||||||
|
mod.fragments++
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
mod.fragments = 0
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "ammonium nitrate",
|
name: "ammonium nitrate",
|
||||||
description: "increase <strong class='color-e'>explosive</strong> <strong class='color-d'>damage</strong> by <strong>20%</strong><br>increase <strong class='color-e'>explosive</strong> <strong>radius</strong> by <strong>20%</strong>",
|
description: "increase <strong class='color-e'>explosive</strong> <strong class='color-d'>damage</strong> by <strong>20%</strong><br>increase <strong class='color-e'>explosive</strong> <strong>radius</strong> by <strong>20%</strong>",
|
||||||
@@ -1044,9 +1060,9 @@ const mod = {
|
|||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() { //&& (mech.fieldUpgrades[mech.fieldMode].name !== "nano-scale manufacturing" || mech.maxEnergy > 1)
|
allowed() { //&& (mech.fieldUpgrades[mech.fieldMode].name !== "nano-scale manufacturing" || mech.maxEnergy > 1)
|
||||||
return mech.maxEnergy > 0.99 && mech.fieldUpgrades[mech.fieldMode].name !== "standing wave harmonics" && !mod.isEnergyHealth && !mod.isEnergyLoss && !mod.isPiezo
|
return mech.maxEnergy > 0.99 && mech.fieldUpgrades[mech.fieldMode].name !== "standing wave harmonics" && !mod.isEnergyHealth
|
||||||
},
|
},
|
||||||
requires: "not nano-scale, mass-energy, standing wave, acute stress, piezoelectricity",
|
requires: "standing wave, mass-energy, piezoelectricity, max energy reduction",
|
||||||
effect() {
|
effect() {
|
||||||
mod.isRewindAvoidDeath = true;
|
mod.isRewindAvoidDeath = true;
|
||||||
},
|
},
|
||||||
@@ -1092,12 +1108,12 @@ const mod = {
|
|||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
return !mod.isEnergyHealth && !mod.isRewindAvoidDeath
|
return !mod.isEnergyHealth
|
||||||
},
|
},
|
||||||
requires: "not mass-energy equivalence, CPT reversal",
|
requires: "not mass-energy equivalence",
|
||||||
effect() {
|
effect() {
|
||||||
mod.isPiezo = true;
|
mod.isPiezo = true;
|
||||||
mech.energy += mech.maxEnergy * 2;
|
mech.energy += 200;
|
||||||
},
|
},
|
||||||
remove() {
|
remove() {
|
||||||
mod.isPiezo = false;
|
mod.isPiezo = false;
|
||||||
@@ -1893,7 +1909,7 @@ const mod = {
|
|||||||
//**************************************************
|
//**************************************************
|
||||||
{
|
{
|
||||||
name: "incendiary ammunition",
|
name: "incendiary ammunition",
|
||||||
description: "<strong>bullets</strong> are loaded with <strong class='color-e'>explosives</strong><br><span style = 'font-size: 90%'>nail gun, shotgun, super balls, drones</span>",
|
description: "<strong>bullets</strong> are loaded with <strong class='color-e'>explosives</strong><br><em style = 'font-size: 90%'>nail gun, shotgun, super balls, drones</em>",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
@@ -1909,7 +1925,7 @@ const mod = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Lorentzian topology",
|
name: "Lorentzian topology",
|
||||||
description: "<strong>bullets</strong> last <strong>30% longer</strong><br><span style = 'font-size: 83%'>drones, spores, missiles, foam, wave, ice IX, neutron</span>",
|
description: "<strong>bullets</strong> last <strong>30% longer</strong><br><em style = 'font-size: 83%'>drones, spores, missiles, foam, wave, ice IX, neutron</em>",
|
||||||
maxCount: 3,
|
maxCount: 3,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
@@ -2364,22 +2380,6 @@ const mod = {
|
|||||||
mod.is3Missiles = false;
|
mod.is3Missiles = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "fragmentation grenade",
|
|
||||||
description: "<strong>grenades</strong> are loaded with <strong>5</strong> nails<br>on detonation <strong>nails</strong> are ejected towards mobs",
|
|
||||||
maxCount: 9,
|
|
||||||
count: 0,
|
|
||||||
allowed() {
|
|
||||||
return mod.haveGunCheck("grenades") && !mod.isNeutronBomb
|
|
||||||
},
|
|
||||||
requires: "grenades, not neutron bomb",
|
|
||||||
effect() {
|
|
||||||
mod.grenadeFragments += 5
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
mod.grenadeFragments = 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "rocket-propelled grenade",
|
name: "rocket-propelled grenade",
|
||||||
description: "<strong>grenades</strong> rapidly <strong>accelerate</strong> forward<br>map <strong>collisions</strong> trigger an <strong class='color-e'>explosion</strong>",
|
description: "<strong>grenades</strong> rapidly <strong>accelerate</strong> forward<br>map <strong>collisions</strong> trigger an <strong class='color-e'>explosion</strong>",
|
||||||
@@ -2422,7 +2422,7 @@ const mod = {
|
|||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
return mod.haveGunCheck("grenades") && !mod.isRPG && !mod.grenadeFragments && !mod.isVacuumBomb
|
return mod.haveGunCheck("grenades") && !mod.isRPG && !mod.fragments && !mod.isVacuumBomb
|
||||||
},
|
},
|
||||||
requires: "grenades, not rocket-propelled or fragmentation",
|
requires: "grenades, not rocket-propelled or fragmentation",
|
||||||
effect() {
|
effect() {
|
||||||
@@ -2504,7 +2504,7 @@ const mod = {
|
|||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
return mod.isMineDrop + mod.nailBotCount + mod.grenadeFragments + mod.nailsDeathMob / 2 + (mod.haveGunCheck("mine") + mod.isRailNails + mod.isNailShot + (mod.haveGunCheck("nail gun") && !mod.isIncendiary)) * 2 > 1
|
return mod.isMineDrop + mod.nailBotCount + mod.fragments + mod.nailsDeathMob / 2 + (mod.haveGunCheck("mine") + mod.isNailShot + (mod.haveGunCheck("nail gun") && !mod.isIncendiary)) * 2 > 1
|
||||||
},
|
},
|
||||||
requires: "nails",
|
requires: "nails",
|
||||||
effect() {
|
effect() {
|
||||||
@@ -2520,7 +2520,7 @@ const mod = {
|
|||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
return mod.isMineDrop + mod.nailBotCount + mod.grenadeFragments + mod.nailsDeathMob / 2 + (mod.haveGunCheck("mine") + mod.isRailNails + mod.isNailShot + (mod.haveGunCheck("nail gun") && !mod.isIncendiary)) * 2 > 1
|
return mod.isMineDrop + mod.nailBotCount + mod.fragments + mod.nailsDeathMob / 2 + (mod.haveGunCheck("mine") + mod.isNailShot + (mod.haveGunCheck("nail gun") && !mod.isIncendiary)) * 2 > 1
|
||||||
},
|
},
|
||||||
requires: "nails",
|
requires: "nails",
|
||||||
effect() {
|
effect() {
|
||||||
@@ -2805,22 +2805,6 @@ const mod = {
|
|||||||
mod.isCapacitor = false;
|
mod.isCapacitor = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
name: "fragmenting projectiles",
|
|
||||||
description: "<strong>rail gun</strong> rods fragment into <strong>nails</strong><br>after hitting mobs at high speeds",
|
|
||||||
maxCount: 1,
|
|
||||||
count: 0,
|
|
||||||
allowed() {
|
|
||||||
return mod.haveGunCheck("rail gun")
|
|
||||||
},
|
|
||||||
requires: "rail gun",
|
|
||||||
effect() {
|
|
||||||
mod.isRailNails = true;
|
|
||||||
},
|
|
||||||
remove() {
|
|
||||||
mod.isRailNails = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: "laser diodes",
|
name: "laser diodes",
|
||||||
description: "<strong>lasers</strong> drain <strong>37%</strong> less <strong class='color-f'>energy</strong><br><em>effects laser-gun and laser-bot</em>",
|
description: "<strong>lasers</strong> drain <strong>37%</strong> less <strong class='color-f'>energy</strong><br><em>effects laser-gun and laser-bot</em>",
|
||||||
@@ -3575,7 +3559,6 @@ const mod = {
|
|||||||
isFlechetteMultiShot: null,
|
isFlechetteMultiShot: null,
|
||||||
isMineAmmoBack: null,
|
isMineAmmoBack: null,
|
||||||
isPlasmaRange: null,
|
isPlasmaRange: null,
|
||||||
isRailNails: null,
|
|
||||||
isFreezeMobs: null,
|
isFreezeMobs: null,
|
||||||
recursiveMissiles: null,
|
recursiveMissiles: null,
|
||||||
isIceCrystals: null,
|
isIceCrystals: null,
|
||||||
@@ -3587,7 +3570,7 @@ const mod = {
|
|||||||
energyRegen: null,
|
energyRegen: null,
|
||||||
isVacuumBomb: null,
|
isVacuumBomb: null,
|
||||||
renormalization: null,
|
renormalization: null,
|
||||||
grenadeFragments: null,
|
fragments: null,
|
||||||
isEnergyDamage: null,
|
isEnergyDamage: null,
|
||||||
isBotSpawner: null,
|
isBotSpawner: null,
|
||||||
waveHelix: null,
|
waveHelix: null,
|
||||||
|
|||||||
66
js/player.js
66
js/player.js
@@ -485,11 +485,36 @@ const mech = {
|
|||||||
if (mod.energyRegen === 0) dmg *= 0.4 //0.22 + 0.78 * mech.energy //77% damage reduction at zero energy
|
if (mod.energyRegen === 0) dmg *= 0.4 //0.22 + 0.78 * mech.energy //77% damage reduction at zero energy
|
||||||
if (mod.isTurret && mech.crouch) dmg *= 0.5;
|
if (mod.isTurret && mech.crouch) dmg *= 0.5;
|
||||||
if (mod.isEntanglement && b.inventory[0] === b.activeGun) {
|
if (mod.isEntanglement && b.inventory[0] === b.activeGun) {
|
||||||
for (let i = 0, len = b.inventory.length; i < len; i++) dmg *= 0.85 // 1 - 0.15
|
for (let i = 0, len = b.inventory.length; i < len; i++) dmg *= 0.87 // 1 - 0.15
|
||||||
}
|
}
|
||||||
return dmg
|
return dmg
|
||||||
},
|
},
|
||||||
rewind(steps, isDrain = true) {
|
rewind(steps) {
|
||||||
|
if (mod.isRewindGrenade) {
|
||||||
|
for (let i = 1, len = Math.floor(1.5 + steps / 40); i < len; i++) {
|
||||||
|
b.grenade(Vector.add(mech.pos, { x: 10 * (Math.random() - 0.5), y: 10 * (Math.random() - 0.5) }), -i * Math.PI / len) //fire different angles for each grenade
|
||||||
|
const who = bullet[bullet.length - 1]
|
||||||
|
if (mod.isVacuumBomb) {
|
||||||
|
Matter.Body.setVelocity(who, {
|
||||||
|
x: who.velocity.x * 0.5,
|
||||||
|
y: who.velocity.y * 0.5
|
||||||
|
});
|
||||||
|
} else if (mod.isRPG) {
|
||||||
|
who.endCycle = (who.endCycle - game.cycle) * 0.2 + game.cycle
|
||||||
|
} else if (mod.isNeutronBomb) {
|
||||||
|
Matter.Body.setVelocity(who, {
|
||||||
|
x: who.velocity.x * 0.3,
|
||||||
|
y: who.velocity.y * 0.3
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Matter.Body.setVelocity(who, {
|
||||||
|
x: who.velocity.x * 0.5,
|
||||||
|
y: who.velocity.y * 0.5
|
||||||
|
});
|
||||||
|
who.endCycle = (who.endCycle - game.cycle) * 0.5 + game.cycle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
let history = mech.history[(mech.cycle - steps) % 300]
|
let history = mech.history[(mech.cycle - steps) % 300]
|
||||||
Matter.Body.setPosition(player, history.position);
|
Matter.Body.setPosition(player, history.position);
|
||||||
Matter.Body.setVelocity(player, { x: history.velocity.x, y: history.velocity.y });
|
Matter.Body.setVelocity(player, { x: history.velocity.x, y: history.velocity.y });
|
||||||
@@ -506,9 +531,7 @@ const mech = {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isDrain) {
|
mech.energy = Math.max(mech.energy - steps / 136, 0.01)
|
||||||
mech.energy = Math.max(mech.energy - steps / 136, 0.01)
|
|
||||||
}
|
|
||||||
mech.immuneCycle = mech.cycle + 30; //player is immune to collision damage for 30 cycles
|
mech.immuneCycle = mech.cycle + 30; //player is immune to collision damage for 30 cycles
|
||||||
|
|
||||||
let isDrawPlayer = true
|
let isDrawPlayer = true
|
||||||
@@ -539,13 +562,13 @@ const mech = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (mech.defaultFPSCycle < mech.cycle) requestAnimationFrame(shortPause);
|
if (mech.defaultFPSCycle < mech.cycle) requestAnimationFrame(shortPause);
|
||||||
game.fpsCap = (isDrain ? 3 : 5) //1 is longest pause, 4 is standard
|
game.fpsCap = 3 //1 is longest pause, 4 is standard
|
||||||
game.fpsInterval = 1000 / game.fpsCap;
|
game.fpsInterval = 1000 / game.fpsCap;
|
||||||
mech.defaultFPSCycle = mech.cycle
|
mech.defaultFPSCycle = mech.cycle
|
||||||
if (mod.isRewindBot) {
|
if (mod.isRewindBot) {
|
||||||
const len = (isDrain ? steps * 0.042 : 2) * mod.isRewindBot
|
const len = steps * 0.042 * mod.isRewindBot
|
||||||
for (let i = 0; i < len; i++) {
|
for (let i = 0; i < len; i++) {
|
||||||
where = mech.history[(mech.cycle - i * 40) % 300].position //spread out spawn locations along past history
|
const where = mech.history[Math.abs(mech.cycle - i * 40) % 300].position //spread out spawn locations along past history
|
||||||
b.randomBot({
|
b.randomBot({
|
||||||
x: where.x + 100 * (Math.random() - 0.5),
|
x: where.x + 100 * (Math.random() - 0.5),
|
||||||
y: where.y + 100 * (Math.random() - 0.5)
|
y: where.y + 100 * (Math.random() - 0.5)
|
||||||
@@ -556,32 +579,7 @@ const mech = {
|
|||||||
},
|
},
|
||||||
damage(dmg) {
|
damage(dmg) {
|
||||||
if (mod.isRewindAvoidDeath && mech.energy > 0.66) {
|
if (mod.isRewindAvoidDeath && mech.energy > 0.66) {
|
||||||
const steps = Math.floor(Math.min(299, 137 * mech.energy)) //go back 2 seconds at 100% energy
|
const steps = Math.floor(Math.min(299, 137 * mech.energy))
|
||||||
if (mod.isRewindGrenade) {
|
|
||||||
for (let i = 1, len = Math.floor(3 + steps / 60); i < len; i++) {
|
|
||||||
b.grenade(Vector.add(mech.pos, { x: 10 * (Math.random() - 0.5), y: 10 * (Math.random() - 0.5) }), -i * Math.PI / len) //fire different angles for each grenade
|
|
||||||
const who = bullet[bullet.length - 1]
|
|
||||||
if (mod.isVacuumBomb) {
|
|
||||||
Matter.Body.setVelocity(who, {
|
|
||||||
x: who.velocity.x * 0.5,
|
|
||||||
y: who.velocity.y * 0.5
|
|
||||||
});
|
|
||||||
} else if (mod.isRPG) {
|
|
||||||
who.endCycle = (who.endCycle - game.cycle) * 0.2 + game.cycle
|
|
||||||
} else if (mod.isNeutronBomb) {
|
|
||||||
Matter.Body.setVelocity(who, {
|
|
||||||
x: who.velocity.x * 0.3,
|
|
||||||
y: who.velocity.y * 0.3
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
Matter.Body.setVelocity(who, {
|
|
||||||
x: who.velocity.x * 0.5,
|
|
||||||
y: who.velocity.y * 0.5
|
|
||||||
});
|
|
||||||
who.endCycle = (who.endCycle - game.cycle) * 0.5 + game.cycle
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mech.rewind(steps)
|
mech.rewind(steps)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
15
todo.txt
15
todo.txt
@@ -1,12 +1,15 @@
|
|||||||
******************************************************** NEXT PATCH ********************************************************
|
******************************************************** NEXT PATCH ********************************************************
|
||||||
|
|
||||||
mod: causality bots - before you rewind, build bots that protect you for for 7 seconds
|
so many bug fixes around CPT
|
||||||
|
mod: fragments - blocks, grenades, rail gun, shotgun slugs can all eject nails on collisions, or detonation
|
||||||
mod grenade: causality bombs - before you rewind, drop some grenades
|
|
||||||
|
|
||||||
|
|
||||||
******************************************************** BUGS ********************************************************
|
******************************************************** BUGS ********************************************************
|
||||||
|
|
||||||
|
possible bug with neutron rewind
|
||||||
|
status doesn't apply correctly for spawned neutron bombs that are stuck to a shield
|
||||||
|
also saw neutron bombs bounce off shield, for normal bullets
|
||||||
|
test this more
|
||||||
|
|
||||||
mod and mob are too similar
|
mod and mob are too similar
|
||||||
|
|
||||||
(always) make it so that when you are immune to harm you can either jump on mobs or you pass through them
|
(always) make it so that when you are immune to harm you can either jump on mobs or you pass through them
|
||||||
@@ -31,7 +34,7 @@ mod and mob are too similar
|
|||||||
|
|
||||||
******************************************************** TODO ********************************************************
|
******************************************************** TODO ********************************************************
|
||||||
|
|
||||||
combine fragmentation grenades that that mod that makes railguns fragment into nails into one single mod, and let it apply to shotgun slug
|
combine fragmentation grenades, railguns fragment and apply to shotgun slug
|
||||||
|
|
||||||
mod: power up magnetism - power ups drift towards player
|
mod: power up magnetism - power ups drift towards player
|
||||||
where would this code go?
|
where would this code go?
|
||||||
@@ -39,7 +42,7 @@ mod: power up magnetism - power ups drift towards player
|
|||||||
super balls start at 3, not 4
|
super balls start at 3, not 4
|
||||||
have to balance damage
|
have to balance damage
|
||||||
|
|
||||||
RPG might need a buff
|
RPG might need a buff, now that it disables the other cool grenade mods
|
||||||
|
|
||||||
retrocausality bomb should fire 3 grenades at once that spread out a small bit before they explode?
|
retrocausality bomb should fire 3 grenades at once that spread out a small bit before they explode?
|
||||||
this means you'd have to make grenades a method.
|
this means you'd have to make grenades a method.
|
||||||
|
|||||||
Reference in New Issue
Block a user