new level boss
This commit is contained in:
@@ -105,15 +105,12 @@
|
||||
<option value="4">why...</option>
|
||||
</select>
|
||||
<br>
|
||||
<label for="community-maps" title="adds in new maps made by other playrs">include community maps:</label>
|
||||
<label for="community-maps" title="adds in 2 maps written by n-gon player: Francois">include community maps:</label>
|
||||
<input type="checkbox" id="community-maps" name="community-maps" style="width:17px; height:17px;">
|
||||
<!-- <br>
|
||||
<label for="body-damage" title="allow damage from the ground and large fast moving blocks">collision damage from blocks:</label>
|
||||
<input type="checkbox" id="body-damage" name="body-damage" checked style="width:17px; height:17px;"> -->
|
||||
<br>
|
||||
<label for="track-pad-mode" title="remove random power ups that don't work well with a track pad">remove power ups that require aiming:</label>
|
||||
<input type="checkbox" id="track-pad-mode" name="track-pad-mode" style="width:17px; height:17px;">
|
||||
<br>
|
||||
<label for="fps-select" title="use this to slow the game down">limit frames per second:</label>
|
||||
<select name="fps-select" id="fps-select">
|
||||
<option value="max" selected>no cap</option>
|
||||
|
||||
106
js/bullet.js
106
js/bullet.js
@@ -674,14 +674,14 @@ const b = {
|
||||
drone(speed = 1) {
|
||||
const me = bullet.length;
|
||||
const THRUST = mod.isFastDrones ? 0.0025 : 0.0015
|
||||
const FRICTION = mod.isFastDrones ? 0.008 : 0.0005
|
||||
// const FRICTION = mod.isFastDrones ? 0.008 : 0.0005
|
||||
const dir = mech.angle + 0.4 * (Math.random() - 0.5);
|
||||
const RADIUS = (4.5 + 3 * Math.random())
|
||||
bullet[me] = Bodies.polygon(mech.pos.x + 30 * Math.cos(mech.angle), mech.pos.y + 30 * Math.sin(mech.angle), 8, RADIUS, {
|
||||
angle: dir,
|
||||
inertia: Infinity,
|
||||
friction: 0.05,
|
||||
frictionAir: FRICTION,
|
||||
frictionAir: 0,
|
||||
restitution: 1,
|
||||
dmg: 0.28, //damage done in addition to the damage from momentum
|
||||
lookFrequency: 80 + Math.floor(23 * Math.random()),
|
||||
@@ -741,33 +741,33 @@ const b = {
|
||||
let closeDist = Infinity;
|
||||
for (let i = 0, len = powerUp.length; i < len; ++i) {
|
||||
if (
|
||||
((powerUp[i].name !== "field" && powerUp[i].name !== "heal") || (powerUp[i].name === "heal" && mech.health < 0.9 * mech.maxHealth)) &&
|
||||
(powerUp[i].name !== "heal" || mech.health < 0.9 * mech.maxHealth || mod.isDroneGrab) &&
|
||||
Matter.Query.ray(map, this.position, powerUp[i].position).length === 0 &&
|
||||
Matter.Query.ray(body, this.position, powerUp[i].position).length === 0
|
||||
) {
|
||||
const TARGET_VECTOR = Vector.sub(this.position, powerUp[i].position)
|
||||
const DIST = Vector.magnitude(TARGET_VECTOR);
|
||||
if (DIST < closeDist) {
|
||||
if (DIST < 100) { //eat the power up if close enough
|
||||
powerUps.onPickUp();
|
||||
powerUp[i].effect();
|
||||
Matter.World.remove(engine.world, powerUp[i]);
|
||||
powerUp.splice(i, 1);
|
||||
if (mod.isDroneGrab) {
|
||||
this.isImproved = true;
|
||||
const SCALE = 2
|
||||
Matter.Body.scale(this, SCALE, SCALE);
|
||||
this.lookFrequency = 30;
|
||||
this.endCycle = game.cycle + Math.floor((1100 + 420 * Math.random()) * mod.isBulletsLastLonger) * 2 //set to double a normal lifespan
|
||||
this.dmg *= 1.5;
|
||||
this.frictionAir *= 0.9
|
||||
}
|
||||
break;
|
||||
}
|
||||
closeDist = DIST;
|
||||
this.lockedOn = powerUp[i]
|
||||
}
|
||||
}
|
||||
if (Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 60000) {
|
||||
powerUps.onPickUp();
|
||||
powerUp[i].effect();
|
||||
Matter.World.remove(engine.world, powerUp[i]);
|
||||
powerUp.splice(i, 1);
|
||||
if (mod.isDroneGrab) {
|
||||
this.isImproved = true;
|
||||
const SCALE = 2
|
||||
Matter.Body.scale(this, SCALE, SCALE);
|
||||
this.lookFrequency = 30;
|
||||
this.endCycle = Infinity
|
||||
this.dmg *= 1.5;
|
||||
this.frictionAir = 0
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1011,13 +1011,13 @@ const b = {
|
||||
if (isKeep) mod.boomBotCount++;
|
||||
}
|
||||
},
|
||||
nailBot(position = mech.pos, isUpgraded = mod.isBotUpgrade) {
|
||||
nailBot(position = mech.pos) {
|
||||
const me = bullet.length;
|
||||
const dir = mech.angle;
|
||||
const RADIUS = (12 + 4 * Math.random())
|
||||
bullet[me] = Bodies.polygon(position.x, position.y, 4, RADIUS, {
|
||||
isUpgraded: isUpgraded,
|
||||
isBot: true,
|
||||
isUpgraded: mod.isNailBotUpgrade,
|
||||
botType: "nail",
|
||||
angle: dir,
|
||||
friction: 0,
|
||||
frictionStatic: 0,
|
||||
@@ -1042,7 +1042,7 @@ const b = {
|
||||
onEnd() {},
|
||||
do() {
|
||||
if (this.lastLookCycle < game.cycle) {
|
||||
this.lastLookCycle = game.cycle + 65 - this.isUpgraded * 25
|
||||
this.lastLookCycle = game.cycle + 80 - this.isUpgraded * 40
|
||||
let target
|
||||
for (let i = 0, len = mob.length; i < len; i++) {
|
||||
const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position));
|
||||
@@ -1066,13 +1066,13 @@ const b = {
|
||||
})
|
||||
World.add(engine.world, bullet[me]); //add bullet to world
|
||||
},
|
||||
foamBot(position = mech.pos, isUpgraded = mod.isBotUpgrade) {
|
||||
foamBot(position = mech.pos) {
|
||||
const me = bullet.length;
|
||||
const dir = mech.angle;
|
||||
const RADIUS = (10 + 5 * Math.random())
|
||||
bullet[me] = Bodies.polygon(position.x, position.y, 6, RADIUS, {
|
||||
isUpgraded: isUpgraded,
|
||||
isBot: true,
|
||||
isUpgraded: mod.isFoamBotUpgrade,
|
||||
botType: "foam",
|
||||
angle: dir,
|
||||
friction: 0,
|
||||
frictionStatic: 0,
|
||||
@@ -1080,7 +1080,7 @@ const b = {
|
||||
restitution: 0.6 * (1 + 0.5 * Math.random()),
|
||||
dmg: 0, // 0.14 //damage done in addition to the damage from momentum
|
||||
minDmgSpeed: 2,
|
||||
lookFrequency: 47 + Math.floor(17 * Math.random()),
|
||||
lookFrequency: 60 + Math.floor(17 * Math.random()) - 10 * mod.isFoamBotUpgrade,
|
||||
cd: 0,
|
||||
delay: 100,
|
||||
acceleration: 0.005 * (1 + 0.5 * Math.random()),
|
||||
@@ -1107,7 +1107,7 @@ const b = {
|
||||
const radius = 6 + 7 * Math.random()
|
||||
const SPEED = 29 - radius * 0.5; //(mech.crouch ? 32 : 20) - radius * 0.7;
|
||||
const velocity = Vector.mult(Vector.normalise(Vector.sub(target, this.position)), SPEED)
|
||||
b.foam(this.position, velocity, radius + 7 * this.isUpgraded)
|
||||
b.foam(this.position, velocity, radius + 8 * this.isUpgraded)
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1122,13 +1122,13 @@ const b = {
|
||||
})
|
||||
World.add(engine.world, bullet[me]); //add bullet to world
|
||||
},
|
||||
laserBot(position = mech.pos, isUpgraded = mod.isBotUpgrade) {
|
||||
laserBot(position = mech.pos) {
|
||||
const me = bullet.length;
|
||||
const dir = mech.angle;
|
||||
const RADIUS = (14 + 6 * Math.random())
|
||||
bullet[me] = Bodies.polygon(position.x, position.y, 3, RADIUS, {
|
||||
isUpgraded: isUpgraded,
|
||||
isBot: true,
|
||||
isUpgraded: mod.isLaserBotUpgrade,
|
||||
botType: "laser",
|
||||
angle: dir,
|
||||
friction: 0,
|
||||
frictionStatic: 0,
|
||||
@@ -1136,9 +1136,9 @@ const b = {
|
||||
restitution: 0.5 * (1 + 0.5 * Math.random()),
|
||||
dmg: 0, // 0.14 //damage done in addition to the damage from momentum
|
||||
minDmgSpeed: 2,
|
||||
lookFrequency: 27 + Math.floor(17 * Math.random()),
|
||||
lookFrequency: 40 + Math.floor(7 * Math.random()),
|
||||
acceleration: 0.0015 * (1 + 0.3 * Math.random()),
|
||||
range: 600 * (1 + 0.2 * Math.random()),
|
||||
range: 600 * (1 + 0.2 * Math.random()) + 200 * mod.isLaserBotUpgrade,
|
||||
followRange: 150 + Math.floor(30 * Math.random()),
|
||||
offPlayer: {
|
||||
x: 0,
|
||||
@@ -1189,7 +1189,7 @@ const b = {
|
||||
}
|
||||
//hit target with laser
|
||||
if (this.lockedOn && this.lockedOn.alive && mech.energy > 0.15) {
|
||||
mech.energy -= 0.0014 * mod.isLaserDiode - 0.0006 * this.isUpgraded
|
||||
mech.energy -= 0.0014 * mod.isLaserDiode
|
||||
//make sure you can still see vertex
|
||||
const DIST = Vector.magnitude(Vector.sub(this.vertices[0], this.lockedOn.position));
|
||||
if (DIST - this.lockedOn.radius < this.range + 150 &&
|
||||
@@ -1207,7 +1207,7 @@ const b = {
|
||||
bestVertexDistance = dist
|
||||
}
|
||||
}
|
||||
const dmg = b.dmgScale * 0.05;
|
||||
const dmg = b.dmgScale * (0.04 + 0.04 * this.isUpgraded);
|
||||
this.lockedOn.damage(dmg);
|
||||
this.lockedOn.locatePlayer();
|
||||
|
||||
@@ -1230,13 +1230,13 @@ const b = {
|
||||
})
|
||||
World.add(engine.world, bullet[me]); //add bullet to world
|
||||
},
|
||||
boomBot(position = mech.pos, isUpgraded = mod.isBotUpgrade) {
|
||||
boomBot(position = mech.pos) {
|
||||
const me = bullet.length;
|
||||
const dir = mech.angle;
|
||||
const RADIUS = (7 + 2 * Math.random())
|
||||
bullet[me] = Bodies.polygon(position.x, position.y, 4, RADIUS, {
|
||||
isUpgraded: isUpgraded,
|
||||
isBot: true,
|
||||
isUpgraded: mod.isBoomBotUpgrade,
|
||||
botType: "boom",
|
||||
angle: dir,
|
||||
friction: 0,
|
||||
frictionStatic: 0,
|
||||
@@ -1244,9 +1244,9 @@ const b = {
|
||||
restitution: 1,
|
||||
dmg: 0,
|
||||
minDmgSpeed: 0,
|
||||
lookFrequency: 35 + Math.floor(7 * Math.random()),
|
||||
lookFrequency: 43 + Math.floor(7 * Math.random()),
|
||||
acceleration: 0.005 * (1 + 0.5 * Math.random()),
|
||||
range: 500 * (1 + 0.1 * Math.random()),
|
||||
range: 500 * (1 + 0.1 * Math.random()) + 250 * mod.isBoomBotUpgrade,
|
||||
endCycle: Infinity,
|
||||
classType: "bullet",
|
||||
collisionFilter: {
|
||||
@@ -1257,7 +1257,7 @@ const b = {
|
||||
explode: 0,
|
||||
onDmg() {
|
||||
if (this.lockedOn) {
|
||||
const explosionRadius = Math.min(170 + 70 * this.isUpgraded, Vector.magnitude(Vector.sub(this.position, mech.pos)) - 30)
|
||||
const explosionRadius = Math.min(170 + 110 * this.isUpgraded, Vector.magnitude(Vector.sub(this.position, mech.pos)) - 30)
|
||||
if (explosionRadius > 60) {
|
||||
this.explode = explosionRadius
|
||||
//
|
||||
@@ -1308,13 +1308,12 @@ const b = {
|
||||
})
|
||||
World.add(engine.world, bullet[me]); //add bullet to world
|
||||
},
|
||||
plasmaBot(position = mech.pos, isUpgraded = mod.isBotUpgrade) {
|
||||
plasmaBot(position = mech.pos) {
|
||||
const me = bullet.length;
|
||||
const dir = mech.angle;
|
||||
const RADIUS = 21
|
||||
bullet[me] = Bodies.polygon(position.x, position.y, 5, RADIUS, {
|
||||
isUpgraded: isUpgraded,
|
||||
isBot: true,
|
||||
botType: "plasma",
|
||||
angle: dir,
|
||||
friction: 0,
|
||||
frictionStatic: 0,
|
||||
@@ -1543,7 +1542,6 @@ const b = {
|
||||
defaultAmmoPack: 75,
|
||||
recordedAmmo: 0,
|
||||
have: false,
|
||||
isEasyToAim: false,
|
||||
nextFireCycle: 0, //use to remember how longs its been since last fire, used to reset count
|
||||
startingHoldCycle: 0,
|
||||
fire() {
|
||||
@@ -1581,7 +1579,6 @@ const b = {
|
||||
ammo: 0,
|
||||
ammoPack: 9,
|
||||
have: false,
|
||||
isEasyToAim: true,
|
||||
fire() {
|
||||
let knock, spread
|
||||
if (mech.crouch) {
|
||||
@@ -1653,7 +1650,6 @@ const b = {
|
||||
ammoPack: 15,
|
||||
have: false,
|
||||
num: 5,
|
||||
isEasyToAim: true,
|
||||
fire() {
|
||||
const SPEED = mech.crouch ? 43 : 32
|
||||
mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 25 : 18) * b.fireCD); // cool down
|
||||
@@ -1709,7 +1705,6 @@ const b = {
|
||||
ammoPack: 42,
|
||||
defaultAmmoPack: 42,
|
||||
have: false,
|
||||
isEasyToAim: false,
|
||||
count: 0, //used to track how many shots are in a volley before a big CD
|
||||
lastFireCycle: 0, //use to remember how longs its been since last fire, used to reset count
|
||||
fire() {
|
||||
@@ -1813,7 +1808,6 @@ const b = {
|
||||
ammo: 0,
|
||||
ammoPack: 110,
|
||||
have: false,
|
||||
isEasyToAim: false,
|
||||
fire() {
|
||||
mech.fireCDcycle = mech.cycle + Math.floor(3 * b.fireCD); // cool down
|
||||
const dir = mech.angle
|
||||
@@ -1949,7 +1943,6 @@ const b = {
|
||||
ammo: 0,
|
||||
ammoPack: 5,
|
||||
have: false,
|
||||
isEasyToAim: true,
|
||||
fireCycle: 0,
|
||||
ammoLoaded: 0,
|
||||
fire() {
|
||||
@@ -2007,7 +2000,6 @@ const b = {
|
||||
ammoPack: 6,
|
||||
defaultAmmoPack: 6, //use to revert ammoPack after mod changes drop rate
|
||||
have: false,
|
||||
isEasyToAim: false,
|
||||
fire() {
|
||||
mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 25 : 10) * b.fireCD); // cool down
|
||||
b.muzzleFlash(30);
|
||||
@@ -2051,7 +2043,6 @@ const b = {
|
||||
ammo: 0,
|
||||
ammoPack: 7,
|
||||
have: false,
|
||||
isEasyToAim: false,
|
||||
fire() {
|
||||
const me = bullet.length;
|
||||
const dir = mech.angle; // + Math.random() * 0.05;
|
||||
@@ -2103,7 +2094,6 @@ const b = {
|
||||
ammo: 0,
|
||||
ammoPack: 3,
|
||||
have: false,
|
||||
isEasyToAim: false,
|
||||
fire() {
|
||||
const me = bullet.length;
|
||||
const dir = mech.angle;
|
||||
@@ -2223,7 +2213,6 @@ const b = {
|
||||
ammo: 0,
|
||||
ammoPack: 7,
|
||||
have: false,
|
||||
isEasyToAim: true,
|
||||
fire() {
|
||||
const me = bullet.length;
|
||||
const dir = mech.angle;
|
||||
@@ -2382,7 +2371,6 @@ const b = {
|
||||
ammo: 0,
|
||||
ammoPack: 3,
|
||||
have: false,
|
||||
isEasyToAim: true,
|
||||
fire() {
|
||||
const pos = {
|
||||
x: mech.pos.x + 30 * Math.cos(mech.angle),
|
||||
@@ -2405,7 +2393,6 @@ const b = {
|
||||
ammo: 0,
|
||||
ammoPack: 5,
|
||||
have: false,
|
||||
isEasyToAim: true,
|
||||
fire() {
|
||||
const me = bullet.length;
|
||||
const dir = mech.angle;
|
||||
@@ -2526,7 +2513,6 @@ const b = {
|
||||
ammo: 0,
|
||||
ammoPack: 15,
|
||||
have: false,
|
||||
isEasyToAim: true,
|
||||
fire() {
|
||||
b.drone(mech.crouch ? 45 : 1)
|
||||
mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 13 : 5) * b.fireCD); // cool down
|
||||
@@ -2538,7 +2524,6 @@ const b = {
|
||||
ammo: 0,
|
||||
ammoPack: 73,
|
||||
have: false,
|
||||
isEasyToAim: true,
|
||||
fire() {
|
||||
if (mech.crouch) {
|
||||
b.iceIX(10, 0.3)
|
||||
@@ -2556,7 +2541,6 @@ const b = {
|
||||
ammo: 0,
|
||||
ammoPack: 50,
|
||||
have: false,
|
||||
isEasyToAim: false,
|
||||
fire() {
|
||||
mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 20 : 6) * b.fireCD); // cool down
|
||||
const radius = mech.crouch ? 10 + 7 * Math.random() : 4 + 6 * Math.random() //(4 + (mech.crouch ? 15 : 6) * Math.random())
|
||||
@@ -2579,7 +2563,6 @@ const b = {
|
||||
ammo: 0,
|
||||
ammoPack: 4,
|
||||
have: false,
|
||||
isEasyToAim: false,
|
||||
fire() {
|
||||
const me = bullet.length;
|
||||
bullet[me] = Bodies.rectangle(0, 0, 0.015, 0.0015, {
|
||||
@@ -2817,7 +2800,6 @@ const b = {
|
||||
ammo: 0,
|
||||
ammoPack: Infinity,
|
||||
have: false,
|
||||
isEasyToAim: false,
|
||||
fire() {
|
||||
const reflectivity = 1 - 1 / (mod.laserReflections * 1.5)
|
||||
let damage = b.dmgScale * mod.laserDamage
|
||||
@@ -2976,7 +2958,6 @@ const b = {
|
||||
ammo: 0,
|
||||
ammoPack: Infinity,
|
||||
have: false,
|
||||
isEasyToAim: false,
|
||||
fire() {
|
||||
//calculate laser collision
|
||||
let best, energy, explosionRange;
|
||||
@@ -3126,7 +3107,6 @@ const b = {
|
||||
// ammo: 0,
|
||||
// ammoPack: Infinity,
|
||||
// have: false,
|
||||
// isEasyToAim: false,
|
||||
// fire() {
|
||||
// if (mech.energy < 0.002) {
|
||||
// mech.fireCDcycle = mech.cycle + 100; // cool down if out of energy
|
||||
|
||||
@@ -222,9 +222,9 @@ function collisionChecks(event) {
|
||||
if (obj.classType === "body" && obj.speed > 6) {
|
||||
const v = Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity));
|
||||
if (v > 9) {
|
||||
let dmg = b.dmgScale * v * obj.mass * 0.065 * mod.throwChargeRate;
|
||||
let dmg = 0.06 * b.dmgScale * v * obj.mass * mod.throwChargeRate;
|
||||
if (mod.isCrit && !mob[k].seePlayer.recall && !mob[k].shield) dmg *= 5
|
||||
if (mob[k].isShielded) dmg *= 0.5
|
||||
if (mob[k].isShielded) dmg *= 0.4
|
||||
mob[k].damage(dmg, true);
|
||||
if (mob[k].distanceToPlayer2() < 1000000) mob[k].foundPlayer();
|
||||
game.drawList.push({
|
||||
|
||||
@@ -118,7 +118,6 @@ const game = {
|
||||
cycle: 0, //total cycles, 60 per second
|
||||
fpsCap: null, //limits frames per second to 144/2=72, on most monitors the fps is capped at 60fps by the hardware
|
||||
fpsCapDefault: 72, //use to change fpsCap back to normal after a hit from a mob
|
||||
isEasyToAimMode: true, //removes power ups that don't work well with a track pad
|
||||
isCommunityMaps: false,
|
||||
cyclePaused: 0,
|
||||
fallHeight: 3000, //below this y position the player dies
|
||||
@@ -476,7 +475,7 @@ const game = {
|
||||
const dx = game.mouse.x / window.innerWidth - 0.5 //x distance from mouse to window center scaled by window width
|
||||
const dy = game.mouse.y / window.innerHeight - 0.5 //y distance from mouse to window center scaled by window height
|
||||
const d = Math.max(dx * dx, dy * dy)
|
||||
game.edgeZoomOutSmooth = (1 + 4 * d * d) * 0.05 + game.edgeZoomOutSmooth * 0.95
|
||||
game.edgeZoomOutSmooth = (1 + 4 * d * d) * 0.04 + game.edgeZoomOutSmooth * 0.96
|
||||
|
||||
|
||||
ctx.save();
|
||||
@@ -754,7 +753,7 @@ const game = {
|
||||
});
|
||||
// move bots
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
if (bullet[i].isBot) {
|
||||
if (bullet[i].botType) {
|
||||
Matter.Body.setPosition(bullet[i], player.position);
|
||||
Matter.Body.setVelocity(bullet[i], {
|
||||
x: 0,
|
||||
@@ -1050,6 +1049,7 @@ const game = {
|
||||
document.execCommand('copy');
|
||||
} catch (err) {
|
||||
// Unable to copy
|
||||
console.log(err)
|
||||
} finally {
|
||||
// Remove the textarea
|
||||
document.body.removeChild(textAreaEle);
|
||||
@@ -1083,6 +1083,7 @@ const game = {
|
||||
out += game.constructMapString[i];
|
||||
outHTML += "<div>" + game.constructMapString[i] + "</div>"
|
||||
}
|
||||
console.log(out)
|
||||
game.copyToClipBoard(out)
|
||||
document.getElementById("construct").innerHTML = outHTML
|
||||
},
|
||||
|
||||
22
js/index.js
22
js/index.js
@@ -357,9 +357,6 @@ if (localSettings) {
|
||||
// game.isBodyDamage = localSettings.isBodyDamage
|
||||
// document.getElementById("body-damage").checked = localSettings.isBodyDamage
|
||||
|
||||
game.isEasyToAimMode = localSettings.isEasyToAimMode
|
||||
document.getElementById("track-pad-mode").checked = localSettings.isEasyToAimMode
|
||||
|
||||
game.isCommunityMaps = localSettings.isCommunityMaps
|
||||
document.getElementById("community-maps").checked = localSettings.isCommunityMaps
|
||||
|
||||
@@ -374,17 +371,12 @@ if (localSettings) {
|
||||
document.getElementById("fps-select").value = localSettings.fpsCapDefault
|
||||
} else {
|
||||
localSettings = {
|
||||
// isBodyDamage: true,
|
||||
isEasyToAimMode: false,
|
||||
isCommunityMaps: false,
|
||||
difficultyMode: '1',
|
||||
fpsCapDefault: 'max',
|
||||
};
|
||||
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
|
||||
// document.getElementById("body-damage").checked = localSettings.isBodyDamage
|
||||
document.getElementById("track-pad-mode").checked = localSettings.isEasyToAimMode
|
||||
game.isEasyToAimMode = localSettings.isEasyToAimMode
|
||||
document.getElementById("community-maps").checked = localSettings.isEasyToAimMode
|
||||
document.getElementById("community-maps").checked = localSettings.isCommunityMaps
|
||||
game.isCommunityMaps = localSettings.isCommunityMaps
|
||||
document.getElementById("difficulty-select").value = localSettings.difficultyMode
|
||||
document.getElementById("fps-select").value = localSettings.fpsCapDefault
|
||||
@@ -510,18 +502,6 @@ document.getElementById("fps-select").addEventListener("input", () => {
|
||||
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
|
||||
});
|
||||
|
||||
// document.getElementById("body-damage").addEventListener("input", () => {
|
||||
// game.isBodyDamage = document.getElementById("body-damage").checked
|
||||
// localSettings.isBodyDamage = game.isBodyDamage
|
||||
// localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
|
||||
// });
|
||||
|
||||
document.getElementById("track-pad-mode").addEventListener("input", () => {
|
||||
game.isEasyToAimMode = document.getElementById("track-pad-mode").checked
|
||||
localSettings.isEasyToAimMode = game.isEasyToAimMode
|
||||
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
|
||||
});
|
||||
|
||||
document.getElementById("community-maps").addEventListener("input", () => {
|
||||
game.isCommunityMaps = document.getElementById("community-maps").checked
|
||||
localSettings.isCommunityMaps = game.isCommunityMaps
|
||||
|
||||
254
js/level.js
254
js/level.js
@@ -62,6 +62,121 @@ const level = {
|
||||
//******************************************************************************************************************
|
||||
//******************************************************************************************************************
|
||||
//******************************************************************************************************************
|
||||
testing() {
|
||||
level.custom = () => {
|
||||
level.playerExitCheck();
|
||||
};
|
||||
level.customTopLayer = () => {};
|
||||
|
||||
level.setPosToSpawn(0, -750); //normal spawn
|
||||
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
|
||||
level.exit.x = 6500;
|
||||
level.exit.y = -230;
|
||||
|
||||
// level.difficultyIncrease(14); //hard mode level 7
|
||||
spawn.setSpawnList();
|
||||
spawn.setSpawnList();
|
||||
level.defaultZoom = 1500
|
||||
game.zoomTransition(level.defaultZoom)
|
||||
document.body.style.backgroundColor = "#ddd";
|
||||
// game.draw.mapFill = "#444"
|
||||
// game.draw.bodyFill = "rgba(140,140,140,0.85)"
|
||||
// game.draw.bodyStroke = "#222"
|
||||
|
||||
level.fill.push({
|
||||
x: 6400,
|
||||
y: -550,
|
||||
width: 300,
|
||||
height: 350,
|
||||
color: "rgba(0,255,255,0.1)"
|
||||
});
|
||||
|
||||
// level.addZone(level.exit.x, level.exit.y, 100, 30, "nextLevel");
|
||||
|
||||
spawn.mapRect(-950, 0, 8200, 800); //ground
|
||||
spawn.mapRect(-950, -1200, 800, 1400); //left wall
|
||||
spawn.mapRect(-950, -1800, 8200, 800); //roof
|
||||
spawn.mapRect(-250, -700, 1000, 900); // shelf
|
||||
spawn.mapRect(-250, -1200, 1000, 250); // shelf roof
|
||||
powerUps.spawnStartingPowerUps(600, -800);
|
||||
powerUps.spawn(550, -800, "reroll", false);
|
||||
|
||||
function blockDoor(x, y, blockSize = 58) {
|
||||
spawn.mapRect(x, y - 290, 40, 60); // door lip
|
||||
spawn.mapRect(x, y, 40, 50); // door lip
|
||||
for (let i = 0; i < 4; ++i) {
|
||||
spawn.bodyRect(x + 5, y - 260 + i * blockSize, 30, blockSize);
|
||||
}
|
||||
}
|
||||
blockDoor(710, -710);
|
||||
spawn.mapRect(2500, -1200, 200, 750); //right wall
|
||||
blockDoor(2585, -210)
|
||||
spawn.mapRect(2500, -200, 200, 300); //right wall
|
||||
spawn.mapRect(4500, -1200, 200, 650); //right wall
|
||||
blockDoor(4585, -310)
|
||||
spawn.mapRect(4500, -300, 200, 400); //right wall
|
||||
spawn.mapRect(6400, -1200, 400, 750); //right wall
|
||||
spawn.mapRect(6400, -200, 400, 300); //right wall
|
||||
spawn.mapRect(6700, -1800, 800, 2600); //right wall
|
||||
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump
|
||||
spawn.boost(1500, 0, 900);
|
||||
|
||||
// spawn.bomberBoss(2900, -500)
|
||||
// spawn.launcherBoss(1200, -500)
|
||||
// spawn.laserTargetingBoss(1600, -400)
|
||||
// spawn.spawner(1600, -500)
|
||||
// spawn.sniper(1700, -120, 50)
|
||||
// spawn.sniper(1400, -120)
|
||||
// spawn.sniper(1800, -120)
|
||||
// spawn.sniper(2200, -120)
|
||||
// spawn.cellBossCulture(1600, -500)
|
||||
// spawn.starter(1600, -500, 60)
|
||||
spawn.powerUpBoss(1600, -500)
|
||||
// spawn.shield(mob[mob.length - 1], 1200, -500, 1);
|
||||
|
||||
// spawn.nodeBoss(1200, -500, "launcher")
|
||||
// spawn.spiderBoss(1200, -500)
|
||||
// spawn.timeSkipBoss(2900, -500)
|
||||
// spawn.randomMob(1600, -500)
|
||||
},
|
||||
template() {
|
||||
level.custom = () => {
|
||||
level.playerExitCheck();
|
||||
};
|
||||
level.customTopLayer = () => {};
|
||||
level.setPosToSpawn(0, -50); //normal spawn
|
||||
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
|
||||
level.exit.x = 1500;
|
||||
level.exit.y = -1875;
|
||||
level.defaultZoom = 1800
|
||||
game.zoomTransition(level.defaultZoom)
|
||||
document.body.style.backgroundColor = "#dcdcde";
|
||||
// powerUps.spawnStartingPowerUps(1475, -1175);
|
||||
// spawn.debris(750, -2200, 3700, 16); //16 debris per level
|
||||
// level.fill.push({ //foreground
|
||||
// x: 2500,
|
||||
// y: -1100,
|
||||
// width: 450,
|
||||
// height: 250,
|
||||
// color: "rgba(0,0,0,0.1)"
|
||||
// });
|
||||
// level.fillBG.push({ //background
|
||||
// x: 1300,
|
||||
// y: -1800,
|
||||
// width: 750,
|
||||
// height: 1800,
|
||||
// color: "#d4d4d7"
|
||||
// });
|
||||
|
||||
spawn.mapRect(-100, 0, 1000, 100);
|
||||
// spawn.bodyRect(1540, -1110, 300, 25, 0.9);
|
||||
// spawn.boost(4150, 0, 1300);
|
||||
// spawn.randomSmallMob(1300, -70);
|
||||
// spawn.randomMob(2650, -975, 0.8);
|
||||
// spawn.randomBoss(1700, -900, 0.4);
|
||||
// if (game.difficulty > 3) spawn.randomLevelBoss(2200, -1300);
|
||||
powerUps.addRerollToLevel() //needs to run after mobs are spawned
|
||||
},
|
||||
testChamber() {
|
||||
level.setPosToSpawn(0, -50); //lower start
|
||||
level.exit.y = level.enter.y - 550;
|
||||
@@ -419,121 +534,6 @@ const level = {
|
||||
if (game.difficulty > 3) spawn.randomLevelBoss(6000, 2300, ["spiderBoss", "launcherBoss", "laserTargetingBoss"]);
|
||||
powerUps.addRerollToLevel() //needs to run after mobs are spawned
|
||||
},
|
||||
template() {
|
||||
level.custom = () => {
|
||||
level.playerExitCheck();
|
||||
};
|
||||
level.customTopLayer = () => {};
|
||||
level.setPosToSpawn(0, -50); //normal spawn
|
||||
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
|
||||
level.exit.x = 1500;
|
||||
level.exit.y = -1875;
|
||||
level.defaultZoom = 1800
|
||||
game.zoomTransition(level.defaultZoom)
|
||||
document.body.style.backgroundColor = "#dcdcde";
|
||||
// powerUps.spawnStartingPowerUps(1475, -1175);
|
||||
// spawn.debris(750, -2200, 3700, 16); //16 debris per level
|
||||
// level.fill.push({ //foreground
|
||||
// x: 2500,
|
||||
// y: -1100,
|
||||
// width: 450,
|
||||
// height: 250,
|
||||
// color: "rgba(0,0,0,0.1)"
|
||||
// });
|
||||
// level.fillBG.push({ //background
|
||||
// x: 1300,
|
||||
// y: -1800,
|
||||
// width: 750,
|
||||
// height: 1800,
|
||||
// color: "#d4d4d7"
|
||||
// });
|
||||
|
||||
spawn.mapRect(-100, 0, 1000, 100);
|
||||
// spawn.bodyRect(1540, -1110, 300, 25, 0.9);
|
||||
// spawn.boost(4150, 0, 1300);
|
||||
// spawn.randomSmallMob(1300, -70);
|
||||
// spawn.randomMob(2650, -975, 0.8);
|
||||
// spawn.randomBoss(1700, -900, 0.4);
|
||||
// if (game.difficulty > 3) spawn.randomLevelBoss(2200, -1300);
|
||||
powerUps.addRerollToLevel() //needs to run after mobs are spawned
|
||||
},
|
||||
testing() {
|
||||
level.custom = () => {
|
||||
level.playerExitCheck();
|
||||
};
|
||||
level.customTopLayer = () => {};
|
||||
|
||||
level.setPosToSpawn(0, -750); //normal spawn
|
||||
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
|
||||
level.exit.x = 6500;
|
||||
level.exit.y = -230;
|
||||
|
||||
// level.difficultyIncrease(14); //hard mode level 7
|
||||
spawn.setSpawnList();
|
||||
spawn.setSpawnList();
|
||||
level.defaultZoom = 1500
|
||||
game.zoomTransition(level.defaultZoom)
|
||||
document.body.style.backgroundColor = "#ddd";
|
||||
// game.draw.mapFill = "#444"
|
||||
// game.draw.bodyFill = "rgba(140,140,140,0.85)"
|
||||
// game.draw.bodyStroke = "#222"
|
||||
|
||||
level.fill.push({
|
||||
x: 6400,
|
||||
y: -550,
|
||||
width: 300,
|
||||
height: 350,
|
||||
color: "rgba(0,255,255,0.1)"
|
||||
});
|
||||
|
||||
// level.addZone(level.exit.x, level.exit.y, 100, 30, "nextLevel");
|
||||
|
||||
spawn.mapRect(-950, 0, 8200, 800); //ground
|
||||
spawn.mapRect(-950, -1200, 800, 1400); //left wall
|
||||
spawn.mapRect(-950, -1800, 8200, 800); //roof
|
||||
spawn.mapRect(-250, -700, 1000, 900); // shelf
|
||||
spawn.mapRect(-250, -1200, 1000, 250); // shelf roof
|
||||
powerUps.spawnStartingPowerUps(600, -800);
|
||||
powerUps.spawn(550, -800, "reroll", false);
|
||||
|
||||
function blockDoor(x, y, blockSize = 58) {
|
||||
spawn.mapRect(x, y - 290, 40, 60); // door lip
|
||||
spawn.mapRect(x, y, 40, 50); // door lip
|
||||
for (let i = 0; i < 4; ++i) {
|
||||
spawn.bodyRect(x + 5, y - 260 + i * blockSize, 30, blockSize);
|
||||
}
|
||||
}
|
||||
blockDoor(710, -710);
|
||||
spawn.mapRect(2500, -1200, 200, 750); //right wall
|
||||
blockDoor(2585, -210)
|
||||
spawn.mapRect(2500, -200, 200, 300); //right wall
|
||||
spawn.mapRect(4500, -1200, 200, 650); //right wall
|
||||
blockDoor(4585, -310)
|
||||
spawn.mapRect(4500, -300, 200, 400); //right wall
|
||||
spawn.mapRect(6400, -1200, 400, 750); //right wall
|
||||
spawn.mapRect(6400, -200, 400, 300); //right wall
|
||||
spawn.mapRect(6700, -1800, 800, 2600); //right wall
|
||||
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump
|
||||
spawn.boost(1500, 0, 900);
|
||||
|
||||
// spawn.bomberBoss(2900, -500)
|
||||
// spawn.launcherBoss(1200, -500)
|
||||
// spawn.laserTargetingBoss(1600, -400)
|
||||
// spawn.spawner(1600, -500)
|
||||
// spawn.sniper(1700, -120, 50)
|
||||
// spawn.sniper(1400, -120)
|
||||
// spawn.sniper(1800, -120)
|
||||
// spawn.sniper(2200, -120)
|
||||
// spawn.cellBossCulture(1600, -500)
|
||||
// spawn.starter(1600, -500, 60)
|
||||
// spawn.striker(1600, -500)
|
||||
// spawn.shield(mob[mob.length - 1], 1200, -500, 1);
|
||||
|
||||
// spawn.nodeBoss(1200, -500, "launcher")
|
||||
spawn.spiderBoss(1200, -500)
|
||||
// spawn.timeSkipBoss(2900, -500)
|
||||
// spawn.randomMob(1600, -500)
|
||||
},
|
||||
bosses() {
|
||||
level.custom = () => {
|
||||
level.playerExitCheck();
|
||||
@@ -1325,7 +1325,7 @@ const level = {
|
||||
spawn.randomBoss(4000, -350, 0.6);
|
||||
spawn.randomBoss(2750, -550, 0.1);
|
||||
if (game.difficulty > 2) {
|
||||
if (Math.random() < 0.09) { // tether ball
|
||||
if (Math.random() < 0.1) { // tether ball
|
||||
spawn.tetherBoss(4250, 0)
|
||||
cons[cons.length] = Constraint.create({
|
||||
pointA: {
|
||||
@@ -1336,7 +1336,7 @@ const level = {
|
||||
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 if (Math.random() < 0.08) {
|
||||
} else if (Math.random() < 0.15) {
|
||||
spawn.randomLevelBoss(4250, -250);
|
||||
} else {
|
||||
//floor below right tall tower
|
||||
@@ -2023,7 +2023,7 @@ const level = {
|
||||
spawn.randomBoss(4150, -1000, 0.6);
|
||||
|
||||
if (game.difficulty > 2) {
|
||||
if (Math.random() < 0.75) {
|
||||
if (Math.random() < 0.65) {
|
||||
// tether ball
|
||||
level.fillBG.push({
|
||||
x: 2495,
|
||||
@@ -2043,8 +2043,8 @@ const level = {
|
||||
});
|
||||
//chance to spawn a ring of exploding mobs around this boss
|
||||
if (game.difficulty > 4) spawn.nodeBoss(2850, -80, "spawns", 8, 20, 105);
|
||||
} else if (game.difficulty > 3) {
|
||||
spawn.shooterBoss(2200, -650);
|
||||
} else {
|
||||
spawn.randomLevelBoss(2200, -650)
|
||||
}
|
||||
}
|
||||
powerUps.addRerollToLevel() //needs to run after mobs are spawned
|
||||
@@ -3072,10 +3072,10 @@ const level = {
|
||||
|
||||
draw = function () {
|
||||
ctx.beginPath(); //portal
|
||||
sensor = this.vertices;
|
||||
ctx.moveTo(sensor[0].x, sensor[0].y);
|
||||
for (let i = 1; i < sensor.length; ++i) {
|
||||
ctx.lineTo(sensor[i].x, sensor[i].y);
|
||||
let v = this.vertices;
|
||||
ctx.moveTo(v[0].x, v[0].y);
|
||||
for (let i = 1; i < v.length; ++i) {
|
||||
ctx.lineTo(v[i].x, v[i].y);
|
||||
}
|
||||
ctx.fillStyle = this.color
|
||||
ctx.fill();
|
||||
@@ -3104,7 +3104,7 @@ const level = {
|
||||
Matter.Body.setVelocity(player, v);
|
||||
// move bots to follow player
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
if (bullet[i].isBot) {
|
||||
if (bullet[i].botType) {
|
||||
Matter.Body.setPosition(bullet[i], this.portalPair.portal.position);
|
||||
Matter.Body.setVelocity(bullet[i], {
|
||||
x: 0,
|
||||
@@ -3113,8 +3113,6 @@ const level = {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (body.length) {
|
||||
for (let i = 0, len = body.length; i < len; i++) {
|
||||
if (body[i] !== mech.holdingTarget) {
|
||||
@@ -3210,7 +3208,7 @@ const level = {
|
||||
color: game.draw.mapFill,
|
||||
draw: draw,
|
||||
query: query,
|
||||
lastPortalCycle: 0
|
||||
lastPortalCycle: 0,
|
||||
});
|
||||
Matter.Body.setStatic(mapB, true); //make static
|
||||
World.add(engine.world, mapB); //add to world
|
||||
|
||||
19
js/mob.js
19
js/mob.js
@@ -47,7 +47,7 @@ const mobs = {
|
||||
applySlow(who)
|
||||
//look for mobs near the target
|
||||
if (mod.isAoESlow) {
|
||||
const range = (220 + 150 * Math.random()) ** 2
|
||||
const range = (320 + 150 * Math.random()) ** 2
|
||||
for (let i = 0, len = mob.length; i < len; i++) {
|
||||
if (Vector.magnitudeSquared(Vector.sub(who.position, mob[i].position)) < range) applySlow(mob[i])
|
||||
}
|
||||
@@ -705,10 +705,13 @@ const mobs = {
|
||||
//accelerate towards the player
|
||||
if (this.seePlayer.recall) {
|
||||
// && dx * dx + dy * dy < 2000000) {
|
||||
const forceMag = this.accelMag * this.mass;
|
||||
const angle = Math.atan2(this.seePlayer.position.y - this.position.y, this.seePlayer.position.x - this.position.x);
|
||||
this.force.x += forceMag * Math.cos(angle);
|
||||
this.force.y += forceMag * Math.sin(angle);
|
||||
// const forceMag = this.accelMag * this.mass;
|
||||
// const angle = Math.atan2(this.seePlayer.position.y - this.position.y, this.seePlayer.position.x - this.position.x);
|
||||
// this.force.x += forceMag * Math.cos(angle);
|
||||
// this.force.y += forceMag * Math.sin(angle);
|
||||
const force = Vector.mult(Vector.normalise(Vector.sub(this.seePlayer.position, this.position)), this.accelMag * this.mass)
|
||||
this.force.x += force.x;
|
||||
this.force.y += force.y;
|
||||
}
|
||||
},
|
||||
repulsionRange: 500000,
|
||||
@@ -1076,7 +1079,7 @@ const mobs = {
|
||||
//replace dead mob with a regular body
|
||||
replace(i) {
|
||||
//if there are too many bodies don't turn into blocks to help performance
|
||||
if (this.leaveBody && body.length < 60 && this.mass < 100) {
|
||||
if (this.leaveBody && body.length < 60 && this.mass < 200) {
|
||||
const len = body.length;
|
||||
const v = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices)) //might help with vertex collision issue, not sure
|
||||
body[len] = Matter.Bodies.fromVertices(this.position.x, this.position.y, v);
|
||||
@@ -1091,7 +1094,7 @@ const mobs = {
|
||||
World.add(engine.world, body[len]); //add to world
|
||||
|
||||
//large mobs shrink so they don't block paths
|
||||
if (body[len].mass > 10) {
|
||||
if (body[len].mass > 9) {
|
||||
const shrink = function (that, massLimit) {
|
||||
if (that.mass > massLimit) {
|
||||
const scale = 0.95;
|
||||
@@ -1099,7 +1102,7 @@ const mobs = {
|
||||
setTimeout(shrink, 20, that, massLimit);
|
||||
}
|
||||
};
|
||||
shrink(body[len], 9 + 5 * Math.random())
|
||||
shrink(body[len], 7 + 4 * Math.random())
|
||||
}
|
||||
}
|
||||
Matter.World.remove(engine.world, this);
|
||||
|
||||
137
js/mods.js
137
js/mods.js
@@ -79,7 +79,7 @@ const mod = {
|
||||
if (mod.isEnergyDamage) dmg *= 1 + mech.energy / 5.5;
|
||||
if (mod.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.006
|
||||
if (mod.isRerollDamage) dmg *= 1 + 0.05 * powerUps.reroll.rerolls
|
||||
if (mod.isOneGun && b.inventory.length < 2) dmg *= 1.25
|
||||
if (mod.isOneGun && b.inventory.length < 2) dmg *= 1.22
|
||||
return dmg * mod.slowFire
|
||||
},
|
||||
totalBots() {
|
||||
@@ -87,7 +87,7 @@ const mod = {
|
||||
},
|
||||
mods: [{
|
||||
name: "integrated armament",
|
||||
description: "increase <strong class='color-d'>damage</strong> by <strong>25%</strong><br>your inventory can only hold <strong>1 gun</strong>",
|
||||
description: "increase <strong class='color-d'>damage</strong> by <strong>22%</strong><br>your inventory can only hold <strong>1 gun</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
allowed() {
|
||||
@@ -389,6 +389,23 @@ const mod = {
|
||||
mod.nailsDeathMob = 0;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "bot fabrication",
|
||||
description: "anytime you collect <strong>4</strong> <strong class='color-r'>rerolls</strong><br>use them to build a random <strong>bot</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
allowed() {
|
||||
return powerUps.reroll.rerolls > 3 || build.isCustomSelection
|
||||
},
|
||||
requires: "at least 4 rerolls",
|
||||
effect() {
|
||||
mod.isRerollBots = true;
|
||||
powerUps.reroll.changeRerolls(0)
|
||||
},
|
||||
remove() {
|
||||
mod.isRerollBots = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "nail-bot",
|
||||
description: "a bot fires <strong>nails</strong> at targets in line of sight",
|
||||
@@ -406,6 +423,28 @@ const mod = {
|
||||
mod.nailBotCount = 0;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "nail-bot upgrade",
|
||||
description: "<strong>100%</strong> increased nail-bot <strong> fire rate</strong><br><em>applies to all current and future nail-bots</em>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
allowed() {
|
||||
return mod.nailBotCount > 1
|
||||
},
|
||||
requires: "2 or more nail bots",
|
||||
effect() {
|
||||
mod.isNailBotUpgrade = true
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
if (bullet[i].botType = 'nail') bullet[i].isUpgraded = true
|
||||
}
|
||||
},
|
||||
remove() {
|
||||
mod.isNailBotUpgrade = false
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
if (bullet[i].botType = 'nail') bullet[i].isUpgraded = false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "foam-bot",
|
||||
description: "a bot fires <strong>foam</strong> at targets in line of sight",
|
||||
@@ -423,6 +462,28 @@ const mod = {
|
||||
mod.foamBotCount = 0;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "foam-bot upgrade",
|
||||
description: "<strong>100%</strong> increased foam-bot <strong>foam size</strong><br><em>applies to all current and future foam-bots</em>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
allowed() {
|
||||
return mod.foamBotCount > 1
|
||||
},
|
||||
requires: "2 or more foam bots",
|
||||
effect() {
|
||||
mod.isFoamBotUpgrade = true
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
if (bullet[i].botType = 'foam') bullet[i].isUpgraded = true
|
||||
}
|
||||
},
|
||||
remove() {
|
||||
mod.isFoamBotUpgrade = false
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
if (bullet[i].botType = 'foam') bullet[i].isUpgraded = false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "boom-bot",
|
||||
description: "a bot <strong>defends</strong> the space around you<br>ignites an <strong class='color-e'>explosion</strong> after hitting a mob",
|
||||
@@ -440,6 +501,28 @@ const mod = {
|
||||
mod.boomBotCount = 0;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "boom-bot upgrade",
|
||||
description: "<strong>100%</strong> increased boom-bot <strong class='color-e'>explosion</strong> size<br><em>applies to all current and future boom-bots</em>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
allowed() {
|
||||
return mod.boomBotCount > 1
|
||||
},
|
||||
requires: "2 or more boom bots",
|
||||
effect() {
|
||||
mod.isBoomBotUpgrade = true
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
if (bullet[i].botType = 'boom') bullet[i].isUpgraded = true
|
||||
}
|
||||
},
|
||||
remove() {
|
||||
mod.isBoomBotUpgrade = false
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
if (bullet[i].botType = 'boom') bullet[i].isUpgraded = false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "laser-bot",
|
||||
description: "a bot <strong>defends</strong> the space around you<br>uses a <strong>short range</strong> laser that drains <strong class='color-f'>energy</strong>",
|
||||
@@ -458,20 +541,25 @@ const mod = {
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "bot fabrication",
|
||||
description: "anytime you collect <strong>4</strong> <strong class='color-r'>rerolls</strong><br>use them to build a random <strong>bot</strong>",
|
||||
name: "laser-bot upgrade",
|
||||
description: "<strong>100%</strong> increased laser-bot <strong class='color-d'>damage</strong><br><em>applies to all current and future laser-bots</em>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
allowed() {
|
||||
return powerUps.reroll.rerolls > 3 || build.isCustomSelection
|
||||
return mod.laserBotCount > 1
|
||||
},
|
||||
requires: "at least 4 rerolls",
|
||||
requires: "2 or more laser bots",
|
||||
effect() {
|
||||
mod.isRerollBots = true;
|
||||
powerUps.reroll.changeRerolls(0)
|
||||
mod.isLaserBotUpgrade = true
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
if (bullet[i].botType = 'laser') bullet[i].isUpgraded = true
|
||||
}
|
||||
},
|
||||
remove() {
|
||||
mod.isRerollBots = false;
|
||||
mod.isLaserBotUpgrade = false
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
if (bullet[i].botType = 'laser') bullet[i].isUpgraded = false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -506,28 +594,6 @@ const mod = {
|
||||
mod.isBotArmor = false
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "bot upgrades",
|
||||
description: "<strong>40% improved:</strong> nail fire rate, boom explosion,<br>foam size, laser drain, and plasma drain",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
allowed() {
|
||||
return mod.totalBots() > 1
|
||||
},
|
||||
requires: "2 or more bots",
|
||||
effect() {
|
||||
mod.isBotUpgrade = true
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
if (bullet[i].isBot) bullet[i].isUpgraded = true
|
||||
}
|
||||
},
|
||||
remove() {
|
||||
mod.isBotUpgrade = false
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
if (bullet[i].isBot) bullet[i].isUpgraded = false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "bot replication",
|
||||
description: "<strong>duplicate</strong> your permanent <strong>bots</strong><br>remove <strong>all</strong> of your <strong class='color-g'>guns</strong>",
|
||||
@@ -1724,7 +1790,7 @@ const mod = {
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
allowed() {
|
||||
return mod.nailBotCount + mod.grenadeFragments + mod.nailsDeathMob > 1 || mod.haveGunCheck("mine") || mod.isRailNails || mod.isNailShot
|
||||
return mod.nailBotCount + mod.grenadeFragments + mod.nailsDeathMob / 2 + mod.haveGunCheck("mine") + mod.isRailNails + mod.isNailShot > 1
|
||||
},
|
||||
requires: "nails",
|
||||
effect() {
|
||||
@@ -1817,7 +1883,7 @@ const mod = {
|
||||
},
|
||||
{
|
||||
name: "harvester",
|
||||
description: "when a <strong>drone</strong> picks up a <strong>power up</strong><br> improve its size, duration, and vision rate",
|
||||
description: "after a <strong>drone</strong> picks up a <strong>power up</strong>,<br>it's <strong>bigger</strong>, <strong>faster</strong>, and infinitely <strong>durable</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
allowed() {
|
||||
@@ -2483,7 +2549,10 @@ const mod = {
|
||||
isMineDrop: null,
|
||||
isRerollBots: null,
|
||||
isRailTimeSlow: null,
|
||||
isBotUpgrade: null,
|
||||
isNailBotUpgrade: null,
|
||||
isFoamBotUpgrade: null,
|
||||
isLaserBotUpgrade: null,
|
||||
isBoomBotUpgrade: null,
|
||||
isDroneGrab: null,
|
||||
isOneGun: null
|
||||
}
|
||||
11
js/player.js
11
js/player.js
@@ -1175,7 +1175,6 @@ const mech = {
|
||||
fieldUpgrades: [{
|
||||
name: "field emitter",
|
||||
description: "use <strong class='color-f'>energy</strong> to <strong>shield</strong> yourself from <strong class='color-harm'>harm</strong><br><strong>pick up</strong> and <strong>throw</strong> objects",
|
||||
isEasyToAim: false,
|
||||
effect: () => {
|
||||
game.replaceTextLog = true; //allow text over write
|
||||
mech.hold = function () {
|
||||
@@ -1202,7 +1201,6 @@ const mech = {
|
||||
{
|
||||
name: "standing wave harmonics",
|
||||
description: "three oscillating <strong>shields</strong> are permanently active<br>reduce <strong class='color-harm'>harm</strong> by <strong>33%</strong>",
|
||||
isEasyToAim: true,
|
||||
effect: () => {
|
||||
mech.fieldHarmReduction = 0.67;
|
||||
mech.fieldBlockCD = 0;
|
||||
@@ -1245,7 +1243,6 @@ const mech = {
|
||||
name: "perfect diamagnetism",
|
||||
// description: "gain <strong class='color-f'>energy</strong> when <strong>blocking</strong><br>no <strong>recoil</strong> when <strong>blocking</strong>",
|
||||
description: "<strong>blocking</strong> does not drain <strong class='color-f'>energy</strong><br><strong>blocking</strong> has no <strong>cool down</strong> and less <strong>recoil</strong>",
|
||||
isEasyToAim: false,
|
||||
effect: () => {
|
||||
mech.fieldShieldingScale = 0;
|
||||
// mech.fieldMeterColor = "#0af"
|
||||
@@ -1302,7 +1299,6 @@ const mech = {
|
||||
{
|
||||
name: "nano-scale manufacturing",
|
||||
description: "excess <strong class='color-f'>energy</strong> used to build <strong>drones</strong><br><strong class='color-f'>energy</strong> regeneration is <strong>doubled</strong>",
|
||||
isEasyToAim: true,
|
||||
effect: () => {
|
||||
// mech.fieldRegen *= 2;
|
||||
mech.hold = function () {
|
||||
@@ -1326,7 +1322,7 @@ const mech = {
|
||||
1, mod.babyMissiles)
|
||||
} else if (mod.isIceField) {
|
||||
// mech.fieldCDcycle = mech.cycle + 17; // set cool down to prevent +energy from making huge numbers of drones
|
||||
mech.energy -= 0.061;
|
||||
mech.energy -= 0.045;
|
||||
b.iceIX(1)
|
||||
} else {
|
||||
// mech.fieldCDcycle = mech.cycle + 10; // set cool down to prevent +energy from making huge numbers of drones
|
||||
@@ -1360,7 +1356,6 @@ const mech = {
|
||||
name: "negative mass field",
|
||||
description: "use <strong class='color-f'>energy</strong> to nullify <strong style='letter-spacing: 12px;'>gravity</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>50%</strong>",
|
||||
fieldDrawRadius: 0,
|
||||
isEasyToAim: true,
|
||||
effect: () => {
|
||||
mech.fieldFire = true;
|
||||
mech.holdingMassScale = 0.03; //can hold heavier blocks with lower cost to jumping
|
||||
@@ -1478,7 +1473,6 @@ const mech = {
|
||||
{
|
||||
name: "plasma torch",
|
||||
description: "use <strong class='color-f'>energy</strong> to emit short range plasma<br>plasma <strong class='color-d'>damages</strong> and <strong>pushes</strong> mobs",
|
||||
isEasyToAim: false,
|
||||
effect() {
|
||||
mech.fieldMeterColor = "#f0f"
|
||||
mech.hold = function () {
|
||||
@@ -1634,7 +1628,6 @@ const mech = {
|
||||
{
|
||||
name: "time dilation field",
|
||||
description: "use <strong class='color-f'>energy</strong> to <strong style='letter-spacing: 1px;'>stop time</strong><br><em>you can move and fire while time is stopped</em>",
|
||||
isEasyToAim: true,
|
||||
effect: () => {
|
||||
// mech.fieldMeterColor = "#000"
|
||||
mech.fieldFire = true;
|
||||
@@ -1727,7 +1720,6 @@ const mech = {
|
||||
{
|
||||
name: "phase decoherence field",
|
||||
description: "use <strong class='color-f'>energy</strong> to become <strong>intangible</strong><br><strong>firing</strong> and touching <strong>shields</strong> increases <strong>drain</strong>",
|
||||
isEasyToAim: true,
|
||||
effect: () => {
|
||||
mech.fieldFire = true;
|
||||
mech.fieldMeterColor = "#fff";
|
||||
@@ -1876,7 +1868,6 @@ const mech = {
|
||||
{
|
||||
name: "pilot wave",
|
||||
description: "use <strong class='color-f'>energy</strong> to push <strong>blocks</strong> with your mouse<br>field <strong>radius</strong> decreases out of <strong>line of sight</strong>",
|
||||
isEasyToAim: false,
|
||||
effect: () => {
|
||||
game.replaceTextLog = true; //allow text over write
|
||||
game.isBodyDamage = false;
|
||||
|
||||
@@ -171,7 +171,7 @@ const powerUps = {
|
||||
function pick(who, skip1 = -1, skip2 = -1, skip3 = -1, skip4 = -1) {
|
||||
let options = [];
|
||||
for (let i = 1; i < who.length; i++) {
|
||||
if (i !== mech.fieldMode && (!game.isEasyToAimMode || mech.fieldUpgrades[i].isEasyToAim) && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4) options.push(i);
|
||||
if (i !== mech.fieldMode && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4) options.push(i);
|
||||
}
|
||||
//remove repeats from last selection
|
||||
const totalChoices = mod.isDeterminism ? 1 : 3 + mod.isExtraChoice * 2
|
||||
@@ -310,7 +310,7 @@ const powerUps = {
|
||||
function pick(who, skip1 = -1, skip2 = -1, skip3 = -1, skip4 = -1) {
|
||||
let options = [];
|
||||
for (let i = 0; i < who.length; i++) {
|
||||
if (!who[i].have && (!game.isEasyToAimMode || b.guns[i].isEasyToAim) && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4) {
|
||||
if (!who[i].have && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4) {
|
||||
options.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
46
js/spawn.js
46
js/spawn.js
@@ -81,7 +81,7 @@ const spawn = {
|
||||
}
|
||||
}
|
||||
},
|
||||
randomLevelBoss(x, y, options = ["shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss"]) {
|
||||
randomLevelBoss(x, y, options = ["shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "powerUpBoss"]) {
|
||||
// other bosses: suckerBoss, laserBoss, tetherBoss, snakeBoss //all need a particular level to work so they are not included
|
||||
spawn[options[Math.floor(Math.random() * options.length)]](x, y)
|
||||
},
|
||||
@@ -227,6 +227,50 @@ const spawn = {
|
||||
}
|
||||
}
|
||||
},
|
||||
powerUpBoss(x, y, vertices = 9, radius = 150) {
|
||||
mobs.spawn(x, y, vertices, radius, "transparent");
|
||||
let me = mob[mob.length - 1];
|
||||
me.isBoss = true;
|
||||
me.frictionAir = 0.05
|
||||
me.seeAtDistance2 = 600000;
|
||||
me.accelMag = 0.0005 * game.accelScale;
|
||||
if (map.length) me.searchTarget = map[Math.floor(Math.random() * (map.length - 1))].position; //required for search
|
||||
Matter.Body.setDensity(me, 0.001); //normal is 0.001
|
||||
me.collisionFilter.mask = cat.bullet | cat.player
|
||||
// me.memory = 480;
|
||||
// me.seePlayerFreq = 40 + Math.floor(10 * Math.random())
|
||||
|
||||
me.lockedOn = null;
|
||||
if (vertices === 9) {
|
||||
powerUps.spawnBossPowerUp(me.position.x, me.position.y)
|
||||
powerUp[powerUp.length - 1].collisionFilter.mask = 0
|
||||
me.powerUpInventory = [powerUp[powerUp.length - 1]];
|
||||
}
|
||||
|
||||
me.onDeath = function () {
|
||||
if (vertices > 3) spawn.powerUpBoss(this.position.x, this.position.y, vertices - 1)
|
||||
for (let i = 0; i < powerUp.length; i++) {
|
||||
powerUp[i].collisionFilter.mask = cat.map | cat.powerUp
|
||||
}
|
||||
};
|
||||
me.do = function () {
|
||||
this.stroke = `hsl(0,0%,${80+25*Math.sin(game.cycle*0.01)}%)`
|
||||
|
||||
//steal all power ups
|
||||
for (let i = 0; i < Math.min(powerUp.length, this.vertices.length); i++) {
|
||||
powerUp[i].collisionFilter.mask = 0
|
||||
Matter.Body.setPosition(powerUp[i], this.vertices[i])
|
||||
Matter.Body.setVelocity(powerUp[i], {
|
||||
x: 0,
|
||||
y: 0
|
||||
})
|
||||
}
|
||||
|
||||
this.seePlayerByLookingAt();
|
||||
this.attraction();
|
||||
this.checkStatus();
|
||||
};
|
||||
},
|
||||
// healer(x, y, radius = 20) {
|
||||
// mobs.spawn(x, y, 3, radius, "rgba(50,255,200,0.4)");
|
||||
// let me = mob[mob.length - 1];
|
||||
|
||||
103
todo.txt
103
todo.txt
@@ -1,15 +1,32 @@
|
||||
the game zooms out a bit when the mouse is near the edge of the browser window
|
||||
(is it annoying or helpful?)
|
||||
maybe I should add in a smoothing variable for the edge zoom
|
||||
removed eay to aim setting
|
||||
the addition of gun selection make this setting less important
|
||||
|
||||
mod: bot upgrades - forked into 4 different mods for each bot
|
||||
effect is increased to 100% improvement (up from 40%)
|
||||
|
||||
drones are more likely to pick up power ups
|
||||
mod harvester: now also gives the drone immortality
|
||||
|
||||
new level boss: after it dies it returns with one less vertex
|
||||
also it steals all your power ups (what!)
|
||||
|
||||
************** TODO - n-gon **************
|
||||
|
||||
drop level boss rate mods a bit earlier
|
||||
or increase damage scaling
|
||||
ghosters are always visible
|
||||
ghoster mobs eat power ups and drop them on death
|
||||
draw ghoster if it has a power up
|
||||
or just always draw ghoster?
|
||||
if no power ups on map go for player
|
||||
|
||||
fix tension on stronghold
|
||||
|
||||
zoom out a bit when mouse is near edge of screen
|
||||
give mobs more animal-like behaviors
|
||||
like rain world
|
||||
give mobs something to do when they don't see player
|
||||
explore map
|
||||
mobs some times aren't aggressive
|
||||
when low on life or after taking a large hit
|
||||
mobs can fight each other
|
||||
this might be hard to code
|
||||
isolated mobs try to group up
|
||||
|
||||
map: laboratory
|
||||
rooms with switches that change physics
|
||||
@@ -54,6 +71,8 @@ lore - a robot (the player) gains self awareness
|
||||
new gun - deploy a turret that last for 20 seconds
|
||||
fire nails at nearby targets once a second.
|
||||
use mine code and bot code
|
||||
mod - mines become a turret that fires nails
|
||||
it could float to the mouse location on fire
|
||||
|
||||
minigun: high caliber - rework
|
||||
slow down the bullets even more and increase the size?
|
||||
@@ -65,10 +84,6 @@ portals:
|
||||
extend to bodies (mobs?)
|
||||
use buttons to turn on and off?
|
||||
|
||||
level boss: boss that dies and comes back to life but with one less side until it hits 3 sides
|
||||
change color too (hsl)
|
||||
boss shrinks and moves faster after each death
|
||||
|
||||
level boss: fires a line intersection in a random direction every few seconds.
|
||||
the last two intersections have a destructive laser between them.
|
||||
|
||||
@@ -83,10 +98,6 @@ map: prison
|
||||
|
||||
map: airport
|
||||
|
||||
button: blocks that are on the button at an angle will slowly slide off the button
|
||||
maybe just avoid long blocks near the button?
|
||||
maybe actively hold the button in place?
|
||||
|
||||
mod - do 50% more damage in close, but 50% less at a distance
|
||||
code it like mod.isFarAwayDmg
|
||||
have these mods disable each other
|
||||
@@ -130,8 +141,6 @@ redblobgames.com/articles/visibility
|
||||
https://github.com/Silverwolf90/2d-visibility/tree/master/src
|
||||
could apply to explosions, neutron bomb, player LOS
|
||||
|
||||
bug - sticking bullets don't always gain the correct speed from mobs after they die
|
||||
|
||||
possible names for mods
|
||||
Hypergolic - A hypergolic propellant combination used in a rocket engine is one whose components spontaneously ignite when they come into contact with each other.
|
||||
|
||||
@@ -145,47 +154,19 @@ boss levels - small levels just a boss, and maybe a few mobs
|
||||
boss level for timeSkipBoss because of game instability for boss on normal levels
|
||||
this might not fix issues
|
||||
|
||||
bullets cost 5 life instead of ammo, but return 5 life when they hit a mob
|
||||
replace life with energy or ammo?
|
||||
|
||||
an effect when canceling a power up
|
||||
ammo? heals?
|
||||
50% chance for a mod, 25% heal, 25% ammo
|
||||
|
||||
liquid nitrogen cooling
|
||||
Mobs freeze on contact with the player
|
||||
|
||||
uranium reactor core
|
||||
Mobs get irradiated on contact with the player
|
||||
|
||||
add player Scent Trails for mob navigation
|
||||
https://abitawake.com/news/articles/enemy-ai-chasing-a-player-without-navigation2d-or-a-star-pathfinding
|
||||
|
||||
mod - scale squirrel cage rotor with current energy
|
||||
is variable speed going to be hard to deal with?
|
||||
|
||||
mod - you can no longer see your current health
|
||||
|
||||
mod - increase laser bot range, and reduce energy drain
|
||||
|
||||
mod - mines become a turret that fires nails
|
||||
it could float to the mouse location on fire
|
||||
|
||||
mod - blocks stun mobs
|
||||
|
||||
settings - custom keys binding
|
||||
|
||||
css transition for pause menu
|
||||
|
||||
gun/field: portals
|
||||
use the code from mines to get them to stick to walls
|
||||
or lasers
|
||||
alternate red and blue portals
|
||||
|
||||
weekly random challenge where everyone playing each week gets the same random setup.
|
||||
The randomness would be determined by the date so it would sync everyone.
|
||||
power ups still drop, but the drops are determined by a preset list that changes each week.
|
||||
|
||||
gun: Spirit Bomb (singularity)
|
||||
use charge up like rail gun
|
||||
electricity graphics like plasma torch
|
||||
@@ -194,41 +175,11 @@ gun: Spirit Bomb (singularity)
|
||||
uses energy
|
||||
hold above the player's head
|
||||
|
||||
add a key that player picks up and needs to set on the exit door to open it
|
||||
|
||||
make power ups keep moving to player if the pickup field is turned off before they get picked up
|
||||
not sure how to do this without adding a constant check
|
||||
|
||||
animate new level spawn by having the map aspects randomly fly into place
|
||||
|
||||
give mobs more animal-like behaviors
|
||||
like rain world
|
||||
give mobs something to do when they don't see player
|
||||
explore map
|
||||
eat power ups
|
||||
drop power up (if killed after eating one)
|
||||
mobs some times aren't aggressive
|
||||
when low on life or after taking a large hit
|
||||
mobs can fight each other
|
||||
this might be hard to code
|
||||
isolated mobs try to group up.
|
||||
|
||||
game mechanics
|
||||
mechanics that support the physics engine
|
||||
add rope/constraint
|
||||
get ideas from game: limbo / inside
|
||||
environmental hazards
|
||||
laser
|
||||
lava
|
||||
button / switch
|
||||
door
|
||||
fizzler
|
||||
moving platform
|
||||
map zones
|
||||
water
|
||||
low friction ground
|
||||
bouncy ground
|
||||
|
||||
n-gon outreach ideas
|
||||
blips - errant signal on youtube
|
||||
reddit - r/IndieGaming
|
||||
|
||||
Reference in New Issue
Block a user