new level boss

This commit is contained in:
landgreen
2020-08-03 16:28:36 -07:00
parent c08a93416d
commit 07f77e41a5
12 changed files with 366 additions and 352 deletions

View File

@@ -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>

View File

@@ -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

View File

@@ -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({

View File

@@ -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
},

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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
}

View File

@@ -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 &nbsp; <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;

View File

@@ -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);
}
}

View File

@@ -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
View File

@@ -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