diff --git a/js/bullets.js b/js/bullets.js
index b5bebae..b657e88 100644
--- a/js/bullets.js
+++ b/js/bullets.js
@@ -50,6 +50,8 @@ const b = {
isModFoamShieldHit: null,
isModDeathAvoid: null,
isModDeathAvoidOnCD: null,
+ modWaveSpeedMap: null,
+ modWaveSpeedBody: null,
modOnHealthChange() { //used with acid mod
if (b.isModAcidDmg && mech.health > 0.8) {
game.playerDmgColor = "rgba(0,80,80,0.9)"
@@ -245,9 +247,9 @@ const b = {
maxCount: 3,
count: 0,
allowed() {
- return mech.fieldUpgrades[mech.fieldMode].name === "nano-scale manufacturing" || b.haveGunCheck("spores") || b.haveGunCheck("drones") || b.haveGunCheck("super balls") || b.haveGunCheck("foam")
+ return mech.fieldUpgrades[mech.fieldMode].name === "nano-scale manufacturing" || b.haveGunCheck("spores") || b.haveGunCheck("drones") || b.haveGunCheck("super balls") || b.haveGunCheck("foam") || b.haveGunCheck("wave beam")
},
- requires: "drones, spores, super balls, or foam",
+ requires: "drones, spores, super balls,
foam, or wave beam",
effect() {
b.isModBulletsLastLonger += 0.33
},
@@ -770,6 +772,38 @@ const b = {
b.isModFastSpores = false
}
},
+ {
+ name: "ice crystal nucleation",
+ description: "fire ice crystals formed from water vapour
your minigun no longer requires ammo",
+ maxCount: 1,
+ count: 0,
+ allowed() {
+ return b.haveGunCheck("minigun")
+ },
+ requires: "minigun",
+ effect() {
+ for (i = 0, len = b.guns.length; i < len; i++) { //find which gun is flak
+ if (b.guns[i].name === "minigun") {
+ b.guns[i].ammoPack = Infinity
+ b.guns[i].recordedAmmo = b.guns[i].ammo
+ b.guns[i].ammo = Infinity
+ game.updateGunHUD();
+ break;
+ }
+ }
+ },
+ remove() {
+ for (i = 0, len = b.guns.length; i < len; i++) { //find which gun is flak
+ if (b.guns[i].name === "minigun") {
+ b.guns[i].ammoPack = b.guns[i].defaultAmmoPack;
+ b.guns[i].ammo = b.guns[i].recordedAmmo
+ game.updateGunHUD();
+ break;
+ }
+ }
+
+ }
+ },
{
name: "super duper",
description: "you fire +1 additional super ball",
@@ -842,6 +876,25 @@ const b = {
b.isModFoamShieldHit = false;
}
},
+ {
+ name: "wave phase velocity",
+ description: "your wave beam propagates faster through solids",
+ maxCount: 1,
+ count: 0,
+ allowed() {
+ return b.haveGunCheck("wave beam")
+ },
+ requires: "wave beam",
+ effect() {
+ b.modWaveSpeedMap = 3
+ b.modWaveSpeedBody = 1.9
+ },
+ remove() {
+ b.modWaveSpeedMap = 0.08
+ b.modWaveSpeedBody = 0.25
+ }
+ },
+
// {
// name: "super mines",
// description: "mines fire super balls when triggered",
@@ -1681,6 +1734,8 @@ const b = {
description: "rapidly fire a stream of small bullets",
ammo: 0,
ammoPack: 55,
+ defaultAmmoPack: 55,
+ recordedAmmo: 0,
have: false,
isStarterGun: true,
fire() {
@@ -1808,59 +1863,77 @@ const b = {
},
{
name: "wave beam", //4
- description: "emit a sine wave of oscillating particles
particles propagate through walls",
+ description: "emit a sine wave of oscillating particles
particles slowly propagate through solids",
ammo: 0,
- ammoPack: 65,
+ ammoPack: 100,
have: false,
isStarterGun: true,
fire() {
const me = bullet.length;
const dir = mech.angle
+ const SPEED = 10
+ const wiggleMag = mech.crouch ? 4 : 11
bullet[me] = Bodies.polygon(mech.pos.x + 25 * Math.cos(dir), mech.pos.y + 25 * Math.sin(dir), 7, 5 * b.modBulletSize, {
angle: dir,
- cycle: -0.43, //adjust this number until the bullets line up with the cross hairs
- endCycle: game.cycle + Math.floor(100 * b.isModBulletsLastLonger),
+ cycle: 0,
+ endCycle: game.cycle + Math.floor(120 * b.isModBulletsLastLonger),
inertia: Infinity,
frictionAir: 0,
+ slow: 0,
minDmgSpeed: 0,
dmg: 0,
classType: "bullet",
collisionFilter: {
- category: cat.bullet,
+ category: 0,
mask: 0, //cat.mob | cat.mobBullet | cat.mobShield
},
onDmg() {},
onEnd() {},
do() {
if (!mech.isBodiesAsleep) {
- this.cycle++
- this.force = Vector.mult(Vector.normalise(this.direction), wiggleMag * Math.cos(this.cycle * 0.35)) //wiggle
- //check if inside a mob
- const q = Matter.Query.point(mob, this.position)
- for (let i = 0; i < q.length; i++) {
- let dmg = b.dmgScale * 0.5
- q[i].foundPlayer();
- q[i].damage(dmg);
- game.drawList.push({ //add dmg to draw queue
- x: this.position.x,
- y: this.position.y,
- radius: Math.log(2 * dmg + 1.1) * 40,
- color: 'rgba(0,0,0,0.4)',
- time: game.drawTime
- });
+ let slowCheck = 1;
+ if (Matter.Query.point(map, this.position).length) { //check if inside map
+ slowCheck = b.modWaveSpeedMap
+ } else { //check if inside a body
+ let q = Matter.Query.point(body, this.position)
+ if (q.length) {
+ slowCheck = b.modWaveSpeedBody
+ Matter.Body.setPosition(this, Vector.add(this.position, q[0].velocity)) //move with the medium
+ } else { // check if inside a mob
+ q = Matter.Query.point(mob, this.position)
+ for (let i = 0; i < q.length; i++) {
+ slowCheck = 0.3;
+ Matter.Body.setPosition(this, Vector.add(this.position, q[i].velocity)) //move with the medium
+ let dmg = b.dmgScale * 0.1
+ q[i].foundPlayer();
+ q[i].damage(dmg);
+ game.drawList.push({ //add dmg to draw queue
+ x: this.position.x,
+ y: this.position.y,
+ radius: Math.log(2 * dmg + 1.1) * 40,
+ color: 'rgba(0,0,0,0.4)',
+ time: game.drawTime
+ });
+ }
+ }
}
+ if (slowCheck !== this.slow) { //toggle velocity based on inside and outside status change
+ this.slow = slowCheck
+ Matter.Body.setVelocity(this, Vector.mult(Vector.normalise(this.velocity), SPEED * slowCheck));
+ }
+ this.cycle++
+ const wiggle = Vector.mult(transverse, wiggleMag * Math.cos(this.cycle * 0.35))
+ Matter.Body.setPosition(this, Vector.add(this.position, wiggle))
}
}
});
World.add(engine.world, bullet[me]); //add bullet to world
mech.fireCDcycle = mech.cycle + Math.floor(3 * b.modFireRate); // cool down
- const wiggleMag = bullet[me].mass * ((mech.crouch) ? 0.01 : 0.02) * ((mech.flipLegs === 1) ? 1 : -1)
- const SPEED = 8;
Matter.Body.setVelocity(bullet[me], {
x: SPEED * Math.cos(dir),
y: SPEED * Math.sin(dir)
});
- bullet[me].direction = Vector.perp(bullet[me].velocity)
+ const transverse = Vector.normalise(Vector.perp(bullet[me].velocity))
}
},
{
@@ -1994,7 +2067,7 @@ const b = {
bullet[me].endCycle = 2 * i + game.cycle + END
bullet[me].restitution = 0;
bullet[me].friction = 1;
- bullet[me].explodeRad = (mech.crouch ? 85 : 60) + (Math.random() - 0.5) * 50;
+ bullet[me].explodeRad = (mech.crouch ? 95 : 70) + (Math.random() - 0.5) * 50;
bullet[me].onEnd = function () {
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
}
diff --git a/js/index.js b/js/index.js
index dd6f473..ce9d0db 100644
--- a/js/index.js
+++ b/js/index.js
@@ -209,7 +209,7 @@ const build = {
for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]);
bullet = [];
- const increase = Number(document.getElementById("starting-level").value) * game.difficultyMode
+ const increase = Math.min(99, Number(document.getElementById("starting-level").value) * game.difficultyMode)
level.levelsCleared += increase;
level.difficultyIncrease(increase) //increase difficulty based on modes
diff --git a/js/level.js b/js/level.js
index 815e686..853913d 100644
--- a/js/level.js
+++ b/js/level.js
@@ -13,21 +13,21 @@ const level = {
levelsCleared: 0,
start() {
if (level.levelsCleared === 0) {
- // level.difficultyIncrease(14)
- // b.giveGuns("foam")
+ level.difficultyIncrease(5)
+ // b.giveGuns("wave beam")
// mech.setField("negative mass field")
// for (let i = 0; i < 9; i++) {
- // b.giveMod("foam stabilization");
+ // b.giveMod("wave phase velocity");
// b.giveMod("anthropic principle");
// b.giveMod("acute stress response");
// }
- level.intro(); //starting level
+ // level.intro(); //starting level
// level.testingMap();
// level.bosses();
// level.satellite();
// level.skyscrapers();
- // level.aerie();
+ level.aerie();
// level.rooftops();
// level.warehouse();
// level.highrise();
@@ -143,7 +143,7 @@ const level = {
// powerUps.spawn(450, -400, "mod", false, 6);
// powerUps.spawn(450, -400, "mod", false);
// spawn.bodyRect(-45, -100, 40, 50);
- spawn.bomberBoss(800, -450);
+ spawn.springer(800, -450);
// spawn.cellBoss(400, -750);
// spawn.randomLevelBoss(400, -750)
@@ -889,17 +889,6 @@ const level = {
spawn.mapRect(2000, -75, 450, 275);
spawn.bodyRect(2450, 150, 150, 150, 0.4);
spawn.mapRect(1550, 300, 4600, 200); //ground
- //floor below right tall tower
- spawn.bodyRect(3000, 50, 150, 250, 0.9);
- spawn.bodyRect(4500, -500, 300, 250, 0.7);
- spawn.bodyRect(3500, -100, 100, 150, 0.7);
- spawn.bodyRect(4200, -500, 110, 30, 0.7);
- spawn.bodyRect(3800, -500, 150, 130, 0.7);
- spawn.bodyRect(4000, 50, 200, 150, 0.9);
- spawn.bodyRect(4500, 50, 300, 200, 0.9);
- spawn.bodyRect(4200, -350, 200, 50, 0.9);
- spawn.bodyRect(4700, -350, 50, 200, 0.9);
- spawn.bodyRect(4900, -100, 300, 300, 0.7);
spawn.boost(5350, 275, 2850);
// spawn.mapRect(6050, -700, 450, 1200);
spawn.mapRect(6050, -1060, 450, 1560);
@@ -941,8 +930,33 @@ const level = {
spawn.randomBoss(350, -500, 1)
spawn.randomBoss(4000, -350, 0.6);
spawn.randomBoss(2750, -550, 0.1);
- if (game.difficulty > 2) spawn.suckerBoss(4500, -400);
-
+ if (game.difficulty > 2) {
+ if (Math.random() < 0.3) { // tether ball
+ spawn.tetherBoss(4250, 0)
+ cons[cons.length] = Constraint.create({
+ pointA: {
+ x: 4250,
+ y: -675
+ },
+ bodyB: mob[mob.length - 1],
+ stiffness: 0.00007
+ });
+ if (game.difficulty > 4) spawn.nodeBoss(4250, 0, "spawns", 8, 20, 105); //chance to spawn a ring of exploding mobs around this boss
+ } else {
+ //floor below right tall tower
+ spawn.bodyRect(3000, 50, 150, 250, 0.9);
+ spawn.bodyRect(4500, -500, 300, 250, 0.7);
+ spawn.bodyRect(3500, -100, 100, 150, 0.7);
+ spawn.bodyRect(4200, -500, 110, 30, 0.7);
+ spawn.bodyRect(3800, -500, 150, 130, 0.7);
+ spawn.bodyRect(4000, 50, 200, 150, 0.9);
+ spawn.bodyRect(4500, 50, 300, 200, 0.9);
+ spawn.bodyRect(4200, -350, 200, 50, 0.9);
+ spawn.bodyRect(4700, -350, 50, 200, 0.9);
+ spawn.bodyRect(4900, -100, 300, 300, 0.7);
+ spawn.suckerBoss(4500, -400);
+ }
+ }
//add mini boss, giant hopper? or a black hole that spawns hoppers?
},
skyscrapers() {
@@ -1599,7 +1613,7 @@ const level = {
spawn.randomBoss(4150, -1000, 0.6);
if (game.difficulty > 2) {
- if (Math.random() < 0.7) {
+ if (Math.random() < 0.75) {
// tether ball
level.fillBG.push({
x: 2495,
@@ -1621,9 +1635,7 @@ const level = {
if (game.difficulty > 4) spawn.nodeBoss(2850, -80, "spawns", 8, 20, 105);
} else if (game.difficulty > 3) {
spawn.shooterBoss(2200, -650);
-
}
-
}
},
//*****************************************************************************************************************
diff --git a/js/player.js b/js/player.js
index 9db1818..e3cf049 100644
--- a/js/player.js
+++ b/js/player.js
@@ -331,10 +331,12 @@ const mech = {
//find what mods I don't have
let options = [];
for (let i = 0, len = b.mods.length; i < len; i++) {
- if (b.mods[i].name !== "quantum immortality" &&
+ if (b.mods[i].count < b.mods[i].maxCount &&
+ b.mods[i].name !== "quantum immortality" &&
b.mods[i].name !== "Born rule" &&
b.mods[i].name !== "leveraged investment" &&
- b.mods[i].count < b.mods[i].maxCount) options.push(i);
+ b.mods[i].allowed()
+ ) options.push(i);
}
//add a new mod
if (options.length > 0) {
@@ -383,16 +385,16 @@ const mech = {
ctx.fillStyle = "rgba(255,255,255,0)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
- randomizeMods()
- randomizeGuns()
- randomizeField()
randomizeHealth()
+ randomizeField()
+ randomizeGuns()
+ randomizeMods()
for (let i = 0, len = 7; i < len; i++) {
setTimeout(function () {
- randomizeMods()
- randomizeGuns()
- randomizeField()
randomizeHealth()
+ randomizeField()
+ randomizeGuns()
+ randomizeMods()
game.replaceTextLog = true;
game.makeTextLog(`probability amplitude will synchronize in ${len-i-1} seconds`, 1000);
game.wipe = function () { //set wipe to have trails
@@ -463,7 +465,6 @@ const mech = {
}
mech.health -= dmg;
if (mech.health < 0) {
- console.log(b.isModDeathAvoid, b.isModDeathAvoidOnCD)
if (b.isModDeathAvoid && !b.isModDeathAvoidOnCD) { //&& Math.random() < 0.5
b.isModDeathAvoidOnCD = true;
mech.health += dmg //undo the damage
diff --git a/js/spawn.js b/js/spawn.js
index 0a33e9e..d2d78d3 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -330,15 +330,15 @@ const spawn = {
};
},
springer(x, y, radius = 20 + Math.ceil(Math.random() * 35)) {
- mobs.spawn(x, y, 8, radius, "#b386e8");
+ mobs.spawn(x, y, 10, radius, "#b386e8");
let me = mob[mob.length - 1];
me.friction = 0;
- me.frictionAir = 0.1;
- me.lookTorque = 0.000005;
+ me.frictionAir = 0.006;
+ me.lookTorque = 0.0000008; //controls spin while looking for player
me.g = 0.0002; //required if using 'gravity'
me.seePlayerFreq = Math.round((40 + 25 * Math.random()) * game.lookFreqScale);
- const springStiffness = 0.002;
- const springDampening = 0.1;
+ const springStiffness = 0.00014;
+ const springDampening = 0.0005;
me.springTarget = {
x: me.position.x,
diff --git a/todo.txt b/todo.txt
index d5355dc..e694c58 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,7 +1,17 @@
************** TODO - n-gon **************
-mod - Collision avoidance system
- 10% chance to dodge a collision
+level - add wrecking ball boss to other levels
+ it could work on rooftops and satellite
+
+mod - make bodies destroyable
+ they drop ammo and heals
+
+mod - BIOS update
+ lose all mods other than BIOS update
+ deal +100% damage from all sources
+mod - Infrared Sensors
+ You can see invisible enemies
+ this seems weak, maybe add to one of the fields
mod - mines - fire something instead of needles on activation
foam?, flak?, vacuum bomb, super balls