diff --git a/js/bullets.js b/js/bullets.js
index 4059719..6184ae3 100644
--- a/js/bullets.js
+++ b/js/bullets.js
@@ -111,7 +111,7 @@ const b = {
},
{
name: "kinetic bombardment", //3
- description: "do up to 33% more damage at a distance
increase starts at about 6 steps away",
+ description: "do up to 33% more damage at a distance
increase maxes out at about 40 steps away",
maxCount: 1,
count: 0,
effect() {
@@ -139,11 +139,11 @@ const b = {
},
{
name: "auto-loading heuristics", //5
- description: "your delay after firing is +12% shorter",
- maxCount: 5,
+ description: "your delay after firing is +14% shorter",
+ maxCount: 3,
count: 0,
effect() {
- b.modFireRate *= 0.88
+ b.modFireRate *= 0.86
}
},
{
@@ -239,11 +239,11 @@ const b = {
},
{
name: "Pauli exclusion", //12
- description: "unable to collide with enemies for +1 second
activates after being harmed from a collision",
+ description: "unable to collide with enemies for +2 second
activates after being harmed from a collision",
maxCount: 9,
count: 0,
effect() {
- b.modCollisionImmuneCycles += 60;
+ b.modCollisionImmuneCycles += 120;
mech.collisionImmune = mech.cycle + b.modCollisionImmuneCycles; //player is immune to collision damage for 30 cycles
}
},
@@ -307,7 +307,7 @@ const b = {
},
{
name: "recursive healing", //22
- description: "healing power ups trigger an extra time.",
+ description: "healing power ups trigger one extra time.",
maxCount: 9,
count: 0,
effect() {
@@ -1191,7 +1191,7 @@ const b = {
name: "super balls", //2
description: "fire five balls in a wide arc
balls bounce with no momentum loss",
ammo: 0,
- ammoPack: 5,
+ ammoPack: 6,
have: false,
isStarterGun: true,
fire() {
@@ -1317,7 +1317,7 @@ const b = {
name: "missiles", //5
description: "fire missiles that accelerate towards enemies
explodes when near target",
ammo: 0,
- ammoPack: 3,
+ ammoPack: 4,
have: false,
isStarterGun: false,
fireCycle: 0,
@@ -1327,7 +1327,7 @@ const b = {
const me = bullet.length;
bullet[me] = Bodies.rectangle(mech.pos.x + 40 * Math.cos(mech.angle), mech.pos.y + 40 * Math.sin(mech.angle) - 3, 30 * b.modBulletSize, 4 * b.modBulletSize, b.fireAttributes(dir));
const thrust = 0.00417 * bullet[me].mass;
- b.fireProps(mech.crouch ? 55 : 30, -3 * (0.5 - Math.random()) + (mech.crouch ? 25 : -8), dir, me); //cd , speed
+ b.fireProps(mech.crouch ? 50 : 25, -3 * (0.5 - Math.random()) + (mech.crouch ? 25 : -8), dir, me); //cd , speed
// bullet[me].collisionFilter.mask = cat.map | cat.body | cat.mobBullet
// Matter.Body.setDensity(bullet[me], 0.01) //doesn't help with reducing explosion knock backs
bullet[me].force.y += 0.0005; //a small push down at first to make it seem like the missile is briefly falling
@@ -1458,7 +1458,7 @@ const b = {
name: "grenades", //7
description: "lob a single bouncy projectile
explodes on contact or after one second",
ammo: 0,
- ammoPack: 6,
+ ammoPack: 7,
have: false,
isStarterGun: false,
fire() {
@@ -1500,7 +1500,7 @@ const b = {
bullet[me].restitution = 0.2;
bullet[me].friction = 0.3;
bullet[me].endCycle = Infinity
- bullet[me].explodeRad = 380 + Math.floor(Math.random() * 60);
+ bullet[me].explodeRad = 400 + Math.floor(Math.random() * 60);
bullet[me].onEnd = function () {
b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end
}
@@ -1844,10 +1844,10 @@ const b = {
} else if (mech.fieldMeter > 0.005) { // charging on mouse down
mech.fireCDcycle = Infinity //can't fire until mouse is released
const lastCharge = this.charge
- let chargeRate = (mech.crouch) ? 0.965 : 0.985
+ let chargeRate = (mech.crouch) ? 0.975 : 0.987
chargeRate *= Math.pow(b.modFireRate, 0.04)
this.charge = this.charge * chargeRate + (1 - chargeRate) // this.charge converges to 1
- mech.fieldMeter -= (this.charge - lastCharge) * 0.25 //energy drain is proportional to charge gained, but doesn't stop normal mech.fieldRegen
+ mech.fieldMeter -= (this.charge - lastCharge) * 0.28 //energy drain is proportional to charge gained, but doesn't stop normal mech.fieldRegen
//draw laser targeting
let best;
@@ -1970,7 +1970,7 @@ const b = {
have: false,
isStarterGun: true,
fire() {
- const FIELD_DRAIN = 0.002 //laser drains energy as well as bullets
+ const FIELD_DRAIN = 0.0018 //laser drains energy as well as bullets
const damage = 0.05
if (mech.fieldMeter < FIELD_DRAIN) {
mech.fireCDcycle = mech.cycle + 100; // cool down if out of energy
@@ -2217,7 +2217,7 @@ const b = {
//use energy to explode
const energy = 0.3 * Math.min(mech.fieldMeter, 1.75)
mech.fieldMeter -= energy
- if (best.who) b.explosion(path[1], 950 * energy)
+ if (best.who) b.explosion(path[1], 1000 * energy)
mech.fireCDcycle = mech.cycle + Math.floor(60 * b.modFireRate); // cool down
//draw laser beam
diff --git a/js/game.js b/js/game.js
index 0e9c923..cb194f7 100644
--- a/js/game.js
+++ b/js/game.js
@@ -180,7 +180,7 @@ const game = {
replaceTextLog: true,
//
- SVGleftMouse: '',
+ SVGleftMouse: '',
SVGrightMouse: '',
makeTextLog(text, time = 180) {
if (game.replaceTextLog) {
diff --git a/js/index.js b/js/index.js
index de2bb33..59d02f4 100644
--- a/js/index.js
+++ b/js/index.js
@@ -2,6 +2,11 @@
/* TODO: *******************************************
*****************************************************
+gun/field: portals
+ use the code from mines to get them to stick to walls
+ or lasers
+ alternate red and blue portals
+
missiles don't explode reliably enough
they can bounce, which is cool, but they should still explode right after a bounce
@@ -249,7 +254,14 @@ const build = {
},
pauseGrid() {
// let text = `
`
- let text = `PAUSED Press P to unpause
`;
+ let text = `
+
+ PAUSED press P to resume
+
`;
+ //
+ // ${game.SVGleftMouse} fire gun
+ // ${game.SVGrightMouse} use field
+ //
let countGuns = 0
let countMods = 0
for (let i = 0, len = b.guns.length; i < len; i++) {
diff --git a/js/level.js b/js/level.js
index 2ecc03c..b734d44 100644
--- a/js/level.js
+++ b/js/level.js
@@ -74,7 +74,7 @@ const level = {
//******************************************************************************************************************
testingMap() {
//start with all guns
- level.difficultyIncrease(9) //level 7 on normal, level 4 on hard, level 1.2 on why?
+ // level.difficultyIncrease(9) //level 7 on normal, level 4 on hard, level 1.2 on why?
game.zoomScale = 1700 //1400 is normal
spawn.setSpawnList();
mech.setPosToSpawn(-75, -60); //normal spawn
@@ -126,8 +126,9 @@ const level = {
// powerUps.spawn(450, -400, "mod", false);
// spawn.bodyRect(-45, -100, 40, 50);
// spawn.bomber(800, -450);
- spawn.hopper(400, -1050);
- // spawn.starter(1200, -1050);
+ spawn.laserBoss(400, -750);
+ // spawn.laser(400, -550);
+ spawn.starter(1200, -1050);
// spawn.nodeBoss(-600, -550, "starter");
// spawn.starter(800, -150);
// spawn.beamer(800, -150);
diff --git a/js/mobs.js b/js/mobs.js
index ffcbcad..5e0d2e4 100644
--- a/js/mobs.js
+++ b/js/mobs.js
@@ -359,7 +359,7 @@ const mobs = {
dmg = 0.002 * game.dmgScale;
mech.damage(dmg);
//draw damage
- ctx.fillStyle = color;
+ ctx.fillStyle = "#f00";
ctx.beginPath();
ctx.arc(best.x, best.y, dmg * 2000, 0, 2 * Math.PI);
ctx.fill();
diff --git a/js/player.js b/js/player.js
index 4a982f4..080bdc7 100644
--- a/js/player.js
+++ b/js/player.js
@@ -865,39 +865,27 @@ const mech = {
const dyP = mech.pos.y - powerUp[i].position.y;
const dist2 = dxP * dxP + dyP * dyP;
// float towards player if looking at and in range or if very close to player
- if (dist2 < grabPowerUpRange2 && (mech.lookingAt(powerUp[i]) || dist2 < 16000)) {
- // mech.fieldMeter -= mech.fieldRegen * 0.5;
- if (mech.health === mech.maxHealth && powerUp[i].name === "heal" && dist2 < 16000) {
- mech.fieldCDcycle = mech.cycle + 30;
- //push away
- Matter.Body.setVelocity(powerUp[i], {
- x: powerUp[i].velocity.x * 0,
- y: powerUp[i].velocity.y * 0
- });
- powerUp[i].force.x -= 0.0005 * dxP * powerUp[i].mass;
- powerUp[i].force.y -= 0.0005 * dyP * powerUp[i].mass;
- } else {
- powerUp[i].force.x += 7 * (dxP / dist2) * powerUp[i].mass;
- powerUp[i].force.y += 7 * (dyP / dist2) * powerUp[i].mass - powerUp[i].mass * game.g; //negate gravity
- //extra friction
- Matter.Body.setVelocity(powerUp[i], {
- x: powerUp[i].velocity.x * 0.11,
- y: powerUp[i].velocity.y * 0.11
- });
- if (dist2 < 5000) { //use power up if it is close enough
- if (b.isModMassEnergy) {
- mech.fieldMeter = mech.fieldEnergyMax;
- mech.addHealth(0.05);
- }
- Matter.Body.setVelocity(player, { //player knock back, after grabbing power up
- x: player.velocity.x + ((powerUp[i].velocity.x * powerUp[i].mass) / player.mass) * 0.3,
- y: player.velocity.y + ((powerUp[i].velocity.y * powerUp[i].mass) / player.mass) * 0.3
- });
- powerUp[i].effect();
- Matter.World.remove(engine.world, powerUp[i]);
- powerUp.splice(i, 1);
- return; //because the array order is messed up after splice
+ if (dist2 < grabPowerUpRange2 && (mech.lookingAt(powerUp[i]) || dist2 < 16000) && !(mech.health === mech.maxHealth && powerUp[i].name === "heal")) {
+ powerUp[i].force.x += 7 * (dxP / dist2) * powerUp[i].mass;
+ powerUp[i].force.y += 7 * (dyP / dist2) * powerUp[i].mass - powerUp[i].mass * game.g; //negate gravity
+ //extra friction
+ Matter.Body.setVelocity(powerUp[i], {
+ x: powerUp[i].velocity.x * 0.11,
+ y: powerUp[i].velocity.y * 0.11
+ });
+ if (dist2 < 5000) { //use power up if it is close enough
+ if (b.isModMassEnergy) {
+ mech.fieldMeter = mech.fieldEnergyMax;
+ mech.addHealth(0.05);
}
+ Matter.Body.setVelocity(player, { //player knock back, after grabbing power up
+ x: player.velocity.x + ((powerUp[i].velocity.x * powerUp[i].mass) / player.mass) * 0.3,
+ y: player.velocity.y + ((powerUp[i].velocity.y * powerUp[i].mass) / player.mass) * 0.3
+ });
+ powerUp[i].effect();
+ Matter.World.remove(engine.world, powerUp[i]);
+ powerUp.splice(i, 1);
+ return; //because the array order is messed up after splice
}
}
}
diff --git a/js/powerups.js b/js/powerups.js
index 1022b2d..dfaf450 100644
--- a/js/powerups.js
+++ b/js/powerups.js
@@ -4,19 +4,19 @@ const powerUps = {
choose(type, index) {
if (type === "gun") {
b.giveGuns(index)
- game.replaceTextLog = true;
- game.makeTextLog(`${game.SVGleftMouse} ${b.guns[index].name}
${b.guns[index].description}`, 500);
- game.replaceTextLog = false;
+ // game.replaceTextLog = true;
+ // game.makeTextLog(`${game.SVGleftMouse} ${b.guns[index].name}
${b.guns[index].description}`, 500);
+ // game.replaceTextLog = false;
} else if (type === "field") {
mech.setField(index)
- game.replaceTextLog = true;
- game.makeTextLog(`${game.SVGrightMouse} ${mech.fieldUpgrades[mech.fieldMode].name}
${mech.fieldUpgrades[mech.fieldMode].description}`, 600);
- game.replaceTextLog = false;
+ // game.replaceTextLog = true;
+ // game.makeTextLog(`${game.SVGrightMouse} ${mech.fieldUpgrades[mech.fieldMode].name}
${mech.fieldUpgrades[mech.fieldMode].description}`, 600);
+ // game.replaceTextLog = false;
} else if (type === "mod") {
b.giveMod(index)
- game.replaceTextLog = true;
- game.makeTextLog(` ${b.mods[index].name}
${b.mods[index].description}`, 500);
- game.replaceTextLog = false;
+ // game.replaceTextLog = true;
+ // game.makeTextLog(` ${b.mods[index].name}
${b.mods[index].description}`, 500);
+ // game.replaceTextLog = false;
}
document.body.style.cursor = "none";
document.getElementById("choose-grid").style.display = "none"
@@ -139,7 +139,12 @@ const powerUps = {
function doNotHave(who, skip1 = -1, skip2 = -1, skip3 = -1) {
let options = [];
for (let i = 0; i < who.length; i++) {
- if (who[i].count < who[i].maxCount && i !== skip1 && i !== skip2 && i !== skip3) options.push(i);
+ if (who[i].count < who[i].maxCount &&
+ i !== skip1 && i !== skip2 && i !== skip3 &&
+ (b.modCount > 4 || who[i].name !== "Born rule")
+ ) {
+ options.push(i);
+ }
}
if (options.length > 0) return options[Math.floor(Math.random() * options.length)]
}
diff --git a/js/spawn.js b/js/spawn.js
index 4c89d2c..da2ca39 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -650,7 +650,6 @@ const spawn = {
}
},
laser(x, y, radius = 30) {
- //only on level 1
mobs.spawn(x, y, 3, radius, "#f00");
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
@@ -666,6 +665,128 @@ const spawn = {
this.laser();
};
},
+ laserBoss(x, y, radius = 130) {
+ mobs.spawn(x, y, 3, radius, "#f00");
+ let me = mob[mob.length - 1];
+ me.startingPosition = {
+ x: x,
+ y: y
+ }
+ // 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);
+ Matter.Body.setDensity(me, 0.004 + 0.001 * Math.sqrt(game.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
+ // spawn.shield(me, x, y, 1);
+ me.onDeath = function () {
+ powerUps.spawnBossPowerUp(this.position.x, this.position.y)
+ };
+ me.laser = function (where, 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 = 4000;
+ best = {
+ x: null,
+ y: null,
+ dist2: Infinity,
+ who: null,
+ v1: null,
+ v2: null
+ };
+ const look = {
+ x: where.x + seeRange * Math.cos(angle),
+ y: where.y + seeRange * Math.sin(angle)
+ };
+ vertexCollision(where, look, mob);
+ vertexCollision(where, look, map);
+ vertexCollision(where, look, body);
+ if (!mech.isStealth) vertexCollision(where, look, [player]);
+ //hitting mob
+ if (best.who) {
+ if (best.who.mob) {
+ // dmg = 0.03 * game.dmgScale;
+ best.who.damage(0.1);
+ //draw damage
+ game.drawList.push({ //add dmg to draw queue
+ x: best.x,
+ y: best.y,
+ radius: Math.sqrt(dmg) * 50,
+ color: game.playerDmgColor,
+ time: game.drawTime
+ });
+ }
+ // hitting player
+ if (best.who === player) {
+ dmg = 0.03 * game.dmgScale;
+ mech.damage(dmg);
+ //draw damage
+ game.drawList.push({ //add dmg to draw queue
+ x: best.x,
+ y: best.y,
+ radius: dmg * 2000,
+ color: game.mobDmgColor,
+ time: game.drawTime
+ });
+ }
+ }
+ //draw beam
+ if (best.dist2 === Infinity) best = look;
+ ctx.moveTo(where.x, where.y);
+ ctx.lineTo(best.x, best.y);
+ }
+ me.do = function () {
+ this.torque = this.lookTorque * this.inertia * 0.2;
+ Matter.Body.setVelocity(this, {
+ x: 0,
+ y: 0
+ });
+ Matter.Body.setPosition(this, this.startingPosition);
+
+ ctx.beginPath();
+ this.laser(this.vertices[0], this.angle + Math.PI / 3);
+ this.laser(this.vertices[1], this.angle + Math.PI);
+ this.laser(this.vertices[2], this.angle - Math.PI / 3);
+ ctx.strokeStyle = "#f00"; // Purple path
+ ctx.lineWidth = 3;
+ ctx.setLineDash([50 + 120 * Math.random(), 55 * Math.random()]);
+ ctx.stroke(); // Draw it
+ ctx.setLineDash([0, 0]);
+ // this.laser(this.vertices[2], this.angle + Math.PI / 3);
+ };
+ },
striker(x, y, radius = 14 + Math.ceil(Math.random() * 25)) {
mobs.spawn(x, y, 5, radius, "rgb(221,102,119)");
let me = mob[mob.length - 1];