diff --git a/js/bullet.js b/js/bullet.js
index a726528..f9a0c93 100644
--- a/js/bullet.js
+++ b/js/bullet.js
@@ -108,7 +108,7 @@ const b = {
mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield
},
minDmgSpeed: 10,
- onDmg() {}, //this.endCycle = 0 //triggers despawn
+ beforeDmg() {}, //this.endCycle = 0 //triggers despawn
onEnd() {}
};
} else {
@@ -125,7 +125,7 @@ const b = {
mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield
},
minDmgSpeed: 10,
- onDmg() {}, //this.endCycle = 0 //triggers despawn
+ beforeDmg() {}, //this.endCycle = 0 //triggers despawn
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;
- 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;
Matter.Body.setVelocity(bullet[me], {
- x: mech.Vx / 2 + speed * Math.cos(dir),
- y: mech.Vy / 2 + speed * Math.sin(dir)
+ x: mech.Vx / 2 + speed * Math.cos(angle),
+ y: mech.Vy / 2 + speed * Math.sin(angle)
});
World.add(engine.world, bullet[me]); //add bullet to world
bullet[me].frictionAir = 0.023
@@ -300,7 +300,7 @@ const b = {
}
}
}
- bullet[me].onDmg = function () {
+ bullet[me].beforeDmg = function () {
this.tryToLockOn();
this.endCycle = 0; //bullet ends cycle after doing damage // also triggers explosion
};
@@ -557,7 +557,7 @@ const b = {
endCycle: Infinity,
lookFrequency: 0,
range: 700,
- onDmg() {},
+ beforeDmg() {},
do() {
this.force.y += this.mass * 0.002; //extra gravity
let collide = Matter.Query.collides(this, map) //check if collides with map
@@ -686,7 +686,7 @@ const b = {
x: 100 * (Math.random() - 0.5),
y: 100 * (Math.random() - 0.5)
},
- onDmg(who) {
+ beforeDmg(who) {
this.endCycle = 0; //bullet ends cycle after doing damage
if (this.isFreeze) mobs.statusSlow(who, 60)
},
@@ -800,7 +800,7 @@ const b = {
minDmgSpeed: 0,
lockedOn: null,
isFollowMouse: true,
- onDmg(who) {
+ beforeDmg(who) {
mobs.statusSlow(who, 60)
this.endCycle = game.cycle
if (mod.isHeavyWater) mobs.statusDoT(who, 0.15, 300)
@@ -877,7 +877,7 @@ const b = {
isFollowMouse: true,
deathCycles: 110 + RADIUS * 5,
isImproved: false,
- onDmg(who) {
+ beforeDmg(who) {
//move away from target after hitting
const unit = Vector.mult(Vector.normalise(Vector.sub(this.position, who.position)), -20)
Matter.Body.setVelocity(this, {
@@ -1002,7 +1002,7 @@ const b = {
target: null,
targetVertex: null,
targetRelativePosition: null,
- onDmg(who) {
+ beforeDmg(who) {
if (!this.target && who.alive) {
this.target = who;
if (who.radius < 20) {
@@ -1154,15 +1154,14 @@ const b = {
},
nail(pos, velocity, dmg = 0) {
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)));
-
Matter.Body.setVelocity(bullet[me], velocity);
World.add(engine.world, bullet[me]); //add bullet to world
bullet[me].endCycle = game.cycle + 60 + 18 * Math.random();
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.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 () {};
},
@@ -1227,7 +1226,7 @@ const b = {
mask: cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield
},
lockedOn: null,
- onDmg() {
+ beforeDmg() {
this.lockedOn = null
},
onEnd() {},
@@ -1283,7 +1282,7 @@ const b = {
mask: cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield
},
lockedOn: null,
- onDmg() {
+ beforeDmg() {
this.lockedOn = null
},
onEnd() {},
@@ -1342,7 +1341,7 @@ const b = {
mask: cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield
},
lockedOn: null,
- onDmg() {
+ beforeDmg() {
this.lockedOn = null
},
onEnd() {},
@@ -1452,7 +1451,7 @@ const b = {
},
lockedOn: null,
explode: 0,
- onDmg() {
+ beforeDmg() {
if (this.lockedOn) {
const explosionRadius = Math.min(170 + 140 * this.isUpgraded, Vector.magnitude(Vector.sub(this.position, mech.pos)) - 30)
if (explosionRadius > 60) {
@@ -1528,7 +1527,7 @@ const b = {
mask: cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield
},
lockedOn: null,
- onDmg() {
+ beforeDmg() {
this.lockedOn = null
},
onEnd() {},
@@ -1706,7 +1705,7 @@ const b = {
category: cat.bullet,
mask: 0 //cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield
},
- onDmg() {},
+ beforeDmg() {},
onEnd() {},
range: 190 + 50 * mod.isOrbitBotUpgrade, //range is set in bot upgrade too! //150 + (80 + 100 * mod.isOrbitBotUpgrade) * Math.random(), // + 5 * mod.orbitBotCount,
orbitalSpeed: 0,
@@ -1850,7 +1849,7 @@ const b = {
y: mech.Vy / 2 + speed * Math.sin(angle)
}, dmg) //position, velocity, damage
if (mod.isIceCrystals) {
- bullet[bullet.length - 1].onDmg = function (who) {
+ bullet[bullet.length - 1].beforeDmg = function (who) {
mobs.statusSlow(who, 30)
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 () {
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)
};
} else {
@@ -2031,6 +2030,11 @@ const b = {
}
} else {
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();
if (mod.isFastDot) {
mobs.statusDoT(who, 3.78, 30)
@@ -2120,7 +2124,7 @@ const b = {
category: 0,
mask: 0, //cat.mob | cat.mobBullet | cat.mobShield
},
- onDmg() {},
+ beforeDmg() {},
onEnd() {},
do() {
if (!mech.isBodiesAsleep) {
@@ -2309,7 +2313,7 @@ const b = {
bullet[me].onEnd = function () {
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
};
bullet[me].do = function () {
@@ -2335,7 +2339,7 @@ const b = {
if (mod.grenadeFragments) b.targetedNail(this.position, mod.grenadeFragments)
}
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
};
@@ -2401,7 +2405,7 @@ const b = {
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
};
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].stuckTo = null;
bullet[me].stuckToRelativePosition = null;
- bullet[me].onDmg = function () {};
+ bullet[me].beforeDmg = function () {};
bullet[me].stuck = function () {};
bullet[me].do = function () {
function onCollide(that) {
@@ -2682,7 +2686,7 @@ const b = {
bullet[me].minDmgSpeed = 0;
bullet[me].totalSpores = 8 + 2 * mod.isFastSpores + 2 * mod.isSporeFreeze
bullet[me].stuck = function () {};
- bullet[me].onDmg = function () {};
+ bullet[me].beforeDmg = function () {};
bullet[me].do = function () {
function onCollide(that) {
that.collisionFilter.mask = 0; //non collide with everything
@@ -2850,7 +2854,7 @@ const b = {
name: "rail gun",
description: "use energy to launch a high-speed dense rod
hold left mouse to charge, release to fire",
ammo: 0,
- ammoPack: 3,
+ ammoPack: 3.5,
have: false,
fire() {
if (mod.isCapacitor) {
@@ -2871,7 +2875,7 @@ const b = {
},
minDmgSpeed: 5,
endCycle: game.cycle + 140,
- onDmg(who) {
+ beforeDmg(who) {
if (who.shield) {
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
@@ -2880,10 +2884,10 @@ const b = {
}
}
Matter.Body.setVelocity(this, {
- x: -0.1 * this.velocity.x,
- y: -0.1 * this.velocity.y
+ x: -0.5 * this.velocity.x,
+ y: -0.5 * this.velocity.y
});
- Matter.Body.setDensity(this, 0.001);
+ // Matter.Body.setDensity(this, 0.001);
}
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
@@ -2980,7 +2984,7 @@ const b = {
mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield
},
minDmgSpeed: 5,
- onDmg(who) {
+ beforeDmg(who) {
if (who.shield) {
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
@@ -3472,7 +3476,7 @@ const b = {
// },
// minDmgSpeed: 5,
// range: 0,
- // onDmg() {
+ // beforeDmg() {
// this.endCycle = 0;
// }, //this.endCycle = 0 //triggers despawn
// onEnd() {},
diff --git a/js/engine.js b/js/engine.js
index ab467b4..5092847 100644
--- a/js/engine.js
+++ b/js/engine.js
@@ -173,11 +173,11 @@ function collisionChecks(event) {
}
//mob + bullet collisions
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)))
if (mod.isCrit && mob[k].isStunned) dmg *= 4
mob[k].foundPlayer();
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
x: pairs[i].activeContacts[0].vertex.x,
y: pairs[i].activeContacts[0].vertex.y,
diff --git a/js/level.js b/js/level.js
index 3a2f756..217884b 100644
--- a/js/level.js
+++ b/js/level.js
@@ -15,12 +15,12 @@ const level = {
// game.zoomScale = 1000;
// game.setZoom();
// mech.isCloak = true;
- mech.setField("wormhole")
- // b.giveGuns("nail gun")
+ // mech.setField("wormhole")
+ // b.giveGuns("flechettes")
// for (let i = 0; i < 10; i++) {
// mod.giveMod("laser-bot");
// }
- mod.giveMod("cosmic string")
+ // mod.giveMod("supercritical fission")
level.intro(); //starting level
@@ -149,10 +149,10 @@ const level = {
// spawn.sniper(1700, -120, 50)
// spawn.bomberBoss(1400, -500)
// spawn.sniper(1800, -120)
- // spawn.sniper(2200, -120)
// spawn.cellBossCulture(1600, -500)
- spawn.powerUpBoss(1600, -500)
- // spawn.shield(mob[mob.length - 1], 1200, -500, 1);
+ // spawn.powerUpBoss(1600, -500)
+ spawn.sniper(1200, -500)
+ spawn.shield(mob[mob.length - 1], 1200, -500, 1);
// spawn.nodeBoss(1200, -500, "launcher")
// spawn.snakeBoss(1200, -500)
@@ -3841,7 +3841,7 @@ const level = {
difficultyIncrease(num = 1) {
for (let i = 0; i < num; i++) {
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
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
@@ -3852,7 +3852,7 @@ const level = {
difficultyDecrease(num = 1) { //used in easy mode for game.reset()
for (let i = 0; i < num; i++) {
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;
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
@@ -3887,6 +3887,7 @@ const level = {
if (level.onLevel > level.levels.length - 1) level.onLevel = 0;
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 * 1.25) 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 (game.isEasyMode && level.levelsCleared % 2) level.difficultyDecrease(1);
diff --git a/js/mob.js b/js/mob.js
index 993a959..7069aad 100644
--- a/js/mob.js
+++ b/js/mob.js
@@ -1043,7 +1043,10 @@ const mobs = {
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.nailsDeathMob) b.targetedNail(this.position, mod.nailsDeathMob, 40 + 7 * Math.random())
} else if (mod.isShieldAmmo && this.shield) {
diff --git a/js/mods.js b/js/mods.js
index 16c3875..623ce66 100644
--- a/js/mods.js
+++ b/js/mods.js
@@ -408,7 +408,7 @@ const mod = {
maxCount: 9,
count: 0,
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",
effect: () => {
@@ -424,7 +424,7 @@ const mod = {
maxCount: 1,
count: 0,
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",
effect: () => {
@@ -440,7 +440,7 @@ const mod = {
maxCount: 1,
count: 0,
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",
effect: () => {
@@ -457,7 +457,7 @@ const mod = {
maxCount: 1,
count: 0,
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",
effect: () => {
@@ -469,15 +469,15 @@ const mod = {
},
{
name: "scrap bots",
- description: "11% chance to build a bot after killing a mob
the bot only functions until the end of the level",
- maxCount: 6,
+ description: "19% chance to build a bot after killing a mob
the bot last for about 30 seconds",
+ maxCount: 3,
count: 0,
allowed() {
return mod.totalBots() > 0
},
requires: "a bot",
effect() {
- mod.isBotSpawner += 0.11;
+ mod.isBotSpawner += 0.19;
},
remove() {
mod.isBotSpawner = 0;
@@ -1596,6 +1596,22 @@ const mod = {
mod.isDamageFromBulletCount = false
}
},
+ {
+ name: "critical bifurcation",
+ description: "nails do 400% more damage
when they strike near the center 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",
description: "nail gun takes 45% less time to ramp up
to it's shortest delay after firing",
@@ -1843,15 +1859,31 @@ const mod = {
mod.isFastDot = false;
}
},
+ {
+ name: "supercritical fission",
+ description: "flechettes can explode
if they strike mobs near their center",
+ 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",
description: "needles penetrate mobs and blocks
potentially hitting multiple targets",
maxCount: 1,
count: 0,
allowed() {
- return mod.haveGunCheck("flechettes")
+ return mod.haveGunCheck("flechettes") && !mod.isFlechetteExplode
},
- requires: "flechettes",
+ requires: "flechettes and not supercritical fission",
effect() {
mod.pierce = true;
},
@@ -2807,7 +2839,7 @@ const mod = {
},
{
name: "cosmic string",
- description: "when you tunnel through a wormhole
damage mobs between the endpoints",
+ description: "when you tunnel through a wormhole
mobs between the endpoints take damage",
maxCount: 1,
count: 0,
allowed() {
@@ -2823,7 +2855,7 @@ const mod = {
},
{
name: "Penrose process",
- description: "after a block falls into a wormhole
overfill your energy to 300% of your maximum
",
+ description: "after a block falls into a wormhole
your energy overfills to 300% of the maximum",
maxCount: 1,
count: 0,
allowed() {
@@ -2837,6 +2869,39 @@ const mod = {
mod.isWormholeEnergy = false
}
},
+ {
+ name: "transdimensional spores",
+ description: "when blocks fall into a wormhole
higher dimension spores 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 bullets can traverse wormholes
spawn a gun 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",
description: "spawn 6 heal power ups",
@@ -3074,5 +3139,9 @@ const mod = {
isPerfectBrake: null,
explosiveRadius: null,
isWormholeEnergy: null,
- isWormholeDamage: null
+ isWormholeDamage: null,
+ isNailCrit: null,
+ isFlechetteExplode: null,
+ isWormSpores: null,
+ isWormBullets: null
}
\ No newline at end of file
diff --git a/js/player.js b/js/player.js
index 488f210..b7a4cf4 100644
--- a/js/player.js
+++ b/js/player.js
@@ -2240,37 +2240,27 @@ const mech = {
},
{
name: "wormhole",
- description: "use energy to tunnel through a wormhole
bullets may also traverse wormholes
blocks and power ups can't exit",
+ description: "use energy to tunnel through a wormhole
wormholes attract blocks and power ups", //
bullets may also traverse wormholes
effect: () => {
game.replaceTextLog = true; //allow text over write
mech.drop();
// mech.hole = { //this is reset with each new field, but I'm leaving it here for reference
// isOn: false,
// isReady: true,
- // pos1: {
- // x: 0,
- // y: 0
- // },
- // pos2: {
- // x: 0,
- // y: 0
- // },
+ // pos1: {x: 0,y: 0},
+ // pos2: {x: 0,y: 0},
+ // angle: 0,
+ // unit:{x:0,y:0},
// }
mech.hold = function () {
-
if (mech.hole.isOn) {
// draw holes
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 sub = Vector.sub(mech.hole.pos1, mech.hole.pos2)
- const unit = Vector.perp(Vector.normalise(sub))
- const edge1a = Vector.add(Vector.mult(unit, semiMajorAxis), mech.hole.pos1)
- const edge1b = Vector.add(Vector.mult(unit, -semiMajorAxis), mech.hole.pos1)
- 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
+ const edge1a = Vector.add(Vector.mult(mech.hole.unit, semiMajorAxis), mech.hole.pos1)
+ const edge1b = Vector.add(Vector.mult(mech.hole.unit, -semiMajorAxis), mech.hole.pos1)
+ const edge2a = Vector.add(Vector.mult(mech.hole.unit, semiMajorAxis), mech.hole.pos2)
+ const edge2b = Vector.add(Vector.mult(mech.hole.unit, -semiMajorAxis), mech.hole.pos2)
ctx.beginPath();
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);
@@ -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.fillStyle = `rgba(255,255,255,${200 / mech.fieldRange / mech.fieldRange})` //"rgba(0,0,0,0.1)"
ctx.fill();
- const angle = Math.atan2(sub.y, sub.x)
ctx.beginPath();
- ctx.ellipse(mech.hole.pos1.x, mech.hole.pos1.y, mech.fieldRange, semiMajorAxis, 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.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, mech.hole.angle, 0, 2 * Math.PI)
ctx.fillStyle = `rgba(255,255,255,${32 / mech.fieldRange})`
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
const suckRange = 500
const shrinkRange = 100
@@ -2354,6 +2329,13 @@ const mech = {
body.splice(i, 1);
mech.fieldRange *= 0.8
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
}
}
@@ -2370,45 +2352,58 @@ const mech = {
body.splice(i, 1);
mech.fieldRange *= 0.8
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
}
}
}
}
}
- //mobs get pushed away
- for (let i = 0, len = mob.length; i < len; i++) {
- // if (!mob[i].shield && !mob[i].isShielded) {
- 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 (mod.isWormBullets) {
+ //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
+ }
+ }
}
- 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));
+ // mobs get pushed away
+ for (let i = 0, len = mob.length; i < len; i++) {
+ 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) {
- mech.drawHold(mech.holdingTarget);
- mech.holding();
- mech.throwBlock();
- } 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
- )
+ if (input.field && mech.fieldCDcycle < mech.cycle) { //not hold but field button is pressed
+ if (mech.hole.isReady &&
+ (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 mag = Vector.magnitude(sub)
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.hole.isReady = false;
mech.fieldRange = 0
@@ -2439,6 +2434,8 @@ const mech = {
mech.hole.pos1.y = mech.pos.y
mech.hole.pos2.x = player.position.x
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) {
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
mech.pickUp();
} else {
diff --git a/js/powerup.js b/js/powerup.js
index 6ec6823..ad69265 100644
--- a/js/powerup.js
+++ b/js/powerup.js
@@ -461,8 +461,8 @@ const powerUps = {
},
randomPowerUpCounter: 0,
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++;
- 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, ...
if (Math.random() * chanceToFail < powerUps.randomPowerUpCounter) {
powerUps.randomPowerUpCounter = 0;
@@ -470,6 +470,16 @@ const powerUps = {
} else {
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() {
if (mech.health < 0.65 && !mod.isEnergyHealth) {
@@ -511,7 +521,7 @@ const powerUps = {
//bonus power ups for clearing runs in the last game
if (level.levelsCleared === 0 && !game.isCheating) {
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
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
diff --git a/todo.txt b/todo.txt
index 639d857..e6d78ae 100644
--- a/todo.txt
+++ b/todo.txt
@@ -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 **************
-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
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
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
can only use variables that change in effect() and remove()
this.description = `8% chance to duplicate spawned power ups
chance to duplicate = ${mod.duplicateChance}`
-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