diff --git a/js/bullets.js b/js/bullets.js
index 5b563b4..f3103c4 100644
--- a/js/bullets.js
+++ b/js/bullets.js
@@ -74,7 +74,7 @@ const b = {
name: "depleted uranium rounds", //0
description: `your bullets are +13% larger
increased mass and physical damage`,
count: 0,
- maxCount: 33,
+ maxCount: 9,
effect() {
b.modBulletSize += 0.13
}
@@ -119,7 +119,7 @@ const b = {
{
name: "high explosives", //15
description: "the radius of explosions are +20% larger
immune to harm from explosions",
- maxCount: 1,
+ maxCount: 3,
count: 0,
effect: () => {
b.modExplosionRadius += 0.2;
@@ -129,7 +129,7 @@ const b = {
{
name: "auto-loading heuristics", //5
description: "your delay after firing is +12% shorter",
- maxCount: 9,
+ maxCount: 5,
count: 0,
effect() {
b.modFireRate *= 0.88
@@ -147,7 +147,7 @@ const b = {
{
name: "Lorentzian topology", //7
description: "your bullets last +33% longer",
- maxCount: 9,
+ maxCount: 3,
count: 0,
effect() {
b.isModBulletsLastLonger += 0.33
@@ -258,7 +258,7 @@ const b = {
{
name: "energy conservation", //18
description: "gain energy proportional to damage done",
- maxCount: 9,
+ maxCount: 3,
count: 0,
effect() {
b.modEnergySiphon += 0.15;
@@ -268,7 +268,7 @@ const b = {
{
name: "entropy exchange", //19
description: "heal proportional to damage done",
- maxCount: 9,
+ maxCount: 3,
count: 0,
effect() {
b.modHealthDrain += 0.015;
@@ -890,7 +890,7 @@ const b = {
}
},
});
- const SPEED = 8 + 3 * Math.random();
+ const SPEED = 4 + 8 * Math.random();
const ANGLE = 2 * Math.PI * Math.random()
Matter.Body.setVelocity(bullet[bIndex], {
x: SPEED * Math.cos(ANGLE),
@@ -1202,13 +1202,13 @@ const b = {
for (let i = 0; i < b.guns.length; i++) {
b.inventory[i] = i;
b.guns[i].have = true;
- b.guns[i].ammo = b.guns[i].ammoPack * ammoPacks;
+ b.guns[i].ammo = Math.floor(b.guns[i].ammoPack * ammoPacks);
}
} else {
if (!b.guns[gun].have) b.inventory.push(gun);
if (b.activeGun === null) b.activeGun = gun //if no active gun switch to new gun
b.guns[gun].have = true;
- b.guns[gun].ammo = b.guns[gun].ammoPack * ammoPacks;
+ b.guns[gun].ammo = Math.floor(b.guns[gun].ammoPack * ammoPacks);
}
game.makeGunHUD();
},
@@ -1397,208 +1397,7 @@ const b = {
}
},
{
- name: "rail gun", //5
- description: "electro-magnetically launch a dense rod
hold left mouse to charge, release to fire", //and repel enemies
- ammo: 0,
- ammoPack: 1,
- have: false,
- isStarterGun: false,
- fire() {
- const me = bullet.length;
- bullet[me] = Bodies.rectangle(0, 0, 0.012 * b.modBulletSize, 0.0025 * b.modBulletSize, {
- density: 0.01, //0.001 is normal
- //frictionAir: 0.01, //restitution: 0,
- // angle: 0,
- // friction: 0.5,
- frictionAir: 0,
- dmg: 0, //damage done in addition to the damage from momentum
- classType: "bullet",
- collisionFilter: {
- category: 0,
- mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield
- },
- minDmgSpeed: 5,
- onDmg() {}, //this.endCycle = 0 //triggers despawn
- onEnd() {}
- });
- mech.fireCDcycle = Infinity; // cool down
- World.add(engine.world, bullet[me]); //add bullet to world
- bullet[me].endCycle = Infinity
- bullet[me].isCharging = true;
- bullet[me].charge = 0;
- bullet[me].do = function () {
- if (this.isCharging) {
- if ((!game.mouseDown && this.charge > 0.6)) { //fire on mouse release
- this.isCharging = false
- mech.fireCDcycle = mech.cycle + 2; // set fire cool down
- Matter.Body.scale(this, 8000, 8000) // show the bullet by scaling it up (don't judge me... I know this is a bad way to do it)
- this.endCycle = game.cycle + 140
- this.collisionFilter.category = cat.bullet
- Matter.Body.setPosition(this, {
- x: mech.pos.x,
- y: mech.pos.y
- })
- Matter.Body.setAngle(this, mech.angle)
- const speed = 90
- Matter.Body.setVelocity(this, {
- x: mech.Vx / 2 + speed * this.charge * Math.cos(mech.angle),
- y: mech.Vy / 2 + speed * this.charge * Math.sin(mech.angle)
- });
-
- //knock back
- const KNOCK = ((mech.crouch) ? 0.1 : 0.5) * b.modBulletSize * b.modBulletSize * this.charge * this.charge
- player.force.x -= KNOCK * Math.cos(mech.angle)
- player.force.y -= KNOCK * Math.sin(mech.angle) * 0.35 //reduce knock back in vertical direction to stop super jumps
-
- //push away blocks when firing
- let range = 700 * this.charge
- for (let i = 0, len = body.length; i < len; ++i) {
- const SUB = Vector.sub(body[i].position, mech.pos)
- const DISTANCE = Vector.magnitude(SUB)
-
- if (DISTANCE < range) {
- const DEPTH = Math.min(range - DISTANCE, 300)
- const FORCE = Vector.mult(Vector.normalise(SUB), 0.003 * Math.sqrt(DEPTH) * body[i].mass)
- body[i].force.x += FORCE.x;
- body[i].force.y += FORCE.y - body[i].mass * (game.g * 1.5); //kick up a bit to give them some arc
- }
- }
- for (let i = 0, len = mob.length; i < len; ++i) {
- const SUB = Vector.sub(mob[i].position, mech.pos)
- const DISTANCE = Vector.magnitude(SUB)
-
- if (DISTANCE < range) {
- const DEPTH = Math.min(range - DISTANCE, 300)
- const FORCE = Vector.mult(Vector.normalise(SUB), 0.003 * Math.sqrt(DEPTH) * mob[i].mass)
- mob[i].force.x += 1.5 * FORCE.x;
- mob[i].force.y += 1.5 * FORCE.y;
- }
- }
- } else { // charging on mouse down
- mech.fireCDcycle = Infinity //can't fire until mouse is released
- if (mech.crouch) {
- this.charge = this.charge * 0.965 + 0.035 // this.charge converges to 1
- } else {
- this.charge = this.charge * 0.985 + 0.015 // this.charge converges to 1
- }
- //draw laser targeting
- let best;
- let range = 3000
- const dir = mech.angle
- const path = [{
- x: mech.pos.x + 20 * Math.cos(dir),
- y: mech.pos.y + 20 * Math.sin(dir)
- },
- {
- x: mech.pos.x + range * Math.cos(dir),
- y: mech.pos.y + range * Math.sin(dir)
- }
- ];
- 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) {
- 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]
- };
- }
- }
- }
- };
-
- //check for collisions
- best = {
- x: null,
- y: null,
- dist2: Infinity,
- who: null,
- v1: null,
- v2: null
- };
- vertexCollision(path[0], path[1], mob);
- vertexCollision(path[0], path[1], map);
- vertexCollision(path[0], path[1], body);
- if (best.dist2 != Infinity) { //if hitting something
- path[path.length - 1] = {
- x: best.x,
- y: best.y
- };
- }
-
- //draw laser beam
- ctx.beginPath();
- ctx.moveTo(path[0].x, path[0].y);
- ctx.lineTo(path[1].x, path[1].y);
- ctx.strokeStyle = `rgba(100,0,180,0.7)`;
- ctx.lineWidth = this.charge * 1
- ctx.setLineDash([10, 20]);
- ctx.stroke();
- ctx.setLineDash([0, 0]);
-
- //draw magnetic field
- const X = mech.pos.x
- const Y = mech.pos.y
- const unitVector = Vector.normalise(Vector.sub(game.mouseInGame, mech.pos))
- const unitVectorPerp = Vector.perp(unitVector)
-
- function magField(mag, arc) {
- ctx.moveTo(X, Y);
- ctx.bezierCurveTo(
- X + unitVector.x * mag, Y + unitVector.y * mag,
- X + unitVector.x * mag + unitVectorPerp.x * arc, Y + unitVector.y * mag + unitVectorPerp.y * arc,
- X + unitVectorPerp.x * arc, Y + unitVectorPerp.y * arc)
- ctx.bezierCurveTo(
- X - unitVector.x * mag + unitVectorPerp.x * arc, Y - unitVector.y * mag + unitVectorPerp.y * arc,
- X - unitVector.x * mag, Y - unitVector.y * mag,
- X, Y)
- }
- ctx.fillStyle = `rgba(50,0,100,0.05)`;
- for (let i = 3; i < 7; i++) {
- const MAG = 8 * i * i * this.charge * (0.93 + 0.07 * Math.random())
- const ARC = 6 * i * i * this.charge * (0.93 + 0.07 * Math.random())
- ctx.beginPath();
- magField(MAG, ARC)
- magField(MAG, -ARC)
- ctx.fill();
- }
- }
- } else { //normal bullet behavior
- this.force.y += this.mass * 0.00015 / this.charge; // low gravity that scales with charge
- }
- }
- }
- },
- {
- name: "missiles", //6
+ name: "missiles", //5
description: "fire missiles that accelerate towards enemies
explodes when near target",
ammo: 0,
ammoPack: 3,
@@ -1694,7 +1493,7 @@ const b = {
}
}
}, {
- name: "flak", //7
+ name: "flak", //6
description: "fire a cluster of short range projectiles
explodes on contact or after half a second",
ammo: 0,
ammoPack: 6,
@@ -1735,7 +1534,7 @@ const b = {
}
}
}, {
- name: "grenades", //8
+ name: "grenades", //7
description: "lob a single bouncy projectile
explodes on contact or after one second",
ammo: 0,
ammoPack: 6,
@@ -1762,7 +1561,7 @@ const b = {
};
}
}, {
- name: "vacuum bomb", //9
+ name: "vacuum bomb", //8
description: "fire a bomb that sucks before exploding
click left mouse again to detonate",
ammo: 0,
ammoPack: 2,
@@ -1866,7 +1665,7 @@ const b = {
}
}
}, {
- name: "mine", //10
+ name: "mine", //9
description: "toss a proximity mine that sticks to walls
fires nails at enemies within range",
ammo: 0,
ammoPack: 3,
@@ -1885,7 +1684,7 @@ const b = {
}
},
{
- name: "spores", //11
+ name: "spores", //10
description: "fire orbs that discharge spores
spores seek out enemies",
ammo: 0,
ammoPack: 4,
@@ -1930,7 +1729,7 @@ const b = {
}
},
{
- name: "drones", //12
+ name: "drones", //11
description: "deploy drones that crash into enemies
collisions reduce drone cycles by 1 second",
ammo: 0,
ammoPack: 9,
@@ -1942,7 +1741,7 @@ const b = {
}
},
{
- name: "foam", //13
+ name: "foam", //12
description: "spray bubbly foam that sticks to enemies
does damage over time and slows movement",
ammo: 0,
ammoPack: 35,
@@ -2035,6 +1834,209 @@ const b = {
});
}
},
+ {
+ name: "rail gun", //13
+ description: "electro-magnetically launch a dense rod
holding left mouse uses energy to charge ",
+ ammo: 0,
+ ammoPack: 2,
+ have: false,
+ isStarterGun: false,
+ fire() {
+ const me = bullet.length;
+ bullet[me] = Bodies.rectangle(0, 0, 0.015 * b.modBulletSize, 0.0015 * b.modBulletSize, {
+ density: 0.01, //0.001 is normal
+ //frictionAir: 0.01, //restitution: 0,
+ // angle: 0,
+ // friction: 0.5,
+ frictionAir: 0,
+ dmg: 0, //damage done in addition to the damage from momentum
+ classType: "bullet",
+ collisionFilter: {
+ category: 0,
+ mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield
+ },
+ minDmgSpeed: 5,
+ onDmg() {}, //this.endCycle = 0 //triggers despawn
+ onEnd() {}
+ });
+ mech.fireCDcycle = Infinity; // cool down
+ World.add(engine.world, bullet[me]); //add bullet to world
+ bullet[me].endCycle = Infinity
+ bullet[me].charge = 0;
+ bullet[me].do = function () {
+ const FIELD_DRAIN = 0.002 //laser drains energy as well as bullets
+
+ if ((!game.mouseDown && this.charge > 0.6)) { //fire on mouse release
+ //normal bullet behavior occurs after firing, overwrite this function
+ this.do = function () {
+ this.force.y += this.mass * 0.00015 / this.charge; // low gravity that scales with charge
+ }
+
+ mech.fireCDcycle = mech.cycle + 2; // set fire cool down
+ Matter.Body.scale(this, 8000, 8000) // show the bullet by scaling it up (don't judge me... I know this is a bad way to do it)
+ this.endCycle = game.cycle + 140
+ this.collisionFilter.category = cat.bullet
+ Matter.Body.setPosition(this, {
+ x: mech.pos.x,
+ y: mech.pos.y
+ })
+ Matter.Body.setAngle(this, mech.angle)
+ const speed = 90
+ Matter.Body.setVelocity(this, {
+ x: mech.Vx / 2 + speed * this.charge * Math.cos(mech.angle),
+ y: mech.Vy / 2 + speed * this.charge * Math.sin(mech.angle)
+ });
+
+ //knock back
+ const KNOCK = ((mech.crouch) ? 0.1 : 0.5) * b.modBulletSize * b.modBulletSize * this.charge * this.charge
+ player.force.x -= KNOCK * Math.cos(mech.angle)
+ player.force.y -= KNOCK * Math.sin(mech.angle) * 0.35 //reduce knock back in vertical direction to stop super jumps
+
+ //push away blocks when firing
+ let range = 700 * this.charge
+ for (let i = 0, len = body.length; i < len; ++i) {
+ const SUB = Vector.sub(body[i].position, mech.pos)
+ const DISTANCE = Vector.magnitude(SUB)
+
+ if (DISTANCE < range) {
+ const DEPTH = Math.min(range - DISTANCE, 300)
+ const FORCE = Vector.mult(Vector.normalise(SUB), 0.003 * Math.sqrt(DEPTH) * body[i].mass)
+ body[i].force.x += FORCE.x;
+ body[i].force.y += FORCE.y - body[i].mass * (game.g * 1.5); //kick up a bit to give them some arc
+ }
+ }
+ for (let i = 0, len = mob.length; i < len; ++i) {
+ const SUB = Vector.sub(mob[i].position, mech.pos)
+ const DISTANCE = Vector.magnitude(SUB)
+
+ if (DISTANCE < range) {
+ const DEPTH = Math.min(range - DISTANCE, 300)
+ const FORCE = Vector.mult(Vector.normalise(SUB), 0.003 * Math.sqrt(DEPTH) * mob[i].mass)
+ mob[i].force.x += 1.5 * FORCE.x;
+ mob[i].force.y += 1.5 * FORCE.y;
+ }
+ }
+ } 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
+ 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
+
+ //draw laser targeting
+ let best;
+ let range = 3000
+ const dir = mech.angle
+ const path = [{
+ x: mech.pos.x + 20 * Math.cos(dir),
+ y: mech.pos.y + 20 * Math.sin(dir)
+ },
+ {
+ x: mech.pos.x + range * Math.cos(dir),
+ y: mech.pos.y + range * Math.sin(dir)
+ }
+ ];
+ 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) {
+ 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]
+ };
+ }
+ }
+ }
+ };
+
+ //check for collisions
+ best = {
+ x: null,
+ y: null,
+ dist2: Infinity,
+ who: null,
+ v1: null,
+ v2: null
+ };
+ vertexCollision(path[0], path[1], mob);
+ vertexCollision(path[0], path[1], map);
+ vertexCollision(path[0], path[1], body);
+ if (best.dist2 != Infinity) { //if hitting something
+ path[path.length - 1] = {
+ x: best.x,
+ y: best.y
+ };
+ }
+
+ //draw laser beam
+ ctx.beginPath();
+ ctx.moveTo(path[0].x, path[0].y);
+ ctx.lineTo(path[1].x, path[1].y);
+ ctx.strokeStyle = `rgba(100,0,180,0.7)`;
+ ctx.lineWidth = this.charge * 1
+ ctx.setLineDash([10, 20]);
+ ctx.stroke();
+ ctx.setLineDash([0, 0]);
+
+ //draw magnetic field
+ const X = mech.pos.x
+ const Y = mech.pos.y
+ const unitVector = Vector.normalise(Vector.sub(game.mouseInGame, mech.pos))
+ const unitVectorPerp = Vector.perp(unitVector)
+
+ function magField(mag, arc) {
+ ctx.moveTo(X, Y);
+ ctx.bezierCurveTo(
+ X + unitVector.x * mag, Y + unitVector.y * mag,
+ X + unitVector.x * mag + unitVectorPerp.x * arc, Y + unitVector.y * mag + unitVectorPerp.y * arc,
+ X + unitVectorPerp.x * arc, Y + unitVectorPerp.y * arc)
+ ctx.bezierCurveTo(
+ X - unitVector.x * mag + unitVectorPerp.x * arc, Y - unitVector.y * mag + unitVectorPerp.y * arc,
+ X - unitVector.x * mag, Y - unitVector.y * mag,
+ X, Y)
+ }
+ ctx.fillStyle = `rgba(50,0,100,0.05)`;
+ for (let i = 3; i < 7; i++) {
+ const MAG = 8 * i * i * this.charge * (0.93 + 0.07 * Math.random())
+ const ARC = 6 * i * i * this.charge * (0.93 + 0.07 * Math.random())
+ ctx.beginPath();
+ magField(MAG, ARC)
+ magField(MAG, -ARC)
+ ctx.fill();
+ }
+ }
+ }
+ }
+ },
{
name: "laser", //14
description: "emit a beam of collimated coherent light
drains energy instead of ammunition",
diff --git a/js/index.js b/js/index.js
index e139944..3550423 100644
--- a/js/index.js
+++ b/js/index.js
@@ -2,20 +2,6 @@
/* TODO: *******************************************
*****************************************************
-show difficulty increase text in custom mode
-
-chart showing info about each mob type
- can use css-grid chart like custom mod
-
-add setting for random drops instead of choosing
-
-custom mode
- custom mode grey out mods that are bad, like selection based mods
-
-change nail-bot's movement
- maybe have it move in a circle around player?
- high friction very high acceleration towards circle location
-
add mouse constraint in testing mode
https://github.com/liabru/matter-js/blob/master/examples/events.js
@@ -199,7 +185,7 @@ const build = {
},
makeGrid() {
let text =
- `