worm hole mods

mod: critical bifurcation - nail gun does 400% more damage if it hits very close to the center of a mob
mod: supercritical fission - flechettes explode if they hit very close to the center of a mob

mod: transdimensional spores - after wormholes eat blocks, they disturb spores
mod: traversable geodesics - your bullets can go through worm holes

scrap bots now only last only 30 seconds, but they have a 20% chance to spawn from a kill (was 11%)
the difficulty should feel a bit harder after clearing the boss level
  (a bit more more damage taken, and fewer mod drops)
This commit is contained in:
landgreen
2020-10-20 17:23:47 -07:00
parent fb13945879
commit 0c2285b1c7
8 changed files with 221 additions and 142 deletions

View File

@@ -108,7 +108,7 @@ const b = {
mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield
}, },
minDmgSpeed: 10, minDmgSpeed: 10,
onDmg() {}, //this.endCycle = 0 //triggers despawn beforeDmg() {}, //this.endCycle = 0 //triggers despawn
onEnd() {} onEnd() {}
}; };
} else { } else {
@@ -125,7 +125,7 @@ const b = {
mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield
}, },
minDmgSpeed: 10, minDmgSpeed: 10,
onDmg() {}, //this.endCycle = 0 //triggers despawn beforeDmg() {}, //this.endCycle = 0 //triggers despawn
onEnd() {} onEnd() {}
}; };
} }
@@ -276,13 +276,13 @@ const b = {
} }
} }
}, },
missile(where, dir, speed, size = 1, spawn = 0) { missile(where, angle, speed, size = 1, spawn = 0) {
const me = bullet.length; const me = bullet.length;
bullet[me] = Bodies.rectangle(where.x, where.y, 30 * size, 4 * size, b.fireAttributes(dir)); bullet[me] = Bodies.rectangle(where.x, where.y, 30 * size, 4 * size, b.fireAttributes(angle));
const thrust = 0.00417 * bullet[me].mass; const thrust = 0.00417 * bullet[me].mass;
Matter.Body.setVelocity(bullet[me], { Matter.Body.setVelocity(bullet[me], {
x: mech.Vx / 2 + speed * Math.cos(dir), x: mech.Vx / 2 + speed * Math.cos(angle),
y: mech.Vy / 2 + speed * Math.sin(dir) y: mech.Vy / 2 + speed * Math.sin(angle)
}); });
World.add(engine.world, bullet[me]); //add bullet to world World.add(engine.world, bullet[me]); //add bullet to world
bullet[me].frictionAir = 0.023 bullet[me].frictionAir = 0.023
@@ -300,7 +300,7 @@ const b = {
} }
} }
} }
bullet[me].onDmg = function () { bullet[me].beforeDmg = function () {
this.tryToLockOn(); this.tryToLockOn();
this.endCycle = 0; //bullet ends cycle after doing damage // also triggers explosion this.endCycle = 0; //bullet ends cycle after doing damage // also triggers explosion
}; };
@@ -557,7 +557,7 @@ const b = {
endCycle: Infinity, endCycle: Infinity,
lookFrequency: 0, lookFrequency: 0,
range: 700, range: 700,
onDmg() {}, beforeDmg() {},
do() { do() {
this.force.y += this.mass * 0.002; //extra gravity this.force.y += this.mass * 0.002; //extra gravity
let collide = Matter.Query.collides(this, map) //check if collides with map let collide = Matter.Query.collides(this, map) //check if collides with map
@@ -686,7 +686,7 @@ const b = {
x: 100 * (Math.random() - 0.5), x: 100 * (Math.random() - 0.5),
y: 100 * (Math.random() - 0.5) y: 100 * (Math.random() - 0.5)
}, },
onDmg(who) { beforeDmg(who) {
this.endCycle = 0; //bullet ends cycle after doing damage this.endCycle = 0; //bullet ends cycle after doing damage
if (this.isFreeze) mobs.statusSlow(who, 60) if (this.isFreeze) mobs.statusSlow(who, 60)
}, },
@@ -800,7 +800,7 @@ const b = {
minDmgSpeed: 0, minDmgSpeed: 0,
lockedOn: null, lockedOn: null,
isFollowMouse: true, isFollowMouse: true,
onDmg(who) { beforeDmg(who) {
mobs.statusSlow(who, 60) mobs.statusSlow(who, 60)
this.endCycle = game.cycle this.endCycle = game.cycle
if (mod.isHeavyWater) mobs.statusDoT(who, 0.15, 300) if (mod.isHeavyWater) mobs.statusDoT(who, 0.15, 300)
@@ -877,7 +877,7 @@ const b = {
isFollowMouse: true, isFollowMouse: true,
deathCycles: 110 + RADIUS * 5, deathCycles: 110 + RADIUS * 5,
isImproved: false, isImproved: false,
onDmg(who) { beforeDmg(who) {
//move away from target after hitting //move away from target after hitting
const unit = Vector.mult(Vector.normalise(Vector.sub(this.position, who.position)), -20) const unit = Vector.mult(Vector.normalise(Vector.sub(this.position, who.position)), -20)
Matter.Body.setVelocity(this, { Matter.Body.setVelocity(this, {
@@ -1002,7 +1002,7 @@ const b = {
target: null, target: null,
targetVertex: null, targetVertex: null,
targetRelativePosition: null, targetRelativePosition: null,
onDmg(who) { beforeDmg(who) {
if (!this.target && who.alive) { if (!this.target && who.alive) {
this.target = who; this.target = who;
if (who.radius < 20) { if (who.radius < 20) {
@@ -1154,15 +1154,14 @@ const b = {
}, },
nail(pos, velocity, dmg = 0) { nail(pos, velocity, dmg = 0) {
const me = bullet.length; const me = bullet.length;
// bullet[me] = Bodies.rectangle(pos.x, pos.y, 25, 2, b.fireAttributes(Math.atan2(velocity.y, velocity.x)));
bullet[me] = Bodies.rectangle(pos.x, pos.y, 25 * mod.biggerNails, 2 * mod.biggerNails, b.fireAttributes(Math.atan2(velocity.y, velocity.x))); bullet[me] = Bodies.rectangle(pos.x, pos.y, 25 * mod.biggerNails, 2 * mod.biggerNails, b.fireAttributes(Math.atan2(velocity.y, velocity.x)));
Matter.Body.setVelocity(bullet[me], velocity); Matter.Body.setVelocity(bullet[me], velocity);
World.add(engine.world, bullet[me]); //add bullet to world World.add(engine.world, bullet[me]); //add bullet to world
bullet[me].endCycle = game.cycle + 60 + 18 * Math.random(); bullet[me].endCycle = game.cycle + 60 + 18 * Math.random();
bullet[me].dmg = dmg bullet[me].dmg = dmg
bullet[me].onDmg = function (who) { bullet[me].beforeDmg = function (who) {
if (mod.isNailPoison) mobs.statusDoT(who, dmg * 0.22, 120) // one tick every 30 cycles if (mod.isNailPoison) mobs.statusDoT(who, dmg * 0.22, 120) // one tick every 30 cycles
if (mod.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.99) this.dmg *= 5 //crit if hit near center
}; };
bullet[me].do = function () {}; bullet[me].do = function () {};
}, },
@@ -1227,7 +1226,7 @@ const b = {
mask: cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield mask: cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield
}, },
lockedOn: null, lockedOn: null,
onDmg() { beforeDmg() {
this.lockedOn = null this.lockedOn = null
}, },
onEnd() {}, onEnd() {},
@@ -1283,7 +1282,7 @@ const b = {
mask: cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield mask: cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield
}, },
lockedOn: null, lockedOn: null,
onDmg() { beforeDmg() {
this.lockedOn = null this.lockedOn = null
}, },
onEnd() {}, onEnd() {},
@@ -1342,7 +1341,7 @@ const b = {
mask: cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield mask: cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield
}, },
lockedOn: null, lockedOn: null,
onDmg() { beforeDmg() {
this.lockedOn = null this.lockedOn = null
}, },
onEnd() {}, onEnd() {},
@@ -1452,7 +1451,7 @@ const b = {
}, },
lockedOn: null, lockedOn: null,
explode: 0, explode: 0,
onDmg() { beforeDmg() {
if (this.lockedOn) { if (this.lockedOn) {
const explosionRadius = Math.min(170 + 140 * this.isUpgraded, Vector.magnitude(Vector.sub(this.position, mech.pos)) - 30) const explosionRadius = Math.min(170 + 140 * this.isUpgraded, Vector.magnitude(Vector.sub(this.position, mech.pos)) - 30)
if (explosionRadius > 60) { if (explosionRadius > 60) {
@@ -1528,7 +1527,7 @@ const b = {
mask: cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield mask: cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield
}, },
lockedOn: null, lockedOn: null,
onDmg() { beforeDmg() {
this.lockedOn = null this.lockedOn = null
}, },
onEnd() {}, onEnd() {},
@@ -1706,7 +1705,7 @@ const b = {
category: cat.bullet, category: cat.bullet,
mask: 0 //cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield mask: 0 //cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield
}, },
onDmg() {}, beforeDmg() {},
onEnd() {}, onEnd() {},
range: 190 + 50 * mod.isOrbitBotUpgrade, //range is set in bot upgrade too! //150 + (80 + 100 * mod.isOrbitBotUpgrade) * Math.random(), // + 5 * mod.orbitBotCount, range: 190 + 50 * mod.isOrbitBotUpgrade, //range is set in bot upgrade too! //150 + (80 + 100 * mod.isOrbitBotUpgrade) * Math.random(), // + 5 * mod.orbitBotCount,
orbitalSpeed: 0, orbitalSpeed: 0,
@@ -1850,7 +1849,7 @@ const b = {
y: mech.Vy / 2 + speed * Math.sin(angle) y: mech.Vy / 2 + speed * Math.sin(angle)
}, dmg) //position, velocity, damage }, dmg) //position, velocity, damage
if (mod.isIceCrystals) { if (mod.isIceCrystals) {
bullet[bullet.length - 1].onDmg = function (who) { bullet[bullet.length - 1].beforeDmg = function (who) {
mobs.statusSlow(who, 30) mobs.statusSlow(who, 30)
if (mod.isNailPoison) mobs.statusDoT(who, dmg * 0.22, 120) // one tick every 30 cycles if (mod.isNailPoison) mobs.statusDoT(who, dmg * 0.22, 120) // one tick every 30 cycles
}; };
@@ -1957,7 +1956,7 @@ const b = {
bullet[me].do = function () { bullet[me].do = function () {
this.force.y += this.mass * 0.001; this.force.y += this.mass * 0.001;
}; };
bullet[me].onDmg = function (who) { bullet[me].beforeDmg = function (who) {
mobs.statusStun(who, 180) // (2.3) * 2 / 14 ticks (2x damage over 7 seconds) mobs.statusStun(who, 180) // (2.3) * 2 / 14 ticks (2x damage over 7 seconds)
}; };
} else { } else {
@@ -2031,6 +2030,11 @@ const b = {
} }
} else { } else {
this.endCycle = 0; this.endCycle = 0;
if (mod.isFlechetteExplode && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.98) {
// mobs.statusStun(who, 120)
this.explodeRad = 250 + 30 * Math.random();
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
}
who.foundPlayer(); who.foundPlayer();
if (mod.isFastDot) { if (mod.isFastDot) {
mobs.statusDoT(who, 3.78, 30) mobs.statusDoT(who, 3.78, 30)
@@ -2120,7 +2124,7 @@ const b = {
category: 0, category: 0,
mask: 0, //cat.mob | cat.mobBullet | cat.mobShield mask: 0, //cat.mob | cat.mobBullet | cat.mobShield
}, },
onDmg() {}, beforeDmg() {},
onEnd() {}, onEnd() {},
do() { do() {
if (!mech.isBodiesAsleep) { if (!mech.isBodiesAsleep) {
@@ -2309,7 +2313,7 @@ const b = {
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
} }
bullet[me].onDmg = function () { bullet[me].beforeDmg = function () {
this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion
}; };
bullet[me].do = function () { bullet[me].do = function () {
@@ -2335,7 +2339,7 @@ const b = {
if (mod.grenadeFragments) b.targetedNail(this.position, mod.grenadeFragments) if (mod.grenadeFragments) b.targetedNail(this.position, mod.grenadeFragments)
} }
bullet[me].minDmgSpeed = 1; bullet[me].minDmgSpeed = 1;
bullet[me].onDmg = function () { bullet[me].beforeDmg = function () {
this.endCycle = 0; //bullet ends cycle after doing damage //this also triggers explosion this.endCycle = 0; //bullet ends cycle after doing damage //this also triggers explosion
}; };
@@ -2401,7 +2405,7 @@ const b = {
if (dist < this.explodeRad) mech.energy = 0 //remove player energy if (dist < this.explodeRad) mech.energy = 0 //remove player energy
} }
} }
bullet[me].onDmg = function () { bullet[me].beforeDmg = function () {
// this.endCycle = 0; //bullet ends cycle after doing damage //this triggers explosion // this.endCycle = 0; //bullet ends cycle after doing damage //this triggers explosion
}; };
bullet[me].radius = 22; //used from drawing timer bullet[me].radius = 22; //used from drawing timer
@@ -2510,7 +2514,7 @@ const b = {
bullet[me].maxDamageRadius = (435 + 150 * Math.random()) * (mod.isNeutronImmune ? 1.2 : 1) bullet[me].maxDamageRadius = (435 + 150 * Math.random()) * (mod.isNeutronImmune ? 1.2 : 1)
bullet[me].stuckTo = null; bullet[me].stuckTo = null;
bullet[me].stuckToRelativePosition = null; bullet[me].stuckToRelativePosition = null;
bullet[me].onDmg = function () {}; bullet[me].beforeDmg = function () {};
bullet[me].stuck = function () {}; bullet[me].stuck = function () {};
bullet[me].do = function () { bullet[me].do = function () {
function onCollide(that) { function onCollide(that) {
@@ -2682,7 +2686,7 @@ const b = {
bullet[me].minDmgSpeed = 0; bullet[me].minDmgSpeed = 0;
bullet[me].totalSpores = 8 + 2 * mod.isFastSpores + 2 * mod.isSporeFreeze bullet[me].totalSpores = 8 + 2 * mod.isFastSpores + 2 * mod.isSporeFreeze
bullet[me].stuck = function () {}; bullet[me].stuck = function () {};
bullet[me].onDmg = function () {}; bullet[me].beforeDmg = function () {};
bullet[me].do = function () { bullet[me].do = function () {
function onCollide(that) { function onCollide(that) {
that.collisionFilter.mask = 0; //non collide with everything that.collisionFilter.mask = 0; //non collide with everything
@@ -2850,7 +2854,7 @@ const b = {
name: "rail gun", name: "rail gun",
description: "use <strong class='color-f'>energy</strong> to launch a high-speed <strong>dense</strong> rod<br><strong>hold</strong> left mouse to charge, <strong>release</strong> to fire", description: "use <strong class='color-f'>energy</strong> to launch a high-speed <strong>dense</strong> rod<br><strong>hold</strong> left mouse to charge, <strong>release</strong> to fire",
ammo: 0, ammo: 0,
ammoPack: 3, ammoPack: 3.5,
have: false, have: false,
fire() { fire() {
if (mod.isCapacitor) { if (mod.isCapacitor) {
@@ -2871,7 +2875,7 @@ const b = {
}, },
minDmgSpeed: 5, minDmgSpeed: 5,
endCycle: game.cycle + 140, endCycle: game.cycle + 140,
onDmg(who) { beforeDmg(who) {
if (who.shield) { if (who.shield) {
for (let i = 0, len = mob.length; i < len; i++) { for (let i = 0, len = mob.length; i < len; i++) {
if (mob[i].id === who.shieldTargetID) { //apply some knock back to shield mob before shield breaks if (mob[i].id === who.shieldTargetID) { //apply some knock back to shield mob before shield breaks
@@ -2880,10 +2884,10 @@ const b = {
} }
} }
Matter.Body.setVelocity(this, { Matter.Body.setVelocity(this, {
x: -0.1 * this.velocity.x, x: -0.5 * this.velocity.x,
y: -0.1 * this.velocity.y y: -0.5 * this.velocity.y
}); });
Matter.Body.setDensity(this, 0.001); // Matter.Body.setDensity(this, 0.001);
} }
if (mod.isRailNails && this.speed > 10) { if (mod.isRailNails && 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, (Math.min(40, this.speed) - 10) * 0.6) // 0.6 as many nails as the normal rail gun
@@ -2980,7 +2984,7 @@ const b = {
mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield
}, },
minDmgSpeed: 5, minDmgSpeed: 5,
onDmg(who) { beforeDmg(who) {
if (who.shield) { if (who.shield) {
for (let i = 0, len = mob.length; i < len; i++) { for (let i = 0, len = mob.length; i < len; i++) {
if (mob[i].id === who.shieldTargetID) { //apply some knock back to shield mob before shield breaks if (mob[i].id === who.shieldTargetID) { //apply some knock back to shield mob before shield breaks
@@ -3472,7 +3476,7 @@ const b = {
// }, // },
// minDmgSpeed: 5, // minDmgSpeed: 5,
// range: 0, // range: 0,
// onDmg() { // beforeDmg() {
// this.endCycle = 0; // this.endCycle = 0;
// }, //this.endCycle = 0 //triggers despawn // }, //this.endCycle = 0 //triggers despawn
// onEnd() {}, // onEnd() {},

View File

@@ -173,11 +173,11 @@ function collisionChecks(event) {
} }
//mob + bullet collisions //mob + bullet collisions
if (obj.classType === "bullet" && obj.speed > obj.minDmgSpeed) { if (obj.classType === "bullet" && obj.speed > obj.minDmgSpeed) {
obj.beforeDmg(mob[k]); //some bullets do actions when they hits things, like despawn //forces don't seem to work here
let dmg = b.dmgScale * (obj.dmg + 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity))) let dmg = b.dmgScale * (obj.dmg + 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity)))
if (mod.isCrit && mob[k].isStunned) dmg *= 4 if (mod.isCrit && mob[k].isStunned) dmg *= 4
mob[k].foundPlayer(); mob[k].foundPlayer();
mob[k].damage(dmg); mob[k].damage(dmg);
obj.onDmg(mob[k]); //some bullets do actions when they hits things, like despawn //forces don't seem to work here
game.drawList.push({ //add dmg to draw queue game.drawList.push({ //add dmg to draw queue
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

@@ -15,12 +15,12 @@ const level = {
// game.zoomScale = 1000; // game.zoomScale = 1000;
// game.setZoom(); // game.setZoom();
// mech.isCloak = true; // mech.isCloak = true;
mech.setField("wormhole") // mech.setField("wormhole")
// b.giveGuns("nail gun") // b.giveGuns("flechettes")
// for (let i = 0; i < 10; i++) { // for (let i = 0; i < 10; i++) {
// mod.giveMod("laser-bot"); // mod.giveMod("laser-bot");
// } // }
mod.giveMod("cosmic string") // mod.giveMod("supercritical fission")
level.intro(); //starting level level.intro(); //starting level
@@ -149,10 +149,10 @@ const level = {
// spawn.sniper(1700, -120, 50) // spawn.sniper(1700, -120, 50)
// spawn.bomberBoss(1400, -500) // spawn.bomberBoss(1400, -500)
// spawn.sniper(1800, -120) // spawn.sniper(1800, -120)
// spawn.sniper(2200, -120)
// spawn.cellBossCulture(1600, -500) // spawn.cellBossCulture(1600, -500)
spawn.powerUpBoss(1600, -500) // spawn.powerUpBoss(1600, -500)
// spawn.shield(mob[mob.length - 1], 1200, -500, 1); spawn.sniper(1200, -500)
spawn.shield(mob[mob.length - 1], 1200, -500, 1);
// spawn.nodeBoss(1200, -500, "launcher") // spawn.nodeBoss(1200, -500, "launcher")
// spawn.snakeBoss(1200, -500) // spawn.snakeBoss(1200, -500)
@@ -3841,7 +3841,7 @@ const level = {
difficultyIncrease(num = 1) { difficultyIncrease(num = 1) {
for (let i = 0; i < num; i++) { for (let i = 0; i < num; i++) {
game.difficulty++ game.difficulty++
game.dmgScale += 0.37; //damage done by mobs increases each level game.dmgScale += 0.38; //damage done by mobs increases each level
b.dmgScale *= 0.93; //damage done by player decreases each level b.dmgScale *= 0.93; //damage done by player decreases each level
if (game.accelScale < 5) game.accelScale *= 1.02 //mob acceleration increases each level if (game.accelScale < 5) game.accelScale *= 1.02 //mob acceleration increases each level
if (game.lookFreqScale > 0.2) game.lookFreqScale *= 0.98 //mob cycles between looks decreases each level if (game.lookFreqScale > 0.2) game.lookFreqScale *= 0.98 //mob cycles between looks decreases each level
@@ -3852,7 +3852,7 @@ const level = {
difficultyDecrease(num = 1) { //used in easy mode for game.reset() difficultyDecrease(num = 1) { //used in easy mode for game.reset()
for (let i = 0; i < num; i++) { for (let i = 0; i < num; i++) {
game.difficulty-- game.difficulty--
game.dmgScale -= 0.37; //damage done by mobs increases each level game.dmgScale -= 0.38; //damage done by mobs increases each level
if (game.dmgScale < 0.1) game.dmgScale = 0.1; if (game.dmgScale < 0.1) game.dmgScale = 0.1;
b.dmgScale /= 0.93; //damage done by player decreases each level b.dmgScale /= 0.93; //damage done by player decreases each level
if (game.accelScale > 0.2) game.accelScale /= 1.02 //mob acceleration increases each level if (game.accelScale > 0.2) game.accelScale /= 1.02 //mob acceleration increases each level
@@ -3887,6 +3887,7 @@ const level = {
if (level.onLevel > level.levels.length - 1) level.onLevel = 0; if (level.onLevel > level.levels.length - 1) level.onLevel = 0;
level.difficultyIncrease(game.difficultyMode) //increase difficulty based on modes level.difficultyIncrease(game.difficultyMode) //increase difficulty based on modes
if (level.levelsCleared > level.levels.length) level.difficultyIncrease(game.difficultyMode) if (level.levelsCleared > level.levels.length) level.difficultyIncrease(game.difficultyMode)
if (level.levelsCleared > level.levels.length * 1.25) level.difficultyIncrease(game.difficultyMode)
if (level.levelsCleared > level.levels.length * 1.5) level.difficultyIncrease(game.difficultyMode) if (level.levelsCleared > level.levels.length * 1.5) level.difficultyIncrease(game.difficultyMode)
if (level.levelsCleared > level.levels.length * 2) level.difficultyIncrease(game.difficultyMode) if (level.levelsCleared > level.levels.length * 2) level.difficultyIncrease(game.difficultyMode)
if (game.isEasyMode && level.levelsCleared % 2) level.difficultyDecrease(1); if (game.isEasyMode && level.levelsCleared % 2) level.difficultyDecrease(1);

View File

@@ -1043,7 +1043,10 @@ const mobs = {
b.spore(this.position) b.spore(this.position)
} }
} }
if (Math.random() < mod.isBotSpawner) b.randomBot(this.position, false) if (Math.random() < mod.isBotSpawner) {
b.randomBot(this.position, false)
bullet[bullet.length - 1].endCycle = game.cycle + 1500 + Math.floor(600 * Math.random())
}
if (mod.isExplodeMob) b.explosion(this.position, Math.min(550, Math.sqrt(this.mass + 2.5) * 50)) if (mod.isExplodeMob) b.explosion(this.position, Math.min(550, Math.sqrt(this.mass + 2.5) * 50))
if (mod.nailsDeathMob) b.targetedNail(this.position, mod.nailsDeathMob, 40 + 7 * Math.random()) if (mod.nailsDeathMob) b.targetedNail(this.position, mod.nailsDeathMob, 40 + 7 * Math.random())
} else if (mod.isShieldAmmo && this.shield) { } else if (mod.isShieldAmmo && this.shield) {

View File

@@ -408,7 +408,7 @@ const mod = {
maxCount: 9, maxCount: 9,
count: 0, count: 0,
allowed() { allowed() {
return mod.haveGunCheck("missiles") || mod.haveGunCheck("flak") || mod.haveGunCheck("grenades") || mod.haveGunCheck("vacuum bomb") || mod.haveGunCheck("pulse") || mod.isMissileField || mod.boomBotCount > 1; return mod.haveGunCheck("missiles") || mod.haveGunCheck("flak") || mod.haveGunCheck("grenades") || mod.haveGunCheck("vacuum bomb") || mod.haveGunCheck("pulse") || mod.isMissileField || mod.boomBotCount > 1 || mod.isFlechetteExplode
}, },
requires: "an explosive damage source", requires: "an explosive damage source",
effect: () => { effect: () => {
@@ -424,7 +424,7 @@ const mod = {
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
return mod.haveGunCheck("missiles") || mod.haveGunCheck("flak") || mod.haveGunCheck("grenades") || mod.haveGunCheck("vacuum bomb") || mod.haveGunCheck("pulse") || mod.isMissileField || mod.boomBotCount > 1; return mod.haveGunCheck("missiles") || mod.haveGunCheck("flak") || mod.haveGunCheck("grenades") || mod.haveGunCheck("vacuum bomb") || mod.haveGunCheck("pulse") || mod.isMissileField || mod.boomBotCount > 1 || mod.isFlechetteExplode
}, },
requires: "an explosive damage source", requires: "an explosive damage source",
effect: () => { effect: () => {
@@ -440,7 +440,7 @@ const mod = {
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
return mod.haveGunCheck("missiles") || mod.haveGunCheck("flak") || mod.haveGunCheck("grenades") || mod.haveGunCheck("vacuum bomb") || mod.haveGunCheck("pulse") || mod.isMissileField return mod.haveGunCheck("missiles") || mod.haveGunCheck("flak") || mod.haveGunCheck("grenades") || mod.haveGunCheck("vacuum bomb") || mod.haveGunCheck("pulse") || mod.isMissileField || mod.isFlechetteExplode
}, },
requires: "an explosive damage source", requires: "an explosive damage source",
effect: () => { effect: () => {
@@ -457,7 +457,7 @@ const mod = {
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
return mod.haveGunCheck("missiles") || mod.haveGunCheck("flak") || mod.haveGunCheck("grenades") || mod.haveGunCheck("vacuum bomb") || mod.isMissileField || mod.isExplodeMob return mod.haveGunCheck("missiles") || mod.haveGunCheck("flak") || mod.haveGunCheck("grenades") || mod.haveGunCheck("vacuum bomb") || mod.isMissileField || mod.isExplodeMob || mod.isFlechetteExplode
}, },
requires: "an explosive damage source", requires: "an explosive damage source",
effect: () => { effect: () => {
@@ -469,15 +469,15 @@ const mod = {
}, },
{ {
name: "scrap bots", name: "scrap bots",
description: "<strong>11%</strong> chance to build a <strong>bot</strong> after killing a mob<br>the bot only functions until the end of the level", description: "<strong>19%</strong> chance to build a <strong>bot</strong> after killing a mob<br>the bot last for about <strong>30</strong> seconds",
maxCount: 6, maxCount: 3,
count: 0, count: 0,
allowed() { allowed() {
return mod.totalBots() > 0 return mod.totalBots() > 0
}, },
requires: "a bot", requires: "a bot",
effect() { effect() {
mod.isBotSpawner += 0.11; mod.isBotSpawner += 0.19;
}, },
remove() { remove() {
mod.isBotSpawner = 0; mod.isBotSpawner = 0;
@@ -1596,6 +1596,22 @@ const mod = {
mod.isDamageFromBulletCount = false mod.isDamageFromBulletCount = false
} }
}, },
{
name: "critical bifurcation",
description: "<strong>nails</strong> do <strong>400%</strong> more <strong class='color-d'>damage</strong><br>when they strike near the <strong>center</strong> of a mob",
maxCount: 1,
count: 0,
allowed() {
return mod.haveGunCheck("nail gun")
},
requires: "nail gun",
effect() {
mod.isNailCrit = true
},
remove() {
mod.isNailCrit = false
}
},
{ {
name: "pneumatic actuator", name: "pneumatic actuator",
description: "<strong>nail gun</strong> takes <strong>45%</strong> less time to ramp up<br>to it's shortest <strong>delay</strong> after firing", description: "<strong>nail gun</strong> takes <strong>45%</strong> less time to ramp up<br>to it's shortest <strong>delay</strong> after firing",
@@ -1843,15 +1859,31 @@ const mod = {
mod.isFastDot = false; mod.isFastDot = false;
} }
}, },
{
name: "supercritical fission",
description: "<strong>flechettes</strong> can <strong class='color-e'>explode</strong><br>if they strike mobs near their <strong>center</strong>",
maxCount: 1,
count: 0,
allowed() {
return mod.haveGunCheck("flechettes") && !mod.pierce
},
requires: "flechettes and not piercing needles",
effect() {
mod.isFlechetteExplode = true
},
remove() {
mod.isFlechetteExplode = false
}
},
{ {
name: "piercing needles", name: "piercing needles",
description: "<strong>needles</strong> penetrate <strong>mobs</strong> and <strong>blocks</strong><br>potentially hitting <strong>multiple</strong> targets", description: "<strong>needles</strong> penetrate <strong>mobs</strong> and <strong>blocks</strong><br>potentially hitting <strong>multiple</strong> targets",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
return mod.haveGunCheck("flechettes") return mod.haveGunCheck("flechettes") && !mod.isFlechetteExplode
}, },
requires: "flechettes", requires: "flechettes and not supercritical fission",
effect() { effect() {
mod.pierce = true; mod.pierce = true;
}, },
@@ -2807,7 +2839,7 @@ const mod = {
}, },
{ {
name: "cosmic string", name: "cosmic string",
description: "when you <strong> tunnel</strong> through a <strong class='color-worm'>wormhole</strong><br><strong class='color-d'>damage</strong> mobs between the <strong>endpoints</strong>", description: "when you <strong> tunnel</strong> through a <strong class='color-worm'>wormhole</strong><br>mobs between the <strong>endpoints</strong> take <strong class='color-d'>damage</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
@@ -2823,7 +2855,7 @@ const mod = {
}, },
{ {
name: "Penrose process", name: "Penrose process",
description: "after a <strong>block</strong> falls into a <strong class='color-worm'>wormhole</strong><br>overfill your <strong class='color-f'>energy</strong> to <strong>300%</strong> of your maximum<br> ", description: "after a <strong>block</strong> falls into a <strong class='color-worm'>wormhole</strong><br>your <strong class='color-f'>energy</strong> overfills to <strong>300%</strong> of the maximum",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
@@ -2837,6 +2869,39 @@ const mod = {
mod.isWormholeEnergy = false mod.isWormholeEnergy = false
} }
}, },
{
name: "transdimensional spores",
description: "when <strong>blocks</strong> fall into a <strong class='color-worm'>wormhole</strong><br>higher dimension <strong class='color-p' style='letter-spacing: 2px;'>spores</strong> are summoned",
maxCount: 1,
count: 0,
allowed() {
return mech.fieldUpgrades[mech.fieldMode].name === "wormhole"
},
requires: "wormhole",
effect() {
mod.isWormSpores = true
},
remove() {
mod.isWormSpores = false
}
},
{
name: "traversable geodesics",
description: "your <strong>bullets</strong> can traverse <strong class='color-worm'>wormholes</strong><br>spawn a <strong class='color-g'>gun</strong> power up",
maxCount: 1,
count: 0,
allowed() {
return mech.fieldUpgrades[mech.fieldMode].name === "wormhole"
},
requires: "wormhole",
effect() {
mod.isWormBullets = true
powerUps.spawn(mech.pos.x, mech.pos.y, "gun");
},
remove() {
mod.isWormBullets = false
}
},
{ {
name: "heals", name: "heals",
description: "spawn <strong>6</strong> <strong class='color-h'>heal</strong> power ups", description: "spawn <strong>6</strong> <strong class='color-h'>heal</strong> power ups",
@@ -3074,5 +3139,9 @@ const mod = {
isPerfectBrake: null, isPerfectBrake: null,
explosiveRadius: null, explosiveRadius: null,
isWormholeEnergy: null, isWormholeEnergy: null,
isWormholeDamage: null isWormholeDamage: null,
isNailCrit: null,
isFlechetteExplode: null,
isWormSpores: null,
isWormBullets: null
} }

View File

@@ -2240,37 +2240,27 @@ const mech = {
}, },
{ {
name: "wormhole", name: "wormhole",
description: "use <strong class='color-f'>energy</strong> to <strong>tunnel</strong> through a <strong class='color-worm'>wormhole</strong><br>bullets may also traverse <strong class='color-worm'>wormholes</strong><br>blocks and power ups can't <strong>exit</strong>", description: "use <strong class='color-f'>energy</strong> to <strong>tunnel</strong> through a <strong class='color-worm'>wormhole</strong><br><strong class='color-worm'>wormholes</strong> attract blocks and power ups", //<br>bullets may also traverse <strong class='color-worm'>wormholes</strong>
effect: () => { effect: () => {
game.replaceTextLog = true; //allow text over write game.replaceTextLog = true; //allow text over write
mech.drop(); mech.drop();
// mech.hole = { //this is reset with each new field, but I'm leaving it here for reference // mech.hole = { //this is reset with each new field, but I'm leaving it here for reference
// isOn: false, // isOn: false,
// isReady: true, // isReady: true,
// pos1: { // pos1: {x: 0,y: 0},
// x: 0, // pos2: {x: 0,y: 0},
// y: 0 // angle: 0,
// }, // unit:{x:0,y:0},
// pos2: {
// x: 0,
// y: 0
// },
// } // }
mech.hold = function () { mech.hold = function () {
if (mech.hole.isOn) { if (mech.hole.isOn) {
// draw holes // draw holes
mech.fieldRange = 0.97 * mech.fieldRange + 0.03 * (50 + 10 * Math.sin(game.cycle * 0.025)) mech.fieldRange = 0.97 * mech.fieldRange + 0.03 * (50 + 10 * Math.sin(game.cycle * 0.025))
//draw bezier curves between the portals
const semiMajorAxis = mech.fieldRange + 30 const semiMajorAxis = mech.fieldRange + 30
const sub = Vector.sub(mech.hole.pos1, mech.hole.pos2) const edge1a = Vector.add(Vector.mult(mech.hole.unit, semiMajorAxis), mech.hole.pos1)
const unit = Vector.perp(Vector.normalise(sub)) const edge1b = Vector.add(Vector.mult(mech.hole.unit, -semiMajorAxis), mech.hole.pos1)
const edge1a = Vector.add(Vector.mult(unit, semiMajorAxis), mech.hole.pos1) const edge2a = Vector.add(Vector.mult(mech.hole.unit, semiMajorAxis), mech.hole.pos2)
const edge1b = Vector.add(Vector.mult(unit, -semiMajorAxis), mech.hole.pos1) const edge2b = Vector.add(Vector.mult(mech.hole.unit, -semiMajorAxis), mech.hole.pos2)
const edge2a = Vector.add(Vector.mult(unit, semiMajorAxis), mech.hole.pos2)
const edge2b = Vector.add(Vector.mult(unit, -semiMajorAxis), mech.hole.pos2)
// const opacity = 200 / mech.fieldRange / mech.fieldRange
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(edge1a.x, edge1a.y) ctx.moveTo(edge1a.x, edge1a.y)
ctx.bezierCurveTo(mech.hole.pos1.x, mech.hole.pos1.y, mech.hole.pos2.x, mech.hole.pos2.y, edge2a.x, edge2a.y); ctx.bezierCurveTo(mech.hole.pos1.x, mech.hole.pos1.y, mech.hole.pos2.x, mech.hole.pos2.y, edge2a.x, edge2a.y);
@@ -2278,10 +2268,9 @@ const mech = {
ctx.bezierCurveTo(mech.hole.pos2.x, mech.hole.pos2.y, mech.hole.pos1.x, mech.hole.pos1.y, edge1b.x, edge1b.y); ctx.bezierCurveTo(mech.hole.pos2.x, mech.hole.pos2.y, mech.hole.pos1.x, mech.hole.pos1.y, edge1b.x, edge1b.y);
ctx.fillStyle = `rgba(255,255,255,${200 / mech.fieldRange / mech.fieldRange})` //"rgba(0,0,0,0.1)" ctx.fillStyle = `rgba(255,255,255,${200 / mech.fieldRange / mech.fieldRange})` //"rgba(0,0,0,0.1)"
ctx.fill(); ctx.fill();
const angle = Math.atan2(sub.y, sub.x)
ctx.beginPath(); ctx.beginPath();
ctx.ellipse(mech.hole.pos1.x, mech.hole.pos1.y, mech.fieldRange, semiMajorAxis, angle, 0, 2 * Math.PI) ctx.ellipse(mech.hole.pos1.x, mech.hole.pos1.y, mech.fieldRange, semiMajorAxis, mech.hole.angle, 0, 2 * Math.PI)
ctx.ellipse(mech.hole.pos2.x, mech.hole.pos2.y, mech.fieldRange, semiMajorAxis, angle, 0, 2 * Math.PI) ctx.ellipse(mech.hole.pos2.x, mech.hole.pos2.y, mech.fieldRange, semiMajorAxis, mech.hole.angle, 0, 2 * Math.PI)
ctx.fillStyle = `rgba(255,255,255,${32 / mech.fieldRange})` ctx.fillStyle = `rgba(255,255,255,${32 / mech.fieldRange})`
ctx.fill(); ctx.fill();
@@ -2318,20 +2307,6 @@ const mech = {
} }
} }
} }
//teleport bullets
for (let i = 0, len = bullet.length; i < len; ++i) { //teleport bullets from hole1 to hole2
if (!bullet[i].botType && !bullet[i].isInHole) { //don't teleport bots
if (Vector.magnitude(Vector.sub(mech.hole.pos1, bullet[i].position)) < mech.fieldRange) { //find if bullet is touching hole1
Matter.Body.setPosition(bullet[i], Vector.add(mech.hole.pos2, Vector.sub(mech.hole.pos1, bullet[i].position)));
mech.fieldRange += 5
bullet[i].isInHole = true
} else if (Vector.magnitude(Vector.sub(mech.hole.pos2, bullet[i].position)) < mech.fieldRange) { //find if bullet is touching hole1
Matter.Body.setPosition(bullet[i], Vector.add(mech.hole.pos1, Vector.sub(mech.hole.pos2, bullet[i].position)));
mech.fieldRange += 5
bullet[i].isInHole = true
}
}
}
//suck and shrink blocks //suck and shrink blocks
const suckRange = 500 const suckRange = 500
const shrinkRange = 100 const shrinkRange = 100
@@ -2354,6 +2329,13 @@ const mech = {
body.splice(i, 1); body.splice(i, 1);
mech.fieldRange *= 0.8 mech.fieldRange *= 0.8
if (mod.isWormholeEnergy && mech.energy < mech.maxEnergy * 3) mech.energy = mech.maxEnergy * 3 if (mod.isWormholeEnergy && mech.energy < mech.maxEnergy * 3) mech.energy = mech.maxEnergy * 3
if (mod.isWormSpores) { //pandimensionalspermia
b.spore(Vector.add(mech.hole.pos2, Vector.rotate({
x: mech.fieldRange,
y: 0
}, 2 * Math.PI * Math.random())))
Matter.Body.setVelocity(bullet[bullet.length - 1], Vector.mult(Vector.rotate(mech.hole.unit, -Math.PI / 2), 15));
}
break break
} }
} }
@@ -2370,45 +2352,58 @@ const mech = {
body.splice(i, 1); body.splice(i, 1);
mech.fieldRange *= 0.8 mech.fieldRange *= 0.8
if (mod.isWormholeEnergy && mech.energy < mech.maxEnergy * 3) mech.energy = mech.maxEnergy * 3 if (mod.isWormholeEnergy && mech.energy < mech.maxEnergy * 3) mech.energy = mech.maxEnergy * 3
if (mod.isWormSpores) { //pandimensionalspermia
b.spore(Vector.add(mech.hole.pos1, Vector.rotate({
x: mech.fieldRange,
y: 0
}, 2 * Math.PI * Math.random())))
Matter.Body.setVelocity(bullet[bullet.length - 1], Vector.mult(Vector.rotate(mech.hole.unit, Math.PI / 2), 15));
}
break break
} }
} }
} }
} }
} }
//mobs get pushed away if (mod.isWormBullets) {
for (let i = 0, len = mob.length; i < len; i++) { //teleport bullets
// if (!mob[i].shield && !mob[i].isShielded) { for (let i = 0, len = bullet.length; i < len; ++i) { //teleport bullets from hole1 to hole2
if (Vector.magnitude(Vector.sub(mech.hole.pos1, mob[i].position)) < 200) { if (!bullet[i].botType && !bullet[i].isInHole) { //don't teleport bots
const pull = Vector.mult(Vector.normalise(Vector.sub(mech.hole.pos1, mob[i].position)), -0.07) if (Vector.magnitude(Vector.sub(mech.hole.pos1, bullet[i].position)) < mech.fieldRange) { //find if bullet is touching hole1
Matter.Body.setVelocity(mob[i], Vector.add(mob[i].velocity, pull)); Matter.Body.setPosition(bullet[i], Vector.add(mech.hole.pos2, Vector.sub(mech.hole.pos1, bullet[i].position)));
mech.fieldRange += 5
bullet[i].isInHole = true
} else if (Vector.magnitude(Vector.sub(mech.hole.pos2, bullet[i].position)) < mech.fieldRange) { //find if bullet is touching hole1
Matter.Body.setPosition(bullet[i], Vector.add(mech.hole.pos1, Vector.sub(mech.hole.pos2, bullet[i].position)));
mech.fieldRange += 5
bullet[i].isInHole = true
}
}
} }
if (Vector.magnitude(Vector.sub(mech.hole.pos2, mob[i].position)) < 200) { // mobs get pushed away
const pull = Vector.mult(Vector.normalise(Vector.sub(mech.hole.pos2, mob[i].position)), -0.07) for (let i = 0, len = mob.length; i < len; i++) {
Matter.Body.setVelocity(mob[i], Vector.add(mob[i].velocity, pull)); if (Vector.magnitude(Vector.sub(mech.hole.pos1, mob[i].position)) < 200) {
const pull = Vector.mult(Vector.normalise(Vector.sub(mech.hole.pos1, mob[i].position)), -0.07)
Matter.Body.setVelocity(mob[i], Vector.add(mob[i].velocity, pull));
}
if (Vector.magnitude(Vector.sub(mech.hole.pos2, mob[i].position)) < 200) {
const pull = Vector.mult(Vector.normalise(Vector.sub(mech.hole.pos2, mob[i].position)), -0.07)
Matter.Body.setVelocity(mob[i], Vector.add(mob[i].velocity, pull));
}
} }
// }
} }
} }
if (mech.isHolding) { if (input.field && mech.fieldCDcycle < mech.cycle) { //not hold but field button is pressed
mech.drawHold(mech.holdingTarget); if (mech.hole.isReady &&
mech.holding(); (Matter.Query.ray(map, mech.pos, game.mouseInGame).length === 0 &&
mech.throwBlock(); Matter.Query.ray(map, mech.pos, Vector.add(Vector.mult(Vector.normalise(Vector.sub(game.mouseInGame, mech.pos)), 50), game.mouseInGame)).length === 0)
} else if ((input.field && mech.fieldCDcycle < mech.cycle)) { //not hold but field button is pressed
// Matter.Query.ray(map, jumpSensor.position, game.mouseInGame).length === 0 ||
if (
mech.hole.isReady && !mech.holdingTarget &&
(
// Matter.Query.ray(map, player.position, game.mouseInGame).length === 0 &&
Matter.Query.ray(map, mech.pos, game.mouseInGame).length === 0 &&
Matter.Query.ray(map, mech.pos, Vector.add(Vector.mult(Vector.normalise(Vector.sub(game.mouseInGame, mech.pos)), 50), game.mouseInGame)).length === 0
)
) { ) {
const sub = Vector.sub(game.mouseInGame, mech.pos) const sub = Vector.sub(game.mouseInGame, mech.pos)
const mag = Vector.magnitude(sub) const mag = Vector.magnitude(sub)
const drain = 0.06 + 0.007 * Math.sqrt(mag) const drain = 0.06 + 0.007 * Math.sqrt(mag)
if (mech.energy > drain && mag > 150) { if (mech.energy > drain && mag > 300) {
mech.energy -= drain mech.energy -= drain
mech.hole.isReady = false; mech.hole.isReady = false;
mech.fieldRange = 0 mech.fieldRange = 0
@@ -2439,6 +2434,8 @@ const mech = {
mech.hole.pos1.y = mech.pos.y mech.hole.pos1.y = mech.pos.y
mech.hole.pos2.x = player.position.x mech.hole.pos2.x = player.position.x
mech.hole.pos2.y = player.position.y mech.hole.pos2.y = player.position.y
mech.hole.angle = Math.atan2(sub.y, sub.x)
mech.hole.unit = Vector.perp(Vector.normalise(sub))
if (mod.isWormholeDamage) { if (mod.isWormholeDamage) {
who = Matter.Query.ray(mob, mech.pos, game.mouseInGame, 60) who = Matter.Query.ray(mob, mech.pos, game.mouseInGame, 60)
@@ -2457,14 +2454,12 @@ const mech = {
} }
} }
} }
} else {
mech.grabPowerUp();
} }
} else {
mech.grabPowerUp();
} }
// mech.grabPowerUp();
// mech.lookForPickUp(); can't pick things up with this field
// if (mech.energy > 0.05) { //can't use shield
// mech.drawField();
// mech.pushMobsFacing();
// }
} 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
mech.pickUp(); mech.pickUp();
} else { } else {

View File

@@ -461,8 +461,8 @@ const powerUps = {
}, },
randomPowerUpCounter: 0, randomPowerUpCounter: 0,
spawnBossPowerUp(x, y) { //boss spawns field and gun mod upgrades spawnBossPowerUp(x, y) { //boss spawns field and gun mod upgrades
// if (game.difficultyMode === 4) powerUps.spawn(x, y, "mod") //why mode gets a free mod
powerUps.randomPowerUpCounter++; powerUps.randomPowerUpCounter++;
if (game.difficultyMode === 4) powerUps.spawn(x, y, "mod") //why mode gets a free mod
const chanceToFail = Math.max(level.levelsCleared, 10) * 0.1 //1 until level 10, then 1.1, 1.2, 1.3, ... const chanceToFail = Math.max(level.levelsCleared, 10) * 0.1 //1 until level 10, then 1.1, 1.2, 1.3, ...
if (Math.random() * chanceToFail < powerUps.randomPowerUpCounter) { if (Math.random() * chanceToFail < powerUps.randomPowerUpCounter) {
powerUps.randomPowerUpCounter = 0; powerUps.randomPowerUpCounter = 0;
@@ -470,6 +470,16 @@ const powerUps = {
} else { } else {
spawnHealthAmmo() spawnHealthAmmo()
} }
if (game.difficultyMode === 4) {
powerUps.randomPowerUpCounter++;
const chanceToFail = Math.max(level.levelsCleared, 10) * 0.1 //1 until level 10, then 1.1, 1.2, 1.3, ...
if (Math.random() * chanceToFail < powerUps.randomPowerUpCounter) {
powerUps.randomPowerUpCounter = 0;
spawnPowerUps()
} else {
spawnHealthAmmo()
}
}
function spawnHealthAmmo() { function spawnHealthAmmo() {
if (mech.health < 0.65 && !mod.isEnergyHealth) { if (mech.health < 0.65 && !mod.isEnergyHealth) {
@@ -511,7 +521,7 @@ const powerUps = {
//bonus power ups for clearing runs in the last game //bonus power ups for clearing runs in the last game
if (level.levelsCleared === 0 && !game.isCheating) { if (level.levelsCleared === 0 && !game.isCheating) {
for (let i = 0; i < localSettings.levelsClearedLastGame / 4 - 1; i++) { for (let i = 0; i < localSettings.levelsClearedLastGame / 4 - 1; i++) {
powerUps.spawn(mech.pos.x, mech.pos.y, "mod", false); //spawn a mod for every 5 levels cleared in last game powerUps.spawn(mech.pos.x, mech.pos.y, "mod", false); //spawn a mod for levels cleared in last game
} }
localSettings.levelsClearedLastGame = 0 //after getting bonus power ups reset run history localSettings.levelsClearedLastGame = 0 //after getting bonus power ups reset run history
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage

View File

@@ -1,33 +1,30 @@
some wormhole bug fixes
wormhole mod: cosmic string - damage mobs when you teleport through them
wormhole mod: Penrose process - overfill energy to 300% of max, with a block gets sucked into a hole
mod: critical bifurcation - nail gun does 400% more damage if it hits very close to the center of a mob
mod: supercritical fission - flechettes explode if they hit very close to the center of a mob
mod: transdimensional spores - after wormholes eat blocks, they disturb spores
mod: traversable geodesics - your bullets can go through worm holes
scrap bots now only last only 30 seconds, but they have a 20% chance to spawn from a kill (was 11%)
the difficulty should feel a bit harder after clearing the boss level
(a bit more more damage taken, and fewer mod drops)
************** TODO - n-gon ************** ************** TODO - n-gon **************
set mouse 4 and 5 for gun switch mod - after a mob or shield dies, remaining dots look for a new nearby host
add an ending to the game add an ending to the game
revamp the boss level, or add a new final level revamp the boss level, or add a new final level
final level requires you to kill something, not skip content final level requires you to kill something
so skipping content is only smart if you are strong enough to beat the final boss
around level 15 around level 15
game never ends if you have used cheats game never ends if you have used cheats
field wormhole
store constant info about the holes: unit, angle to save processing
maybe bullets should be able to enter and exit multiple times
or bullets shouldn't get stuck at all?
maybe give bullets an attraction to holes
player: drain energy when near a hole, does damage if no energy
mod: Hawking radiation: do damage, to mobs that get near the end points
this is good because it explains why mobs don't teleport
mod: extend immunity cycle after a teleport //mech.immuneCycle = mech.cycle + 15;
look for mods that could update description text with count and mod.is information look for mods that could update description text with count and mod.is information
can only use variables that change in effect() and remove() can only use variables that change in effect() and remove()
this.description = `<strong>8%</strong> chance to <strong>duplicate</strong> spawned <strong>power ups</strong><br><em>chance to duplicate = ${mod.duplicateChance}</em>` this.description = `<strong>8%</strong> chance to <strong>duplicate</strong> spawned <strong>power ups</strong><br><em>chance to duplicate = ${mod.duplicateChance}</em>`
mod (drones or spores) explode after 10 seconds mod self destruct - drones explode when they die, but they last 1/2 as long
mouse event e.which is deprecated mouse event e.which is deprecated