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> <option value="4">why...</option>
</select> </select>
<br> <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;"> <input type="checkbox" id="community-maps" name="community-maps" style="width:17px; height:17px;">
<!-- <br> <!-- <br>
<label for="body-damage" title="allow damage from the ground and large fast moving blocks">collision damage from blocks:</label> <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;"> --> <input type="checkbox" id="body-damage" name="body-damage" checked style="width:17px; height:17px;"> -->
<br> <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> <label for="fps-select" title="use this to slow the game down">limit frames per second:</label>
<select name="fps-select" id="fps-select"> <select name="fps-select" id="fps-select">
<option value="max" selected>no cap</option> <option value="max" selected>no cap</option>

View File

@@ -674,14 +674,14 @@ const b = {
drone(speed = 1) { drone(speed = 1) {
const me = bullet.length; const me = bullet.length;
const THRUST = mod.isFastDrones ? 0.0025 : 0.0015 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 dir = mech.angle + 0.4 * (Math.random() - 0.5);
const RADIUS = (4.5 + 3 * Math.random()) 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, { bullet[me] = Bodies.polygon(mech.pos.x + 30 * Math.cos(mech.angle), mech.pos.y + 30 * Math.sin(mech.angle), 8, RADIUS, {
angle: dir, angle: dir,
inertia: Infinity, inertia: Infinity,
friction: 0.05, friction: 0.05,
frictionAir: FRICTION, frictionAir: 0,
restitution: 1, restitution: 1,
dmg: 0.28, //damage done in addition to the damage from momentum dmg: 0.28, //damage done in addition to the damage from momentum
lookFrequency: 80 + Math.floor(23 * Math.random()), lookFrequency: 80 + Math.floor(23 * Math.random()),
@@ -741,33 +741,33 @@ const b = {
let closeDist = Infinity; let closeDist = Infinity;
for (let i = 0, len = powerUp.length; i < len; ++i) { for (let i = 0, len = powerUp.length; i < len; ++i) {
if ( 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(map, this.position, powerUp[i].position).length === 0 &&
Matter.Query.ray(body, 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 TARGET_VECTOR = Vector.sub(this.position, powerUp[i].position)
const DIST = Vector.magnitude(TARGET_VECTOR); const DIST = Vector.magnitude(TARGET_VECTOR);
if (DIST < closeDist) { 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; closeDist = DIST;
this.lockedOn = powerUp[i] 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++; if (isKeep) mod.boomBotCount++;
} }
}, },
nailBot(position = mech.pos, isUpgraded = mod.isBotUpgrade) { nailBot(position = mech.pos) {
const me = bullet.length; const me = bullet.length;
const dir = mech.angle; const dir = mech.angle;
const RADIUS = (12 + 4 * Math.random()) const RADIUS = (12 + 4 * Math.random())
bullet[me] = Bodies.polygon(position.x, position.y, 4, RADIUS, { bullet[me] = Bodies.polygon(position.x, position.y, 4, RADIUS, {
isUpgraded: isUpgraded, isUpgraded: mod.isNailBotUpgrade,
isBot: true, botType: "nail",
angle: dir, angle: dir,
friction: 0, friction: 0,
frictionStatic: 0, frictionStatic: 0,
@@ -1042,7 +1042,7 @@ const b = {
onEnd() {}, onEnd() {},
do() { do() {
if (this.lastLookCycle < game.cycle) { if (this.lastLookCycle < game.cycle) {
this.lastLookCycle = game.cycle + 65 - this.isUpgraded * 25 this.lastLookCycle = game.cycle + 80 - this.isUpgraded * 40
let target let target
for (let i = 0, len = mob.length; i < len; i++) { for (let i = 0, len = mob.length; i < len; i++) {
const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)); 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 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 me = bullet.length;
const dir = mech.angle; const dir = mech.angle;
const RADIUS = (10 + 5 * Math.random()) const RADIUS = (10 + 5 * Math.random())
bullet[me] = Bodies.polygon(position.x, position.y, 6, RADIUS, { bullet[me] = Bodies.polygon(position.x, position.y, 6, RADIUS, {
isUpgraded: isUpgraded, isUpgraded: mod.isFoamBotUpgrade,
isBot: true, botType: "foam",
angle: dir, angle: dir,
friction: 0, friction: 0,
frictionStatic: 0, frictionStatic: 0,
@@ -1080,7 +1080,7 @@ const b = {
restitution: 0.6 * (1 + 0.5 * Math.random()), restitution: 0.6 * (1 + 0.5 * Math.random()),
dmg: 0, // 0.14 //damage done in addition to the damage from momentum dmg: 0, // 0.14 //damage done in addition to the damage from momentum
minDmgSpeed: 2, minDmgSpeed: 2,
lookFrequency: 47 + Math.floor(17 * Math.random()), lookFrequency: 60 + Math.floor(17 * Math.random()) - 10 * mod.isFoamBotUpgrade,
cd: 0, cd: 0,
delay: 100, delay: 100,
acceleration: 0.005 * (1 + 0.5 * Math.random()), acceleration: 0.005 * (1 + 0.5 * Math.random()),
@@ -1107,7 +1107,7 @@ const b = {
const radius = 6 + 7 * Math.random() const radius = 6 + 7 * Math.random()
const SPEED = 29 - radius * 0.5; //(mech.crouch ? 32 : 20) - radius * 0.7; 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) 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; break;
} }
} }
@@ -1122,13 +1122,13 @@ const b = {
}) })
World.add(engine.world, bullet[me]); //add bullet to world 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 me = bullet.length;
const dir = mech.angle; const dir = mech.angle;
const RADIUS = (14 + 6 * Math.random()) const RADIUS = (14 + 6 * Math.random())
bullet[me] = Bodies.polygon(position.x, position.y, 3, RADIUS, { bullet[me] = Bodies.polygon(position.x, position.y, 3, RADIUS, {
isUpgraded: isUpgraded, isUpgraded: mod.isLaserBotUpgrade,
isBot: true, botType: "laser",
angle: dir, angle: dir,
friction: 0, friction: 0,
frictionStatic: 0, frictionStatic: 0,
@@ -1136,9 +1136,9 @@ const b = {
restitution: 0.5 * (1 + 0.5 * Math.random()), restitution: 0.5 * (1 + 0.5 * Math.random()),
dmg: 0, // 0.14 //damage done in addition to the damage from momentum dmg: 0, // 0.14 //damage done in addition to the damage from momentum
minDmgSpeed: 2, minDmgSpeed: 2,
lookFrequency: 27 + Math.floor(17 * Math.random()), lookFrequency: 40 + Math.floor(7 * Math.random()),
acceleration: 0.0015 * (1 + 0.3 * 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()), followRange: 150 + Math.floor(30 * Math.random()),
offPlayer: { offPlayer: {
x: 0, x: 0,
@@ -1189,7 +1189,7 @@ const b = {
} }
//hit target with laser //hit target with laser
if (this.lockedOn && this.lockedOn.alive && mech.energy > 0.15) { 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 //make sure you can still see vertex
const DIST = Vector.magnitude(Vector.sub(this.vertices[0], this.lockedOn.position)); const DIST = Vector.magnitude(Vector.sub(this.vertices[0], this.lockedOn.position));
if (DIST - this.lockedOn.radius < this.range + 150 && if (DIST - this.lockedOn.radius < this.range + 150 &&
@@ -1207,7 +1207,7 @@ const b = {
bestVertexDistance = dist bestVertexDistance = dist
} }
} }
const dmg = b.dmgScale * 0.05; const dmg = b.dmgScale * (0.04 + 0.04 * this.isUpgraded);
this.lockedOn.damage(dmg); this.lockedOn.damage(dmg);
this.lockedOn.locatePlayer(); this.lockedOn.locatePlayer();
@@ -1230,13 +1230,13 @@ const b = {
}) })
World.add(engine.world, bullet[me]); //add bullet to world 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 me = bullet.length;
const dir = mech.angle; const dir = mech.angle;
const RADIUS = (7 + 2 * Math.random()) const RADIUS = (7 + 2 * Math.random())
bullet[me] = Bodies.polygon(position.x, position.y, 4, RADIUS, { bullet[me] = Bodies.polygon(position.x, position.y, 4, RADIUS, {
isUpgraded: isUpgraded, isUpgraded: mod.isBoomBotUpgrade,
isBot: true, botType: "boom",
angle: dir, angle: dir,
friction: 0, friction: 0,
frictionStatic: 0, frictionStatic: 0,
@@ -1244,9 +1244,9 @@ const b = {
restitution: 1, restitution: 1,
dmg: 0, dmg: 0,
minDmgSpeed: 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()), 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, endCycle: Infinity,
classType: "bullet", classType: "bullet",
collisionFilter: { collisionFilter: {
@@ -1257,7 +1257,7 @@ const b = {
explode: 0, explode: 0,
onDmg() { onDmg() {
if (this.lockedOn) { 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) { if (explosionRadius > 60) {
this.explode = explosionRadius this.explode = explosionRadius
// //
@@ -1308,13 +1308,12 @@ const b = {
}) })
World.add(engine.world, bullet[me]); //add bullet to world 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 me = bullet.length;
const dir = mech.angle; const dir = mech.angle;
const RADIUS = 21 const RADIUS = 21
bullet[me] = Bodies.polygon(position.x, position.y, 5, RADIUS, { bullet[me] = Bodies.polygon(position.x, position.y, 5, RADIUS, {
isUpgraded: isUpgraded, botType: "plasma",
isBot: true,
angle: dir, angle: dir,
friction: 0, friction: 0,
frictionStatic: 0, frictionStatic: 0,
@@ -1543,7 +1542,6 @@ const b = {
defaultAmmoPack: 75, defaultAmmoPack: 75,
recordedAmmo: 0, recordedAmmo: 0,
have: false, have: false,
isEasyToAim: false,
nextFireCycle: 0, //use to remember how longs its been since last fire, used to reset count nextFireCycle: 0, //use to remember how longs its been since last fire, used to reset count
startingHoldCycle: 0, startingHoldCycle: 0,
fire() { fire() {
@@ -1581,7 +1579,6 @@ const b = {
ammo: 0, ammo: 0,
ammoPack: 9, ammoPack: 9,
have: false, have: false,
isEasyToAim: true,
fire() { fire() {
let knock, spread let knock, spread
if (mech.crouch) { if (mech.crouch) {
@@ -1653,7 +1650,6 @@ const b = {
ammoPack: 15, ammoPack: 15,
have: false, have: false,
num: 5, num: 5,
isEasyToAim: true,
fire() { fire() {
const SPEED = mech.crouch ? 43 : 32 const SPEED = mech.crouch ? 43 : 32
mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 25 : 18) * b.fireCD); // cool down mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 25 : 18) * b.fireCD); // cool down
@@ -1709,7 +1705,6 @@ const b = {
ammoPack: 42, ammoPack: 42,
defaultAmmoPack: 42, defaultAmmoPack: 42,
have: false, have: false,
isEasyToAim: false,
count: 0, //used to track how many shots are in a volley before a big CD 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 lastFireCycle: 0, //use to remember how longs its been since last fire, used to reset count
fire() { fire() {
@@ -1813,7 +1808,6 @@ const b = {
ammo: 0, ammo: 0,
ammoPack: 110, ammoPack: 110,
have: false, have: false,
isEasyToAim: false,
fire() { fire() {
mech.fireCDcycle = mech.cycle + Math.floor(3 * b.fireCD); // cool down mech.fireCDcycle = mech.cycle + Math.floor(3 * b.fireCD); // cool down
const dir = mech.angle const dir = mech.angle
@@ -1949,7 +1943,6 @@ const b = {
ammo: 0, ammo: 0,
ammoPack: 5, ammoPack: 5,
have: false, have: false,
isEasyToAim: true,
fireCycle: 0, fireCycle: 0,
ammoLoaded: 0, ammoLoaded: 0,
fire() { fire() {
@@ -2007,7 +2000,6 @@ const b = {
ammoPack: 6, ammoPack: 6,
defaultAmmoPack: 6, //use to revert ammoPack after mod changes drop rate defaultAmmoPack: 6, //use to revert ammoPack after mod changes drop rate
have: false, have: false,
isEasyToAim: false,
fire() { fire() {
mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 25 : 10) * b.fireCD); // cool down mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 25 : 10) * b.fireCD); // cool down
b.muzzleFlash(30); b.muzzleFlash(30);
@@ -2051,7 +2043,6 @@ const b = {
ammo: 0, ammo: 0,
ammoPack: 7, ammoPack: 7,
have: false, have: false,
isEasyToAim: false,
fire() { fire() {
const me = bullet.length; const me = bullet.length;
const dir = mech.angle; // + Math.random() * 0.05; const dir = mech.angle; // + Math.random() * 0.05;
@@ -2103,7 +2094,6 @@ const b = {
ammo: 0, ammo: 0,
ammoPack: 3, ammoPack: 3,
have: false, have: false,
isEasyToAim: false,
fire() { fire() {
const me = bullet.length; const me = bullet.length;
const dir = mech.angle; const dir = mech.angle;
@@ -2223,7 +2213,6 @@ const b = {
ammo: 0, ammo: 0,
ammoPack: 7, ammoPack: 7,
have: false, have: false,
isEasyToAim: true,
fire() { fire() {
const me = bullet.length; const me = bullet.length;
const dir = mech.angle; const dir = mech.angle;
@@ -2382,7 +2371,6 @@ const b = {
ammo: 0, ammo: 0,
ammoPack: 3, ammoPack: 3,
have: false, have: false,
isEasyToAim: true,
fire() { fire() {
const pos = { const pos = {
x: mech.pos.x + 30 * Math.cos(mech.angle), x: mech.pos.x + 30 * Math.cos(mech.angle),
@@ -2405,7 +2393,6 @@ const b = {
ammo: 0, ammo: 0,
ammoPack: 5, ammoPack: 5,
have: false, have: false,
isEasyToAim: true,
fire() { fire() {
const me = bullet.length; const me = bullet.length;
const dir = mech.angle; const dir = mech.angle;
@@ -2526,7 +2513,6 @@ const b = {
ammo: 0, ammo: 0,
ammoPack: 15, ammoPack: 15,
have: false, have: false,
isEasyToAim: true,
fire() { fire() {
b.drone(mech.crouch ? 45 : 1) b.drone(mech.crouch ? 45 : 1)
mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 13 : 5) * b.fireCD); // cool down mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 13 : 5) * b.fireCD); // cool down
@@ -2538,7 +2524,6 @@ const b = {
ammo: 0, ammo: 0,
ammoPack: 73, ammoPack: 73,
have: false, have: false,
isEasyToAim: true,
fire() { fire() {
if (mech.crouch) { if (mech.crouch) {
b.iceIX(10, 0.3) b.iceIX(10, 0.3)
@@ -2556,7 +2541,6 @@ const b = {
ammo: 0, ammo: 0,
ammoPack: 50, ammoPack: 50,
have: false, have: false,
isEasyToAim: false,
fire() { fire() {
mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 20 : 6) * b.fireCD); // cool down 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()) 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, ammo: 0,
ammoPack: 4, ammoPack: 4,
have: false, have: false,
isEasyToAim: false,
fire() { fire() {
const me = bullet.length; const me = bullet.length;
bullet[me] = Bodies.rectangle(0, 0, 0.015, 0.0015, { bullet[me] = Bodies.rectangle(0, 0, 0.015, 0.0015, {
@@ -2817,7 +2800,6 @@ const b = {
ammo: 0, ammo: 0,
ammoPack: Infinity, ammoPack: Infinity,
have: false, have: false,
isEasyToAim: false,
fire() { fire() {
const reflectivity = 1 - 1 / (mod.laserReflections * 1.5) const reflectivity = 1 - 1 / (mod.laserReflections * 1.5)
let damage = b.dmgScale * mod.laserDamage let damage = b.dmgScale * mod.laserDamage
@@ -2976,7 +2958,6 @@ const b = {
ammo: 0, ammo: 0,
ammoPack: Infinity, ammoPack: Infinity,
have: false, have: false,
isEasyToAim: false,
fire() { fire() {
//calculate laser collision //calculate laser collision
let best, energy, explosionRange; let best, energy, explosionRange;
@@ -3126,7 +3107,6 @@ const b = {
// ammo: 0, // ammo: 0,
// ammoPack: Infinity, // ammoPack: Infinity,
// have: false, // have: false,
// isEasyToAim: false,
// fire() { // fire() {
// if (mech.energy < 0.002) { // if (mech.energy < 0.002) {
// mech.fireCDcycle = mech.cycle + 100; // cool down if out of energy // 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) { if (obj.classType === "body" && obj.speed > 6) {
const v = Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity)); const v = Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity));
if (v > 9) { 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 (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); mob[k].damage(dmg, true);
if (mob[k].distanceToPlayer2() < 1000000) mob[k].foundPlayer(); if (mob[k].distanceToPlayer2() < 1000000) mob[k].foundPlayer();
game.drawList.push({ game.drawList.push({

View File

@@ -118,7 +118,6 @@ const game = {
cycle: 0, //total cycles, 60 per second 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 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 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, isCommunityMaps: false,
cyclePaused: 0, cyclePaused: 0,
fallHeight: 3000, //below this y position the player dies 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 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 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) 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(); ctx.save();
@@ -754,7 +753,7 @@ const game = {
}); });
// move bots // move bots
for (let i = 0; i < bullet.length; i++) { 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.setPosition(bullet[i], player.position);
Matter.Body.setVelocity(bullet[i], { Matter.Body.setVelocity(bullet[i], {
x: 0, x: 0,
@@ -1050,6 +1049,7 @@ const game = {
document.execCommand('copy'); document.execCommand('copy');
} catch (err) { } catch (err) {
// Unable to copy // Unable to copy
console.log(err)
} finally { } finally {
// Remove the textarea // Remove the textarea
document.body.removeChild(textAreaEle); document.body.removeChild(textAreaEle);
@@ -1083,6 +1083,7 @@ const game = {
out += game.constructMapString[i]; out += game.constructMapString[i];
outHTML += "<div>" + game.constructMapString[i] + "</div>" outHTML += "<div>" + game.constructMapString[i] + "</div>"
} }
console.log(out)
game.copyToClipBoard(out) game.copyToClipBoard(out)
document.getElementById("construct").innerHTML = outHTML document.getElementById("construct").innerHTML = outHTML
}, },

View File

@@ -357,9 +357,6 @@ if (localSettings) {
// game.isBodyDamage = localSettings.isBodyDamage // game.isBodyDamage = localSettings.isBodyDamage
// document.getElementById("body-damage").checked = 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 game.isCommunityMaps = localSettings.isCommunityMaps
document.getElementById("community-maps").checked = localSettings.isCommunityMaps document.getElementById("community-maps").checked = localSettings.isCommunityMaps
@@ -374,17 +371,12 @@ if (localSettings) {
document.getElementById("fps-select").value = localSettings.fpsCapDefault document.getElementById("fps-select").value = localSettings.fpsCapDefault
} else { } else {
localSettings = { localSettings = {
// isBodyDamage: true,
isEasyToAimMode: false,
isCommunityMaps: false, isCommunityMaps: false,
difficultyMode: '1', difficultyMode: '1',
fpsCapDefault: 'max', fpsCapDefault: 'max',
}; };
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
// document.getElementById("body-damage").checked = localSettings.isBodyDamage document.getElementById("community-maps").checked = localSettings.isCommunityMaps
document.getElementById("track-pad-mode").checked = localSettings.isEasyToAimMode
game.isEasyToAimMode = localSettings.isEasyToAimMode
document.getElementById("community-maps").checked = localSettings.isEasyToAimMode
game.isCommunityMaps = localSettings.isCommunityMaps game.isCommunityMaps = localSettings.isCommunityMaps
document.getElementById("difficulty-select").value = localSettings.difficultyMode document.getElementById("difficulty-select").value = localSettings.difficultyMode
document.getElementById("fps-select").value = localSettings.fpsCapDefault 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 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", () => { document.getElementById("community-maps").addEventListener("input", () => {
game.isCommunityMaps = document.getElementById("community-maps").checked game.isCommunityMaps = document.getElementById("community-maps").checked
localSettings.isCommunityMaps = game.isCommunityMaps 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() { testChamber() {
level.setPosToSpawn(0, -50); //lower start level.setPosToSpawn(0, -50); //lower start
level.exit.y = level.enter.y - 550; level.exit.y = level.enter.y - 550;
@@ -419,121 +534,6 @@ const level = {
if (game.difficulty > 3) spawn.randomLevelBoss(6000, 2300, ["spiderBoss", "launcherBoss", "laserTargetingBoss"]); if (game.difficulty > 3) spawn.randomLevelBoss(6000, 2300, ["spiderBoss", "launcherBoss", "laserTargetingBoss"]);
powerUps.addRerollToLevel() //needs to run after mobs are spawned 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() { bosses() {
level.custom = () => { level.custom = () => {
level.playerExitCheck(); level.playerExitCheck();
@@ -1325,7 +1325,7 @@ const level = {
spawn.randomBoss(4000, -350, 0.6); spawn.randomBoss(4000, -350, 0.6);
spawn.randomBoss(2750, -550, 0.1); spawn.randomBoss(2750, -550, 0.1);
if (game.difficulty > 2) { if (game.difficulty > 2) {
if (Math.random() < 0.09) { // tether ball if (Math.random() < 0.1) { // tether ball
spawn.tetherBoss(4250, 0) spawn.tetherBoss(4250, 0)
cons[cons.length] = Constraint.create({ cons[cons.length] = Constraint.create({
pointA: { pointA: {
@@ -1336,7 +1336,7 @@ const level = {
stiffness: 0.00007 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 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); spawn.randomLevelBoss(4250, -250);
} else { } else {
//floor below right tall tower //floor below right tall tower
@@ -2023,7 +2023,7 @@ const level = {
spawn.randomBoss(4150, -1000, 0.6); spawn.randomBoss(4150, -1000, 0.6);
if (game.difficulty > 2) { if (game.difficulty > 2) {
if (Math.random() < 0.75) { if (Math.random() < 0.65) {
// tether ball // tether ball
level.fillBG.push({ level.fillBG.push({
x: 2495, x: 2495,
@@ -2043,8 +2043,8 @@ const level = {
}); });
//chance to spawn a ring of exploding mobs around this boss //chance to spawn a ring of exploding mobs around this boss
if (game.difficulty > 4) spawn.nodeBoss(2850, -80, "spawns", 8, 20, 105); if (game.difficulty > 4) spawn.nodeBoss(2850, -80, "spawns", 8, 20, 105);
} else if (game.difficulty > 3) { } else {
spawn.shooterBoss(2200, -650); spawn.randomLevelBoss(2200, -650)
} }
} }
powerUps.addRerollToLevel() //needs to run after mobs are spawned powerUps.addRerollToLevel() //needs to run after mobs are spawned
@@ -3072,10 +3072,10 @@ const level = {
draw = function () { draw = function () {
ctx.beginPath(); //portal ctx.beginPath(); //portal
sensor = this.vertices; let v = this.vertices;
ctx.moveTo(sensor[0].x, sensor[0].y); ctx.moveTo(v[0].x, v[0].y);
for (let i = 1; i < sensor.length; ++i) { for (let i = 1; i < v.length; ++i) {
ctx.lineTo(sensor[i].x, sensor[i].y); ctx.lineTo(v[i].x, v[i].y);
} }
ctx.fillStyle = this.color ctx.fillStyle = this.color
ctx.fill(); ctx.fill();
@@ -3104,7 +3104,7 @@ const level = {
Matter.Body.setVelocity(player, v); Matter.Body.setVelocity(player, v);
// move bots to follow player // move bots to follow player
for (let i = 0; i < bullet.length; i++) { 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.setPosition(bullet[i], this.portalPair.portal.position);
Matter.Body.setVelocity(bullet[i], { Matter.Body.setVelocity(bullet[i], {
x: 0, x: 0,
@@ -3113,8 +3113,6 @@ const level = {
} }
} }
} }
if (body.length) { if (body.length) {
for (let i = 0, len = body.length; i < len; i++) { for (let i = 0, len = body.length; i < len; i++) {
if (body[i] !== mech.holdingTarget) { if (body[i] !== mech.holdingTarget) {
@@ -3210,7 +3208,7 @@ const level = {
color: game.draw.mapFill, color: game.draw.mapFill,
draw: draw, draw: draw,
query: query, query: query,
lastPortalCycle: 0 lastPortalCycle: 0,
}); });
Matter.Body.setStatic(mapB, true); //make static Matter.Body.setStatic(mapB, true); //make static
World.add(engine.world, mapB); //add to world World.add(engine.world, mapB); //add to world

View File

@@ -47,7 +47,7 @@ const mobs = {
applySlow(who) applySlow(who)
//look for mobs near the target //look for mobs near the target
if (mod.isAoESlow) { 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++) { for (let i = 0, len = mob.length; i < len; i++) {
if (Vector.magnitudeSquared(Vector.sub(who.position, mob[i].position)) < range) applySlow(mob[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 //accelerate towards the player
if (this.seePlayer.recall) { if (this.seePlayer.recall) {
// && dx * dx + dy * dy < 2000000) { // && dx * dx + dy * dy < 2000000) {
const forceMag = this.accelMag * this.mass; // const forceMag = this.accelMag * this.mass;
const angle = Math.atan2(this.seePlayer.position.y - this.position.y, this.seePlayer.position.x - this.position.x); // 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.x += forceMag * Math.cos(angle);
this.force.y += forceMag * Math.sin(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, repulsionRange: 500000,
@@ -1076,7 +1079,7 @@ const mobs = {
//replace dead mob with a regular body //replace dead mob with a regular body
replace(i) { replace(i) {
//if there are too many bodies don't turn into blocks to help performance //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 len = body.length;
const v = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices)) //might help with vertex collision issue, not sure 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); 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 World.add(engine.world, body[len]); //add to world
//large mobs shrink so they don't block paths //large mobs shrink so they don't block paths
if (body[len].mass > 10) { if (body[len].mass > 9) {
const shrink = function (that, massLimit) { const shrink = function (that, massLimit) {
if (that.mass > massLimit) { if (that.mass > massLimit) {
const scale = 0.95; const scale = 0.95;
@@ -1099,7 +1102,7 @@ const mobs = {
setTimeout(shrink, 20, that, massLimit); 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); 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.isEnergyDamage) dmg *= 1 + mech.energy / 5.5;
if (mod.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.006 if (mod.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.006
if (mod.isRerollDamage) dmg *= 1 + 0.05 * powerUps.reroll.rerolls 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 return dmg * mod.slowFire
}, },
totalBots() { totalBots() {
@@ -87,7 +87,7 @@ const mod = {
}, },
mods: [{ mods: [{
name: "integrated armament", 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, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
@@ -389,6 +389,23 @@ const mod = {
mod.nailsDeathMob = 0; 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", name: "nail-bot",
description: "a bot fires <strong>nails</strong> at targets in line of sight", description: "a bot fires <strong>nails</strong> at targets in line of sight",
@@ -406,6 +423,28 @@ const mod = {
mod.nailBotCount = 0; 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", name: "foam-bot",
description: "a bot fires <strong>foam</strong> at targets in line of sight", description: "a bot fires <strong>foam</strong> at targets in line of sight",
@@ -423,6 +462,28 @@ const mod = {
mod.foamBotCount = 0; 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", 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", 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; 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", 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>", 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", name: "laser-bot upgrade",
description: "anytime you collect <strong>4</strong> <strong class='color-r'>rerolls</strong><br>use them to build a random <strong>bot</strong>", 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, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
return powerUps.reroll.rerolls > 3 || build.isCustomSelection return mod.laserBotCount > 1
}, },
requires: "at least 4 rerolls", requires: "2 or more laser bots",
effect() { effect() {
mod.isRerollBots = true; mod.isLaserBotUpgrade = true
powerUps.reroll.changeRerolls(0) for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType = 'laser') bullet[i].isUpgraded = true
}
}, },
remove() { 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 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", 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>", 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, maxCount: 1,
count: 0, count: 0,
allowed() { 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", requires: "nails",
effect() { effect() {
@@ -1817,7 +1883,7 @@ const mod = {
}, },
{ {
name: "harvester", 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, maxCount: 1,
count: 0, count: 0,
allowed() { allowed() {
@@ -2483,7 +2549,10 @@ const mod = {
isMineDrop: null, isMineDrop: null,
isRerollBots: null, isRerollBots: null,
isRailTimeSlow: null, isRailTimeSlow: null,
isBotUpgrade: null, isNailBotUpgrade: null,
isFoamBotUpgrade: null,
isLaserBotUpgrade: null,
isBoomBotUpgrade: null,
isDroneGrab: null, isDroneGrab: null,
isOneGun: null isOneGun: null
} }

View File

@@ -1175,7 +1175,6 @@ const mech = {
fieldUpgrades: [{ fieldUpgrades: [{
name: "field emitter", 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", 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: () => { effect: () => {
game.replaceTextLog = true; //allow text over write game.replaceTextLog = true; //allow text over write
mech.hold = function () { mech.hold = function () {
@@ -1202,7 +1201,6 @@ const mech = {
{ {
name: "standing wave harmonics", 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>", description: "three oscillating <strong>shields</strong> are permanently active<br>reduce <strong class='color-harm'>harm</strong> by <strong>33%</strong>",
isEasyToAim: true,
effect: () => { effect: () => {
mech.fieldHarmReduction = 0.67; mech.fieldHarmReduction = 0.67;
mech.fieldBlockCD = 0; mech.fieldBlockCD = 0;
@@ -1245,7 +1243,6 @@ const mech = {
name: "perfect diamagnetism", 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: "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>", 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: () => { effect: () => {
mech.fieldShieldingScale = 0; mech.fieldShieldingScale = 0;
// mech.fieldMeterColor = "#0af" // mech.fieldMeterColor = "#0af"
@@ -1302,7 +1299,6 @@ const mech = {
{ {
name: "nano-scale manufacturing", 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>", 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: () => { effect: () => {
// mech.fieldRegen *= 2; // mech.fieldRegen *= 2;
mech.hold = function () { mech.hold = function () {
@@ -1326,7 +1322,7 @@ const mech = {
1, mod.babyMissiles) 1, mod.babyMissiles)
} else if (mod.isIceField) { } else if (mod.isIceField) {
// mech.fieldCDcycle = mech.cycle + 17; // set cool down to prevent +energy from making huge numbers of drones // 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) b.iceIX(1)
} else { } else {
// mech.fieldCDcycle = mech.cycle + 10; // set cool down to prevent +energy from making huge numbers of drones // 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", 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>", 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, fieldDrawRadius: 0,
isEasyToAim: true,
effect: () => { effect: () => {
mech.fieldFire = true; mech.fieldFire = true;
mech.holdingMassScale = 0.03; //can hold heavier blocks with lower cost to jumping mech.holdingMassScale = 0.03; //can hold heavier blocks with lower cost to jumping
@@ -1478,7 +1473,6 @@ const mech = {
{ {
name: "plasma torch", 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", 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() { effect() {
mech.fieldMeterColor = "#f0f" mech.fieldMeterColor = "#f0f"
mech.hold = function () { mech.hold = function () {
@@ -1634,7 +1628,6 @@ const mech = {
{ {
name: "time dilation field", 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>", 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: () => { effect: () => {
// mech.fieldMeterColor = "#000" // mech.fieldMeterColor = "#000"
mech.fieldFire = true; mech.fieldFire = true;
@@ -1727,7 +1720,6 @@ const mech = {
{ {
name: "phase decoherence field", 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>", 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: () => { effect: () => {
mech.fieldFire = true; mech.fieldFire = true;
mech.fieldMeterColor = "#fff"; mech.fieldMeterColor = "#fff";
@@ -1876,7 +1868,6 @@ const mech = {
{ {
name: "pilot wave", 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>", 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: () => { effect: () => {
game.replaceTextLog = true; //allow text over write game.replaceTextLog = true; //allow text over write
game.isBodyDamage = false; game.isBodyDamage = false;

View File

@@ -171,7 +171,7 @@ const powerUps = {
function pick(who, skip1 = -1, skip2 = -1, skip3 = -1, skip4 = -1) { function pick(who, skip1 = -1, skip2 = -1, skip3 = -1, skip4 = -1) {
let options = []; let options = [];
for (let i = 1; i < who.length; i++) { 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 //remove repeats from last selection
const totalChoices = mod.isDeterminism ? 1 : 3 + mod.isExtraChoice * 2 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) { function pick(who, skip1 = -1, skip2 = -1, skip3 = -1, skip4 = -1) {
let options = []; let options = [];
for (let i = 0; i < who.length; i++) { 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); 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 // 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) 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) { // healer(x, y, radius = 20) {
// mobs.spawn(x, y, 3, radius, "rgba(50,255,200,0.4)"); // mobs.spawn(x, y, 3, radius, "rgba(50,255,200,0.4)");
// let me = mob[mob.length - 1]; // 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 removed eay to aim setting
(is it annoying or helpful?) the addition of gun selection make this setting less important
maybe I should add in a smoothing variable for the edge zoom
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 ************** ************** TODO - n-gon **************
drop level boss rate mods a bit earlier ghosters are always visible
or increase damage scaling 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 give mobs more animal-like behaviors
like rain world
zoom out a bit when mouse is near edge of screen 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 map: laboratory
rooms with switches that change physics 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 new gun - deploy a turret that last for 20 seconds
fire nails at nearby targets once a second. fire nails at nearby targets once a second.
use mine code and bot code 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 minigun: high caliber - rework
slow down the bullets even more and increase the size? slow down the bullets even more and increase the size?
@@ -65,10 +84,6 @@ portals:
extend to bodies (mobs?) extend to bodies (mobs?)
use buttons to turn on and off? 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. level boss: fires a line intersection in a random direction every few seconds.
the last two intersections have a destructive laser between them. the last two intersections have a destructive laser between them.
@@ -83,10 +98,6 @@ map: prison
map: airport 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 mod - do 50% more damage in close, but 50% less at a distance
code it like mod.isFarAwayDmg code it like mod.isFarAwayDmg
have these mods disable each other have these mods disable each other
@@ -130,8 +141,6 @@ redblobgames.com/articles/visibility
https://github.com/Silverwolf90/2d-visibility/tree/master/src https://github.com/Silverwolf90/2d-visibility/tree/master/src
could apply to explosions, neutron bomb, player LOS 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 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. 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 boss level for timeSkipBoss because of game instability for boss on normal levels
this might not fix issues 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 an effect when canceling a power up
ammo? heals? ammo? heals?
50% chance for a mod, 25% heal, 25% ammo 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 add player Scent Trails for mob navigation
https://abitawake.com/news/articles/enemy-ai-chasing-a-player-without-navigation2d-or-a-star-pathfinding 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 - 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 settings - custom keys binding
css transition for pause menu 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) gun: Spirit Bomb (singularity)
use charge up like rail gun use charge up like rail gun
electricity graphics like plasma torch electricity graphics like plasma torch
@@ -194,41 +175,11 @@ gun: Spirit Bomb (singularity)
uses energy uses energy
hold above the player's head 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 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 not sure how to do this without adding a constant check
animate new level spawn by having the map aspects randomly fly into place 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 n-gon outreach ideas
blips - errant signal on youtube blips - errant signal on youtube
reddit - r/IndieGaming reddit - r/IndieGaming