mod: logistics

added mods to spawn a gun, a field, and rerolls
added mod that gives max health for leftover power ups
   this mod has some interesting interactions with other mods
mod annihilation now uses 20% of base energy and doesn't trigger damage immunity
mod Hawking radiation removed
mod negative temperature: freezed mobs in range of negative mass field, but drain energy
mod: logistics
  ammo power ups are added to your current gun
  spawn 4 ammo immediately
This commit is contained in:
landgreen
2020-06-08 08:55:53 -07:00
parent cea1bcc7a3
commit d9d07b4f5d
9 changed files with 278 additions and 176 deletions

View File

@@ -22,15 +22,14 @@ const b = {
} }
} else { } else {
if (mod.isAmmoFromHealth) { if (mod.isAmmoFromHealth) {
if (mech.health > 0.05) { if (mech.health > 2 * mod.isAmmoFromHealth * mech.maxHealth) {
mech.damage(Math.max(0.01, mod.isAmmoFromHealth * mech.health)); mech.damage(mod.isAmmoFromHealth * mech.maxHealth);
powerUps.spawn(mech.pos.x, mech.pos.y, "ammo"); powerUps.spawn(mech.pos.x, mech.pos.y, "ammo");
if (Math.random() < mod.bayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "ammo"); if (Math.random() < mod.bayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "ammo");
} 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);
} }
} else { } else {
game.replaceTextLog = true; game.replaceTextLog = true;
game.makeTextLog("<div style='font-size:140%;'>NO AMMO</div> <p style='font-size:90%;'><strong>Q</strong>, <strong>E</strong>, and <strong>mouse wheel</strong> change weapons</p>", 200); game.makeTextLog("<div style='font-size:140%;'>NO AMMO</div> <p style='font-size:90%;'><strong>Q</strong>, <strong>E</strong>, and <strong>mouse wheel</strong> change weapons</p>", 200);
@@ -496,15 +495,11 @@ const b = {
this.endCycle = 0; //bullet ends cycle after doing damage this.endCycle = 0; //bullet ends cycle after doing damage
}, },
onEnd() { onEnd() {
if (mod.isMutualism && this.isMutualismActive) { if (mod.isMutualism && this.isMutualismActive && !mod.isEnergyHealth) {
if (mod.isEnergyHealth) { mech.health += 0.01
mech.energy += 0.01; if (mech.health > mech.maxHealth) mech.health = mech.maxHealth;
} else { mod.onHealthChange();
mech.health += 0.01 mech.displayHealth();
if (mech.health > mech.maxHealth) mech.health = mech.maxHealth;
mod.onHealthChange();
mech.displayHealth();
}
} }
}, },
do() { do() {
@@ -551,18 +546,11 @@ const b = {
}); });
World.add(engine.world, bullet[bIndex]); //add bullet to world World.add(engine.world, bullet[bIndex]); //add bullet to world
if (mod.isMutualism) { if (mod.isMutualism && mech.health > 0.02) {
if (mod.isEnergyHealth) { mech.health -= 0.01
if (mech.energy > 0.02) { mod.onHealthChange();
mech.energy -= 0.01; //energy takes an extra 25% damage for balancing purposes mech.displayHealth();
bullet[bIndex].isMutualismActive = true bullet[bIndex].isMutualismActive = true
}
} else if (mech.health > 0.02) {
mech.health -= 0.01
mod.onHealthChange();
mech.displayHealth();
bullet[bIndex].isMutualismActive = true
}
} }
}, },
iceIX(speed = 0, spread = 2 * Math.PI) { iceIX(speed = 0, spread = 2 * Math.PI) {
@@ -772,7 +760,12 @@ const b = {
onDmg(who) { onDmg(who) {
if (!this.target && who.alive) { if (!this.target && who.alive) {
this.target = who; this.target = who;
if (Matter.Query.collides(this, [who]).length > 0) { if (who.radius < 20) {
this.targetRelativePosition = {
x: 0,
y: 0
} //find relative position vector for zero mob rotation
} else if (Matter.Query.collides(this, [who]).length > 0) {
const normal = Matter.Query.collides(this, [who])[0].normal const normal = Matter.Query.collides(this, [who])[0].normal
this.targetRelativePosition = Vector.rotate(Vector.sub(Vector.sub(this.position, who.position), Vector.mult(normal, -this.radius)), -who.angle) //find relative position vector for zero mob rotation this.targetRelativePosition = Vector.rotate(Vector.sub(Vector.sub(this.position, who.position), Vector.mult(normal, -this.radius)), -who.angle) //find relative position vector for zero mob rotation
} else { } else {
@@ -843,6 +836,8 @@ const b = {
Matter.Body.setPosition(this, Vector.add(Vector.add(rotate, this.target.velocity), this.target.position)) Matter.Body.setPosition(this, Vector.add(Vector.add(rotate, this.target.velocity), this.target.position))
} }
Matter.Body.setVelocity(this.target, Vector.mult(this.target.velocity, 0.9)) Matter.Body.setVelocity(this.target, Vector.mult(this.target.velocity, 0.9))
Matter.Body.setAngularVelocity(this.target, this.target.angularVelocity * 0.9);
// Matter.Body.setAngularVelocity(this.target, this.target.angularVelocity * 0.9) // Matter.Body.setAngularVelocity(this.target, this.target.angularVelocity * 0.9)
if (this.target.isShielded) { if (this.target.isShielded) {
this.target.damage(b.dmgScale * 0.005, true); //shield damage bypass this.target.damage(b.dmgScale * 0.005, true); //shield damage bypass
@@ -1092,8 +1087,8 @@ const b = {
//randomize position relative to player //randomize position relative to player
if (Math.random() < 0.15) { if (Math.random() < 0.15) {
this.offPlayer = { this.offPlayer = {
x: 100 * (Math.random() - 0.5), x: 120 * (Math.random() - 0.5),
y: 90 * (Math.random() - 0.5), y: 120 * (Math.random() - 0.5) - 20,
} }
} }
} }
@@ -1182,7 +1177,7 @@ const b = {
}, },
guns: [{ guns: [{
name: "minigun", name: "minigun",
description: "<strong>rapidly</strong> fire a stream of small <strong>bullets</strong>", description: "<strong>rapidly</strong> fire a stream of small <strong>bullets</strong><br>fire <strong>delay</strong> decreases as you shoot",
ammo: 0, ammo: 0,
ammoPack: 75, ammoPack: 75,
defaultAmmoPack: 75, defaultAmmoPack: 75,
@@ -1211,7 +1206,7 @@ const b = {
bullet[me].onDmg = function (who) { bullet[me].onDmg = function (who) {
mobs.statusSlow(who, 30) mobs.statusSlow(who, 30)
}; };
mech.energy -= mech.fieldRegen + 0.007 mech.energy -= mech.fieldRegen + 0.0075
if (mech.energy < 0.02) { if (mech.energy < 0.02) {
mech.fireCDcycle = mech.cycle + 60; // cool down mech.fireCDcycle = mech.cycle + 60; // cool down
} }
@@ -1219,7 +1214,6 @@ const b = {
bullet[me].do = function () { bullet[me].do = function () {
this.force.y += this.mass * 0.0003; this.force.y += this.mass * 0.0003;
}; };
} }
}, },
{ {
@@ -1353,7 +1347,7 @@ const b = {
count: 0, //used to track how many shots are in a volley before a big CD count: 0, //used to track how many shots are in a volley before a big CD
lastFireCycle: 0, //use to remember how longs its been since last fire, used to reset count lastFireCycle: 0, //use to remember how longs its been since last fire, used to reset count
fire() { fire() {
function makeFlechette(angle = mech.angle) { function makeFlechette(angle = mech.angle + 0.02 * (Math.random() - 0.5)) {
const me = bullet.length; 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, 1.4, b.fireAttributes(angle)); bullet[me] = Bodies.rectangle(mech.pos.x + 40 * Math.cos(mech.angle), mech.pos.y + 40 * Math.sin(mech.angle), 45, 1.4, b.fireAttributes(angle));
bullet[me].collisionFilter.mask = cat.body; //cat.mobShield | //cat.map | cat.body | bullet[me].collisionFilter.mask = cat.body; //cat.mobShield | //cat.map | cat.body |
@@ -1914,7 +1908,6 @@ const b = {
} }
} }
const mobCollisions = Matter.Query.collides(this, mob) const mobCollisions = Matter.Query.collides(this, mob)
if (mobCollisions.length) { if (mobCollisions.length) {
onCollide(this) onCollide(this)
@@ -2320,7 +2313,7 @@ const b = {
mech.fireCDcycle = Infinity //can't fire until mouse is released mech.fireCDcycle = Infinity //can't fire until mouse is released
const lastCharge = this.charge const lastCharge = this.charge
let chargeRate = (mech.crouch) ? 0.975 : 0.987 let chargeRate = (mech.crouch) ? 0.975 : 0.987
chargeRate *= Math.pow(b.fireCD, 0.04) chargeRate *= Math.pow(b.fireCD, 0.03)
this.charge = this.charge * chargeRate + (1 - chargeRate) // this.charge converges to 1 this.charge = this.charge * chargeRate + (1 - chargeRate) // this.charge converges to 1
mech.energy -= (this.charge - lastCharge) * 0.28 //energy drain is proportional to charge gained, but doesn't stop normal mech.fieldRegen mech.energy -= (this.charge - lastCharge) * 0.28 //energy drain is proportional to charge gained, but doesn't stop normal mech.fieldRegen
@@ -2679,7 +2672,7 @@ const b = {
const energy = 0.3 * Math.min(mech.energy, 1.75) const energy = 0.3 * Math.min(mech.energy, 1.75)
mech.energy -= energy * mod.isLaserDiode mech.energy -= energy * mod.isLaserDiode
if (best.who) b.explosion(path[1], 1000 * energy, true) if (best.who) b.explosion(path[1], 1000 * energy, true)
mech.fireCDcycle = mech.cycle + Math.floor(60 * b.fireCD); // cool down mech.fireCDcycle = mech.cycle + Math.floor(50 * b.fireCD); // cool down
if (mod.isPulseStun) { if (mod.isPulseStun) {
const range = 100 + 2000 * energy const range = 100 + 2000 * energy

View File

@@ -175,7 +175,9 @@ function collisionChecks(event) {
y: mob[k].velocity.y - 8 * Math.sin(angle) y: mob[k].velocity.y - 8 * Math.sin(angle)
}); });
if (mod.isAnnihilation && !mob[k].shield && !mob[k].isShielded) { if (mod.isAnnihilation && !mob[k].shield && !mob[k].isShielded && mech.energy > 0.2) {
mech.energy -= 0.2
mech.immuneCycle = 0; //player doesn't go immune to collision damage
mob[k].death(); mob[k].death();
game.drawList.push({ game.drawList.push({
//add dmg to draw queue //add dmg to draw queue
@@ -207,6 +209,7 @@ function collisionChecks(event) {
// console.log(obj.dmg / (0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity)))) // console.log(obj.dmg / (0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity))))
if (mod.isCrit && !mob[k].seePlayer.recall && !mob[k].shield) dmg *= 5 if (mod.isCrit && !mob[k].seePlayer.recall && !mob[k].shield) dmg *= 5
mob[k].foundPlayer(); mob[k].foundPlayer();
console.log(dmg)
mob[k].damage(dmg); mob[k].damage(dmg);
// console.log(dmg) // console.log(dmg)
obj.onDmg(mob[k]); //some bullets do actions when they hits things, like despawn obj.onDmg(mob[k]); //some bullets do actions when they hits things, like despawn

View File

@@ -499,6 +499,7 @@ const game = {
mod.setupAllMods(); //sets mods to default values mod.setupAllMods(); //sets mods to default values
b.setFireCD(); b.setFireCD();
game.updateModHUD(); game.updateModHUD();
powerUps.totalPowerUps = 0;
powerUps.reroll.rerolls = 0; powerUps.reroll.rerolls = 0;
mech.maxHealth = 1 mech.maxHealth = 1
mech.maxEnergy = 1 mech.maxEnergy = 1
@@ -645,21 +646,19 @@ const game = {
} }
} }
if (mod.isMutualism) { if (mod.isMutualism && !mod.isEnergyHealth) {
for (let i = 0; i < bullet.length; i++) { for (let i = 0; i < bullet.length; i++) {
if (bullet[i].isMutualismActive) { if (bullet[i].isMutualismActive) {
if (mod.isEnergyHealth) { mech.health += 0.01
mech.energy += 0.01; if (mech.health > mech.maxHealth) mech.health = mech.maxHealth;
} else { mod.onHealthChange();
mech.health += 0.01 mech.displayHealth();
if (mech.health > mech.maxHealth) mech.health = mech.maxHealth;
mod.onHealthChange();
mech.displayHealth();
}
} }
} }
} }
powerUps.totalPowerUps = powerUp.length
//if player is holding something this remembers it before it gets deleted //if player is holding something this remembers it before it gets deleted
let holdTarget; let holdTarget;
if (mech.holdingTarget) { if (mech.holdingTarget) {

View File

@@ -17,12 +17,12 @@ const level = {
// game.enableConstructMode() //used to build maps in testing mode // game.enableConstructMode() //used to build maps in testing mode
// level.difficultyIncrease(9) // level.difficultyIncrease(9)
// mech.setField("time dilation field") // mech.setField("time dilation field")
// mod.giveMod("timelike world line"); // mod.giveMod("logistics");
// mod.giveMod("Lorentz transformation"); // mod.giveMod("negative temperature");
b.giveGuns("minigun") // b.giveGuns("flechettes")
// b.giveGuns("spores") // b.giveGuns("spores")
// mech.setField("pilot wave") // mech.setField("negative mass field")
// mech.setField("phase decoherence field") // mech.setField("phase decoherence field")
level.intro(); //starting level level.intro(); //starting level
@@ -56,6 +56,11 @@ const level = {
for (let i = 0; i < mod.foamBotCount; i++) { for (let i = 0; i < mod.foamBotCount; i++) {
b.foamBot() b.foamBot()
} }
if (mod.isArmorFromPowerUps) {
// for (let i = 0; i < powerUps.totalPowerUps; i++) {}
mech.maxHealth += 0.03 * powerUps.totalPowerUps
game.makeTextLog("<span style='font-size:115%;'> max health increased by " + (0.05 * powerUps.totalPowerUps * 100).toFixed(0) + "%</span>", 300)
}
}, },
isBuildRun: false, isBuildRun: false,
difficultyIncrease(num = 1) { difficultyIncrease(num = 1) {
@@ -188,7 +193,7 @@ const level = {
// spawn.launcherBoss(1200, -500) // spawn.launcherBoss(1200, -500)
// spawn.laserTargetingBoss(1600, -400) // spawn.laserTargetingBoss(1600, -400)
// spawn.spawner(1600, -500) // spawn.spawner(1600, -500)
spawn.sniper(1700, -120) spawn.sniper(1700, -120, 50)
// spawn.sniper(1600, -120) // spawn.sniper(1600, -120)
// spawn.sniper(1800, -120) // spawn.sniper(1800, -120)
// spawn.cellBossCulture(1600, -500) // spawn.cellBossCulture(1600, -500)

View File

@@ -76,7 +76,7 @@ const mod = {
if (mod.isEnergyLoss) dmg *= 1.33; if (mod.isEnergyLoss) dmg *= 1.33;
if (mod.isRest && player.speed < 1) dmg *= 1.20; if (mod.isRest && player.speed < 1) dmg *= 1.20;
if (mod.isEnergyDamage) dmg *= 1 + mech.energy / 5.5; if (mod.isEnergyDamage) dmg *= 1 + mech.energy / 5.5;
if (mod.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.007 if (mod.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.006
return dmg * mod.slowFire return dmg * mod.slowFire
}, },
onHealthChange() { //used with acid mod onHealthChange() { //used with acid mod
@@ -111,42 +111,6 @@ const mod = {
}, },
mods: [{ mods: [{
name: "heal",
description: "spawn <strong>6</strong> <strong class='color-h'>heal</strong> power ups",
maxCount: 9,
count: 0,
isNonRefundable: true,
allowed() {
return true
},
requires: "",
effect() {
for (let i = 0; i < 6; i++) {
powerUps.spawn(mech.pos.x, mech.pos.y, "heal");
if (Math.random() < mod.bayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "heal");
}
},
remove() {}
},
{
name: "ammo",
description: "spawn <strong>6 ammo</strong> power ups",
maxCount: 9,
count: 0,
isNonRefundable: true,
allowed() {
return true
},
requires: "",
effect() {
for (let i = 0; i < 6; i++) {
powerUps.spawn(mech.pos.x, mech.pos.y, "ammo");
if (Math.random() < mod.bayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "ammo");
}
},
remove() {}
},
{
name: "capacitor", name: "capacitor",
// nameInfo: "<span id='mod-capacitor'></span>", // nameInfo: "<span id='mod-capacitor'></span>",
description: "increase <strong class='color-d'>damage</strong> based on stored <strong class='color-f'>energy</strong><br><strong>+1%</strong> <strong class='color-d'>damage</strong> for every <strong>5.5%</strong> <strong class='color-f'>energy</strong>", description: "increase <strong class='color-d'>damage</strong> based on stored <strong class='color-f'>energy</strong><br><strong>+1%</strong> <strong class='color-d'>damage</strong> for every <strong>5.5%</strong> <strong class='color-f'>energy</strong>",
@@ -296,22 +260,6 @@ const mod = {
b.setFireCD(); b.setFireCD();
} }
}, },
{
name: "desublimated ammunition",
description: "use <strong>50%</strong> less <strong>ammo</strong> when <strong>crouching</strong>",
maxCount: 1,
count: 0,
allowed() {
return true
},
requires: "",
effect() {
mod.noAmmo = 1
},
remove() {
mod.noAmmo = 0;
}
},
{ {
name: "mass driver", name: "mass driver",
description: "<strong>blocks</strong> do <strong>2x</strong> more <strong class='color-d'>damage</strong> to mobs<br>charge <strong>throws</strong> more <strong>quickly</strong> for less <strong class='color-f'>energy</strong>", description: "<strong>blocks</strong> do <strong>2x</strong> more <strong class='color-d'>damage</strong> to mobs<br>charge <strong>throws</strong> more <strong>quickly</strong> for less <strong class='color-f'>energy</strong>",
@@ -381,7 +329,7 @@ const mod = {
}, },
{ {
name: "scrap bots", name: "scrap bots",
description: "<strong>+12%</strong> chance to build a <strong>bot</strong> after killing a mob<br>the bot will follow you until you <strong>exit</strong> the map", description: "<strong>+12%</strong> chance to build a <strong>bot</strong> after killing a mob<br>the bot only functions until the end of the level",
maxCount: 6, maxCount: 6,
count: 0, count: 0,
allowed() { allowed() {
@@ -396,11 +344,11 @@ const mod = {
} }
}, },
{ {
name: "self-replication", name: "bot replication",
description: "<strong>duplicate</strong> your permanent <strong>bots</strong><br>remove <strong>80%</strong> of your <strong>ammo</strong>", description: "<strong>duplicate</strong> your permanent <strong>bots</strong><br>remove <strong>80%</strong> of your <strong>ammo</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
isNonRefundable: true, // isNonRefundable: true,
allowed() { allowed() {
return mod.foamBotCount + mod.nailBotCount + mod.laserBotCount > 2 return mod.foamBotCount + mod.nailBotCount + mod.laserBotCount > 2
}, },
@@ -720,22 +668,6 @@ const mod = {
mod.energySiphon = 0; mod.energySiphon = 0;
} }
}, },
{
name: "entropy exchange",
description: "<strong class='color-h'>heal</strong> for <strong>+1.5%</strong> of <strong class='color-d'>damage</strong> done",
maxCount: 9,
count: 0,
allowed() {
return !mod.isEnergyHealth
},
requires: "not mass-energy equivalence",
effect() {
mod.healthDrain += 0.015;
},
remove() {
mod.healthDrain = 0;
}
},
{ {
name: "overcharge", name: "overcharge",
description: "increase your <strong>maximum</strong> <strong class='color-f'>energy</strong> by <strong>+50%</strong>", description: "increase your <strong>maximum</strong> <strong class='color-f'>energy</strong> by <strong>+50%</strong>",
@@ -753,6 +685,22 @@ const mod = {
mech.maxEnergy = 1; mech.maxEnergy = 1;
} }
}, },
{
name: "entropy exchange",
description: "<strong class='color-h'>heal</strong> for <strong>+1.5%</strong> of <strong class='color-d'>damage</strong> done",
maxCount: 9,
count: 0,
allowed() {
return !mod.isEnergyHealth
},
requires: "not mass-energy equivalence",
effect() {
mod.healthDrain += 0.015;
},
remove() {
mod.healthDrain = 0;
}
},
{ {
name: "supersaturation", name: "supersaturation",
description: "increase your <strong>maximum</strong> <strong class='color-h'>health</strong> by <strong>+50%</strong>", description: "increase your <strong>maximum</strong> <strong class='color-h'>health</strong> by <strong>+50%</strong>",
@@ -788,6 +736,22 @@ const mod = {
mod.recursiveHealing = 1; mod.recursiveHealing = 1;
} }
}, },
{
name: "crystallized armor",
description: "increase <strong>maximum</strong> <strong class='color-h'>health</strong> by <strong>3%</strong> for each<br>unused <strong>power up</strong> at the end of a <strong>level</strong>",
maxCount: 1,
count: 0,
allowed() {
return !mod.isEnergyHealth
},
requires: "not mass-energy equivalence",
effect() {
mod.isArmorFromPowerUps = true;
},
remove() {
mod.isArmorFromPowerUps = false;
}
},
{ {
name: "pair production", name: "pair production",
description: "<strong>power ups</strong> overfill your <strong class='color-f'>energy</strong><br>temporarily gain <strong>twice</strong> your max <strong class='color-f'>energy</strong>", description: "<strong>power ups</strong> overfill your <strong class='color-f'>energy</strong><br>temporarily gain <strong>twice</strong> your max <strong class='color-f'>energy</strong>",
@@ -807,7 +771,7 @@ const mod = {
}, },
{ {
name: "Bayesian inference", name: "Bayesian inference",
description: "<strong>37%</strong> chance for double <strong>power ups</strong> to drop<br><strong>ammo</strong> will no longer <strong>spawn</strong> from mobs", description: "<strong>40%</strong> chance for double <strong>power ups</strong> to drop<br><strong>ammo</strong> will no longer <strong>spawn</strong> from mobs",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
@@ -815,15 +779,35 @@ const mod = {
}, },
requires: "", requires: "",
effect: () => { effect: () => {
mod.bayesian = 0.37; mod.bayesian = 0.40;
}, },
remove() { remove() {
mod.bayesian = 0; mod.bayesian = 0;
} }
}, },
{
name: "logistics",
description: "<strong>ammo</strong> power ups <strong>add</strong> to your current <strong>gun</strong><br>spawn <strong>4 ammo</strong>",
maxCount: 1,
count: 0,
allowed() {
return true
},
requires: "",
effect() {
mod.isAmmoForGun = true;
for (let i = 0; i < 4; i++) {
powerUps.spawn(mech.pos.x, mech.pos.y, "ammo");
if (Math.random() < mod.bayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "ammo");
}
},
remove() {
mod.isAmmoForGun = false;
}
},
{ {
name: "catabolism", name: "catabolism",
description: "gain <strong>ammo</strong> when you <strong>fire</strong> while <strong>out</strong> of <strong>ammo</strong><br>drains <strong>3%</strong> of current remaining <strong>health</strong>", description: "gain <strong>ammo</strong> when you <strong>fire</strong> while <strong>out</strong> of <strong>ammo</strong><br>drains <strong>2%</strong> of <strong>max health</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
@@ -831,12 +815,28 @@ const mod = {
}, },
requires: "not mass-energy equivalence", requires: "not mass-energy equivalence",
effect: () => { effect: () => {
mod.isAmmoFromHealth = 0.03; mod.isAmmoFromHealth = 0.02;
}, },
remove() { remove() {
mod.isAmmoFromHealth = 0; mod.isAmmoFromHealth = 0;
} }
}, },
{
name: "desublimated ammunition",
description: "use <strong>50%</strong> less <strong>ammo</strong> when <strong>crouching</strong>",
maxCount: 1,
count: 0,
allowed() {
return true
},
requires: "",
effect() {
mod.noAmmo = 1
},
remove() {
mod.noAmmo = 0;
}
},
{ {
name: "cardinality", name: "cardinality",
description: "<strong>2</strong> extra <strong>choices</strong> when selecting <strong>power ups</strong>", description: "<strong>2</strong> extra <strong>choices</strong> when selecting <strong>power ups</strong>",
@@ -858,7 +858,6 @@ const mod = {
description: "spawn <strong>5</strong> <strong class='color-m'>mods</strong><br><strong>power ups</strong> are limited to <strong>one choice</strong>", description: "spawn <strong>5</strong> <strong class='color-m'>mods</strong><br><strong>power ups</strong> are limited to <strong>one choice</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
// isNonRefundable: true,
allowed() { allowed() {
return !mod.isExtraChoice return !mod.isExtraChoice
}, },
@@ -940,11 +939,14 @@ const mod = {
}, },
requires: "more than 6 mods", requires: "more than 6 mods",
effect: () => { effect: () => {
//remove bullets //mostly to get rid of bots //remove bullets //to get rid of bots
for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]); for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]);
bullet = []; bullet = [];
let count = mod.totalCount + 1 let count = 0 //count mods
for (let i = 0, len = mod.mods.length; i < len; i++) { // spawn new mods power ups
if (!mod.mods[i].isNonRefundable) count += mod.mods[i].count
}
if (mod.isDeterminism) count -= 5 //remove the 5 bonus mods when getting rid of determinism if (mod.isDeterminism) count -= 5 //remove the 5 bonus mods when getting rid of determinism
mod.setupAllMods(); // remove all mods mod.setupAllMods(); // remove all mods
for (let i = 0; i < count; i++) { // spawn new mods power ups for (let i = 0; i < count; i++) { // spawn new mods power ups
@@ -1003,7 +1005,7 @@ const mod = {
}, },
{ {
name: "microstates", name: "microstates",
description: "<strong>+7%</strong> <strong class='color-d'>damage</strong> for every <strong>10</strong> active <strong>bullets</strong>", description: "<strong>+6%</strong> <strong class='color-d'>damage</strong> for every <strong>10</strong> active <strong>bullets</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
@@ -1040,7 +1042,7 @@ const mod = {
}, },
{ {
name: "depleted uranium rounds", name: "depleted uranium rounds",
description: `your <strong>bullets</strong> are <strong>+16%</strong> larger<br>increased mass and physical <strong class='color-d'>damage</strong>`, description: `your <strong>bullets</strong> are <strong>+18%</strong> larger<br>increased mass and physical <strong class='color-d'>damage</strong>`,
count: 0, count: 0,
maxCount: 9, maxCount: 9,
allowed() { allowed() {
@@ -1048,7 +1050,7 @@ const mod = {
}, },
requires: "minigun, shotgun, super balls", requires: "minigun, shotgun, super balls",
effect() { effect() {
mod.bulletSize += 0.16 mod.bulletSize += 0.18
}, },
remove() { remove() {
mod.bulletSize = 1; mod.bulletSize = 1;
@@ -1515,7 +1517,7 @@ const mod = {
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
return mod.haveGunCheck("spores") || mod.sporesOnDeath > 0 || mod.isSporeField return (mod.haveGunCheck("spores") || mod.sporesOnDeath > 0 || mod.isSporeField) && !mod.isEnergyHealth
}, },
requires: "spores", requires: "spores",
effect() { effect() {
@@ -1720,7 +1722,7 @@ const mod = {
}, },
{ {
name: "degenerate matter", name: "degenerate matter",
description: "<strong>negative mass field</strong><br><strong>harm</strong> reduction is increased to <strong>80%</strong>", description: "<strong>harm</strong> reduction from <strong>negative mass field</strong><br>is increased from 60% to <strong>80%</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
@@ -1738,7 +1740,7 @@ const mod = {
}, },
{ {
name: "annihilation", name: "annihilation",
description: "after <strong>touching</strong> mobs, they are <strong>annihilated</strong>", description: "after <strong>touching</strong> mobs, they are <strong>annihilated</strong><br>drains <strong>20%</strong> of base <strong class='color-f'>energy</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
@@ -1753,8 +1755,8 @@ const mod = {
} }
}, },
{ {
name: "Hawking radiation", name: "negative temperature",
description: "<strong>negative mass field</strong> leaks virtual particles<br>mobs inside the field take <strong class='color-d'>damage</strong>", description: "<strong>negative mass field</strong> uses <strong class='color-f'>energy</strong><br>to <strong class='color-s'>freeze</strong> mobs caught in it's effect",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
@@ -1762,10 +1764,10 @@ const mod = {
}, },
requires: "negative mass field", requires: "negative mass field",
effect() { effect() {
mod.isHawking = true; mod.isFreezeMobs = true;
}, },
remove() { remove() {
mod.isHawking = 0; mod.isFreezeMobs = false;
} }
}, },
{ {
@@ -1899,6 +1901,93 @@ const mod = {
mod.isPilotFreeze = false mod.isPilotFreeze = false
} }
}, },
{
name: "heals",
description: "spawn <strong>6</strong> <strong class='color-h'>heal</strong> power ups",
maxCount: 9,
count: 0,
isNonRefundable: true,
allowed() {
return true
},
requires: "",
effect() {
for (let i = 0; i < 6; i++) {
powerUps.spawn(mech.pos.x, mech.pos.y, "heal");
if (Math.random() < mod.bayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "heal");
}
},
remove() {}
},
{
name: "ammo",
description: "spawn <strong>6 ammo</strong> power ups",
maxCount: 9,
count: 0,
isNonRefundable: true,
allowed() {
return true
},
requires: "",
effect() {
for (let i = 0; i < 6; i++) {
powerUps.spawn(mech.pos.x, mech.pos.y, "ammo");
if (Math.random() < mod.bayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "ammo");
}
},
remove() {}
},
{
name: "rerolls",
description: "spawn <strong>6</strong> <strong class='color-r'>reroll</strong> power ups",
maxCount: 9,
count: 0,
isNonRefundable: true,
allowed() {
return true
},
requires: "",
effect() {
for (let i = 0; i < 6; i++) {
powerUps.spawn(mech.pos.x, mech.pos.y, "reroll");
if (Math.random() < mod.bayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "reroll");
}
},
remove() {}
},
{
name: "gun",
description: "spawn a <strong>gun</strong> power up",
maxCount: 9,
count: 0,
isNonRefundable: true,
allowed() {
return true
},
requires: "",
effect() {
powerUps.spawn(mech.pos.x, mech.pos.y, "gun");
if (Math.random() < mod.bayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "gun");
},
remove() {}
},
{
name: "field",
description: "spawn a <strong>field</strong> power up",
maxCount: 9,
count: 0,
isNonRefundable: true,
allowed() {
return true
},
requires: "",
effect() {
powerUps.spawn(mech.pos.x, mech.pos.y, "field");
if (Math.random() < mod.bayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "field");
},
remove() {}
},
], ],
//variables use for gun mod upgrades //variables use for gun mod upgrades
fireRate: null, fireRate: null,
@@ -1954,7 +2043,7 @@ const mod = {
isMineAmmoBack: null, isMineAmmoBack: null,
isPlasmaRange: null, isPlasmaRange: null,
isRailNails: null, isRailNails: null,
isHawking: null, isFreezeMobs: null,
babyMissiles: null, babyMissiles: null,
isIceCrystals: null, isIceCrystals: null,
throwChargeRate: null, throwChargeRate: null,
@@ -1991,4 +2080,6 @@ const mod = {
squirrelJump: null, squirrelJump: null,
fastTimeJump: null, fastTimeJump: null,
isFastDot: null, isFastDot: null,
isArmorFromPowerUps: null,
isAmmoForGun: null
} }

View File

@@ -554,7 +554,7 @@ const mech = {
document.getElementById("dmg").style.opacity = 0.1 + Math.min(0.6, dmg * 4); document.getElementById("dmg").style.opacity = 0.1 + Math.min(0.6, dmg * 4);
} }
if (dmg > 0.2 * mech.holdingMassScale) mech.drop(); //drop block if holding if (dmg > 0.06 / mech.holdingMassScale) mech.drop(); //drop block if holding
const normalFPS = function () { const normalFPS = function () {
if (mech.defaultFPSCycle < mech.cycle) { //back to default values if (mech.defaultFPSCycle < mech.cycle) { //back to default values
@@ -1468,6 +1468,20 @@ const mech = {
y: player.velocity.y * 0.98 y: player.velocity.y * 0.98
}); });
} }
if (mod.isFreezeMobs) {
const ICE_DRAIN = 0.00015
for (let i = 0, len = mob.length; i < len; i++) {
if (mob[i].distanceToPlayer() + mob[i].radius < this.fieldDrawRadius && !mob[i].shield && !mob[i].isShielded) {
if (mech.energy > ICE_DRAIN) {
this.fieldDrawRadius -= 2;
mech.energy -= ICE_DRAIN;
mobs.statusSlow(mob[i], 45)
} else {
break;
}
}
}
}
//draw zero-G range //draw zero-G range
ctx.beginPath(); ctx.beginPath();
@@ -1475,31 +1489,6 @@ const mech = {
ctx.fillStyle = "#f5f5ff"; ctx.fillStyle = "#f5f5ff";
ctx.globalCompositeOperation = "difference"; ctx.globalCompositeOperation = "difference";
ctx.fill(); ctx.fill();
if (mod.isHawking) {
for (let i = 0, len = mob.length; i < len; i++) {
if (mob[i].distanceToPlayer2() < this.fieldDrawRadius * this.fieldDrawRadius && Matter.Query.ray(map, mech.pos, mob[i].position).length === 0 && Matter.Query.ray(body, mech.pos, mob[i].position).length === 0) {
mob[i].damage(b.dmgScale * 0.085);
mob[i].locatePlayer();
//draw electricity
const sub = Vector.sub(mob[i].position, mech.pos)
const unit = Vector.normalise(sub);
const steps = 6
const step = Vector.magnitude(sub) / steps;
ctx.beginPath();
let x = mech.pos.x + 30 * unit.x;
let y = mech.pos.y + 30 * unit.y;
ctx.moveTo(x, y);
for (let i = 0; i < steps; i++) {
x += step * (unit.x + 0.7 * (Math.random() - 0.5))
y += step * (unit.y + 0.7 * (Math.random() - 0.5))
ctx.lineTo(x, y);
}
ctx.lineWidth = 1;
ctx.strokeStyle = "rgba(0,255,0,0.5)" //"#fff";
ctx.stroke();
}
}
}
ctx.globalCompositeOperation = "source-over"; ctx.globalCompositeOperation = "source-over";
} }
} else if (mech.holdingTarget && mech.fieldCDcycle < mech.cycle) { //holding, but field button is released } else if (mech.holdingTarget && mech.fieldCDcycle < mech.cycle) { //holding, but field button is released

View File

@@ -1,6 +1,7 @@
let powerUp = []; let powerUp = [];
const powerUps = { const powerUps = {
totalPowerUps: 0, //used for mods that count power ups at the end of a level
choose(type, index) { choose(type, index) {
if (type === "gun") { if (type === "gun") {
b.giveGuns(index) b.giveGuns(index)
@@ -110,16 +111,21 @@ const powerUps = {
//only get ammo for guns player has //only get ammo for guns player has
let target; let target;
if (b.inventory.length > 0) { if (b.inventory.length > 0) {
//add ammo to a gun in inventory if (mod.isAmmoForGun) {
target = b.guns[b.inventory[Math.floor(Math.random() * (b.inventory.length))]]; target = b.guns[b.activeGun];
//try 3 more times to give ammo to a gun with ammo, not Infinity } else {
if (target.ammo === Infinity) { //find a gun in your inventory
target = b.guns[b.inventory[Math.floor(Math.random() * (b.inventory.length))]] target = b.guns[b.inventory[Math.floor(Math.random() * (b.inventory.length))]];
//try 3 more times to give ammo to a gun with ammo, not Infinity
if (target.ammo === Infinity) { if (target.ammo === Infinity) {
target = b.guns[b.inventory[Math.floor(Math.random() * (b.inventory.length))]] target = b.guns[b.inventory[Math.floor(Math.random() * (b.inventory.length))]]
if (target.ammo === Infinity) target = b.guns[b.inventory[Math.floor(Math.random() * (b.inventory.length))]] if (target.ammo === Infinity) {
target = b.guns[b.inventory[Math.floor(Math.random() * (b.inventory.length))]]
if (target.ammo === Infinity) target = b.guns[b.inventory[Math.floor(Math.random() * (b.inventory.length))]]
}
} }
} }
//give ammo
if (target.ammo === Infinity) { if (target.ammo === Infinity) {
if (mech.energy < mech.maxEnergy) mech.energy = mech.maxEnergy; if (mech.energy < mech.maxEnergy) mech.energy = mech.maxEnergy;
if (!game.lastLogTime) game.makeTextLog("<span style='font-size:115%;'><span class='color-f'>+energy</span></span>", 300); if (!game.lastLogTime) game.makeTextLog("<span style='font-size:115%;'><span class='color-f'>+energy</span></span>", 300);

View File

@@ -900,7 +900,7 @@ const spawn = {
Matter.Body.rotate(me, Math.random() * Math.PI * 2); Matter.Body.rotate(me, Math.random() * Math.PI * 2);
me.accelMag = 0.0005 * game.accelScale; me.accelMag = 0.0005 * game.accelScale;
me.seePlayerFreq = Math.floor(25 * game.lookFreqScale); me.seePlayerFreq = Math.floor(25 * game.lookFreqScale);
me.memory = 600; me.memory = 420;
me.restitution = 1; me.restitution = 1;
me.frictionAir = 0.05; me.frictionAir = 0.05;
me.frictionStatic = 0; me.frictionStatic = 0;
@@ -1009,7 +1009,7 @@ const spawn = {
// hitting player // hitting player
if (best.who === player) { if (best.who === player) {
if (mech.immuneCycle < mech.cycle) { if (mech.immuneCycle < mech.cycle) {
const dmg = 0.0005 * game.dmgScale; const dmg = 0.002 * game.dmgScale;
mech.damage(dmg); mech.damage(dmg);
//draw damage //draw damage
ctx.fillStyle = color; ctx.fillStyle = color;
@@ -1801,7 +1801,7 @@ const spawn = {
}; };
Matter.Body.setDensity(me, 0.00005); //normal is 0.001 Matter.Body.setDensity(me, 0.00005); //normal is 0.001
me.timeLeft = 420 * (0.8 + 0.4 * Math.random()); me.timeLeft = 420 * (0.8 + 0.4 * Math.random());
me.accelMag = 0.00015 * (0.8 + 0.4 * Math.random()) * game.accelScale; me.accelMag = 0.00017 * (0.8 + 0.4 * Math.random()) * game.accelScale;
me.frictionAir = 0.01 * (0.8 + 0.4 * Math.random()); me.frictionAir = 0.01 * (0.8 + 0.4 * Math.random());
me.restitution = 0.5; me.restitution = 0.5;
me.leaveBody = false; me.leaveBody = false;

View File

@@ -1,9 +1,25 @@
mod flechettes do all DoT damage in 1/2 a second added mods to spawn a gun, a field, and rerolls
minigun increases fire speed as you hold the fire button added mod that gives max health for leftover power ups
this mod has some interesting interactions with other mods
mod annihilation now uses 20% of base energy and doesn't trigger damage immunity
mod Hawking radiation removed
mod negative temperature: freezed mobs in range of negative mass field, but drain energy
mod: logistics
ammo power ups are added to your current gun
spawn 4 ammo immediately
************** TODO - n-gon ************** ************** TODO - n-gon **************
very high speed projectile that checks for collisions in future positions to avoid tunneling
make a visual indication of max health
mod: give a gun auto aiming
minigun?
ice status effect lasts twice as long
shrink font on small screens (so you can see 5 options on power ups) shrink font on small screens (so you can see 5 options on power ups)
graphic idea: bezier curve that moves smoothly from mob to mob graphic idea: bezier curve that moves smoothly from mob to mob