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:
landgreen
2020-12-10 06:55:00 -08:00
parent 46fbb90d8d
commit 75f6f268eb
8 changed files with 106 additions and 260 deletions

View File

@@ -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
} }
}, },

View File

@@ -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); mech.damage(dmg);
if (mod.isPiezo) mech.energy += mech.maxEnergy * 2; return
}
mech.damage(dmg);
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,

View File

@@ -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 {

View File

@@ -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

View File

@@ -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) {

View File

@@ -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,

View File

@@ -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
} }

View File

@@ -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.