many worlds mod
This commit is contained in:
@@ -87,6 +87,7 @@ const b = {
|
|||||||
modNailsDeathMob: null,
|
modNailsDeathMob: null,
|
||||||
isModSlowFPS: null,
|
isModSlowFPS: null,
|
||||||
isModNeutronStun: null,
|
isModNeutronStun: null,
|
||||||
|
manyWorlds: null,
|
||||||
modOnHealthChange() { //used with acid mod
|
modOnHealthChange() { //used with acid mod
|
||||||
if (b.isModAcidDmg && mech.health > 0.8) {
|
if (b.isModAcidDmg && mech.health > 0.8) {
|
||||||
b.modAcidDmg = 0.5
|
b.modAcidDmg = 0.5
|
||||||
@@ -762,7 +763,7 @@ const b = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "pair production",
|
name: "pair production",
|
||||||
description: "<strong>power ups</strong> overfill your <strong class='color-f'>energy</strong><br>temporarily gain <strong>twice</strong> your maximum",
|
description: "<strong>power ups</strong> overfill your <strong class='color-f'>energy</strong><br>temporarily gain <strong>twice</strong> your max <strong class='color-f'>energy</strong>",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
@@ -850,31 +851,23 @@ const b = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "reallocation",
|
name: "many worlds",
|
||||||
description: "convert <strong>1</strong> random <strong class='color-m'>mod</strong> into <strong>2</strong> new <strong>guns</strong><br><em>recursive mods lose all stacks</em>",
|
description: "spawn a <strong class='color-r'>reroll</strong> after choosing a power up",
|
||||||
maxCount: 1,
|
maxCount: 1,
|
||||||
count: 0,
|
count: 0,
|
||||||
allowed() {
|
allowed() {
|
||||||
return (b.modCount > 0) && !build.isCustomSelection
|
return true
|
||||||
},
|
},
|
||||||
requires: "at least 1 mod",
|
requires: "",
|
||||||
effect: () => {
|
effect: () => {
|
||||||
const have = [] //find which mods you have
|
b.manyWorlds = true;
|
||||||
for (let i = 0; i < b.mods.length; i++) {
|
// for (let i = 0; i < 9; i++) {
|
||||||
if (b.mods[i].count > 0) have.push(i)
|
// powerUps.spawn(mech.pos.x, mech.pos.y, "reroll");
|
||||||
}
|
// if (Math.random() < b.modBayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "reroll");
|
||||||
const choose = have[Math.floor(Math.random() * have.length)]
|
// }
|
||||||
b.mods[choose].remove(); // remove a random mod form the list of mods you have
|
|
||||||
b.mods[choose].count = 0;
|
|
||||||
game.updateModHUD();
|
|
||||||
|
|
||||||
for (let i = 0; i < 2; i++) {
|
|
||||||
powerUps.spawn(mech.pos.x, mech.pos.y, "gun");
|
|
||||||
if (Math.random() < b.modBayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "gun");
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
remove() {
|
remove() {
|
||||||
//nothing to remove
|
b.manyWorlds = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -903,6 +896,34 @@ const b = {
|
|||||||
//nothing to undo
|
//nothing to undo
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "reallocation",
|
||||||
|
description: "convert <strong>1</strong> random <strong class='color-m'>mod</strong> into <strong>2</strong> new <strong>guns</strong><br><em>recursive mods lose all stacks</em>",
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
allowed() {
|
||||||
|
return (b.modCount > 0) && !build.isCustomSelection
|
||||||
|
},
|
||||||
|
requires: "at least 1 mod",
|
||||||
|
effect: () => {
|
||||||
|
const have = [] //find which mods you have
|
||||||
|
for (let i = 0; i < b.mods.length; i++) {
|
||||||
|
if (b.mods[i].count > 0) have.push(i)
|
||||||
|
}
|
||||||
|
const choose = have[Math.floor(Math.random() * have.length)]
|
||||||
|
b.mods[choose].remove(); // remove a random mod form the list of mods you have
|
||||||
|
b.mods[choose].count = 0;
|
||||||
|
game.updateModHUD();
|
||||||
|
|
||||||
|
for (let i = 0; i < 2; i++) {
|
||||||
|
powerUps.spawn(mech.pos.x, mech.pos.y, "gun");
|
||||||
|
if (Math.random() < b.modBayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "gun");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
remove() {
|
||||||
|
//nothing to remove
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "Lorentzian topology",
|
name: "Lorentzian topology",
|
||||||
description: "your <strong>bullets</strong> last <strong>+33% longer</strong>",
|
description: "your <strong>bullets</strong> last <strong>+33% longer</strong>",
|
||||||
@@ -1973,6 +1994,7 @@ const b = {
|
|||||||
dist = Vector.magnitude(sub) - mob[i].radius;
|
dist = Vector.magnitude(sub) - mob[i].radius;
|
||||||
if (dist < radius) {
|
if (dist < radius) {
|
||||||
if (mob[i].shield) dmg *= 3 //balancing explosion dmg to shields
|
if (mob[i].shield) dmg *= 3 //balancing explosion dmg to shields
|
||||||
|
if (Matter.Query.ray(map, mob[i].position, where).length > 0) dmg *= 0.5 //reduce damage if a wall is in the way
|
||||||
mob[i].damage(dmg * damageScale);
|
mob[i].damage(dmg * damageScale);
|
||||||
mob[i].locatePlayer();
|
mob[i].locatePlayer();
|
||||||
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg * damageScale) * mob[i].mass) / 50);
|
knock = Vector.mult(Vector.normalise(sub), (-Math.sqrt(dmg * damageScale) * mob[i].mass) / 50);
|
||||||
@@ -2353,7 +2375,7 @@ const b = {
|
|||||||
friction: 0.05,
|
friction: 0.05,
|
||||||
frictionAir: 0.0005,
|
frictionAir: 0.0005,
|
||||||
restitution: 1,
|
restitution: 1,
|
||||||
dmg: 0.17, //damage done in addition to the damage from momentum
|
dmg: 0.23, //damage done in addition to the damage from momentum
|
||||||
lookFrequency: 107 + Math.floor(47 * Math.random()),
|
lookFrequency: 107 + Math.floor(47 * Math.random()),
|
||||||
endCycle: game.cycle + Math.floor((1200 + 420 * Math.random()) * b.isModBulletsLastLonger),
|
endCycle: game.cycle + Math.floor((1200 + 420 * Math.random()) * b.isModBulletsLastLonger),
|
||||||
classType: "bullet",
|
classType: "bullet",
|
||||||
@@ -2365,7 +2387,14 @@ const b = {
|
|||||||
lockedOn: null,
|
lockedOn: null,
|
||||||
isFollowMouse: true,
|
isFollowMouse: true,
|
||||||
deathCycles: 110 + RADIUS * 5,
|
deathCycles: 110 + RADIUS * 5,
|
||||||
onDmg() {
|
onDmg(who) {
|
||||||
|
//move away from target after hitting
|
||||||
|
const unit = Vector.mult(Vector.normalise(Vector.sub(this.position, who.position)), -20)
|
||||||
|
Matter.Body.setVelocity(this, {
|
||||||
|
x: unit.x,
|
||||||
|
y: unit.y
|
||||||
|
});
|
||||||
|
|
||||||
this.lockedOn = null
|
this.lockedOn = null
|
||||||
if (this.endCycle > game.cycle + this.deathCycles && b.isModDroneCollide) {
|
if (this.endCycle > game.cycle + this.deathCycles && b.isModDroneCollide) {
|
||||||
this.endCycle -= 60
|
this.endCycle -= 60
|
||||||
@@ -3119,7 +3148,7 @@ const b = {
|
|||||||
// check if inside a mob
|
// check if inside a mob
|
||||||
q = Matter.Query.point(mob, this.position)
|
q = Matter.Query.point(mob, this.position)
|
||||||
for (let i = 0; i < q.length; i++) {
|
for (let i = 0; i < q.length; i++) {
|
||||||
let dmg = b.dmgScale * 0.43 / Math.sqrt(q[i].mass) * (b.modWaveHelix === 1 ? 1 : 0.6) //1 - 0.4 = 0.6 for helix mod 40% damage reduction
|
let dmg = b.dmgScale * 0.40 / Math.sqrt(q[i].mass) * (b.modWaveHelix === 1 ? 1 : 0.6) //1 - 0.4 = 0.6 for helix mod 40% damage reduction
|
||||||
q[i].damage(dmg);
|
q[i].damage(dmg);
|
||||||
q[i].foundPlayer();
|
q[i].foundPlayer();
|
||||||
game.drawList.push({ //add dmg to draw queue
|
game.drawList.push({ //add dmg to draw queue
|
||||||
@@ -3631,11 +3660,10 @@ const b = {
|
|||||||
//aoe damage to mobs
|
//aoe damage to mobs
|
||||||
for (let i = 0, len = mob.length; i < len; i++) {
|
for (let i = 0, len = mob.length; i < len; i++) {
|
||||||
if (Vector.magnitude(Vector.sub(mob[i].position, this.position)) < this.damageRadius) {
|
if (Vector.magnitude(Vector.sub(mob[i].position, this.position)) < this.damageRadius) {
|
||||||
if (mob[i].shield) {
|
let dmg = b.dmgScale * 0.023
|
||||||
mob[i].damage(5 * b.dmgScale * 0.023);
|
if (Matter.Query.ray(map, mob[i].position, this.position).length > 0) dmg *= 0.5 //reduce damage if a wall is in the way
|
||||||
} else {
|
if (mob[i].shield) dmg *= 5 //x5 to make up for the /5 that shields normally take
|
||||||
mob[i].damage(b.dmgScale * 0.023);
|
mob[i].damage(dmg);
|
||||||
}
|
|
||||||
mob[i].locatePlayer();
|
mob[i].locatePlayer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3859,6 +3887,7 @@ const b = {
|
|||||||
//frictionAir: 0.01, //restitution: 0,
|
//frictionAir: 0.01, //restitution: 0,
|
||||||
// angle: 0,
|
// angle: 0,
|
||||||
// friction: 0.5,
|
// friction: 0.5,
|
||||||
|
restitution: 0,
|
||||||
frictionAir: 0,
|
frictionAir: 0,
|
||||||
dmg: 0, //damage done in addition to the damage from momentum
|
dmg: 0, //damage done in addition to the damage from momentum
|
||||||
classType: "bullet",
|
classType: "bullet",
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ const game = {
|
|||||||
b.bulletDraw();
|
b.bulletDraw();
|
||||||
b.bulletDo();
|
b.bulletDo();
|
||||||
game.drawCircle();
|
game.drawCircle();
|
||||||
|
game.clip();
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
game.drawCursor();
|
game.drawCursor();
|
||||||
},
|
},
|
||||||
@@ -132,6 +133,9 @@ const game = {
|
|||||||
// };
|
// };
|
||||||
// requestAnimationFrame(normalFPS);
|
// requestAnimationFrame(normalFPS);
|
||||||
// },
|
// },
|
||||||
|
clip() {
|
||||||
|
|
||||||
|
},
|
||||||
drawCursor() {
|
drawCursor() {
|
||||||
const size = 10;
|
const size = 10;
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
@@ -481,6 +485,7 @@ const game = {
|
|||||||
|
|
||||||
b.setupAllMods(); //sets mods to default values
|
b.setupAllMods(); //sets mods to default values
|
||||||
game.updateModHUD();
|
game.updateModHUD();
|
||||||
|
powerUps.reroll.rerolls = 0;
|
||||||
mech.maxHealth = 1
|
mech.maxHealth = 1
|
||||||
mech.maxEnergy = 1
|
mech.maxEnergy = 1
|
||||||
game.paused = false;
|
game.paused = false;
|
||||||
|
|||||||
@@ -87,8 +87,6 @@ const build = {
|
|||||||
<br>global damage increase: ${((b.damageFromMods()-1)*100).toFixed(0)}%
|
<br>global damage increase: ${((b.damageFromMods()-1)*100).toFixed(0)}%
|
||||||
<br>global harm reduction: ${((1-mech.harmReduction())*100).toFixed(0)}%
|
<br>global harm reduction: ${((1-mech.harmReduction())*100).toFixed(0)}%
|
||||||
</div>`;
|
</div>`;
|
||||||
|
|
||||||
|
|
||||||
let countGuns = 0
|
let countGuns = 0
|
||||||
let countMods = 0
|
let countMods = 0
|
||||||
for (let i = 0, len = b.guns.length; i < len; i++) {
|
for (let i = 0, len = b.guns.length; i < len; i++) {
|
||||||
@@ -269,10 +267,6 @@ const build = {
|
|||||||
document.getElementById("build-grid").style.display = "grid"
|
document.getElementById("build-grid").style.display = "grid"
|
||||||
},
|
},
|
||||||
shareURL() {
|
shareURL() {
|
||||||
game.copyToClipBoard(build.generateURL())
|
|
||||||
alert('n-gon build URL copied to clipboard.\nPaste into browser address bar.')
|
|
||||||
},
|
|
||||||
generateURL() {
|
|
||||||
let url = "https://landgreen.github.io/sidescroller/index.html?"
|
let url = "https://landgreen.github.io/sidescroller/index.html?"
|
||||||
let count = 0;
|
let count = 0;
|
||||||
for (let i = 0; i < b.guns.length; i++) {
|
for (let i = 0; i < b.guns.length; i++) {
|
||||||
@@ -292,7 +286,8 @@ const build = {
|
|||||||
url += `&difficulty=${game.difficultyMode}`
|
url += `&difficulty=${game.difficultyMode}`
|
||||||
url += `&level=${Number(document.getElementById("starting-level").value)}`
|
url += `&level=${Number(document.getElementById("starting-level").value)}`
|
||||||
console.log(url)
|
console.log(url)
|
||||||
return url
|
game.copyToClipBoard(url)
|
||||||
|
alert('n-gon build URL copied to clipboard.\nPaste into browser address bar.')
|
||||||
},
|
},
|
||||||
startBuildRun() {
|
startBuildRun() {
|
||||||
build.isCustomSelection = false;
|
build.isCustomSelection = false;
|
||||||
|
|||||||
@@ -16,11 +16,8 @@ const level = {
|
|||||||
if (level.levelsCleared === 0) { //this code only runs on the first level
|
if (level.levelsCleared === 0) { //this code only runs on the first level
|
||||||
// game.enableConstructMode() //used to build maps in testing mode
|
// game.enableConstructMode() //used to build maps in testing mode
|
||||||
// level.difficultyIncrease(9)
|
// level.difficultyIncrease(9)
|
||||||
// b.giveGuns("foam")
|
|
||||||
// mech.setField("time dilation field")
|
// mech.setField("time dilation field")
|
||||||
// b.giveMod("necrophoresis");
|
// b.giveMod("many worlds");
|
||||||
// b.giveMod("impact shear");
|
|
||||||
// b.giveMod("foam-bot");
|
|
||||||
// b.giveGuns("neutron bomb")
|
// b.giveGuns("neutron bomb")
|
||||||
// b.giveGuns("foam")
|
// b.giveGuns("foam")
|
||||||
// mech.setField("pilot wave")
|
// mech.setField("pilot wave")
|
||||||
@@ -162,10 +159,11 @@ const level = {
|
|||||||
|
|
||||||
// spawn.bomberBoss(2900, -500)
|
// spawn.bomberBoss(2900, -500)
|
||||||
// spawn.shooterBoss(1200, -500)
|
// spawn.shooterBoss(1200, -500)
|
||||||
spawn.spinner(1200, -500, 40)
|
// spawn.starter(2500, -40, 40)
|
||||||
// spawn.stabber(1600, -500)
|
// spawn.stabber(1600, -500)
|
||||||
// spawn.cellBossCulture(1600, -500)
|
// spawn.cellBossCulture(1600, -500)
|
||||||
// spawn.shooter(1600, -500)
|
// spawn.shooter(1600, -500)
|
||||||
|
spawn.focuser(1600, -500)
|
||||||
// spawn.shield(mob[mob.length - 1], 1200, -500, 1);
|
// spawn.shield(mob[mob.length - 1], 1200, -500, 1);
|
||||||
|
|
||||||
// spawn.nodeBoss(1200, -500, "spiker")
|
// spawn.nodeBoss(1200, -500, "spiker")
|
||||||
|
|||||||
49
js/mobs.js
49
js/mobs.js
@@ -507,7 +507,7 @@ const mobs = {
|
|||||||
},
|
},
|
||||||
springAttack() {
|
springAttack() {
|
||||||
// set new values of the ends of the spring constraints
|
// set new values of the ends of the spring constraints
|
||||||
if (this.seePlayer.recall) {
|
if (this.seePlayer.recall && Matter.Query.ray(map, this.position, player.position).length === 0) {
|
||||||
if (!(game.cycle % (this.seePlayerFreq * 2))) {
|
if (!(game.cycle % (this.seePlayerFreq * 2))) {
|
||||||
this.springTarget.x = this.seePlayer.position.x;
|
this.springTarget.x = this.seePlayer.position.x;
|
||||||
this.springTarget.y = this.seePlayer.position.y;
|
this.springTarget.y = this.seePlayer.position.y;
|
||||||
@@ -850,7 +850,6 @@ const mobs = {
|
|||||||
if (!(game.cycle % this.seePlayerFreq)) {
|
if (!(game.cycle % this.seePlayerFreq)) {
|
||||||
this.fireDir = Vector.normalise(Vector.sub(this.seePlayer.position, this.position));
|
this.fireDir = Vector.normalise(Vector.sub(this.seePlayer.position, this.position));
|
||||||
this.fireDir.y -= Math.abs(this.seePlayer.position.x - this.position.x) / 1600; //gives the bullet an arc
|
this.fireDir.y -= Math.abs(this.seePlayer.position.x - this.position.x) / 1600; //gives the bullet an arc
|
||||||
this.fireAngle = Math.atan2(this.fireDir.y, this.fireDir.x);
|
|
||||||
}
|
}
|
||||||
//rotate towards fireAngle
|
//rotate towards fireAngle
|
||||||
const angle = this.angle + Math.PI / 2;
|
const angle = this.angle + Math.PI / 2;
|
||||||
@@ -885,6 +884,52 @@ const mobs = {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
launch() {
|
||||||
|
if (!mech.isBodiesAsleep) {
|
||||||
|
const setNoseShape = () => {
|
||||||
|
const mag = this.radius + this.radius * this.noseLength;
|
||||||
|
this.vertices[1].x = this.position.x + Math.cos(this.angle) * mag;
|
||||||
|
this.vertices[1].y = this.position.y + Math.sin(this.angle) * mag;
|
||||||
|
};
|
||||||
|
//throw a mob/bullet at player
|
||||||
|
if (this.seePlayer.recall) {
|
||||||
|
//set direction to turn to fire
|
||||||
|
if (!(game.cycle % this.seePlayerFreq)) {
|
||||||
|
this.fireDir = Vector.normalise(Vector.sub(this.seePlayer.position, this.position));
|
||||||
|
}
|
||||||
|
//rotate towards fireAngle
|
||||||
|
const angle = this.angle + Math.PI / 2;
|
||||||
|
c = Math.cos(angle) * this.fireDir.x + Math.sin(angle) * this.fireDir.y;
|
||||||
|
const threshold = 0.1;
|
||||||
|
if (c > threshold) {
|
||||||
|
this.torque += 0.0000045 * this.inertia;
|
||||||
|
} else if (c < -threshold) {
|
||||||
|
this.torque -= 0.0000045 * this.inertia;
|
||||||
|
} else if (this.noseLength > 1.5) {
|
||||||
|
//fire
|
||||||
|
spawn.seeker(this.vertices[1].x, this.vertices[1].y, 5 + Math.ceil(this.radius / 15), 5);
|
||||||
|
const v = 15;
|
||||||
|
Matter.Body.setVelocity(mob[mob.length - 1], {
|
||||||
|
x: this.velocity.x + this.fireDir.x * v + Math.random(),
|
||||||
|
y: this.velocity.y + this.fireDir.y * v + Math.random()
|
||||||
|
});
|
||||||
|
this.noseLength = 0;
|
||||||
|
// recoil
|
||||||
|
this.force.x -= 0.005 * this.fireDir.x * this.mass;
|
||||||
|
this.force.y -= 0.005 * this.fireDir.y * this.mass;
|
||||||
|
}
|
||||||
|
if (this.noseLength < 1.5) this.noseLength += this.fireFreq;
|
||||||
|
setNoseShape();
|
||||||
|
} else if (this.noseLength > 0.1) {
|
||||||
|
this.noseLength -= this.fireFreq / 2;
|
||||||
|
setNoseShape();
|
||||||
|
}
|
||||||
|
// else if (this.noseLength < -0.1) {
|
||||||
|
// this.noseLength += this.fireFreq / 4;
|
||||||
|
// setNoseShape();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
},
|
||||||
turnToFacePlayer() {
|
turnToFacePlayer() {
|
||||||
//turn to face player
|
//turn to face player
|
||||||
const dx = player.position.x - this.position.x;
|
const dx = player.position.x - this.position.x;
|
||||||
|
|||||||
21
js/player.js
21
js/player.js
@@ -363,6 +363,7 @@ const mech = {
|
|||||||
if (b.isModImmortal) { //if player has the immortality buff, spawn on the same level with randomized stats
|
if (b.isModImmortal) { //if player has the immortality buff, spawn on the same level with randomized stats
|
||||||
spawn.setSpawnList(); //new mob types
|
spawn.setSpawnList(); //new mob types
|
||||||
game.clearNow = true; //triggers a map reset
|
game.clearNow = true; //triggers a map reset
|
||||||
|
powerUps.reroll.rerolls = Math.floor(Math.random() * Math.random() * 8)
|
||||||
|
|
||||||
//count mods
|
//count mods
|
||||||
let totalMods = 0;
|
let totalMods = 0;
|
||||||
@@ -380,6 +381,7 @@ const mech = {
|
|||||||
b.mods[i].name !== "Born rule" &&
|
b.mods[i].name !== "Born rule" &&
|
||||||
b.mods[i].name !== "determinism" &&
|
b.mods[i].name !== "determinism" &&
|
||||||
b.mods[i].name !== "reallocation" &&
|
b.mods[i].name !== "reallocation" &&
|
||||||
|
b.mods[i].name !== "many worlds" &&
|
||||||
b.mods[i].allowed()
|
b.mods[i].allowed()
|
||||||
) options.push(i);
|
) options.push(i);
|
||||||
}
|
}
|
||||||
@@ -1045,7 +1047,7 @@ const mech = {
|
|||||||
}
|
}
|
||||||
if (mech.energy > mech.maxEnergy) mech.energy = mech.maxEnergy;
|
if (mech.energy > mech.maxEnergy) mech.energy = mech.maxEnergy;
|
||||||
|
|
||||||
if (b.modBlockDmg) {
|
if (b.modBlockDmg && mech.fieldUpgrades[mech.fieldMode].name === "standing wave harmonics") {
|
||||||
who.damage(b.modBlockDmg)
|
who.damage(b.modBlockDmg)
|
||||||
//draw electricity
|
//draw electricity
|
||||||
const step = 40
|
const step = 40
|
||||||
@@ -1087,7 +1089,7 @@ const mech = {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (b.isModStunField) mobs.statusStun(who, b.isModStunField)
|
if (b.isModStunField && mech.fieldUpgrades[mech.fieldMode].name === "perfect diamagnetism") mobs.statusStun(who, b.isModStunField)
|
||||||
// mobs.statusSlow(who, b.isModStunField)
|
// mobs.statusSlow(who, b.isModStunField)
|
||||||
const massRoot = Math.sqrt(Math.max(0.15, who.mass)); // masses above 12 can start to overcome the push back
|
const massRoot = Math.sqrt(Math.max(0.15, who.mass)); // masses above 12 can start to overcome the push back
|
||||||
Matter.Body.setVelocity(who, {
|
Matter.Body.setVelocity(who, {
|
||||||
@@ -1434,7 +1436,7 @@ const mech = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "negative mass field",
|
name: "negative mass field",
|
||||||
description: "use <strong class='color-f'>energy</strong> to nullify <strong style='letter-spacing: 12px;'>gravity</strong><br>reduce <strong>harm</strong> by <strong>80%</strong> while field is active", //<br><strong>launch</strong> larger blocks at much higher speeds
|
description: "use <strong class='color-f'>energy</strong> to nullify <strong style='letter-spacing: 12px;'>gravity</strong><br>reduce <strong>harm</strong> by <strong>80%</strong> while field is active",
|
||||||
fieldDrawRadius: 0,
|
fieldDrawRadius: 0,
|
||||||
isEasyToAim: true,
|
isEasyToAim: true,
|
||||||
effect: () => {
|
effect: () => {
|
||||||
@@ -1569,10 +1571,11 @@ const mech = {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "plasma torch",
|
name: "plasma torch",
|
||||||
description: "use <strong class='color-f'>energy</strong> to emit <strong class='color-d'>damaging</strong> plasma<br><em>effective at close range</em>",
|
description: "use <strong class='color-f'>energy</strong> to emit <strong class='color-d'>damaging</strong> plasma<br>reduce <strong>harm</strong> by <strong>33%</strong>",
|
||||||
isEasyToAim: false,
|
isEasyToAim: false,
|
||||||
effect: () => {
|
effect: () => {
|
||||||
mech.fieldMeterColor = "#f0f"
|
mech.fieldMeterColor = "#f0f"
|
||||||
|
mech.fieldDamageResistance = 0.67; //reduce harm by 33%
|
||||||
|
|
||||||
mech.hold = function () {
|
mech.hold = function () {
|
||||||
if (mech.isHolding) {
|
if (mech.isHolding) {
|
||||||
@@ -1582,7 +1585,7 @@ const mech = {
|
|||||||
} else if ((keys[32] || game.mouseDownRight) && mech.fieldCDcycle < mech.cycle) { //not hold but field button is pressed
|
} else if ((keys[32] || game.mouseDownRight) && mech.fieldCDcycle < mech.cycle) { //not hold but field button is pressed
|
||||||
mech.grabPowerUp();
|
mech.grabPowerUp();
|
||||||
mech.lookForPickUp();
|
mech.lookForPickUp();
|
||||||
const DRAIN = 0.00065
|
const DRAIN = 0.0006
|
||||||
if (mech.energy > DRAIN) {
|
if (mech.energy > DRAIN) {
|
||||||
mech.energy -= DRAIN;
|
mech.energy -= DRAIN;
|
||||||
if (mech.energy < 0) {
|
if (mech.energy < 0) {
|
||||||
@@ -1666,8 +1669,12 @@ const mech = {
|
|||||||
best.who.locatePlayer();
|
best.who.locatePlayer();
|
||||||
|
|
||||||
//push mobs away
|
//push mobs away
|
||||||
const force = Vector.mult(Vector.normalise(Vector.sub(mech.pos, path[1])), -0.02 * Math.sqrt(best.who.mass))
|
const force = Vector.mult(Vector.normalise(Vector.sub(mech.pos, path[1])), -0.01 * Math.min(5, best.who.mass))
|
||||||
Matter.Body.applyForce(best.who, path[1], force)
|
Matter.Body.applyForce(best.who, path[1], force)
|
||||||
|
Matter.Body.setVelocity(best.who, { //friction
|
||||||
|
x: best.who.velocity.x * 0.6,
|
||||||
|
y: best.who.velocity.y * 0.6
|
||||||
|
});
|
||||||
// const angle = Math.atan2(player.position.y - best.who.position.y, player.position.x - best.who.position.x);
|
// const angle = Math.atan2(player.position.y - best.who.position.y, player.position.x - best.who.position.x);
|
||||||
// const mass = Math.min(Math.sqrt(best.who.mass), 6);
|
// const mass = Math.min(Math.sqrt(best.who.mass), 6);
|
||||||
// Matter.Body.setVelocity(best.who, {
|
// Matter.Body.setVelocity(best.who, {
|
||||||
@@ -1685,7 +1692,7 @@ const mech = {
|
|||||||
});
|
});
|
||||||
} else if (!best.who.isStatic) {
|
} else if (!best.who.isStatic) {
|
||||||
//push blocks away
|
//push blocks away
|
||||||
const force = Vector.mult(Vector.normalise(Vector.sub(mech.pos, path[1])), -0.006 * Math.sqrt(Math.sqrt(best.who.mass)))
|
const force = Vector.mult(Vector.normalise(Vector.sub(mech.pos, path[1])), -0.007 * Math.sqrt(Math.sqrt(best.who.mass)))
|
||||||
Matter.Body.applyForce(best.who, path[1], force)
|
Matter.Body.applyForce(best.who, path[1], force)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ const powerUps = {
|
|||||||
powerUps.endDraft();
|
powerUps.endDraft();
|
||||||
},
|
},
|
||||||
endDraft() {
|
endDraft() {
|
||||||
|
if (b.manyWorlds) {
|
||||||
|
powerUps.spawn(mech.pos.x, mech.pos.y, "reroll");
|
||||||
|
if (Math.random() < b.modBayesian) powerUps.spawn(mech.pos.x, mech.pos.y, "reroll");
|
||||||
|
}
|
||||||
document.body.style.cursor = "none";
|
document.body.style.cursor = "none";
|
||||||
document.getElementById("choose-grid").style.display = "none"
|
document.getElementById("choose-grid").style.display = "none"
|
||||||
document.getElementById("choose-background").style.display = "none"
|
document.getElementById("choose-background").style.display = "none"
|
||||||
@@ -162,7 +166,7 @@ const powerUps = {
|
|||||||
let choice2 = -1
|
let choice2 = -1
|
||||||
let choice3 = -1
|
let choice3 = -1
|
||||||
if (choice1 > -1) {
|
if (choice1 > -1) {
|
||||||
let text = `<div class='cancel' onclick='powerUps.endDraft("field")'>✕</div><h3 style = 'color:#fff; text-align:left; margin: 0px;'>choose a field</h3>`
|
let text = `<div class='cancel' onclick='powerUps.endDraft()'>✕</div><h3 style = 'color:#fff; text-align:left; margin: 0px;'>choose a field</h3>`
|
||||||
text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice1})"><div class="grid-title"><div class="circle-grid field"></div> ${mech.fieldUpgrades[choice1].name}</div> ${mech.fieldUpgrades[choice1].description}</div>`
|
text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice1})"><div class="grid-title"><div class="circle-grid field"></div> ${mech.fieldUpgrades[choice1].name}</div> ${mech.fieldUpgrades[choice1].description}</div>`
|
||||||
if (!b.isModDeterminism) {
|
if (!b.isModDeterminism) {
|
||||||
choice2 = pick(mech.fieldUpgrades, choice1)
|
choice2 = pick(mech.fieldUpgrades, choice1)
|
||||||
@@ -207,7 +211,7 @@ const powerUps = {
|
|||||||
let choice2 = -1
|
let choice2 = -1
|
||||||
let choice3 = -1
|
let choice3 = -1
|
||||||
if (choice1 > -1) {
|
if (choice1 > -1) {
|
||||||
let text = `<div class='cancel' onclick='powerUps.endDraft("mod")'>✕</div><h3 style = 'color:#fff; text-align:left; margin: 0px;'>choose a mod</h3>`
|
let text = `<div class='cancel' onclick='powerUps.endDraft()'>✕</div><h3 style = 'color:#fff; text-align:left; margin: 0px;'>choose a mod</h3>`
|
||||||
text += `<div class="choose-grid-module" onclick="powerUps.choose('mod',${choice1})"><div class="grid-title"><div class="circle-grid mod"></div> ${b.mods[choice1].name}</div> ${b.mods[choice1].description}</div>`
|
text += `<div class="choose-grid-module" onclick="powerUps.choose('mod',${choice1})"><div class="grid-title"><div class="circle-grid mod"></div> ${b.mods[choice1].name}</div> ${b.mods[choice1].description}</div>`
|
||||||
if (!b.isModDeterminism) {
|
if (!b.isModDeterminism) {
|
||||||
choice2 = pick(choice1)
|
choice2 = pick(choice1)
|
||||||
@@ -249,7 +253,7 @@ const powerUps = {
|
|||||||
let choice2 = -1
|
let choice2 = -1
|
||||||
let choice3 = -1
|
let choice3 = -1
|
||||||
if (choice1 > -1) {
|
if (choice1 > -1) {
|
||||||
let text = `<div class='cancel' onclick='powerUps.endDraft("gun")'>✕</div><h3 style = 'color:#fff; text-align:left; margin: 0px;'>choose a gun</h3>`
|
let text = `<div class='cancel' onclick='powerUps.endDraft()'>✕</div><h3 style = 'color:#fff; text-align:left; margin: 0px;'>choose a gun</h3>`
|
||||||
text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice1})"><div class="grid-title"><div class="circle-grid gun"></div> ${b.guns[choice1].name}</div> ${b.guns[choice1].description}</div>`
|
text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice1})"><div class="grid-title"><div class="circle-grid gun"></div> ${b.guns[choice1].name}</div> ${b.guns[choice1].description}</div>`
|
||||||
if (!b.isModDeterminism) {
|
if (!b.isModDeterminism) {
|
||||||
choice2 = pick(b.guns, choice1)
|
choice2 = pick(b.guns, choice1)
|
||||||
@@ -312,7 +316,7 @@ const powerUps = {
|
|||||||
if (Math.random() < b.modBayesian) powerUps.spawn(x, y, "field");
|
if (Math.random() < b.modBayesian) powerUps.spawn(x, y, "field");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Math.random() < 0.01) {
|
if (Math.random() < 0.005) {
|
||||||
powerUps.spawn(x, y, "reroll");
|
powerUps.spawn(x, y, "reroll");
|
||||||
if (Math.random() < b.modBayesian) powerUps.spawn(x, y, "reroll");
|
if (Math.random() < b.modBayesian) powerUps.spawn(x, y, "reroll");
|
||||||
return;
|
return;
|
||||||
@@ -352,7 +356,7 @@ const powerUps = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
chooseRandomPowerUp(x, y) { //100% chance to drop a random power up //used in spawn.debris
|
chooseRandomPowerUp(x, y) { //100% chance to drop a random power up //used in spawn.debris
|
||||||
if (Math.random() < 0.02) {
|
if (Math.random() < 0.05) {
|
||||||
powerUps.spawn(x, y, "reroll");
|
powerUps.spawn(x, y, "reroll");
|
||||||
} else if (Math.random() < 0.5) {
|
} else if (Math.random() < 0.5) {
|
||||||
powerUps.spawn(x, y, "heal", false);
|
powerUps.spawn(x, y, "heal", false);
|
||||||
|
|||||||
75
js/spawn.js
75
js/spawn.js
@@ -2,13 +2,14 @@
|
|||||||
const spawn = {
|
const spawn = {
|
||||||
pickList: ["starter", "starter"],
|
pickList: ["starter", "starter"],
|
||||||
fullPickList: [
|
fullPickList: [
|
||||||
"shooter", "shooter", "shooter", "shooter", "shooter",
|
"shooter", "shooter", "shooter", "shooter",
|
||||||
"hopper", "hopper", "hopper", "hopper",
|
"hopper", "hopper", "hopper", "hopper",
|
||||||
"chaser", "chaser", "chaser",
|
"chaser", "chaser", "chaser",
|
||||||
"striker", "striker",
|
"striker", "striker",
|
||||||
"laser", "laser",
|
"laser", "laser",
|
||||||
"exploder", "exploder",
|
"exploder", "exploder",
|
||||||
"stabber", "stabber",
|
"stabber", "stabber",
|
||||||
|
"launcher", "launcher",
|
||||||
"spinner",
|
"spinner",
|
||||||
"grower",
|
"grower",
|
||||||
"springer",
|
"springer",
|
||||||
@@ -19,7 +20,7 @@ const spawn = {
|
|||||||
"ghoster",
|
"ghoster",
|
||||||
"sneaker",
|
"sneaker",
|
||||||
],
|
],
|
||||||
allowedBossList: ["chaser", "spinner", "striker", "springer", "laser", "focuser", "beamer", "exploder", "spawner", "shooter", "stabber"],
|
allowedBossList: ["chaser", "spinner", "striker", "springer", "laser", "focuser", "beamer", "exploder", "spawner", "shooter", "launcher", "stabber"],
|
||||||
setSpawnList() { //this is run at the start of each new level to determine the possible mobs for the level
|
setSpawnList() { //this is run at the start of each new level to determine the possible mobs for the level
|
||||||
//each level has 2 mobs: one new mob and one from the last level
|
//each level has 2 mobs: one new mob and one from the last level
|
||||||
spawn.pickList.splice(0, 1);
|
spawn.pickList.splice(0, 1);
|
||||||
@@ -845,30 +846,30 @@ const spawn = {
|
|||||||
if (!mech.isBodiesAsleep) {
|
if (!mech.isBodiesAsleep) {
|
||||||
this.seePlayerByLookingAt();
|
this.seePlayerByLookingAt();
|
||||||
this.checkStatus();
|
this.checkStatus();
|
||||||
|
this.attraction();
|
||||||
const dist2 = this.distanceToPlayer2();
|
const dist2 = this.distanceToPlayer2();
|
||||||
//laser Tracking
|
//laser Tracking
|
||||||
if (this.seePlayer.yes && dist2 < 4000000 && !mech.isStealth) {
|
if (this.seePlayer.yes && dist2 < 4000000) {
|
||||||
this.attraction();
|
|
||||||
const rangeWidth = 2000; //this is sqrt of 4000000 from above if()
|
const rangeWidth = 2000; //this is sqrt of 4000000 from above if()
|
||||||
//targeting laser will slowly move from the mob to the player's position
|
//targeting laser will slowly move from the mob to the player's position
|
||||||
this.laserPos = Vector.add(this.laserPos, Vector.mult(Vector.sub(player.position, this.laserPos), 0.1));
|
this.laserPos = Vector.add(this.laserPos, Vector.mult(Vector.sub(player.position, this.laserPos), 0.1));
|
||||||
let targetDist = Vector.magnitude(Vector.sub(this.laserPos, mech.pos));
|
let targetDist = Vector.magnitude(Vector.sub(this.laserPos, mech.pos));
|
||||||
const r = 10;
|
const r = 12;
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.moveTo(this.position.x, this.position.y);
|
ctx.moveTo(this.position.x, this.position.y);
|
||||||
if (targetDist < r + 15) {
|
if (targetDist < r + 16) {
|
||||||
targetDist = r + 10;
|
targetDist = r + 10;
|
||||||
//charge at player
|
//charge at player
|
||||||
const forceMag = this.accelMag * 40 * this.mass;
|
const forceMag = this.accelMag * 30 * 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);
|
||||||
} else {
|
} else {
|
||||||
//high friction if can't lock onto player
|
//high friction if can't lock onto player
|
||||||
Matter.Body.setVelocity(this, {
|
// Matter.Body.setVelocity(this, {
|
||||||
x: this.velocity.x * 0.96,
|
// x: this.velocity.x * 0.98,
|
||||||
y: this.velocity.y * 0.96
|
// y: this.velocity.y * 0.98
|
||||||
});
|
// });
|
||||||
}
|
}
|
||||||
if (dist2 > 80000) {
|
if (dist2 > 80000) {
|
||||||
const laserWidth = 0.002;
|
const laserWidth = 0.002;
|
||||||
@@ -1436,6 +1437,58 @@ const spawn = {
|
|||||||
this.timeLimit();
|
this.timeLimit();
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
launcher(x, y, radius = 25 + Math.ceil(Math.random() * 50)) {
|
||||||
|
mobs.spawn(x, y, 3, radius, "rgb(150,150,255)");
|
||||||
|
let me = mob[mob.length - 1];
|
||||||
|
me.vertices = Matter.Vertices.clockwiseSort(Matter.Vertices.rotate(me.vertices, Math.PI, me.position)); //make the pointy side of triangle the front
|
||||||
|
me.isVerticesChange = true
|
||||||
|
// Matter.Body.rotate(me, Math.PI)
|
||||||
|
|
||||||
|
me.memory = 120;
|
||||||
|
me.fireFreq = 0.006 + Math.random() * 0.003;
|
||||||
|
me.noseLength = 0;
|
||||||
|
me.fireAngle = 0;
|
||||||
|
me.accelMag = 0.0005 * game.accelScale;
|
||||||
|
me.frictionAir = 0.05;
|
||||||
|
me.lookTorque = 0.0000028 * (Math.random() > 0.5 ? -1 : 1);
|
||||||
|
me.fireDir = {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
};
|
||||||
|
me.onDeath = function () { //helps collisions functions work better after vertex have been changed
|
||||||
|
// this.vertices = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices))
|
||||||
|
}
|
||||||
|
// spawn.shield(me, x, y);
|
||||||
|
me.do = function () {
|
||||||
|
this.seePlayerByLookingAt();
|
||||||
|
this.checkStatus();
|
||||||
|
this.launch();
|
||||||
|
};
|
||||||
|
},
|
||||||
|
seeker(x, y, radius = 6, sides = 0) {
|
||||||
|
//bullets
|
||||||
|
mobs.spawn(x, y, sides, radius, "rgb(0,0,255)");
|
||||||
|
let me = mob[mob.length - 1];
|
||||||
|
me.stroke = "transparent";
|
||||||
|
me.onHit = function () {
|
||||||
|
this.explode(this.mass * 10);
|
||||||
|
};
|
||||||
|
Matter.Body.setDensity(me, 0.00005); //normal is 0.001
|
||||||
|
me.timeLeft = 420;
|
||||||
|
me.accelMag = 0.0004 * game.accelScale;
|
||||||
|
me.frictionAir = 0.035;
|
||||||
|
me.restitution = 0.5;
|
||||||
|
me.leaveBody = false;
|
||||||
|
me.dropPowerUp = false;
|
||||||
|
me.showHealthBar = false;
|
||||||
|
me.collisionFilter.category = cat.mobBullet;
|
||||||
|
me.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet;
|
||||||
|
me.do = function () {
|
||||||
|
this.seePlayerCheck();
|
||||||
|
this.attraction();
|
||||||
|
this.timeLimit();
|
||||||
|
};
|
||||||
|
},
|
||||||
spawner(x, y, radius = 55 + Math.ceil(Math.random() * 50)) {
|
spawner(x, y, radius = 55 + Math.ceil(Math.random() * 50)) {
|
||||||
mobs.spawn(x, y, 4, radius, "rgb(255,150,0)");
|
mobs.spawn(x, y, 4, radius, "rgb(255,150,0)");
|
||||||
let me = mob[mob.length - 1];
|
let me = mob[mob.length - 1];
|
||||||
|
|||||||
@@ -466,6 +466,11 @@ em {
|
|||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.color-r {
|
||||||
|
color: #f7b;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
.faded {
|
.faded {
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
font-size: 90%;
|
font-size: 90%;
|
||||||
@@ -511,7 +516,6 @@ em {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.reroll {
|
.reroll {
|
||||||
|
|
||||||
/* #f84 #f99*/
|
/* #f84 #f99*/
|
||||||
background: #f7b;
|
background: #f7b;
|
||||||
}
|
}
|
||||||
|
|||||||
43
todo.txt
43
todo.txt
@@ -1,20 +1,21 @@
|
|||||||
foam bullets are faster, smaller, shrink slower, stick to mobs better
|
mod - many worlds: spawn a reroll after choosing (or canceling) a power up
|
||||||
foam can now stick to shielded mobs, but shrinks faster
|
new mob type - launcher: similar to the shooter, but fires bullets that chase you
|
||||||
mod: foam-bots
|
plasma torch - reduces harm to player by 1/3 and has more reliable stopping power against charging mobs
|
||||||
|
explosions and neutron bomb do 50% less damage through walls
|
||||||
|
drone bullets bounce off mobs more predictably
|
||||||
|
|
||||||
************** TODO - n-gon **************
|
************** TODO - n-gon **************
|
||||||
|
|
||||||
power up reroll
|
what about a neutron bomb mod, that cause the bomb to activate right after you fire and slowly move forward with no gravity
|
||||||
color yellow?
|
|
||||||
|
|
||||||
|
Drop a reroll when the player exits the selection screen without picking one of the choices
|
||||||
|
|
||||||
|
redblobgames.com/articles/visibility
|
||||||
|
https://github.com/Silverwolf90/2d-visibility/tree/master/src
|
||||||
|
could apply to explosions, neutron bomb, player LOS
|
||||||
|
|
||||||
sticking bullets don't always gain the correct speed from mobs after they die
|
sticking bullets don't always gain the correct speed from mobs after they die
|
||||||
|
|
||||||
mod - frozen mobs take +33% damage
|
|
||||||
|
|
||||||
mod heal to full at the end of each level
|
|
||||||
heal mods no longer drop?
|
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
@@ -24,19 +25,6 @@ have a mob apply a positive status effect on other mobs,
|
|||||||
damage bonus, but how?
|
damage bonus, but how?
|
||||||
possible balance issues
|
possible balance issues
|
||||||
|
|
||||||
mobs that fire grenades
|
|
||||||
mobs that fire bullets
|
|
||||||
bullets that chase the player a bit (blue color)
|
|
||||||
short lived bullets that fire in every direction
|
|
||||||
or fire in a spiral over time
|
|
||||||
|
|
||||||
construct
|
|
||||||
display outline of map to be draw while mouse is down
|
|
||||||
toggle between maps and bodies
|
|
||||||
?highlight map/body mouse is over and be able to remove it?
|
|
||||||
display current output text in a box
|
|
||||||
live update it
|
|
||||||
|
|
||||||
boss levels - small levels just a boss, and maybe a few mobs
|
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
|
||||||
@@ -65,10 +53,6 @@ lore - a robot (the player) gains self awareness
|
|||||||
the next level is the final level
|
the next level is the final level
|
||||||
when you die with Quantum Immortality there is a chance of lore text
|
when you die with Quantum Immortality there is a chance of lore text
|
||||||
|
|
||||||
scrap drops that can be used to buy things in a shop
|
|
||||||
scrap could be yellow
|
|
||||||
shop could appear every 4 levels
|
|
||||||
|
|
||||||
mob - stuns, or slows player
|
mob - stuns, or slows player
|
||||||
|
|
||||||
boss mob - let it die multiple times and come back to life
|
boss mob - let it die multiple times and come back to life
|
||||||
@@ -90,16 +74,11 @@ uranium reactor core
|
|||||||
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 - killing a stunned mob gives something
|
|
||||||
ammo or heal power up?
|
|
||||||
|
|
||||||
mod - scale squirrel cage rotor with current energy
|
mod - scale squirrel cage rotor with current energy
|
||||||
is variable speed going to be hard to deal with?
|
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
|
||||||
|
|
||||||
mob sniper - targeting laser, then a high speed, no gravity bullet
|
|
||||||
|
|
||||||
mod - increase laser bot range, and reduce energy drain
|
mod - increase laser bot range, and reduce energy drain
|
||||||
|
|
||||||
mod - mines become a turret that fires nails
|
mod - mines become a turret that fires nails
|
||||||
|
|||||||
Reference in New Issue
Block a user