diff --git a/js/bullet.js b/js/bullet.js
index 3e807d8..188b99d 100644
--- a/js/bullet.js
+++ b/js/bullet.js
@@ -398,7 +398,7 @@ const b = {
const that = this
setTimeout(function () {
if (Matter.Query.collides(that, map).length === 0 || Matter.Query.point(map, that.position).length > 0) {
- console.log(that)
+ // console.log(that)
that.endCycle = 0 // if not touching map explode
that.isArmed = false
b.mine(that.position, that.velocity, that.angle)
@@ -1203,27 +1203,43 @@ const b = {
player.force.y -= knock * Math.sin(mech.angle) * 0.3 //reduce knock back in vertical direction to stop super jumps
if (mod.isShotgunImmune) mech.immuneCycle = mech.cycle + 60; //player is immune to collision damage for 30 cycles
b.muzzleFlash(35);
- const side = 19 * mod.bulletSize
- for (let i = 0; i < 15; i++) {
- const me = bullet.length;
- const dir = mech.angle + (Math.random() - 0.5) * spread
- bullet[me] = Bodies.rectangle(mech.pos.x + 35 * Math.cos(mech.angle) + 15 * (Math.random() - 0.5), mech.pos.y + 35 * Math.sin(mech.angle) + 15 * (Math.random() - 0.5), side, side, b.fireAttributes(dir));
- World.add(engine.world, bullet[me]); //add bullet to world
- const SPEED = 50 + Math.random() * 10
- Matter.Body.setVelocity(bullet[me], {
- x: SPEED * Math.cos(dir),
- y: SPEED * Math.sin(dir)
- });
- bullet[me].endCycle = game.cycle + 40
- bullet[me].minDmgSpeed = 20
- // bullet[me].dmg = 0.1
- bullet[me].frictionAir = 0.034;
- bullet[me].do = function () {
- if (!mech.isBodiesAsleep) {
- const scale = 1 - 0.035 / mod.isBulletsLastLonger
- Matter.Body.scale(this, scale, scale);
+ if (mod.isNailShot) {
+ for (let i = 0; i < 15; i++) {
+ const dir = mech.angle + (Math.random() - 0.5) * spread * 0.2
+ const pos = {
+ x: mech.pos.x + 35 * Math.cos(mech.angle) + 15 * (Math.random() - 0.5),
+ y: mech.pos.y + 35 * Math.sin(mech.angle) + 15 * (Math.random() - 0.5)
}
- };
+ speed = 35 + 15 * Math.random()
+ const velocity = {
+ x: speed * Math.cos(dir),
+ y: speed * Math.sin(dir)
+ }
+ b.nail(pos, velocity, 0.6)
+ }
+ } else {
+ const side = 19 * mod.bulletSize
+ for (let i = 0; i < 15; i++) {
+ const me = bullet.length;
+ const dir = mech.angle + (Math.random() - 0.5) * spread
+ bullet[me] = Bodies.rectangle(mech.pos.x + 35 * Math.cos(mech.angle) + 15 * (Math.random() - 0.5), mech.pos.y + 35 * Math.sin(mech.angle) + 15 * (Math.random() - 0.5), side, side, b.fireAttributes(dir));
+ World.add(engine.world, bullet[me]); //add bullet to world
+ const SPEED = 50 + Math.random() * 10
+ Matter.Body.setVelocity(bullet[me], {
+ x: SPEED * Math.cos(dir),
+ y: SPEED * Math.sin(dir)
+ });
+ bullet[me].endCycle = game.cycle + 40
+ bullet[me].minDmgSpeed = 20
+ // bullet[me].dmg = 0.1
+ bullet[me].frictionAir = 0.034;
+ bullet[me].do = function () {
+ if (!mech.isBodiesAsleep) {
+ const scale = 1 - 0.035 / mod.isBulletsLastLonger
+ Matter.Body.scale(this, scale, scale);
+ }
+ };
+ }
}
}
},
diff --git a/js/level.js b/js/level.js
index 4df99eb..d770020 100644
--- a/js/level.js
+++ b/js/level.js
@@ -23,8 +23,8 @@ const level = {
// mech.setField("pilot wave")
// mech.setField("phase decoherence field")
- // level.intro(); //starting level
- level.testing();
+ level.intro(); //starting level
+ // level.testing();
// level.stronghold()
// level.bosses();
// level.satellite();
@@ -184,9 +184,9 @@ const level = {
// spawn.bomberBoss(2900, -500)
// spawn.launcherBoss(1200, -500)
- // spawn.sniper(1600, -400)
+ spawn.laserTargetingBoss(1600, -400)
// spawn.sneaker(1600, -500)
- spawn.sniper(1700, -120)
+ // spawn.sniper(1700, -120)
// spawn.cellBossCulture(1600, -500)
// spawn.shooter(1600, -500)
// spawn.striker(1600, -500)
diff --git a/js/mob.js b/js/mob.js
index f85b586..978ac4e 100644
--- a/js/mob.js
+++ b/js/mob.js
@@ -467,7 +467,7 @@ const mobs = {
//draw damage
ctx.fillStyle = "#f00";
ctx.beginPath();
- ctx.arc(best.x, best.y, dmg * 2000, 0, 2 * Math.PI);
+ ctx.arc(best.x, best.y, dmg * 10000, 0, 2 * Math.PI);
ctx.fill();
}
}
diff --git a/js/mods.js b/js/mods.js
index 8d38775..8111fbb 100644
--- a/js/mods.js
+++ b/js/mods.js
@@ -947,7 +947,7 @@ const mod = {
{
name: "microstates",
description: "+7% damage for every 10 active bullets",
- maxCount: 3,
+ maxCount: 1,
count: 0,
allowed() {
return mod.isBulletsLastLonger > 1
@@ -1046,6 +1046,22 @@ const mod = {
mod.isShotgunImmune = false;
}
},
+ {
+ name: "nailshot",
+ description: "the shotgun fires nails
effective at a distance",
+ maxCount: 1,
+ count: 0,
+ allowed() {
+ return mod.haveGunCheck("shotgun")
+ },
+ requires: "shotgun",
+ effect() {
+ mod.isNailShot = true;
+ },
+ remove() {
+ mod.isNailShot = false;
+ }
+ },
{
name: "super duper",
description: "fire +2 additional super balls",
@@ -1362,7 +1378,7 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
- return mod.nailBotCount > 1 || mod.haveGunCheck("mine") || mod.grenadeFragments > 5 || mod.isRailNails || mod.nailsDeathMob > 2
+ return mod.nailBotCount + mod.grenadeFragments + mod.nailsDeathMob > 1 || mod.haveGunCheck("mine") || mod.isRailNails || mod.isNailShot
},
requires: "nails",
effect() {
@@ -1838,4 +1854,5 @@ const mod = {
manyWorlds: null,
isDamageFromBulletCount: null,
isLaserDiode: null,
+ isNailShot: null
}
\ No newline at end of file
diff --git a/js/powerup.js b/js/powerup.js
index 0ba6da9..ef11596 100644
--- a/js/powerup.js
+++ b/js/powerup.js
@@ -389,37 +389,53 @@ const powerUps = {
}
},
spawnBossPowerUp(x, y) { //boss spawns field and gun mod upgrades
- if (mech.fieldMode === 0) {
- powerUps.spawn(x, y, "field")
- if (Math.random() < mod.bayesian) powerUps.spawn(x, y, "field")
- } else if (Math.random() < 0.9) {
- powerUps.spawn(x, y, "mod")
- if (Math.random() < mod.bayesian) powerUps.spawn(x, y, "mod")
- } else if (Math.random() < 0.5) {
- powerUps.spawn(x, y, "gun")
- if (Math.random() < mod.bayesian) powerUps.spawn(x, y, "gun")
- // } else if (Math.random() < 0.5) {
- // powerUps.spawn(x, y, "field");
- // if (Math.random() < mod.bayesian) powerUps.spawn(x, y, "field");
- } else if (mech.health < 0.65 && !mod.isEnergyHealth) {
- powerUps.spawn(x, y, "heal");
- powerUps.spawn(x, y, "heal");
- powerUps.spawn(x, y, "heal");
- powerUps.spawn(x, y, "heal");
- powerUps.spawn(x, y, "heal");
- powerUps.spawn(x, y, "heal");
- if (Math.random() < mod.bayesian) {
- powerUps.spawn(x, y, "heal");
+ if (game.difficultyMode > 1 || Math.random() < 0.66) { //easy and normal have only a 66% chance for a power up
+ spawnPowerUps()
+ if (game.difficultyMode > 2 && Math.random() < 0.33) spawnPowerUps() //why? has a 33% chance for an extra power up
+ } else {
+ if (mech.health < 0.65 && !mod.isEnergyHealth) {
powerUps.spawn(x, y, "heal");
powerUps.spawn(x, y, "heal");
+ if (Math.random() < mod.bayesian) {
+ powerUps.spawn(x, y, "heal");
+ powerUps.spawn(x, y, "heal");
+ }
+ } else if (!mod.bayesian) {
+ powerUps.spawn(x, y, "ammo");
+ powerUps.spawn(x, y, "ammo");
}
- } else if (!mod.bayesian) {
- powerUps.spawn(x, y, "ammo");
- powerUps.spawn(x, y, "ammo");
- powerUps.spawn(x, y, "ammo");
- powerUps.spawn(x, y, "ammo");
- powerUps.spawn(x, y, "ammo");
}
+
+ function spawnPowerUps() {
+ if (mech.fieldMode === 0) {
+ powerUps.spawn(x, y, "field")
+ if (Math.random() < mod.bayesian) powerUps.spawn(x, y, "field")
+ } else if (Math.random() < 0.9) {
+ powerUps.spawn(x, y, "mod")
+ if (Math.random() < mod.bayesian) powerUps.spawn(x, y, "mod")
+ } else if (Math.random() < 0.5) {
+ powerUps.spawn(x, y, "gun")
+ if (Math.random() < mod.bayesian) powerUps.spawn(x, y, "gun")
+ } else if (mech.health < 0.65 && !mod.isEnergyHealth) {
+ powerUps.spawn(x, y, "heal");
+ powerUps.spawn(x, y, "heal");
+ powerUps.spawn(x, y, "heal");
+ powerUps.spawn(x, y, "heal");
+ if (Math.random() < mod.bayesian) {
+ powerUps.spawn(x, y, "heal");
+ powerUps.spawn(x, y, "heal");
+ powerUps.spawn(x, y, "heal");
+ powerUps.spawn(x, y, "heal");
+ }
+ } else if (!mod.bayesian) {
+ powerUps.spawn(x, y, "ammo");
+ powerUps.spawn(x, y, "ammo");
+ powerUps.spawn(x, y, "ammo");
+ powerUps.spawn(x, y, "ammo");
+ }
+ }
+
+
},
chooseRandomPowerUp(x, y) { //100% chance to drop a random power up //used in spawn.debris
if (Math.random() < 0.05) {
diff --git a/js/spawn.js b/js/spawn.js
index 5552d2c..84b85f6 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -2,24 +2,24 @@
const spawn = {
pickList: ["starter", "starter"],
fullPickList: [
- // "hopper", "hopper", "hopper", "hopper",
- // "shooter", "shooter", "shooter",
- // "chaser", "chaser",
- // "striker", "striker",
- // "laser", "laser",
- // "exploder", "exploder",
- // "stabber", "stabber",
- // "launcher", "launcher",
+ "hopper", "hopper", "hopper", "hopper",
+ "shooter", "shooter", "shooter",
+ "chaser", "chaser",
+ "striker", "striker",
+ "laser", "laser",
+ "exploder", "exploder",
+ "stabber", "stabber",
+ "launcher", "launcher",
"sniper",
- // "spinner",
- // "grower",
- // "springer",
- // "beamer",
- // "focuser",
- // "sucker",
- // "spawner",
- // "ghoster",
- // "sneaker",
+ "spinner",
+ "grower",
+ "springer",
+ "beamer",
+ "focuser",
+ "sucker",
+ "spawner",
+ "ghoster",
+ "sneaker",
],
allowedBossList: ["chaser", "spinner", "striker", "springer", "laser", "focuser", "beamer", "exploder", "spawner", "shooter", "launcher", "stabber", "sniper"],
setSpawnList() { //this is run at the start of each new level to determine the possible mobs for the level
@@ -83,7 +83,7 @@ const spawn = {
},
randomLevelBoss(x, y) {
// other bosses: suckerBoss, laserBoss, tetherBoss, snakeBoss //all need a particular level to work so they are not included
- const options = ["shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss"] // , "timeSkipBoss"
+ const options = ["shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss"] // , "timeSkipBoss"
spawn[options[Math.floor(Math.random() * options.length)]](x, y)
},
//mob templates *********************************************************************************************
@@ -892,6 +892,148 @@ const spawn = {
};
}
},
+ laserTargetingBoss(x, y, radius = 70) {
+ const color = "#05f"
+ mobs.spawn(x, y, 3, radius, color);
+ let me = mob[mob.length - 1];
+ me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
+ Matter.Body.rotate(me, Math.random() * Math.PI * 2);
+ me.accelMag = 0.0006 * game.accelScale;
+ me.seePlayerFreq = Math.floor(25 * game.lookFreqScale);
+ me.memory = 600;
+ me.restitution = 1;
+ me.frictionAir = 0.06;
+ me.frictionStatic = 0;
+ me.friction = 0;
+
+ me.lookTorque = 0.000005 * (Math.random() > 0.5 ? -1 : 1);
+
+ me.fireDir = {
+ x: 0,
+ y: 0
+ }
+ Matter.Body.setDensity(me, 0.03); //extra dense //normal is 0.001 //makes effective life much larger
+ spawn.shield(me, x, y, 1);
+ me.onHit = function () {
+ //run this function on hitting player
+ // this.explode();
+ };
+ // spawn.shield(me, x, y, 1); //not working, not sure why
+ me.onDeath = function () {
+ powerUps.spawnBossPowerUp(this.position.x, this.position.y)
+ };
+ me.do = function () {
+ this.seePlayerByLookingAt();
+ this.checkStatus();
+ this.attraction();
+
+ if (this.seePlayer.recall) {
+ //set direction to turn to fire
+ if (!(game.cycle % this.seePlayerFreq)) {
+ this.fireDir = Vector.normalise(Vector.sub(this.seePlayer.position, this.position));
+ // this.fireDir.y -= Math.abs(this.seePlayer.position.x - this.position.x) / 1600; //gives the bullet an arc
+ }
+
+ //rotate towards fireAngle
+ const angle = this.angle + Math.PI / 2;
+ c = Math.cos(angle) * this.fireDir.x + Math.sin(angle) * this.fireDir.y;
+ const threshold = 0.04;
+ if (c > threshold) {
+ this.torque += 0.000004 * this.inertia;
+ } else if (c < -threshold) {
+ this.torque -= 0.000004 * this.inertia;
+ }
+ // if (Math.abs(c) < 0.3) {
+ // const mag = 0.05
+ // this.force.x += mag * Math.cos(this.angle)
+ // this.force.y += mag * Math.sin(this.angle)
+ // }
+
+ const vertexCollision = function (v1, v1End, domain) {
+ for (let i = 0; i < domain.length; ++i) {
+ let vertices = domain[i].vertices;
+ const len = vertices.length - 1;
+ for (let j = 0; j < len; j++) {
+ results = game.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
+ if (results.onLine1 && results.onLine2) {
+ const dx = v1.x - results.x;
+ const dy = v1.y - results.y;
+ const dist2 = dx * dx + dy * dy;
+ if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
+ best = {
+ x: results.x,
+ y: results.y,
+ dist2: dist2,
+ who: domain[i],
+ v1: vertices[j],
+ v2: vertices[j + 1]
+ };
+ }
+ }
+ }
+ results = game.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
+ if (results.onLine1 && results.onLine2) {
+ const dx = v1.x - results.x;
+ const dy = v1.y - results.y;
+ const dist2 = dx * dx + dy * dy;
+ if (dist2 < best.dist2) {
+ best = {
+ x: results.x,
+ y: results.y,
+ dist2: dist2,
+ who: domain[i],
+ v1: vertices[0],
+ v2: vertices[len]
+ };
+ }
+ }
+ }
+ };
+
+ const seeRange = 8000;
+ best = {
+ x: null,
+ y: null,
+ dist2: Infinity,
+ who: null,
+ v1: null,
+ v2: null
+ };
+ const look = {
+ x: this.position.x + seeRange * Math.cos(this.angle),
+ y: this.position.y + seeRange * Math.sin(this.angle)
+ };
+ vertexCollision(this.position, look, map);
+ vertexCollision(this.position, look, body);
+ if (!mech.isStealth) vertexCollision(this.position, look, [player]);
+ // hitting player
+ if (best.who === player) {
+ if (mech.immuneCycle < mech.cycle) {
+ const dmg = 0.0005 * game.dmgScale;
+ mech.damage(dmg);
+ //draw damage
+ ctx.fillStyle = color;
+ ctx.beginPath();
+ ctx.arc(best.x, best.y, dmg * 10000, 0, 2 * Math.PI);
+ ctx.fill();
+ }
+ }
+ //draw beam
+ if (best.dist2 === Infinity) {
+ best = look;
+ }
+ ctx.beginPath();
+ ctx.moveTo(this.vertices[1].x, this.vertices[1].y);
+ ctx.lineTo(best.x, best.y);
+ ctx.strokeStyle = color;
+ ctx.lineWidth = 3;
+ ctx.setLineDash([50 + 120 * Math.random(), 50 * Math.random()]);
+ ctx.stroke();
+ ctx.setLineDash([0, 0]);
+
+ }
+ };
+ },
laser(x, y, radius = 30) {
mobs.spawn(x, y, 3, radius, "#f00");
let me = mob[mob.length - 1];
@@ -1364,6 +1506,8 @@ const spawn = {
me.noseLength = 0;
me.fireAngle = 0;
me.accelMag = 0.0005 * game.accelScale;
+ me.frictionStatic = 0;
+ me.friction = 0;
me.frictionAir = 0.05;
me.lookTorque = 0.0000025 * (Math.random() > 0.5 ? -1 : 1);
me.fireDir = {
@@ -1439,6 +1583,7 @@ const spawn = {
this.timeLimit();
};
},
+
sniper(x, y, radius = 35 + Math.ceil(Math.random() * 30)) {
mobs.spawn(x, y, 3, radius, "transparent"); //"rgb(25,0,50)")
let me = mob[mob.length - 1];
@@ -1448,7 +1593,8 @@ const spawn = {
me.stroke = "transparent"; //used for drawSneaker
me.alpha = 1; //used in drawSneaker
me.showHealthBar = false;
-
+ me.frictionStatic = 0;
+ me.friction = 0;
me.canTouchPlayer = false; //used in drawSneaker
me.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob //can't touch player
@@ -1572,8 +1718,8 @@ const spawn = {
me.do = function () {
// this.gravity();
this.timeLimit();
- if (Matter.Query.collides(this, map).length > 0 || Matter.Query.collides(this, body).length > 0) {
- // this.timeLeft = 0
+
+ if (Matter.Query.collides(this, map).length > 0 || Matter.Query.collides(this, body).length > 0 && this.speed < 3) {
this.dropPowerUp = false;
this.death(); //death with no power up
}
diff --git a/todo.txt b/todo.txt
index 5154eba..33fcfc3 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,10 +1,24 @@
-new mod: doubles current bots
+mod: doubles current bots
+mod: shotgun fires nails
+difficulty mode why? now has 33% chance for a second boss power up
+difficulty mode normal and easy now have a 33% lower chance for a boss power up
+mob: sniper
+mob boss: Laser Targeting (might need balancing)
+
************** TODO - n-gon **************
+maybe increase chance of boss power ups on why difficulty
+ hard as well?
+
+mod - shotgun: fire nails instead of bullets
+ gain range?
+
shielded mobs don't knock back the same as unshielded mobs
-buff harmonic field to cover legs
+buff harmonic field
+ cover legs?
+ no flicker after blocking?
movement fluidity
let legs jump on mobs, but player will still take damage