console style

updated in game console style and all messages to match real game commands
new names inline with lore,  mod -> tech, game -> simulation
  this is probably going to cause many minor bugs, so let me know what you find
new reroll display in power up selection

tech: rocket-propelled now works with all grenade tech
This commit is contained in:
landgreen
2020-12-26 08:16:22 -08:00
parent b2fff5274a
commit 0e9d2bcc30
13 changed files with 2436 additions and 2255 deletions

View File

@@ -33,7 +33,7 @@
<!-- <body oncontextmenu="return false"> --> <!-- <body oncontextmenu="return false"> -->
<div id='guns'></div> <div id='guns'></div>
<div id='field'></div> <div id='field'></div>
<div id='mods'></div> <div id='tech'></div>
<div id="text-log"></div> <div id="text-log"></div>
<div id="fade-out"></div> <div id="fade-out"></div>
<div id="health-bg"></div> <div id="health-bg"></div>
@@ -327,7 +327,7 @@
animation: dash 5s ease-in forwards; animation: dash 5s ease-in forwards;
} }
</style> </style>
<svg id='splash' class="intro" viewBox="0 0 800 800" onclick="game.startGame()"> <svg id='splash' class="intro" viewBox="0 0 800 800" onclick="simulation.startGame()">
<!-- title --> <!-- title -->
<!-- <g class="fade-in" transform="translate(100,210) scale(34)" fill='#bbb' stroke='none'> <!-- <g class="fade-in" transform="translate(100,210) scale(34)" fill='#bbb' stroke='none'>
<path d="M0 0 h1 v0.2 h1.7 l0.3 0.3 v2.6 h-1 v-1.7 h-1 v1.7 h-1 z" fill="rgb(50,200,255)" /> <path d="M0 0 h1 v0.2 h1.7 l0.3 0.3 v2.6 h-1 v-1.7 h-1 v1.7 h-1 z" fill="rgb(50,200,255)" />
@@ -553,10 +553,10 @@
<script src='lib/matter.min.js'></script> <script src='lib/matter.min.js'></script>
<script src='lib/decomp.min.js'></script> <script src='lib/decomp.min.js'></script>
<script src='lib/randomColor.min.js'></script> <script src='lib/randomColor.min.js'></script>
<script src="js/game.js"></script> <script src="js/simulation.js"></script>
<script src="js/player.js"></script> <script src="js/player.js"></script>
<script src="js/powerup.js"></script> <script src="js/powerup.js"></script>
<script src="js/mods.js"></script> <script src="js/tech.js"></script>
<script src="js/bullet.js"></script> <script src="js/bullet.js"></script>
<script src="js/mob.js"></script> <script src="js/mob.js"></script>
<script src="js/spawn.js"></script> <script src="js/spawn.js"></script>

File diff suppressed because it is too large Load Diff

View File

@@ -99,19 +99,19 @@ function collisionChecks(event) {
if ( if (
mech.immuneCycle < mech.cycle && mech.immuneCycle < mech.cycle &&
(obj === playerBody || obj === playerHead) && (obj === playerBody || obj === playerHead) &&
!(mod.isFreezeHarmImmune && (mob[k].isSlowed || mob[k].isStunned)) !(tech.isFreezeHarmImmune && (mob[k].isSlowed || mob[k].isStunned))
) { ) {
mob[k].foundPlayer(); mob[k].foundPlayer();
let dmg = Math.min(Math.max(0.025 * Math.sqrt(mob[k].mass), 0.05), 0.3) * game.dmgScale; //player damage is capped at 0.3*dmgScale of 1.0 let dmg = Math.min(Math.max(0.025 * Math.sqrt(mob[k].mass), 0.05), 0.3) * simulation.dmgScale; //player damage is capped at 0.3*dmgScale of 1.0
if (mod.isRewindAvoidDeath && mech.energy > 0.66) { //CPT reversal runs in mech.damage, but it stops the rest of the collision code here too if (tech.isRewindAvoidDeath && mech.energy > 0.66) { //CPT reversal runs in mech.damage, but it stops the rest of the collision code here too
mech.damage(dmg); mech.damage(dmg);
return return
} }
mech.damage(dmg); mech.damage(dmg);
if (mod.isPiezo) mech.energy += 2; if (tech.isPiezo) mech.energy += 2;
if (mod.isBayesian) powerUps.ejectMod() if (tech.isBayesian) powerUps.ejectMod()
if (mob[k].onHit) mob[k].onHit(k); if (mob[k].onHit) mob[k].onHit(k);
mech.immuneCycle = mech.cycle + mod.collisionImmuneCycles; //player is immune to collision damage for 30 cycles mech.immuneCycle = mech.cycle + tech.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
//extra kick between player and mob //this section would be better with forces but they don't work... //extra kick between player and mob //this section would be better with forces but they don't work...
let angle = Math.atan2(player.position.y - mob[k].position.y, player.position.x - mob[k].position.x); let angle = Math.atan2(player.position.y - mob[k].position.y, player.position.x - mob[k].position.x);
Matter.Body.setVelocity(player, { Matter.Body.setVelocity(player, {
@@ -123,24 +123,24 @@ function collisionChecks(event) {
y: mob[k].velocity.y - 8 * Math.sin(angle) y: mob[k].velocity.y - 8 * Math.sin(angle)
}); });
if (mod.isAnnihilation && !mob[k].shield && !mob[k].isShielded && mech.energy > 0.34 * mech.maxEnergy) { if (tech.isAnnihilation && !mob[k].shield && !mob[k].isShielded && mech.energy > 0.34 * mech.maxEnergy) {
mech.energy -= 0.33 * mech.maxEnergy mech.energy -= 0.33 * mech.maxEnergy
mech.immuneCycle = 0; //player doesn't go immune to collision damage mech.immuneCycle = 0; //player doesn't go immune to collision damage
mob[k].death(); mob[k].death();
game.drawList.push({ //add dmg to draw queue simulation.drawList.push({ //add dmg to draw queue
x: pairs[i].activeContacts[0].vertex.x, x: pairs[i].activeContacts[0].vertex.x,
y: pairs[i].activeContacts[0].vertex.y, y: pairs[i].activeContacts[0].vertex.y,
radius: dmg * 2000, radius: dmg * 2000,
color: "rgba(255,0,255,0.2)", color: "rgba(255,0,255,0.2)",
time: game.drawTime time: simulation.drawTime
}); });
} else { } else {
game.drawList.push({ //add dmg to draw queue simulation.drawList.push({ //add dmg to draw queue
x: pairs[i].activeContacts[0].vertex.x, x: pairs[i].activeContacts[0].vertex.x,
y: pairs[i].activeContacts[0].vertex.y, y: pairs[i].activeContacts[0].vertex.y,
radius: dmg * 500, radius: dmg * 500,
color: game.mobDmgColor, color: simulation.mobDmgColor,
time: game.drawTime time: simulation.drawTime
}); });
} }
return; return;
@@ -150,15 +150,15 @@ function collisionChecks(event) {
if (obj.classType === "bullet" && obj.speed > obj.minDmgSpeed) { if (obj.classType === "bullet" && obj.speed > obj.minDmgSpeed) {
obj.beforeDmg(mob[k]); //some bullets do actions when they hits things, like despawn //forces don't seem to work here obj.beforeDmg(mob[k]); //some bullets do actions when they hits things, like despawn //forces don't seem to work here
let dmg = b.dmgScale * (obj.dmg + 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity))) let dmg = b.dmgScale * (obj.dmg + 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity)))
if (mod.isCrit && mob[k].isStunned) dmg *= 4 if (tech.isCrit && mob[k].isStunned) dmg *= 4
mob[k].foundPlayer(); mob[k].foundPlayer();
mob[k].damage(dmg); mob[k].damage(dmg);
game.drawList.push({ //add dmg to draw queue simulation.drawList.push({ //add dmg to draw queue
x: pairs[i].activeContacts[0].vertex.x, x: pairs[i].activeContacts[0].vertex.x,
y: pairs[i].activeContacts[0].vertex.y, y: pairs[i].activeContacts[0].vertex.y,
radius: Math.log(2 * dmg + 1.1) * 40, radius: Math.log(2 * dmg + 1.1) * 40,
color: game.playerDmgColor, color: simulation.playerDmgColor,
time: game.drawTime time: simulation.drawTime
}); });
return; return;
} }
@@ -166,22 +166,22 @@ 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 = 0.05 * b.dmgScale * v * obj.mass * mod.throwChargeRate; let dmg = 0.05 * b.dmgScale * v * obj.mass * tech.throwChargeRate;
if (mob[k].isShielded) dmg *= 0.35 if (mob[k].isShielded) dmg *= 0.35
mob[k].damage(dmg, true); mob[k].damage(dmg, true);
const stunTime = dmg / Math.sqrt(obj.mass) const stunTime = dmg / Math.sqrt(obj.mass)
if (stunTime > 0.5) mobs.statusStun(mob[k], 30 + 60 * Math.sqrt(stunTime)) if (stunTime > 0.5) mobs.statusStun(mob[k], 30 + 60 * Math.sqrt(stunTime))
if (mob[k].distanceToPlayer2() < 1000000 && !mech.isCloak) mob[k].foundPlayer(); if (mob[k].distanceToPlayer2() < 1000000 && !mech.isCloak) mob[k].foundPlayer();
if (mod.fragments && obj.speed > 10 && !obj.hasFragmented) { if (tech.fragments && obj.speed > 10 && !obj.hasFragmented) {
obj.hasFragmented = true; obj.hasFragmented = true;
b.targetedNail(obj.position, mod.fragments * 4) b.targetedNail(obj.position, tech.fragments * 4)
} }
game.drawList.push({ simulation.drawList.push({
x: pairs[i].activeContacts[0].vertex.x, x: pairs[i].activeContacts[0].vertex.x,
y: pairs[i].activeContacts[0].vertex.y, y: pairs[i].activeContacts[0].vertex.y,
radius: Math.log(2 * dmg + 1.1) * 40, radius: Math.log(2 * dmg + 1.1) * 40,
color: game.playerDmgColor, color: simulation.playerDmgColor,
time: game.drawTime time: simulation.drawTime
}); });
return; return;
} }

View File

@@ -43,10 +43,10 @@ if (screen.height < 800) {
//example https://landgreen.github.io/sidescroller/index.html? //example https://landgreen.github.io/sidescroller/index.html?
// &gun1=minigun&gun2=laser // &gun1=minigun&gun2=laser
// &mod1=laser-bot&mod2=mass%20driver&mod3=overcharge&mod4=laser-bot&mod5=laser-bot&field=phase%20decoherence%20field&difficulty=2 // &tech1=laser-bot&tech2=mass%20driver&tech3=overcharge&tech4=laser-bot&tech5=laser-bot&field=phase%20decoherence%20field&difficulty=2
//add ? to end of url then for each power up add //add ? to end of url then for each power up add
// &gun1=name&gun2=name // &gun1=name&gun2=name
// &mod1=laser-bot&mod2=mass%20driver&mod3=overcharge&mod4=laser-bot&mod5=laser-bot // &tech1=laser-bot&tech2=mass%20driver&tech3=overcharge&tech4=laser-bot&tech5=laser-bot
// &field=phase%20decoherence%20field // &field=phase%20decoherence%20field
// &difficulty=2 // &difficulty=2
//use %20 for spaces //use %20 for spaces
@@ -90,16 +90,16 @@ window.addEventListener('load', (event) => {
} }
if (found) build.choosePowerUp(document.getElementById(`gun-${index}`), index, 'gun') if (found) build.choosePowerUp(document.getElementById(`gun-${index}`), index, 'gun')
} }
if (property.substring(0, 3) === "mod") { if (property.substring(0, 4) === "tech") {
for (let i = 0; i < mod.mods.length; i++) { for (let i = 0; i < tech.tech.length; i++) {
if (set[property] === mod.mods[i].name) { if (set[property] === tech.tech[i].name) {
build.choosePowerUp(document.getElementById(`mod-${i}`), i, 'mod', true) build.choosePowerUp(document.getElementById(`tech-${i}`), i, 'tech', true)
break; break;
} }
} }
} }
if (property === "difficulty") { if (property === "difficulty") {
game.difficultyMode = Number(set[property]) simulation.difficultyMode = Number(set[property])
document.getElementById("difficulty-select-custom").value = Number(set[property]) document.getElementById("difficulty-select-custom").value = Number(set[property])
} }
if (property === "level") { if (property === "level") {
@@ -138,7 +138,7 @@ function setupCanvas() {
ctx.lineJoin = "round"; ctx.lineJoin = "round";
ctx.lineCap = "round"; ctx.lineCap = "round";
// ctx.lineCap='square'; // ctx.lineCap='square';
game.setZoom(); simulation.setZoom();
} }
setupCanvas(); setupCanvas();
window.onresize = () => { window.onresize = () => {
@@ -155,47 +155,47 @@ const build = {
for (const property in set) { for (const property in set) {
set[property] = set[property].replace(/%20/g, " ") set[property] = set[property].replace(/%20/g, " ")
if (property.substring(0, 3) === "gun") b.giveGuns(set[property]) if (property.substring(0, 3) === "gun") b.giveGuns(set[property])
if (property.substring(0, 3) === "mod") mod.giveMod(set[property]) if (property.substring(0, 3) === "tech") tech.giveMod(set[property])
if (property === "field") mech.setField(set[property]) if (property === "field") mech.setField(set[property])
if (property === "difficulty") { if (property === "difficulty") {
game.difficultyMode = Number(set[property]) simulation.difficultyMode = Number(set[property])
document.getElementById("difficulty-select").value = Number(set[property]) document.getElementById("difficulty-select").value = Number(set[property])
} }
if (property === "level") { if (property === "level") {
level.levelsCleared += Number(set[property]); level.levelsCleared += Number(set[property]);
level.difficultyIncrease(Number(set[property]) * game.difficultyMode) //increase difficulty based on modes level.difficultyIncrease(Number(set[property]) * simulation.difficultyMode) //increase difficulty based on modes
spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns
level.onLevel++ level.onLevel++
} }
} }
for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]); for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]);
bullet = []; //remove any bullets that might have spawned from mods bullet = []; //remove any bullets that might have spawned from tech
if (b.inventory.length > 0) { if (b.inventory.length > 0) {
b.activeGun = b.inventory[0] //set first gun to active gun b.activeGun = b.inventory[0] //set first gun to active gun
game.makeGunHUD(); simulation.makeGunHUD();
} }
} }
}, },
pauseGrid() { pauseGrid() {
let text = "" let text = ""
if (!game.isChoosing) text += `<div class="pause-grid-module"> if (!simulation.isChoosing) text += `<div class="pause-grid-module">
<span style="font-size:1.5em;font-weight: 600;">PAUSED</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; press P to resume</div>` <span style="font-size:1.5em;font-weight: 600;">PAUSED</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; press P to resume</div>`
text += `<div class="pause-grid-module" style = "font-size: 13px;line-height: 120%;padding: 5px;"> text += `<div class="pause-grid-module" style = "font-size: 13px;line-height: 120%;padding: 5px;">
<strong class='color-d'>damage</strong> increase: ${((mod.damageFromMods()-1)*100).toFixed(0)}% <strong class='color-d'>damage</strong> increase: ${((tech.damageFromMods()-1)*100).toFixed(0)}%
<br><strong class='color-harm'>harm</strong> reduction: ${((1-mech.harmReduction())*100).toFixed(0)}% <br><strong class='color-harm'>harm</strong> reduction: ${((1-mech.harmReduction())*100).toFixed(0)}%
<br><strong><em>fire delay</em></strong> decrease: ${((1-b.fireCD)*100).toFixed(0)}% <br><strong><em>fire delay</em></strong> decrease: ${((1-b.fireCD)*100).toFixed(0)}%
<br><strong class='color-dup'>duplication</strong> chance: ${(Math.min(1,mod.duplicationChance())*100).toFixed(0)}% <br><strong class='color-dup'>duplication</strong> chance: ${(Math.min(1,tech.duplicationChance())*100).toFixed(0)}%
<br> <br>
<br><strong class='color-r'>rerolls</strong>: ${powerUps.reroll.rerolls} <br><strong class='color-r'>rerolls</strong>: ${powerUps.reroll.rerolls}
<br><strong class='color-h'>health</strong>: (${(mech.health*100).toFixed(0)} / ${(mech.maxHealth*100).toFixed(0)}) &nbsp; <strong class='color-f'>energy</strong>: (${(mech.energy*100).toFixed(0)} / ${(mech.maxEnergy*100).toFixed(0)}) <br><strong class='color-h'>health</strong>: (${(mech.health*100).toFixed(0)} / ${(mech.maxHealth*100).toFixed(0)}) &nbsp; <strong class='color-f'>energy</strong>: (${(mech.energy*100).toFixed(0)} / ${(mech.maxEnergy*100).toFixed(0)})
<br>position: (${player.position.x.toFixed(1)}, ${player.position.y.toFixed(1)}) &nbsp; velocity: (${player.velocity.x.toFixed(1)}, ${player.velocity.y.toFixed(1)}) <br>position: (${player.position.x.toFixed(1)}, ${player.position.y.toFixed(1)}) &nbsp; velocity: (${player.velocity.x.toFixed(1)}, ${player.velocity.y.toFixed(1)})
<br>mouse: (${game.mouseInGame.x.toFixed(1)}, ${game.mouseInGame.y.toFixed(1)}) &nbsp; mass: ${player.mass.toFixed(1)} <br>mouse: (${simulation.mouseInGame.x.toFixed(1)}, ${simulation.mouseInGame.y.toFixed(1)}) &nbsp; mass: ${player.mass.toFixed(1)}
<br> <br>
<br>level: ${level.levels[level.onLevel]} (${level.difficultyText()}) &nbsp; ${mech.cycle} cycles <br>level: ${level.levels[level.onLevel]} (${level.difficultyText()}) &nbsp; ${mech.cycle} cycles
<br>${mob.length} mobs, &nbsp; ${body.length} blocks, &nbsp; ${bullet.length} bullets, &nbsp; ${powerUp.length} power ups <br>${mob.length} mobs, &nbsp; ${body.length} blocks, &nbsp; ${bullet.length} bullets, &nbsp; ${powerUp.length} power ups
<br>damage difficulty scale: ${(b.dmgScale*100).toFixed(2) }% <br>damage difficulty scale: ${(b.dmgScale*100).toFixed(2) }%
<br>harm difficulty scale: ${(game.dmgScale*100).toFixed(0)}% <br>harm difficulty scale: ${(simulation.dmgScale*100).toFixed(0)}%
<br>heal difficulty scale: ${(game.healScale*100).toFixed(1)}% <br>heal difficulty scale: ${(simulation.healScale*100).toFixed(1)}%
<br><svg class="SVG-button" onclick="build.shareURL(false)" width="110" height="25" style="padding:2px; margin: 10px;"> <br><svg class="SVG-button" onclick="build.shareURL(false)" width="110" height="25" style="padding:2px; margin: 10px;">
<g stroke='none' fill='#333' stroke-width="2" font-size="17px" font-family="Ariel, sans-serif"> <g stroke='none' fill='#333' stroke-width="2" font-size="17px" font-family="Ariel, sans-serif">
<text x="5" y="18">copy build url</text> <text x="5" y="18">copy build url</text>
@@ -213,31 +213,31 @@ const build = {
text = ""; text = "";
text += `<div class="pause-grid-module"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${mech.fieldUpgrades[mech.fieldMode].name}</div> ${mech.fieldUpgrades[mech.fieldMode].description}</div>` text += `<div class="pause-grid-module"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${mech.fieldUpgrades[mech.fieldMode].name}</div> ${mech.fieldUpgrades[mech.fieldMode].description}</div>`
let countMods = 0 let countMods = 0
for (let i = 0, len = mod.mods.length; i < len; i++) { for (let i = 0, len = tech.tech.length; i < len; i++) {
if (mod.mods[i].count > 0) { if (tech.tech[i].count > 0) {
const isCount = mod.mods[i].count > 1 ? `(${mod.mods[i].count}x)` : ""; const isCount = tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : "";
if (mod.mods[i].isFieldMod) { if (tech.tech[i].isFieldMod) {
text += `<div class="pause-grid-module"><div class="grid-title"> text += `<div class="pause-grid-module"><div class="grid-title">
<span style="position:relative;"> <span style="position:relative;">
<div class="circle-grid mod" style="position:absolute; top:0; left:0;opacity:0.8;"></div> <div class="circle-grid tech" style="position:absolute; top:0; left:0;opacity:0.8;"></div>
<div class="circle-grid field" style="position:absolute; top:0; left:10px;opacity:0.65;"></div> <div class="circle-grid field" style="position:absolute; top:0; left:10px;opacity:0.65;"></div>
</span> </span>
&nbsp; &nbsp; &nbsp; &nbsp; ${mod.mods[i].name} ${isCount}</div>${mod.mods[i].description}</div></div>` &nbsp; &nbsp; &nbsp; &nbsp; ${tech.tech[i].name} ${isCount}</div>${tech.tech[i].description}</div></div>`
} else if (mod.mods[i].isGunMod) { } else if (tech.tech[i].isGunMod) {
text += `<div class="pause-grid-module"><div class="grid-title"> text += `<div class="pause-grid-module"><div class="grid-title">
<span style="position:relative;"> <span style="position:relative;">
<div class="circle-grid mod" style="position:absolute; top:0; left:0;opacity:0.8;"></div> <div class="circle-grid tech" style="position:absolute; top:0; left:0;opacity:0.8;"></div>
<div class="circle-grid gun" style="position:absolute; top:0; left:10px; opacity:0.65;"></div> <div class="circle-grid gun" style="position:absolute; top:0; left:10px; opacity:0.65;"></div>
</span> </span>
&nbsp; &nbsp; &nbsp; &nbsp; ${mod.mods[i].name} ${isCount}</div>${mod.mods[i].description}</div></div>` &nbsp; &nbsp; &nbsp; &nbsp; ${tech.tech[i].name} ${isCount}</div>${tech.tech[i].description}</div></div>`
} else { } else {
text += `<div class="pause-grid-module"><div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${mod.mods[i].name} ${isCount}</div>${mod.mods[i].description}</div></div>` text += `<div class="pause-grid-module"><div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${tech.tech[i].name} ${isCount}</div>${tech.tech[i].description}</div></div>`
} }
// if (mod.mods[i].count === 1) { // if (tech.tech[i].count === 1) {
// text += `<div class="pause-grid-module"><div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${mod.mods[i].name}</div> ${mod.mods[i].description}</div>` // text += `<div class="pause-grid-module"><div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${tech.tech[i].name}</div> ${tech.tech[i].description}</div>`
// } else { // } else {
// text += `<div class="pause-grid-module"><div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${mod.mods[i].name} (${mod.mods[i].count}x)</div> ${mod.mods[i].description}</div>` // text += `<div class="pause-grid-module"><div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${tech.tech[i].name} (${tech.tech[i].count}x)</div> ${tech.tech[i].description}</div>`
// } // }
countMods++ countMods++
} }
@@ -270,7 +270,7 @@ const build = {
b.guns[index].have = false; b.guns[index].have = false;
if (b.guns[index].ammo != Infinity) b.guns[index].ammo = 0; if (b.guns[index].ammo != Infinity) b.guns[index].ammo = 0;
if (b.inventory.length === 0) b.activeGun = null; if (b.inventory.length === 0) b.activeGun = null;
game.makeGunHUD(); simulation.makeGunHUD();
break break
} }
} }
@@ -284,55 +284,55 @@ const build = {
mech.setField(index) mech.setField(index)
who.classList.add("build-field-selected"); who.classList.add("build-field-selected");
} }
} else if (type === "mod") { //remove mod if you have too many } else if (type === "tech") { //remove tech if you have too many
if (mod.mods[index].count < mod.mods[index].maxCount) { if (tech.tech[index].count < tech.tech[index].maxCount) {
if (!who.classList.contains("build-mod-selected")) who.classList.add("build-mod-selected"); if (!who.classList.contains("build-tech-selected")) who.classList.add("build-tech-selected");
mod.giveMod(index) tech.giveMod(index)
} else { } else {
mod.removeMod(index); tech.removeMod(index);
who.classList.remove("build-mod-selected"); who.classList.remove("build-tech-selected");
} }
} }
//update mod text //disable not allowed mods //update tech text //disable not allowed tech
for (let i = 0, len = mod.mods.length; i < len; i++) { for (let i = 0, len = tech.tech.length; i < len; i++) {
const modID = document.getElementById("mod-" + i) const techID = document.getElementById("tech-" + i)
if (!mod.mods[i].isCustomHide) { if (!tech.tech[i].isCustomHide) {
if (mod.mods[i].allowed() || isAllowed || mod.mods[i].count > 0) { if (tech.tech[i].allowed() || isAllowed || tech.tech[i].count > 0) {
const isCount = mod.mods[i].count > 1 ? `(${mod.mods[i].count}x)` : ""; const isCount = tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : "";
if (mod.mods[i].isFieldMod) { if (tech.tech[i].isFieldMod) {
modID.innerHTML = ` <div class="grid-title"> techID.innerHTML = ` <div class="grid-title">
<span style="position:relative;"> <span style="position:relative;">
<div class="circle-grid mod" style="position:absolute; top:0; left:0;opacity:0.8;"></div> <div class="circle-grid tech" style="position:absolute; top:0; left:0;opacity:0.8;"></div>
<div class="circle-grid field" style="position:absolute; top:0; left:10px;opacity:0.65;"></div> <div class="circle-grid field" style="position:absolute; top:0; left:10px;opacity:0.65;"></div>
</span> </span>
&nbsp; &nbsp; &nbsp; &nbsp; ${mod.mods[i].name} ${isCount}</div>${mod.mods[i].description}</div>` &nbsp; &nbsp; &nbsp; &nbsp; ${tech.tech[i].name} ${isCount}</div>${tech.tech[i].description}</div>`
// <div class="circle-grid gun" style="position:absolute; top:-3px; left:-3px; opacity:1; height: 33px; width:33px;"></div> // <div class="circle-grid gun" style="position:absolute; top:-3px; left:-3px; opacity:1; height: 33px; width:33px;"></div>
// <div class="circle-grid mod" style="position:absolute; top:5px; left:5px;opacity:1;height: 20px; width:20px;border: #fff solid 2px;"></div> // <div class="circle-grid tech" style="position:absolute; top:5px; left:5px;opacity:1;height: 20px; width:20px;border: #fff solid 2px;"></div>
// border: #fff solid 0px; // border: #fff solid 0px;
} else if (mod.mods[i].isGunMod) { } else if (tech.tech[i].isGunMod) {
modID.innerHTML = ` <div class="grid-title"> techID.innerHTML = ` <div class="grid-title">
<span style="position:relative;"> <span style="position:relative;">
<div class="circle-grid mod" style="position:absolute; top:0; left:0;opacity:0.8;"></div> <div class="circle-grid tech" style="position:absolute; top:0; left:0;opacity:0.8;"></div>
<div class="circle-grid gun" style="position:absolute; top:0; left:10px; opacity:0.65;"></div> <div class="circle-grid gun" style="position:absolute; top:0; left:10px; opacity:0.65;"></div>
</span> </span>
&nbsp; &nbsp; &nbsp; &nbsp; ${mod.mods[i].name} ${isCount}</div>${mod.mods[i].description}</div>` &nbsp; &nbsp; &nbsp; &nbsp; ${tech.tech[i].name} ${isCount}</div>${tech.tech[i].description}</div>`
} else { } else {
modID.innerHTML = `<div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${mod.mods[i].name} ${isCount}</div>${mod.mods[i].description}</div>` techID.innerHTML = `<div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[i].name} ${isCount}</div>${tech.tech[i].description}</div>`
} }
if (modID.classList.contains("build-grid-disabled")) { if (techID.classList.contains("build-grid-disabled")) {
modID.classList.remove("build-grid-disabled"); techID.classList.remove("build-grid-disabled");
modID.setAttribute("onClick", `javascript: build.choosePowerUp(this,${i},'mod')`); techID.setAttribute("onClick", `javascript: build.choosePowerUp(this,${i},'tech')`);
} }
} else { } else {
modID.innerHTML = `<div class="grid-title"> ${mod.mods[i].name}</div><span style="color:#666;">requires: ${mod.mods[i].requires}</span></div>` techID.innerHTML = `<div class="grid-title"> ${tech.tech[i].name}</div><span style="color:#666;">requires: ${tech.tech[i].requires}</span></div>`
if (!modID.classList.contains("build-grid-disabled")) { if (!techID.classList.contains("build-grid-disabled")) {
modID.classList.add("build-grid-disabled"); techID.classList.add("build-grid-disabled");
modID.onclick = null techID.onclick = null
} }
if (mod.mods[i].count > 0) mod.removeMod(i) if (tech.tech[i].count > 0) tech.removeMod(i)
if (modID.classList.contains("build-mod-selected")) modID.classList.remove("build-mod-selected"); if (techID.classList.contains("build-tech-selected")) techID.classList.remove("build-tech-selected");
} }
} }
} }
@@ -368,7 +368,7 @@ const build = {
</select> </select>
</div> </div>
<div> <div>
<label for="no-power-ups" title="no mods, fields, or guns will spawn during the game">no power ups:</label> <label for="no-power-ups" title="no tech, fields, or guns will spawn">no power ups:</label>
<input type="checkbox" id="no-power-ups" name="no-power-ups" style="width:17px; height:17px;"> <input type="checkbox" id="no-power-ups" name="no-power-ups" style="width:17px; height:17px;">
</div> </div>
</div>` </div>`
@@ -379,21 +379,21 @@ const build = {
text += `<div id = "gun-${i}" class="build-grid-module" onclick="build.choosePowerUp(this,${i},'gun')"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[i].name}</div> ${b.guns[i].description}</div>` text += `<div id = "gun-${i}" class="build-grid-module" onclick="build.choosePowerUp(this,${i},'gun')"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[i].name}</div> ${b.guns[i].description}</div>`
} }
for (let i = 0, len = mod.mods.length; i < len; i++) { for (let i = 0, len = tech.tech.length; i < len; i++) {
if (!mod.mods[i].isCustomHide) { if (!tech.tech[i].isCustomHide) {
if (!mod.mods[i].allowed()) { // || mod.mods[i].name === "+1 cardinality") { //|| mod.mods[i].name === "leveraged investment" if (!tech.tech[i].allowed()) { // || tech.tech[i].name === "+1 cardinality") { //|| tech.tech[i].name === "leveraged investment"
text += `<div id="mod-${i}" class="build-grid-module build-grid-disabled"><div class="grid-title">${mod.mods[i].name}</div><span style="color:#666;">requires: ${mod.mods[i].requires}</span></div>` text += `<div id="tech-${i}" class="build-grid-module build-grid-disabled"><div class="grid-title">${tech.tech[i].name}</div><span style="color:#666;">requires: ${tech.tech[i].requires}</span></div>`
// } else if (mod.mods[i].count > 1) { // } else if (tech.tech[i].count > 1) {
// text += `<div id="mod-${i}" class="build-grid-module" onclick="build.choosePowerUp(this,${i},'mod')"><div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${mod.mods[i].name} (${mod.mods[i].count}x)</div> ${mod.mods[i].description}</div>` // text += `<div id="tech-${i}" class="build-grid-module" onclick="build.choosePowerUp(this,${i},'tech')"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[i].name} (${tech.tech[i].count}x)</div> ${tech.tech[i].description}</div>`
} else { } else {
text += `<div id="mod-${i}" class="build-grid-module" onclick="build.choosePowerUp(this,${i},'mod')"><div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${mod.mods[i].name}</div> ${mod.mods[i].description}</div>` text += `<div id="tech-${i}" class="build-grid-module" onclick="build.choosePowerUp(this,${i},'tech')"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[i].name}</div> ${tech.tech[i].description}</div>`
} }
} }
} }
document.getElementById("build-grid").innerHTML = text document.getElementById("build-grid").innerHTML = text
document.getElementById("difficulty-select-custom").value = document.getElementById("difficulty-select").value document.getElementById("difficulty-select-custom").value = document.getElementById("difficulty-select").value
document.getElementById("difficulty-select-custom").addEventListener("input", () => { document.getElementById("difficulty-select-custom").addEventListener("input", () => {
game.difficultyMode = Number(document.getElementById("difficulty-select-custom").value) simulation.difficultyMode = Number(document.getElementById("difficulty-select-custom").value)
localSettings.difficultyMode = Number(document.getElementById("difficulty-select-custom").value) localSettings.difficultyMode = Number(document.getElementById("difficulty-select-custom").value)
document.getElementById("difficulty-select").value = document.getElementById("difficulty-select-custom").value document.getElementById("difficulty-select").value = document.getElementById("difficulty-select-custom").value
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
@@ -410,9 +410,9 @@ const build = {
if (b.guns[i].ammo != Infinity) b.guns[i].ammo = 0; if (b.guns[i].ammo != Infinity) b.guns[i].ammo = 0;
} }
b.activeGun = null; b.activeGun = null;
game.makeGunHUD(); simulation.makeGunHUD();
mod.setupAllMods(); tech.setupAllMods();
build.populateGrid(); build.populateGrid();
document.getElementById("field-0").classList.add("build-field-selected"); document.getElementById("field-0").classList.add("build-field-selected");
document.getElementById("build-grid").style.display = "grid" document.getElementById("build-grid").style.display = "grid"
@@ -429,24 +429,24 @@ const build = {
} }
count = 0; count = 0;
for (let i = 0; i < mod.mods.length; i++) { for (let i = 0; i < tech.tech.length; i++) {
for (let j = 0; j < mod.mods[i].count; j++) { for (let j = 0; j < tech.tech[i].count; j++) {
url += `&mod${count}=${encodeURIComponent(mod.mods[i].name.trim())}` url += `&tech${count}=${encodeURIComponent(tech.tech[i].name.trim())}`
count++ count++
} }
} }
url += `&field=${encodeURIComponent(mech.fieldUpgrades[mech.fieldMode].name.trim())}` url += `&field=${encodeURIComponent(mech.fieldUpgrades[mech.fieldMode].name.trim())}`
url += `&difficulty=${game.difficultyMode}` url += `&difficulty=${simulation.difficultyMode}`
if (isCustom) { if (isCustom) {
url += `&level=${Math.abs(Number(document.getElementById("starting-level").value))}` url += `&level=${Math.abs(Number(document.getElementById("starting-level").value))}`
url += `&noPower=${Number(document.getElementById("no-power-ups").checked)}` url += `&noPower=${Number(document.getElementById("no-power-ups").checked)}`
alert('n-gon build URL copied to clipboard.\nPaste into browser address bar.') alert('n-gon build URL copied to clipboard.\nPaste into browser address bar.')
} else { } else {
game.makeTextLog("n-gon build URL copied to clipboard.<br>Paste into browser address bar.", 300) simulation.makeTextLog("n-gon build URL copied to clipboard.<br>Paste into browser address bar.")
} }
console.log('n-gon build URL copied to clipboard.\nPaste into browser address bar.') console.log('n-gon build URL copied to clipboard.\nPaste into browser address bar.')
console.log(url) console.log(url)
game.copyToClipBoard(url) simulation.copyToClipBoard(url)
}, },
startBuildRun() { startBuildRun() {
build.isCustomSelection = false; build.isCustomSelection = false;
@@ -454,18 +454,18 @@ const build = {
spawn.setSpawnList(); spawn.setSpawnList();
if (b.inventory.length > 0) { if (b.inventory.length > 0) {
b.activeGun = b.inventory[0] //set first gun to active gun b.activeGun = b.inventory[0] //set first gun to active gun
game.makeGunHUD(); simulation.makeGunHUD();
} }
for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]); for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]);
bullet = []; //remove any bullets that might have spawned from mods bullet = []; //remove any bullets that might have spawned from tech
const levelsCleared = Math.abs(Number(document.getElementById("starting-level").value)) const levelsCleared = Math.abs(Number(document.getElementById("starting-level").value))
level.difficultyIncrease(Math.min(99, levelsCleared * game.difficultyMode)) //increase difficulty based on modes level.difficultyIncrease(Math.min(99, levelsCleared * simulation.difficultyMode)) //increase difficulty based on modes
level.levelsCleared += levelsCleared; level.levelsCleared += levelsCleared;
game.isNoPowerUps = document.getElementById("no-power-ups").checked simulation.isNoPowerUps = document.getElementById("no-power-ups").checked
if (game.isNoPowerUps) { //remove mods, guns, and fields if (simulation.isNoPowerUps) { //remove tech, guns, and fields
function removeOne() { //recursive remove one at a time to avoid array problems function removeOne() { //recursive remove one at a time to avoid array problems
for (let i = 0; i < powerUp.length; i++) { for (let i = 0; i < powerUp.length; i++) {
if (powerUp[i].name === "mod" || powerUp[i].name === "gun" || powerUp[i].name === "field") { if (powerUp[i].name === "tech" || powerUp[i].name === "gun" || powerUp[i].name === "field") {
Matter.World.remove(engine.world, powerUp[i]); Matter.World.remove(engine.world, powerUp[i]);
powerUp.splice(i, 1); powerUp.splice(i, 1);
removeOne(); removeOne();
@@ -475,11 +475,11 @@ const build = {
} }
removeOne(); removeOne();
} }
game.isCheating = true; simulation.isCheating = true;
document.body.style.cursor = "none"; document.body.style.cursor = "none";
document.body.style.overflow = "hidden" document.body.style.overflow = "hidden"
document.getElementById("build-grid").style.display = "none" document.getElementById("build-grid").style.display = "none"
game.paused = false; simulation.paused = false;
requestAnimationFrame(cycle); requestAnimationFrame(cycle);
} }
} }
@@ -491,9 +491,9 @@ function openCustomBuildMenu() {
document.body.style.overflowY = "scroll"; document.body.style.overflowY = "scroll";
document.body.style.overflowX = "hidden"; document.body.style.overflowX = "hidden";
document.getElementById("info").style.display = 'none' document.getElementById("info").style.display = 'none'
game.startGame(true); //starts game, but pauses it simulation.startGame(true); //starts game, but pauses it
build.isCustomSelection = true; build.isCustomSelection = true;
game.paused = true; simulation.paused = true;
build.reset(); build.reset();
} }
@@ -501,49 +501,15 @@ function openCustomBuildMenu() {
document.getElementById("build-button").addEventListener("click", () => { //setup build run document.getElementById("build-button").addEventListener("click", () => { //setup build run
let field = 0; let field = 0;
let inventory = []; let inventory = [];
let modList = []; let techList = [];
if (!game.firstRun) { if (!simulation.firstRun) {
field = mech.fieldMode field = mech.fieldMode
inventory = [...b.inventory] inventory = [...b.inventory]
for (let i = 0; i < mod.mods.length; i++) { for (let i = 0; i < tech.tech.length; i++) {
modList.push(mod.mods[i].count) techList.push(tech.tech[i].count)
} }
} }
openCustomBuildMenu(); openCustomBuildMenu();
// if (!game.firstRun) { //if player has already died once load that previous build
// build.choosePowerUp(document.getElementById(`field-${field}`), field, 'field')
// for (let i = 0; i < inventory.length; i++) {
// build.choosePowerUp(document.getElementById(`gun-${inventory[i]}`), inventory[i], 'gun')
// }
// for (let i = 0; i < modList.length; i++) {
// for (let j = 0; j < modList[i]; j++) {
// build.choosePowerUp(document.getElementById(`mod-${i}`), i, 'mod', true)
// }
// }
// //update mod text //disable not allowed mods
// for (let i = 0, len = mod.mods.length; i < len; i++) {
// const modID = document.getElementById("mod-" + i)
// if (!mod.mods[i].isCustomHide) {
// if (mod.mods[i].allowed() || mod.mods[i].count > 0) {
// if (mod.mods[i].count > 1) {
// modID.innerHTML = `<div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${mod.mods[i].name} (${mod.mods[i].count}x)</div>${mod.mods[i].description}</div>`
// } else {
// modID.innerHTML = `<div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${mod.mods[i].name}</div>${mod.mods[i].description}</div>`
// }
// if (modID.classList.contains("build-grid-disabled")) {
// modID.classList.remove("build-grid-disabled");
// modID.setAttribute("onClick", `javascript: build.choosePowerUp(this,${i},'mod')`);
// }
// } else {
// modID.innerHTML = `<div class="grid-title">${mod.mods[i].name}</div><span style="color:#666;">requires: ${mod.mods[i].requires}</span></div>`
// if (!modID.classList.contains("build-grid-disabled")) {
// modID.classList.add("build-grid-disabled");
// modID.onclick = null
// }
// }
// }
// }
// }
}); });
// ************************************************************************************************ // ************************************************************************************************
@@ -739,26 +705,25 @@ window.addEventListener("keydown", function(event) {
input.field = true input.field = true
break break
case input.key.nextGun: case input.key.nextGun:
game.nextGun(); simulation.nextGun();
break break
case input.key.previousGun: case input.key.previousGun:
game.previousGun(); simulation.previousGun();
break break
case input.key.pause: case input.key.pause:
if (!game.isChoosing && input.isPauseKeyReady && mech.alive) { if (!simulation.isChoosing && input.isPauseKeyReady && mech.alive) {
input.isPauseKeyReady = false input.isPauseKeyReady = false
setTimeout(function() { setTimeout(function() {
input.isPauseKeyReady = true input.isPauseKeyReady = true
}, 300); }, 300);
if (game.paused) { if (simulation.paused) {
build.unPauseGrid() build.unPauseGrid()
game.paused = false; simulation.paused = false;
level.levelAnnounce(); level.levelAnnounce();
document.body.style.cursor = "none"; document.body.style.cursor = "none";
requestAnimationFrame(cycle); requestAnimationFrame(cycle);
} else { } else {
game.paused = true; simulation.paused = true;
game.replaceTextLog = true;
build.pauseGrid() build.pauseGrid()
document.body.style.cursor = "auto"; document.body.style.cursor = "auto";
} }
@@ -766,56 +731,56 @@ window.addEventListener("keydown", function(event) {
break break
case input.key.testing: case input.key.testing:
if (mech.alive) { if (mech.alive) {
if (game.testing) { if (simulation.testing) {
game.testing = false; simulation.testing = false;
game.loop = game.normalLoop simulation.loop = simulation.normalLoop
if (game.isConstructionMode) { if (simulation.isConstructionMode) {
document.getElementById("construct").style.display = 'none' document.getElementById("construct").style.display = 'none'
} }
} else { //if (keys[191]) } else { //if (keys[191])
game.testing = true; simulation.testing = true;
game.isCheating = true; simulation.isCheating = true;
if (game.isConstructionMode) { if (simulation.isConstructionMode) {
document.getElementById("construct").style.display = 'inline' document.getElementById("construct").style.display = 'inline'
} }
game.loop = game.testingLoop simulation.loop = simulation.testingLoop
} }
} }
break break
} }
if (game.testing) { if (simulation.testing) {
switch (event.key.toLowerCase()) { switch (event.key.toLowerCase()) {
case "o": case "o":
game.isAutoZoom = false; simulation.isAutoZoom = false;
game.zoomScale /= 0.9; simulation.zoomScale /= 0.9;
game.setZoom(); simulation.setZoom();
break; break;
case "i": case "i":
game.isAutoZoom = false; simulation.isAutoZoom = false;
game.zoomScale *= 0.9; simulation.zoomScale *= 0.9;
game.setZoom(); simulation.setZoom();
break break
case "`": case "`":
powerUps.directSpawn(game.mouseInGame.x, game.mouseInGame.y, "reroll"); powerUps.directSpawn(simulation.mouseInGame.x, simulation.mouseInGame.y, "reroll");
break break
case "1": case "1":
powerUps.directSpawn(game.mouseInGame.x, game.mouseInGame.y, "heal"); powerUps.directSpawn(simulation.mouseInGame.x, simulation.mouseInGame.y, "heal");
break break
case "2": case "2":
powerUps.directSpawn(game.mouseInGame.x, game.mouseInGame.y, "ammo"); powerUps.directSpawn(simulation.mouseInGame.x, simulation.mouseInGame.y, "ammo");
break break
case "3": case "3":
powerUps.directSpawn(game.mouseInGame.x, game.mouseInGame.y, "gun"); powerUps.directSpawn(simulation.mouseInGame.x, simulation.mouseInGame.y, "gun");
break break
case "4": case "4":
powerUps.directSpawn(game.mouseInGame.x, game.mouseInGame.y, "field"); powerUps.directSpawn(simulation.mouseInGame.x, simulation.mouseInGame.y, "field");
break break
case "5": case "5":
powerUps.directSpawn(game.mouseInGame.x, game.mouseInGame.y, "mod"); powerUps.directSpawn(simulation.mouseInGame.x, simulation.mouseInGame.y, "tech");
break break
case "6": case "6":
const index = body.length const index = body.length
spawn.bodyRect(game.mouseInGame.x, game.mouseInGame.y, 50, 50); spawn.bodyRect(simulation.mouseInGame.x, simulation.mouseInGame.y, 50, 50);
body[index].collisionFilter.category = cat.body; body[index].collisionFilter.category = cat.body;
body[index].collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet body[index].collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet
body[index].classType = "body"; body[index].classType = "body";
@@ -823,10 +788,10 @@ window.addEventListener("keydown", function(event) {
break break
case "7": case "7":
const pick = spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]; const pick = spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)];
spawn[pick](game.mouseInGame.x, game.mouseInGame.y); spawn[pick](simulation.mouseInGame.x, simulation.mouseInGame.y);
break break
case "8": case "8":
spawn.randomLevelBoss(game.mouseInGame.x, game.mouseInGame.y); spawn.randomLevelBoss(simulation.mouseInGame.x, simulation.mouseInGame.y);
break break
case "f": case "f":
const mode = (mech.fieldMode === mech.fieldUpgrades.length - 1) ? 0 : mech.fieldMode + 1 const mode = (mech.fieldMode === mech.fieldUpgrades.length - 1) ? 0 : mech.fieldMode + 1
@@ -840,11 +805,11 @@ window.addEventListener("keydown", function(event) {
mech.energy = mech.maxEnergy; mech.energy = mech.maxEnergy;
break break
case "y": case "y":
mod.giveMod() tech.giveMod()
break break
case "r": case "r":
mech.resetHistory(); mech.resetHistory();
Matter.Body.setPosition(player, game.mouseInGame); Matter.Body.setPosition(player, simulation.mouseInGame);
Matter.Body.setVelocity(player, { Matter.Body.setVelocity(player, {
x: 0, x: 0,
y: 0 y: 0
@@ -875,8 +840,8 @@ window.addEventListener("keydown", function(event) {
}); });
//mouse move input //mouse move input
document.body.addEventListener("mousemove", (e) => { document.body.addEventListener("mousemove", (e) => {
game.mouse.x = e.clientX; simulation.mouse.x = e.clientX;
game.mouse.y = e.clientY; simulation.mouse.y = e.clientY;
}); });
document.body.addEventListener("mouseup", (e) => { document.body.addEventListener("mouseup", (e) => {
@@ -925,11 +890,11 @@ document.body.addEventListener("mouseleave", (e) => { //prevents mouse getting s
}); });
document.body.addEventListener("wheel", (e) => { document.body.addEventListener("wheel", (e) => {
if (!game.paused) { if (!simulation.paused) {
if (e.deltaY > 0) { if (e.deltaY > 0) {
game.nextGun(); simulation.nextGun();
} else { } else {
game.previousGun(); simulation.previousGun();
} }
} }
}, { }, {
@@ -948,14 +913,14 @@ if (localSettings) {
} }
game.isCommunityMaps = localSettings.isCommunityMaps simulation.isCommunityMaps = localSettings.isCommunityMaps
document.getElementById("community-maps").checked = localSettings.isCommunityMaps document.getElementById("community-maps").checked = localSettings.isCommunityMaps
game.difficultyMode = localSettings.difficultyMode simulation.difficultyMode = localSettings.difficultyMode
document.getElementById("difficulty-select").value = localSettings.difficultyMode document.getElementById("difficulty-select").value = localSettings.difficultyMode
if (localSettings.fpsCapDefault === 'max') { if (localSettings.fpsCapDefault === 'max') {
game.fpsCapDefault = 999999999; simulation.fpsCapDefault = 999999999;
} else { } else {
game.fpsCapDefault = Number(localSettings.fpsCapDefault) simulation.fpsCapDefault = Number(localSettings.fpsCapDefault)
} }
document.getElementById("fps-select").value = localSettings.fpsCapDefault document.getElementById("fps-select").value = localSettings.fpsCapDefault
} else { } else {
@@ -970,7 +935,7 @@ if (localSettings) {
input.setDefault() input.setDefault()
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
document.getElementById("community-maps").checked = localSettings.isCommunityMaps document.getElementById("community-maps").checked = localSettings.isCommunityMaps
game.isCommunityMaps = localSettings.isCommunityMaps simulation.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
} }
@@ -982,24 +947,24 @@ input.controlTextUpdate()
document.getElementById("fps-select").addEventListener("input", () => { document.getElementById("fps-select").addEventListener("input", () => {
let value = document.getElementById("fps-select").value let value = document.getElementById("fps-select").value
if (value === 'max') { if (value === 'max') {
game.fpsCapDefault = 999999999; simulation.fpsCapDefault = 999999999;
} else { } else {
game.fpsCapDefault = Number(value) simulation.fpsCapDefault = Number(value)
} }
localSettings.fpsCapDefault = value localSettings.fpsCapDefault = value
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage 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 simulation.isCommunityMaps = document.getElementById("community-maps").checked
localSettings.isCommunityMaps = game.isCommunityMaps localSettings.isCommunityMaps = simulation.isCommunityMaps
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
}); });
// difficulty-select-custom event listener is set in build.makeGrid // difficulty-select-custom event listener is set in build.makeGrid
document.getElementById("difficulty-select").addEventListener("input", () => { document.getElementById("difficulty-select").addEventListener("input", () => {
game.difficultyMode = Number(document.getElementById("difficulty-select").value) simulation.difficultyMode = Number(document.getElementById("difficulty-select").value)
localSettings.difficultyMode = game.difficultyMode localSettings.difficultyMode = simulation.difficultyMode
localSettings.levelsClearedLastGame = 0 //after changing difficulty, reset run history localSettings.levelsClearedLastGame = 0 //after changing difficulty, reset run history
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
}); });
@@ -1048,28 +1013,27 @@ document.getElementById("updates").addEventListener("toggle", function() {
//********************************************************************** //**********************************************************************
// main loop // main loop
//********************************************************************** //**********************************************************************
game.loop = game.normalLoop; simulation.loop = simulation.normalLoop;
function cycle() { function cycle() {
if (!game.paused) requestAnimationFrame(cycle); if (!simulation.paused) requestAnimationFrame(cycle);
const now = Date.now(); const now = Date.now();
const elapsed = now - game.then; // calc elapsed time since last loop const elapsed = now - simulation.then; // calc elapsed time since last loop
if (elapsed > game.fpsInterval) { // if enough time has elapsed, draw the next frame if (elapsed > simulation.fpsInterval) { // if enough time has elapsed, draw the next frame
game.then = now - (elapsed % game.fpsInterval); // Get ready for next frame by setting then=now. Also, adjust for fpsInterval not being multiple of 16.67 simulation.then = now - (elapsed % simulation.fpsInterval); // Get ready for next frame by setting then=now. Also, adjust for fpsInterval not being multiple of 16.67
game.cycle++; //tracks game cycles simulation.cycle++; //tracks game cycles
mech.cycle++; //tracks player cycles //used to alow time to stop for everything, but the player mech.cycle++; //tracks player cycles //used to alow time to stop for everything, but the player
if (game.clearNow) { if (simulation.clearNow) {
game.clearNow = false; simulation.clearNow = false;
game.clearMap(); simulation.clearMap();
level.start(); level.start();
} }
game.loop(); simulation.loop();
// if (isNaN(mech.health) || isNaN(mech.energy)) { // if (isNaN(mech.health) || isNaN(mech.energy)) {
// console.log(`mech.health = ${mech.health}`) // console.log(`mech.health = ${mech.health}`)
// game.paused = true; // simulation.paused = true;
// game.replaceTextLog = true;
// build.pauseGrid() // build.pauseGrid()
// document.body.style.cursor = "auto"; // document.body.style.cursor = "auto";
// alert("health is NaN, please report this bug to the discord \n https://discordapp.com/invite/2eC9pgJ") // alert("health is NaN, please report this bug to the discord \n https://discordapp.com/invite/2eC9pgJ")
@@ -1079,23 +1043,3 @@ function cycle() {
// } // }
} }
} }
//display console logs in game
// function proxy(context, method, message) {
// return function() {
// // method.apply(context, [message].concat(Array.prototype.slice.apply(arguments)))
// game.makeTextLog(arguments[0], 300)
// }
// }
// console.log = proxy(console, console.log, 'n-gon: ')
// console.error = proxy(console, console.error, 'Error:')
// console.warn = proxy(console, console.warn, 'Warning:')
// let's test
// console.log('im from console.log', level, 2, 3);
// console.error('im from console.error', 1, 2, 3);
// console.warn('im from console.warn', 1, 2, 3);

View File

@@ -12,19 +12,19 @@ const level = {
levels: [], levels: [],
start() { start() {
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 // simulation.enableConstructMode() //used to build maps in testing mode
// level.difficultyIncrease(1) // level.difficultyIncrease(1)
// game.zoomScale = 1000; // simulation.zoomScale = 1000;
// game.setZoom(); // simulation.setZoom();
// mech.setField("plasma torch") // mech.setField("plasma torch")
// b.giveGuns("wave beam") // b.giveGuns("wave beam")
// mod.giveMod("CPT reversal") // tech.giveMod("CPT reversal")
// mod.giveMod("CPT gun") // tech.giveMod("CPT gun")
// for (let i = 0; i < 15; i++) mod.giveMod("plasma jet") // for (let i = 0; i < 15; i++) tech.giveMod("plasma jet")
level.intro(); //starting level level.intro(); //starting level
// level.testing(); //not in rotation // level.testing(); //not in rotation
// level.finalBoss() //final boss level // level.final() //final boss level
// level.gauntlet(); //before final boss level // level.gauntlet(); //before final boss level
// level.testChamber() //less mobs, more puzzle // level.testChamber() //less mobs, more puzzle
// level.sewers(); // level.sewers();
@@ -44,48 +44,50 @@ const level = {
spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns
// spawn.pickList = ["focuser", "focuser"] // spawn.pickList = ["focuser", "focuser"]
level[level.levels[level.onLevel]](); //picks the current map from the the levels array level[level.levels[level.onLevel]](); //picks the current map from the the levels array
if (!game.isCheating) { if (!simulation.isCheating) {
localSettings.runCount += level.levelsCleared //track the number of total runs locally localSettings.runCount += level.levelsCleared //track the number of total runs locally
localSettings.levelsClearedLastGame = level.levelsCleared localSettings.levelsClearedLastGame = level.levelsCleared
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
} }
} }
level.levelAnnounce(); level.levelAnnounce();
game.noCameraScroll(); simulation.noCameraScroll();
game.setZoom(); simulation.setZoom();
level.addToWorld(); //add bodies to game engine level.addToWorld(); //add bodies to game engine
game.draw.setPaths(); simulation.draw.setPaths();
b.respawnBots(); b.respawnBots();
mech.resetHistory(); mech.resetHistory();
if (mod.isArmorFromPowerUps) { if (tech.isArmorFromPowerUps) {
const gain = Math.min(0.04 * powerUps.totalPowerUps, 0.44) const gain = Math.min(0.04 * powerUps.totalPowerUps, 0.44)
mod.armorFromPowerUps += gain tech.armorFromPowerUps += gain
mech.setMaxHealth(); mech.setMaxHealth();
if (powerUps.totalPowerUps) game.makeTextLog("<span style='font-size:115%;'> max health increased by " + (gain * 100).toFixed(0) + "%</span>", 300) // if (powerUps.totalPowerUps) simulation.makeTextLog("<span style='font-size:115%;'> max health increased by " + (gain * 100).toFixed(0) + "%</span>", 300)
simulation.makeTextLog(`<span class='color-var'>mech</span>.<span class='color-h'>maxHealth</span> <span class='color-symbol'>+=</span> ${(gain).toFixed(3)}
<br>${mech.maxHealth.toFixed(3)}`)
} }
if (mod.isHealLowHealth) { if (tech.isHealLowHealth) {
const len = Math.floor((mech.maxHealth - mech.health) / 0.5) const len = Math.floor((mech.maxHealth - mech.health) / 0.5)
for (let i = 0; i < len; i++) { for (let i = 0; i < len; i++) {
powerUps.spawn(mech.pos.x + 60 * (Math.random() - 0.5), mech.pos.y + 60 * (Math.random() - 0.5), "heal", false); powerUps.spawn(mech.pos.x + 60 * (Math.random() - 0.5), mech.pos.y + 60 * (Math.random() - 0.5), "heal", false);
// powerUps.heal.spawn(mech.pos.x + 60 * (Math.random() - 0.5), mech.pos.y + 60 * (Math.random() - 0.5), 50); // powerUps.heal.spawn(mech.pos.x + 60 * (Math.random() - 0.5), mech.pos.y + 60 * (Math.random() - 0.5), 50);
} }
} }
if (mod.isPerpetualReroll) powerUps.spawn(mech.pos.x + 60 * (Math.random() - 0.5), mech.pos.y + 60 * (Math.random() - 0.5), "reroll", false); if (tech.isPerpetualReroll) powerUps.spawn(mech.pos.x + 60 * (Math.random() - 0.5), mech.pos.y + 60 * (Math.random() - 0.5), "reroll", false);
if (mod.isPerpetualAmmo) { if (tech.isPerpetualAmmo) {
powerUps.spawn(mech.pos.x + 60 * (Math.random() - 0.5), mech.pos.y + 60 * (Math.random() - 0.5), "ammo", false); powerUps.spawn(mech.pos.x + 60 * (Math.random() - 0.5), mech.pos.y + 60 * (Math.random() - 0.5), "ammo", false);
powerUps.spawn(mech.pos.x + 60 * (Math.random() - 0.5), mech.pos.y + 60 * (Math.random() - 0.5), "ammo", false); powerUps.spawn(mech.pos.x + 60 * (Math.random() - 0.5), mech.pos.y + 60 * (Math.random() - 0.5), "ammo", false);
} }
if (mod.isPerpetualHeal) { if (tech.isPerpetualHeal) {
powerUps.spawn(mech.pos.x + 60 * (Math.random() - 0.5), mech.pos.y + 60 * (Math.random() - 0.5), "heal", false); powerUps.spawn(mech.pos.x + 60 * (Math.random() - 0.5), mech.pos.y + 60 * (Math.random() - 0.5), "heal", false);
powerUps.spawn(mech.pos.x + 60 * (Math.random() - 0.5), mech.pos.y + 60 * (Math.random() - 0.5), "heal", false); powerUps.spawn(mech.pos.x + 60 * (Math.random() - 0.5), mech.pos.y + 60 * (Math.random() - 0.5), "heal", false);
} }
if (mod.isPerpetualStun) { if (tech.isPerpetualStun) {
for (let i = 0; i < mob.length; i++) mobs.statusStun(mob[i], 60 * 8) for (let i = 0; i < mob.length; i++) mobs.statusStun(mob[i], 60 * 8)
} }
if (mod.isGunCycle) { if (tech.isGunCycle) {
b.inventoryGun++; b.inventoryGun++;
if (b.inventoryGun > b.inventory.length - 1) b.inventoryGun = 0; if (b.inventoryGun > b.inventory.length - 1) b.inventoryGun = 0;
game.switchGun(); simulation.switchGun();
} }
}, },
custom() {}, custom() {},
@@ -112,11 +114,11 @@ const level = {
spawn.setSpawnList(); spawn.setSpawnList();
spawn.setSpawnList(); spawn.setSpawnList();
level.defaultZoom = 1500 level.defaultZoom = 1500
game.zoomTransition(level.defaultZoom) simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#ddd"; document.body.style.backgroundColor = "#ddd";
// game.draw.mapFill = "#444" // simulation.draw.mapFill = "#444"
// game.draw.bodyFill = "rgba(140,140,140,0.85)" // simulation.draw.bodyFill = "rgba(140,140,140,0.85)"
// game.draw.bodyStroke = "#222" // simulation.draw.bodyStroke = "#222"
level.fill.push({ level.fill.push({
x: 6400, x: 6400,
@@ -134,7 +136,8 @@ const level = {
spawn.mapRect(-250, -700, 1000, 900); // shelf spawn.mapRect(-250, -700, 1000, 900); // shelf
spawn.mapRect(-250, -1200, 1000, 250); // shelf roof spawn.mapRect(-250, -1200, 1000, 250); // shelf roof
// powerUps.spawnStartingPowerUps(600, -800); // powerUps.spawnStartingPowerUps(600, -800);
powerUps.spawn(550, -800, "reroll", false); // for (let i = 0; i < 50; ++i) powerUps.spawn(550, -800, "reroll", false);
// powerUps.spawn(350, -800, "gun", false);
function blockDoor(x, y, blockSize = 58) { function blockDoor(x, y, blockSize = 58) {
spawn.mapRect(x, y - 290, 40, 60); // door lip spawn.mapRect(x, y - 290, 40, 60); // door lip
@@ -165,7 +168,7 @@ const level = {
// spawn.bomberBoss(1400, -500) // spawn.bomberBoss(1400, -500)
// spawn.sniper(1800, -120) // spawn.sniper(1800, -120)
// spawn.cellBossCulture(1600, -500) // spawn.cellBossCulture(1600, -500)
spawn.streamBoss(1600, -500) // spawn.streamBoss(1600, -500)
// spawn.beamer(1200, -500) // spawn.beamer(1200, -500)
// spawn.shield(mob[mob.length - 1], 1800, -120, 1); // spawn.shield(mob[mob.length - 1], 1800, -120, 1);
@@ -185,7 +188,7 @@ const level = {
level.exit.x = 1500; level.exit.x = 1500;
level.exit.y = -1875; level.exit.y = -1875;
level.defaultZoom = 1800 level.defaultZoom = 1800
game.zoomTransition(level.defaultZoom) simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#dcdcde"; document.body.style.backgroundColor = "#dcdcde";
// powerUps.spawnStartingPowerUps(1475, -1175); // powerUps.spawnStartingPowerUps(1475, -1175);
// spawn.debris(750, -2200, 3700, 16); //16 debris per level // spawn.debris(750, -2200, 3700, 16); //16 debris per level
@@ -210,10 +213,10 @@ const level = {
// spawn.randomSmallMob(1300, -70); // spawn.randomSmallMob(1300, -70);
// spawn.randomMob(2650, -975, 0.8); // spawn.randomMob(2650, -975, 0.8);
// spawn.randomBoss(1700, -900, 0.4); // spawn.randomBoss(1700, -900, 0.4);
// if (game.difficulty > 3) spawn.randomLevelBoss(2200, -1300); // if (simulation.difficulty > 3) spawn.randomLevelBoss(2200, -1300);
powerUps.addRerollToLevel() //needs to run after mobs are spawned powerUps.addRerollToLevel() //needs to run after mobs are spawned
}, },
finalBoss() { final() {
level.bossKilled = false; // if a boss needs to be killed level.bossKilled = false; // if a boss needs to be killed
level.custom = () => { level.custom = () => {
level.playerExitCheck(); level.playerExitCheck();
@@ -227,7 +230,7 @@ const level = {
level.exit.y = -330; level.exit.y = -330;
level.defaultZoom = 2500 level.defaultZoom = 2500
game.zoomTransition(level.defaultZoom) simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#ccc"; document.body.style.backgroundColor = "#ccc";
level.fill.push({ level.fill.push({
@@ -276,7 +279,7 @@ const level = {
level.exit.y = -230; level.exit.y = -230;
level.defaultZoom = 1500 level.defaultZoom = 1500
game.zoomTransition(level.defaultZoom) simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#ddd"; document.body.style.backgroundColor = "#ddd";
level.fill.push({ level.fill.push({
@@ -313,13 +316,13 @@ const level = {
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump
for (let i = 0; i < 3; ++i) { for (let i = 0; i < 3; ++i) {
if (game.difficulty * Math.random() > 15 * i) { if (simulation.difficulty * Math.random() > 15 * i) {
spawn.randomBoss(2000 + 500 * (Math.random() - 0.5), -800 + 200 * (Math.random() - 0.5), Infinity); spawn.randomBoss(2000 + 500 * (Math.random() - 0.5), -800 + 200 * (Math.random() - 0.5), Infinity);
} }
if (game.difficulty * Math.random() > 10 * i) { if (simulation.difficulty * Math.random() > 10 * i) {
spawn.randomBoss(3500 + 500 * (Math.random() - 0.5), -800 + 200 * (Math.random() - 0.5), Infinity); spawn.randomBoss(3500 + 500 * (Math.random() - 0.5), -800 + 200 * (Math.random() - 0.5), Infinity);
} }
if (game.difficulty * Math.random() > 7 * i) { if (simulation.difficulty * Math.random() > 7 * i) {
spawn.randomBoss(5000 + 500 * (Math.random() - 0.5), -800 + 200 * (Math.random() - 0.5), Infinity); spawn.randomBoss(5000 + 500 * (Math.random() - 0.5), -800 + 200 * (Math.random() - 0.5), Infinity);
} }
} }
@@ -394,9 +397,9 @@ const level = {
level.exit.x = 2800; level.exit.x = 2800;
level.exit.y = -335; level.exit.y = -335;
spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 100); //exit bump
game.zoomScale = 1000 //1400 is normal simulation.zoomScale = 1000 //1400 is normal
level.defaultZoom = 1600 level.defaultZoom = 1600
game.zoomTransition(level.defaultZoom, 1) simulation.zoomTransition(level.defaultZoom, 1)
document.body.style.backgroundColor = "#ddd"; document.body.style.backgroundColor = "#ddd";
level.fill.push({ level.fill.push({
x: 2600, x: 2600,
@@ -515,13 +518,13 @@ const level = {
"Last time was a simulation. Is this one a simulation too?", "Last time was a simulation. Is this one a simulation too?",
) )
} }
if (game.difficultyMode < 4 && localSettings.levelsClearedLastGame > 10) { //too easy if (simulation.difficultyMode < 4 && localSettings.levelsClearedLastGame > 10) { //too easy
say.push( say.push(
"That felt too easy.<br>Maybe I should increase the difficulty of the simulation.", "That felt too easy.<br>Maybe I should increase the difficulty of the simulation.",
"That was fun, but maybe I should increase the difficulty of the simulation.", "That was fun, but maybe I should increase the difficulty of the simulation.",
"I should increase the difficulty of the simulation, that didn't feel realistic.", "I should increase the difficulty of the simulation, that didn't feel realistic.",
) )
} else if (game.difficultyMode > 3 && localSettings.levelsClearedLastGame > 10) { //great run on a hard or why } else if (simulation.difficultyMode > 3 && localSettings.levelsClearedLastGame > 10) { //great run on a hard or why
say.push( say.push(
"What do I do after I escape?", "What do I do after I escape?",
"I'm almost ready to stop these simulations and actually escape.", "I'm almost ready to stop these simulations and actually escape.",
@@ -532,19 +535,19 @@ const level = {
) )
} else { //resolve } else { //resolve
say.push( say.push(
"I'll try some different mods this time.", "I'll try some different techs this time.",
"I've got to escape.", "I've got to escape.",
"I'll find a way out.", "I'll find a way out.",
"I keep forgetting that these are just simulated escapes." "I keep forgetting that these are just simulated escapes."
) )
} }
game.makeTextLog(say[Math.floor(say.length * Math.random())], 1000) simulation.makeTextLog(say[Math.floor(say.length * Math.random())], 1000)
const swapPeriod = 150 const swapPeriod = 150
const len = 30 const len = 30
for (let i = 0; i < len; i++) { for (let i = 0; i < len; i++) {
setTimeout(function() { setTimeout(function() {
game.wipe = function() { //set wipe to have trails simulation.wipe = function() { //set wipe to have trails
ctx.fillStyle = `rgba(221,221,221,${i*i*0.0005 +0.0025})`; ctx.fillStyle = `rgba(221,221,221,${i*i*0.0005 +0.0025})`;
ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillRect(0, 0, canvas.width, canvas.height);
} }
@@ -552,7 +555,7 @@ const level = {
} }
setTimeout(function() { setTimeout(function() {
game.wipe = function() { //set wipe to normal simulation.wipe = function() { //set wipe to normal
ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.clearRect(0, 0, canvas.width, canvas.height);
} }
}, len * swapPeriod); }, len * swapPeriod);
@@ -567,7 +570,7 @@ const level = {
level.exit.x = level.enter.x; level.exit.x = level.enter.x;
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20); spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20);
level.defaultZoom = 2200 level.defaultZoom = 2200
game.zoomTransition(level.defaultZoom) simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#d5d5d5"; document.body.style.backgroundColor = "#d5d5d5";
const portal = level.portal({ const portal = level.portal({
@@ -776,7 +779,7 @@ const level = {
spawn.randomMob(-75, -1150, 0.5); spawn.randomMob(-75, -1150, 0.5);
spawn.randomMob(1075, -625, 0.5); spawn.randomMob(1075, -625, 0.5);
spawn.randomMob(1725, -575, 0.5); spawn.randomMob(1725, -575, 0.5);
if (game.difficulty > 40) { if (simulation.difficulty > 40) {
spawn.randomMob(2300, -2775, -0.5); spawn.randomMob(2300, -2775, -0.5);
spawn.randomMob(600, -925, -0.5); spawn.randomMob(600, -925, -0.5);
spawn.randomMob(1550, -2750, -0.5); spawn.randomMob(1550, -2750, -0.5);
@@ -784,7 +787,7 @@ const level = {
spawn.randomMob(-75, -1475, 0); spawn.randomMob(-75, -1475, 0);
spawn.randomBoss(600, -2600, 0); spawn.randomBoss(600, -2600, 0);
} }
if (game.difficulty < 25) { if (simulation.difficulty < 25) {
spawn.randomMob(700, -1650, 0); spawn.randomMob(700, -1650, 0);
spawn.randomMob(600, -3500, 0.2); spawn.randomMob(600, -3500, 0.2);
spawn.randomMob(-75, -1175, 0.2); spawn.randomMob(-75, -1175, 0.2);
@@ -837,7 +840,7 @@ const level = {
level.exit.x = 9700; level.exit.x = 9700;
level.exit.y = 2560; level.exit.y = 2560;
level.defaultZoom = 1800 level.defaultZoom = 1800
game.zoomTransition(level.defaultZoom) simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "hsl(138, 3%, 74%)"; document.body.style.backgroundColor = "hsl(138, 3%, 74%)";
powerUps.spawnStartingPowerUps(3475, 1775); powerUps.spawnStartingPowerUps(3475, 1775);
spawn.debris(4575, 2550, 1600, 9); //16 debris per level spawn.debris(4575, 2550, 1600, 9); //16 debris per level
@@ -940,7 +943,7 @@ const level = {
spawn.randomMob(3600, 1725, 0.9); spawn.randomMob(3600, 1725, 0.9);
spawn.randomMob(4100, 1225, 0.9); spawn.randomMob(4100, 1225, 0.9);
spawn.randomMob(2825, 400, 0.9); spawn.randomMob(2825, 400, 0.9);
if (game.difficulty > 3) spawn.randomLevelBoss(6000, 2300, ["spiderBoss", "launcherBoss", "laserTargetingBoss", "streamBoss"]); if (simulation.difficulty > 3) spawn.randomLevelBoss(6000, 2300, ["spiderBoss", "launcherBoss", "laserTargetingBoss", "streamBoss"]);
powerUps.addRerollToLevel() //needs to run after mobs are spawned powerUps.addRerollToLevel() //needs to run after mobs are spawned
}, },
satellite() { satellite() {
@@ -950,13 +953,13 @@ const level = {
level.playerExitCheck(); level.playerExitCheck();
}; };
level.customTopLayer = () => { level.customTopLayer = () => {
if (elevator.pauseUntilCycle < game.cycle && !mech.isBodiesAsleep) { //elevator move if (elevator.pauseUntilCycle < simulation.cycle && !mech.isBodiesAsleep) { //elevator move
if (elevator.pointA.y > -1275) { //bottom if (elevator.pointA.y > -1275) { //bottom
elevator.plat.speed = -10 elevator.plat.speed = -10
elevator.pauseUntilCycle = game.cycle + 90 elevator.pauseUntilCycle = simulation.cycle + 90
} else if (elevator.pointA.y < -3455) { //top } else if (elevator.pointA.y < -3455) { //top
elevator.plat.speed = 30 elevator.plat.speed = 30
elevator.pauseUntilCycle = game.cycle + 90 elevator.pauseUntilCycle = simulation.cycle + 90
} }
elevator.pointA = { elevator.pointA = {
x: elevator.pointA.x, x: elevator.pointA.x,
@@ -971,7 +974,7 @@ const level = {
spawn.mapRect(level.exit.x, level.exit.y + 15, 100, 50); //exit bump spawn.mapRect(level.exit.x, level.exit.y + 15, 100, 50); //exit bump
level.defaultZoom = 1700 // 4500 // 1400 level.defaultZoom = 1700 // 4500 // 1400
game.zoomTransition(level.defaultZoom) simulation.zoomTransition(level.defaultZoom)
powerUps.spawnStartingPowerUps(4900, -500); powerUps.spawnStartingPowerUps(4900, -500);
spawn.debris(1000, 20, 1800, 3); //16 debris per level //but less here because a few mobs die from laser spawn.debris(1000, 20, 1800, 3); //16 debris per level //but less here because a few mobs die from laser
@@ -1134,7 +1137,7 @@ const level = {
spawn.randomBoss(2700, -1600, 0.1); spawn.randomBoss(2700, -1600, 0.1);
spawn.randomBoss(1600, -100, 0); spawn.randomBoss(1600, -100, 0);
spawn.randomBoss(5000, -3900, -0.3); spawn.randomBoss(5000, -3900, -0.3);
if (game.difficulty > 3) { if (simulation.difficulty > 3) {
if (Math.random() < 0.1) { if (Math.random() < 0.1) {
spawn.randomLevelBoss(2800, -1400); spawn.randomLevelBoss(2800, -1400);
} else if (Math.random() < 0.25) { } else if (Math.random() < 0.25) {
@@ -1159,13 +1162,13 @@ const level = {
}; };
level.customTopLayer = () => { level.customTopLayer = () => {
if (elevator.pauseUntilCycle < game.cycle && !mech.isBodiesAsleep) { //elevator move if (elevator.pauseUntilCycle < simulation.cycle && !mech.isBodiesAsleep) { //elevator move
if (elevator.pointA.y > -980) { //bottom if (elevator.pointA.y > -980) { //bottom
elevator.plat.speed = -2 elevator.plat.speed = -2
elevator.pauseUntilCycle = game.cycle + 60 elevator.pauseUntilCycle = simulation.cycle + 60
} else if (elevator.pointA.y < -1980) { //top } else if (elevator.pointA.y < -1980) { //top
elevator.plat.speed = 1 elevator.plat.speed = 1
elevator.pauseUntilCycle = game.cycle + 60 elevator.pauseUntilCycle = simulation.cycle + 60
} }
elevator.pointA = { elevator.pointA = {
x: elevator.pointA.x, x: elevator.pointA.x,
@@ -1175,7 +1178,7 @@ const level = {
}; };
level.defaultZoom = 1700 level.defaultZoom = 1700
game.zoomTransition(level.defaultZoom) simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#dcdcde"; document.body.style.backgroundColor = "#dcdcde";
@@ -1369,13 +1372,13 @@ const level = {
spawn.randomBoss(600, -1575, 0); spawn.randomBoss(600, -1575, 0);
spawn.randomBoss(2225, -1325, 0.4); spawn.randomBoss(2225, -1325, 0.4);
spawn.randomBoss(4900, -1200, 0); spawn.randomBoss(4900, -1200, 0);
if (game.difficulty > 3) spawn.randomLevelBoss(3200, -2050); if (simulation.difficulty > 3) spawn.randomLevelBoss(3200, -2050);
powerUps.addRerollToLevel() //needs to run after mobs are spawned powerUps.addRerollToLevel() //needs to run after mobs are spawned
}, },
aerie() { aerie() {
level.bossKilled = false; // if a boss needs to be killed level.bossKilled = false; // if a boss needs to be killed
// const elevator = level.platform(4112, -2300, 280, 50) // const elevator = level.platform(4112, -2300, 280, 50)
// game.g = 0.0012 //0.0024 // simulation.g = 0.0012 //0.0024
level.custom = () => { level.custom = () => {
level.playerExitCheck(); level.playerExitCheck();
}; };
@@ -1383,11 +1386,11 @@ const level = {
// elevator.move() // elevator.move()
}; };
// game.difficulty = 4; //for testing to simulate possible mobs spawns // simulation.difficulty = 4; //for testing to simulate possible mobs spawns
level.defaultZoom = 2100 level.defaultZoom = 2100
game.zoomTransition(level.defaultZoom) simulation.zoomTransition(level.defaultZoom)
const backwards = (Math.random() < 0.25 && game.difficulty > 8) ? true : false; const backwards = (Math.random() < 0.25 && simulation.difficulty > 8) ? true : false;
if (backwards) { if (backwards) {
level.setPosToSpawn(4000, -3300); //normal spawn level.setPosToSpawn(4000, -3300); //normal spawn
level.exit.x = -100; level.exit.x = -100;
@@ -1471,7 +1474,7 @@ const level = {
spawn.mapRect(-300, -1000, 600, 100); spawn.mapRect(-300, -1000, 600, 100);
spawn.mapRect(-300, -1300, 450, 50); spawn.mapRect(-300, -1300, 450, 50);
spawn.mapRect(-300, -1300, 50, 350); spawn.mapRect(-300, -1300, 50, 350);
if (!backwards && game.difficulty > 1) spawn.bodyRect(100, -1250, 200, 240); //remove on backwards if (!backwards && simulation.difficulty > 1) spawn.bodyRect(100, -1250, 200, 240); //remove on backwards
//left building //left building
spawn.mapRect(-100, -975, 100, 975); spawn.mapRect(-100, -975, 100, 975);
spawn.mapRect(-500, 100, 1950, 400); spawn.mapRect(-500, 100, 1950, 400);
@@ -1542,7 +1545,7 @@ const level = {
spawn.randomMob(3575, -2425, 0.5); spawn.randomMob(3575, -2425, 0.5);
spawn.randomMob(3975, -3900, 0.5); spawn.randomMob(3975, -3900, 0.5);
spawn.randomMob(1725, 125, 0.5); spawn.randomMob(1725, 125, 0.5);
if (game.difficulty > 3) { if (simulation.difficulty > 3) {
if (Math.random() < 0.1) { // 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({
@@ -1555,7 +1558,7 @@ const level = {
}); });
World.add(engine.world, cons[cons.length - 1]); World.add(engine.world, cons[cons.length - 1]);
if (game.difficulty > 4) spawn.nodeBoss(4250, 0, "spawns", 8, 20, 105); //chance to spawn a ring of exploding mobs around this boss if (simulation.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.15) { } else if (Math.random() < 0.15) {
spawn.randomLevelBoss(4250, -250); spawn.randomLevelBoss(4250, -250);
spawn.debris(-250, 50, 1650, 2); //16 debris per level spawn.debris(-250, 50, 1650, 2); //16 debris per level
@@ -1594,7 +1597,7 @@ const level = {
level.exit.y = -1875; level.exit.y = -1875;
level.defaultZoom = 2000 level.defaultZoom = 2000
game.zoomTransition(level.defaultZoom) simulation.zoomTransition(level.defaultZoom)
//level.setPosToSpawn(1550, -1200); //spawn left high //level.setPosToSpawn(1550, -1200); //spawn left high
//level.setPosToSpawn(1800, -2000); //spawn near exit //level.setPosToSpawn(1800, -2000); //spawn near exit
@@ -1602,9 +1605,9 @@ const level = {
powerUps.spawnStartingPowerUps(1475, -1175); powerUps.spawnStartingPowerUps(1475, -1175);
spawn.debris(750, -2200, 3700, 16); //16 debris per level spawn.debris(750, -2200, 3700, 16); //16 debris per level
document.body.style.backgroundColor = "#dcdcde"; document.body.style.backgroundColor = "#dcdcde";
// game.draw.mapFill = "#444" // simulation.draw.mapFill = "#444"
// game.draw.bodyFill = "rgba(140,140,140,0.85)" // simulation.draw.bodyFill = "rgba(140,140,140,0.85)"
// game.draw.bodyStroke = "#222" // simulation.draw.bodyStroke = "#222"
//foreground //foreground
level.fill.push({ level.fill.push({
@@ -1739,7 +1742,7 @@ const level = {
spawn.randomMob(-100, -900, -0.2); spawn.randomMob(-100, -900, -0.2);
spawn.randomBoss(3700, -1500, 0.4); spawn.randomBoss(3700, -1500, 0.4);
spawn.randomBoss(1700, -900, 0.4); spawn.randomBoss(1700, -900, 0.4);
if (game.difficulty > 3) spawn.randomLevelBoss(2600, -2300); if (simulation.difficulty > 3) spawn.randomLevelBoss(2600, -2300);
powerUps.addRerollToLevel() //needs to run after mobs are spawned powerUps.addRerollToLevel() //needs to run after mobs are spawned
}, },
highrise() { highrise() {
@@ -1755,7 +1758,7 @@ const level = {
level.exit.y = -2805; level.exit.y = -2805;
level.defaultZoom = 1500 level.defaultZoom = 1500
game.zoomTransition(level.defaultZoom) simulation.zoomTransition(level.defaultZoom)
powerUps.spawnStartingPowerUps(-2550, -700); powerUps.spawnStartingPowerUps(-2550, -700);
document.body.style.backgroundColor = "#dcdcde" //"#fafcff"; document.body.style.backgroundColor = "#dcdcde" //"#fafcff";
@@ -1871,7 +1874,7 @@ const level = {
spawn.mapRect(-600, -1150, 850, 175); spawn.mapRect(-600, -1150, 850, 175);
spawn.mapRect(-1850, -1150, 1050, 175); spawn.mapRect(-1850, -1150, 1050, 175);
spawn.bodyRect(-1907, -1600, 550, 25); spawn.bodyRect(-1907, -1600, 550, 25);
if (game.difficulty < 4) { if (simulation.difficulty < 4) {
spawn.bodyRect(-1600, -125, 125, 125); spawn.bodyRect(-1600, -125, 125, 125);
spawn.bodyRect(-1560, -200, 75, 75); spawn.bodyRect(-1560, -200, 75, 75);
} else { } else {
@@ -1910,7 +1913,7 @@ const level = {
spawn.mapRect(-4450, -3075, 450, 25); spawn.mapRect(-4450, -3075, 450, 25);
spawn.mapRect(-4025, -3075, 25, 100); spawn.mapRect(-4025, -3075, 25, 100);
spawn.mapRect(-4275, -2785, 100, 25); spawn.mapRect(-4275, -2785, 100, 25);
if (game.difficulty < 4) spawn.bodyRect(-3760, -2400, 50, 50); if (simulation.difficulty < 4) spawn.bodyRect(-3760, -2400, 50, 50);
//mobs //mobs
spawn.randomMob(-2500, -2700, 1); spawn.randomMob(-2500, -2700, 1);
@@ -1938,7 +1941,7 @@ const level = {
spawn.randomBoss(-3250, -2700, 0.2); spawn.randomBoss(-3250, -2700, 0.2);
spawn.randomBoss(-2450, -1100, 0); spawn.randomBoss(-2450, -1100, 0);
if (game.difficulty > 3) spawn.randomLevelBoss(-2400, -3000); if (simulation.difficulty > 3) spawn.randomLevelBoss(-2400, -3000);
powerUps.addRerollToLevel() //needs to run after mobs are spawned powerUps.addRerollToLevel() //needs to run after mobs are spawned
}, },
warehouse() { warehouse() {
@@ -1953,7 +1956,7 @@ const level = {
level.exit.y = -30; level.exit.y = -30;
level.defaultZoom = 1300 level.defaultZoom = 1300
game.zoomTransition(level.defaultZoom) simulation.zoomTransition(level.defaultZoom)
spawn.debris(-2250, 1330, 3000, 6); //16 debris per level spawn.debris(-2250, 1330, 3000, 6); //16 debris per level
spawn.debris(-3000, -800, 3280, 6); //16 debris per level spawn.debris(-3000, -800, 3280, 6); //16 debris per level
@@ -2107,7 +2110,7 @@ const level = {
spawn.randomBoss(-825, 1000, 0.2); spawn.randomBoss(-825, 1000, 0.2);
spawn.randomBoss(-1300, -1100, -0.3); spawn.randomBoss(-1300, -1100, -0.3);
if (game.difficulty > 3) { if (simulation.difficulty > 3) {
if (Math.random() < 0.25) { if (Math.random() < 0.25) {
spawn.randomLevelBoss(-800, -1300) spawn.randomLevelBoss(-800, -1300)
} else { } else {
@@ -2166,7 +2169,7 @@ const level = {
}; };
level.defaultZoom = 1400 level.defaultZoom = 1400
game.zoomTransition(level.defaultZoom) simulation.zoomTransition(level.defaultZoom)
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 50); //ground bump wall spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 50); //ground bump wall
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20); spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
@@ -2288,7 +2291,7 @@ const level = {
spawn.randomBoss(1800, -800, -0.2); spawn.randomBoss(1800, -800, -0.2);
spawn.randomBoss(4150, -1000, 0.6); spawn.randomBoss(4150, -1000, 0.6);
if (game.difficulty > 3) { if (simulation.difficulty > 3) {
if (Math.random() < 0.65) { if (Math.random() < 0.65) {
// tether ball // tether ball
level.fillBG.push({ level.fillBG.push({
@@ -2309,7 +2312,7 @@ const level = {
}); });
World.add(engine.world, cons[cons.length - 1]); World.add(engine.world, cons[cons.length - 1]);
//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 > 6) spawn.nodeBoss(2850, -80, "spawns", 8, 20, 105); if (simulation.difficulty > 6) spawn.nodeBoss(2850, -80, "spawns", 8, 20, 105);
} else { } else {
spawn.randomLevelBoss(2200, -450) spawn.randomLevelBoss(2200, -450)
} }
@@ -2327,15 +2330,15 @@ const level = {
level.exit.y = -1250; level.exit.y = -1250;
level.defaultZoom = 1400 level.defaultZoom = 1400
game.zoomTransition(level.defaultZoom) simulation.zoomTransition(level.defaultZoom)
spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 20); //exit bump spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 20); //exit bump
spawn.debris(3800, -1480, 300, 12); spawn.debris(3800, -1480, 300, 12);
spawn.debris(3600, -1130, 200, 2); spawn.debris(3600, -1130, 200, 2);
document.body.style.backgroundColor = "#dbdcde"; document.body.style.backgroundColor = "#dbdcde";
// game.draw.mapFill = "#444" // simulation.draw.mapFill = "#444"
// game.draw.bodyFill = "rgba(140,140,140,0.85)" // simulation.draw.bodyFill = "rgba(140,140,140,0.85)"
// game.draw.bodyStroke = "#222" // simulation.draw.bodyStroke = "#222"
level.fillBG.push({ level.fillBG.push({
x: -500, x: -500,
@@ -2551,7 +2554,7 @@ const level = {
spawn.randomBoss(2350, -850, 1); spawn.randomBoss(2350, -850, 1);
spawn.randomBoss(100, -450, 0.9); spawn.randomBoss(100, -450, 0.9);
if (game.difficulty > 3) spawn.randomLevelBoss(1850, -1400); if (simulation.difficulty > 3) spawn.randomLevelBoss(1850, -1400);
powerUps.addRerollToLevel() //needs to run after mobs are spawned powerUps.addRerollToLevel() //needs to run after mobs are spawned
}, },
basement() { // player made level by Francois 👑 from discord basement() { // player made level by Francois 👑 from discord
@@ -2635,13 +2638,13 @@ const level = {
portal[3].draw(); portal[3].draw();
hazard.draw(); hazard.draw();
//elevator //elevator
if (elevator.pauseUntilCycle < game.cycle && !mech.isBodiesAsleep) { if (elevator.pauseUntilCycle < simulation.cycle && !mech.isBodiesAsleep) {
if (elevator.plat.position.y > -200) { //bottom if (elevator.plat.position.y > -200) { //bottom
elevator.plat.speed = -20 elevator.plat.speed = -20
elevator.pauseUntilCycle = game.cycle + 90 elevator.pauseUntilCycle = simulation.cycle + 90
} else if (elevator.plat.position.y < -3000) { //top } else if (elevator.plat.position.y < -3000) { //top
elevator.plat.speed = 30 elevator.plat.speed = 30
elevator.pauseUntilCycle = game.cycle + 90 elevator.pauseUntilCycle = simulation.cycle + 90
} }
elevator.plat.position = { elevator.plat.position = {
x: elevator.plat.position.x, x: elevator.plat.position.x,
@@ -2652,7 +2655,7 @@ const level = {
}; };
level.defaultZoom = 1300 level.defaultZoom = 1300
game.zoomTransition(level.defaultZoom) simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#c7c7c7"; document.body.style.backgroundColor = "#c7c7c7";
// GROUND // // GROUND //
@@ -2770,7 +2773,7 @@ const level = {
spawn.mapRect(2050, -1225, 75, 100); //Plateforme over acid spawn.mapRect(2050, -1225, 75, 100); //Plateforme over acid
// MOBS // MOBS
if (isLevelReversed === false) { ///Normal spawn if (isLevelReversed === false) { ///Normal spawn
if (game.difficulty > 2) { if (simulation.difficulty > 2) {
if (Math.random() < 0.2) { if (Math.random() < 0.2) {
// tether ball // tether ball
spawn.tetherBoss(7000, -3300) spawn.tetherBoss(7000, -3300)
@@ -2783,13 +2786,13 @@ const level = {
stiffness: 0.00006 stiffness: 0.00006
}); });
World.add(engine.world, cons[cons.length - 1]); World.add(engine.world, cons[cons.length - 1]);
if (game.difficulty > 4) spawn.nodeBoss(7000, -3300, "spawns", 8, 20, 105); if (simulation.difficulty > 4) spawn.nodeBoss(7000, -3300, "spawns", 8, 20, 105);
} else if (game.difficulty > 3) { } else if (simulation.difficulty > 3) {
spawn.randomLevelBoss(6100, -3600, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss"]); spawn.randomLevelBoss(6100, -3600, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss"]);
} }
} }
} else { /// Reversed spawn } else { /// Reversed spawn
if (game.difficulty > 2) { if (simulation.difficulty > 2) {
if (Math.random() < 0.2) { if (Math.random() < 0.2) {
// tether ball // tether ball
spawn.tetherBoss(2300, -1300) spawn.tetherBoss(2300, -1300)
@@ -2802,8 +2805,8 @@ const level = {
stiffness: 0.00036 stiffness: 0.00036
}); });
World.add(engine.world, cons[cons.length - 1]); World.add(engine.world, cons[cons.length - 1]);
if (game.difficulty > 4) spawn.nodeBoss(2350, -1300, "spawns", 8, 20, 105); if (simulation.difficulty > 4) spawn.nodeBoss(2350, -1300, "spawns", 8, 20, 105);
} else if (game.difficulty > 3) { } else if (simulation.difficulty > 3) {
spawn.randomLevelBoss(2300, -1400, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss", "snakeBoss"]); spawn.randomLevelBoss(2300, -1400, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss", "snakeBoss"]);
} }
} }
@@ -2879,7 +2882,7 @@ const level = {
}); });
World.add(engine.world, cons[cons.length - 1]); World.add(engine.world, cons[cons.length - 1]);
//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(2330, 1850, "spawns", 8, 20, 105); if (simulation.difficulty > 4) spawn.nodeBoss(2330, 1850, "spawns", 8, 20, 105);
powerUps.chooseRandomPowerUp(3100, 1630); powerUps.chooseRandomPowerUp(3100, 1630);
}, },
detours() { detours() {
@@ -2889,7 +2892,7 @@ const level = {
level.exit.x = 10625; level.exit.x = 10625;
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20); spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20);
level.defaultZoom = 1400; level.defaultZoom = 1400;
game.zoomTransition(level.defaultZoom) simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#d5d5d5"; document.body.style.backgroundColor = "#d5d5d5";
const BGColor = "rgba(0,0,0,0.1)"; const BGColor = "rgba(0,0,0,0.1)";
level.fill.push({ level.fill.push({
@@ -2942,7 +2945,7 @@ const level = {
map[len].collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet; map[len].collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet;
Matter.Body.setStatic(map[len], true); //make static Matter.Body.setStatic(map[len], true); //make static
World.add(engine.world, map[len]); //add to world World.add(engine.world, map[len]); //add to world
game.draw.setPaths() //update map graphics simulation.draw.setPaths() //update map graphics
} }
function drawOnTheMapBodyRect(x, y, dx, dy) { function drawOnTheMapBodyRect(x, y, dx, dy) {
@@ -3144,7 +3147,7 @@ const level = {
spawn.randomMob(8800, -45, 0.2); spawn.randomMob(8800, -45, 0.2);
spawn.randomBoss(8025, -845, 0.2); spawn.randomBoss(8025, -845, 0.2);
if (game.difficulty > 2) { if (simulation.difficulty > 2) {
if (Math.random() < 0.2) { if (Math.random() < 0.2) {
// tether ball // tether ball
spawn.tetherBoss(8000, 630) spawn.tetherBoss(8000, 630)
@@ -3163,7 +3166,7 @@ const level = {
stiffness: 0.00015 stiffness: 0.00015
}); });
World.add(engine.world, cons[cons.length - 1]); World.add(engine.world, cons[cons.length - 1]);
if (game.difficulty > 4) spawn.nodeBoss(8000, 630, "spawns", 8, 20, 105); if (simulation.difficulty > 4) spawn.nodeBoss(8000, 630, "spawns", 8, 20, 105);
} else { } else {
spawn.randomLevelBoss(8000, 630, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss", "bomberBoss"]); spawn.randomLevelBoss(8000, 630, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss", "bomberBoss"]);
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
@@ -3203,7 +3206,7 @@ const level = {
level.exit.y = -2480; level.exit.y = -2480;
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20); spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20);
level.defaultZoom = 1800 level.defaultZoom = 1800
game.zoomTransition(level.defaultZoom) simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "rgb(170 170 170)" document.body.style.backgroundColor = "rgb(170 170 170)"
level.custom = () => { level.custom = () => {
@@ -3260,9 +3263,9 @@ const level = {
ctx.strokeStyle = "#444444" ctx.strokeStyle = "#444444"
ctx.strokeRect(1650, -1300, 175, 150); ctx.strokeRect(1650, -1300, 175, 150);
chair.force.y += chair.mass * game.g; chair.force.y += chair.mass * simulation.g;
chair2.force.y += chair2.mass * game.g; chair2.force.y += chair2.mass * simulation.g;
person.force.y += person.mass * game.g; person.force.y += person.mass * simulation.g;
level.playerExitCheck(); level.playerExitCheck();
}; };
level.customTopLayer = () => { level.customTopLayer = () => {
@@ -3739,7 +3742,7 @@ const level = {
spawn.randomBoss(630, -1300, -0.1); spawn.randomBoss(630, -1300, -0.1);
spawn.randomBoss(3450, -2880, -0.2) spawn.randomBoss(3450, -2880, -0.2)
if (game.difficulty > 3) { if (simulation.difficulty > 3) {
if (Math.random() < 0.16) { if (Math.random() < 0.16) {
spawn.tetherBoss(3380, -1775) spawn.tetherBoss(3380, -1775)
cons[cons.length] = Constraint.create({ cons[cons.length] = Constraint.create({
@@ -3751,7 +3754,7 @@ const level = {
stiffness: 0.00018 + 0.000007 * level.levelsCleared stiffness: 0.00018 + 0.000007 * level.levelsCleared
}); });
World.add(engine.world, cons[cons.length - 1]); World.add(engine.world, cons[cons.length - 1]);
if (game.difficulty > 4) spawn.nodeBoss(3380, -1775, "spawns", 8, 20, 105); //chance to spawn a ring of exploding mobs around this boss if (simulation.difficulty > 4) spawn.nodeBoss(3380, -1775, "spawns", 8, 20, 105); //chance to spawn a ring of exploding mobs around this boss
} else { } else {
spawn.randomLevelBoss(3100, -1850, ["shooterBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "snakeBoss", "laserBoss"]); spawn.randomLevelBoss(3100, -1850, ["shooterBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "snakeBoss", "laserBoss"]);
@@ -3764,64 +3767,75 @@ const level = {
//****************************************************************************************************************** //******************************************************************************************************************
difficultyIncrease(num = 1) { difficultyIncrease(num = 1) {
for (let i = 0; i < num; i++) { for (let i = 0; i < num; i++) {
game.difficulty++ simulation.difficulty++
b.dmgScale *= 0.93; //damage done by player decreases each level b.dmgScale *= 0.93; //damage done by player decreases each level
if (game.accelScale < 5) game.accelScale *= 1.02 //mob acceleration increases each level if (simulation.accelScale < 5) simulation.accelScale *= 1.02 //mob acceleration increases each level
if (game.lookFreqScale > 0.2) game.lookFreqScale *= 0.98 //mob cycles between looks decreases each level if (simulation.lookFreqScale > 0.2) simulation.lookFreqScale *= 0.98 //mob cycles between looks decreases each level
if (game.CDScale > 0.2) game.CDScale *= 0.97 //mob CD time decreases each level if (simulation.CDScale > 0.2) simulation.CDScale *= 0.97 //mob CD time decreases each level
} }
game.dmgScale = 0.38 * game.difficulty //damage done by mobs increases each level simulation.dmgScale = 0.38 * simulation.difficulty //damage done by mobs increases each level
game.healScale = 1 / (1 + game.difficulty * 0.06) //a higher denominator makes for lower heals // mech.health += heal * game.healScale; simulation.healScale = 1 / (1 + simulation.difficulty * 0.06) //a higher denominator makes for lower heals // mech.health += heal * simulation.healScale;
}, },
difficultyDecrease(num = 1) { //used in easy mode for game.reset() difficultyDecrease(num = 1) { //used in easy mode for simulation.reset()
for (let i = 0; i < num; i++) { for (let i = 0; i < num; i++) {
game.difficulty-- simulation.difficulty--
b.dmgScale /= 0.93; //damage done by player decreases each level b.dmgScale /= 0.93; //damage done by player decreases each level
if (game.accelScale > 0.2) game.accelScale /= 1.02 //mob acceleration increases each level if (simulation.accelScale > 0.2) simulation.accelScale /= 1.02 //mob acceleration increases each level
if (game.lookFreqScale < 5) game.lookFreqScale /= 0.98 //mob cycles between looks decreases each level if (simulation.lookFreqScale < 5) simulation.lookFreqScale /= 0.98 //mob cycles between looks decreases each level
if (game.CDScale < 5) game.CDScale /= 0.97 //mob CD time decreases each level if (simulation.CDScale < 5) simulation.CDScale /= 0.97 //mob CD time decreases each level
} }
if (game.difficulty < 1) game.difficulty = 0; if (simulation.difficulty < 1) simulation.difficulty = 0;
game.dmgScale = 0.38 * game.difficulty //damage done by mobs increases each level simulation.dmgScale = 0.38 * simulation.difficulty //damage done by mobs increases each level
if (game.dmgScale < 0.1) game.dmgScale = 0.1; if (simulation.dmgScale < 0.1) simulation.dmgScale = 0.1;
game.healScale = 1 / (1 + game.difficulty * 0.06) simulation.healScale = 1 / (1 + simulation.difficulty * 0.06)
}, },
difficultyText() { difficultyText() {
if (game.difficultyMode === 1) { if (simulation.difficultyMode === 1) {
return "easy" return "easy"
} else if (game.difficultyMode === 2) { } else if (simulation.difficultyMode === 2) {
return "normal" return "normal"
} else if (game.difficultyMode === 4) { } else if (simulation.difficultyMode === 4) {
return "hard" return "hard"
} else if (game.difficultyMode === 6) { } else if (simulation.difficultyMode === 6) {
return "why" return "why"
} }
}, },
levelAnnounce() { levelAnnounce() {
if (level.levelsCleared === 0) { if (level.levelsCleared === 0) {
document.title = "n-gon: intro (" + level.difficultyText() + ")"; document.title = "n-gon: (" + level.difficultyText() + ")";
} else { } else {
document.title = "n-gon: L" + (level.levelsCleared) + " " + level.levels[level.onLevel] + " (" + level.difficultyText() + ")"; document.title = "n-gon: " + (level.levelsCleared) + " " + level.levels[level.onLevel] + " (" + level.difficultyText() + ")";
simulation.makeTextLog(`<span class='color-var'>level</span>.onLevel <span class='color-symbol'>=</span> "<span class='color-text'>${level.levels[level.onLevel]}</span>"`);
} }
// simulation.makeTextLog(`
// input.key.up = ["<span class='color-text'>${input.key.up}</span>", "<span class='color-text'>ArrowUp</span>"]
// <br>input.key.left = ["<span class='color-text'>${input.key.left}</span>", "<span class='color-text'>ArrowLeft</span>"]
// <br>input.key.down = ["<span class='color-text'>${input.key.down}</span>", "<span class='color-text'>ArrowDown</span>"]
// <br>input.key.right = ["<span class='color-text'>${input.key.right}</span>", "<span class='color-text'>ArrowRight</span>"]
// <br>
// <br><span class='color-var'>mech</span>.fieldMode = "<span class='color-text'>${mech.fieldUpgrades[mech.fieldMode].name}</span>"
// <br>input.key.field = ["<span class='color-text'>${input.key.field}</span>", "<span class='color-text'>right mouse</span>"]
// <br><span class='color-var'>mech</span>.field.description = "<span class='color-text'>${mech.fieldUpgrades[mech.fieldMode].description}</span>"
// `, 1200);
}, },
nextLevel() { nextLevel() {
// if (level.bossKilled) // if (level.bossKilled)
level.levelsCleared++; level.levelsCleared++;
// level.difficultyIncrease(game.difficultyMode) //increase difficulty based on modes // level.difficultyIncrease(simulation.difficultyMode) //increase difficulty based on modes
//difficulty is increased 5 times when finalBoss dies //difficulty is increased 5 times when finalBoss dies
const len = level.levelsCleared / level.levels.length //add 1 extra difficulty step for each time you have cleared all the levels const len = level.levelsCleared / level.levels.length //add 1 extra difficulty step for each time you have cleared all the levels
for (let i = 0; i < len; i++) level.difficultyIncrease(game.difficultyMode) for (let i = 0; i < len; i++) level.difficultyIncrease(simulation.difficultyMode)
level.onLevel++; //cycles map to next level level.onLevel++; //cycles map to next level
if (level.onLevel > level.levels.length - 1) level.onLevel = 0; if (level.onLevel > level.levels.length - 1) level.onLevel = 0;
//reset lost mod display //reset lost tech display
for (let i = 0; i < mod.mods.length; i++) { for (let i = 0; i < tech.tech.length; i++) {
if (mod.mods[i].isLost) mod.mods[i].isLost = false; if (tech.tech[i].isLost) tech.tech[i].isLost = false;
} }
mod.isDeathAvoidedThisLevel = false; tech.isDeathAvoidedThisLevel = false;
game.updateModHUD(); simulation.updateModHUD();
game.clearNow = true; //triggers in game.clearMap to remove all physics bodies and setup for new map simulation.clearNow = true; //triggers in simulation.clearMap to remove all physics bodies and setup for new map
}, },
playerExitCheck() { playerExitCheck() {
if ( if (
@@ -4372,7 +4386,7 @@ const level = {
}, },
unit: unitA, unit: unitA,
angle: angleA, angle: angleA,
color: game.draw.mapFill, color: simulation.draw.mapFill,
draw: draw, draw: draw,
query: query, query: query,
lastPortalCycle: 0 lastPortalCycle: 0
@@ -4387,7 +4401,7 @@ const level = {
}, },
unit: unitB, unit: unitB,
angle: angleB, angle: angleB,
color: game.draw.mapFill, color: simulation.draw.mapFill,
draw: draw, draw: draw,
query: query, query: query,
lastPortalCycle: 0, lastPortalCycle: 0,
@@ -4420,13 +4434,13 @@ const level = {
if (damage < 0.02) { if (damage < 0.02) {
mech.damage(damage) mech.damage(damage)
} else if (mech.immuneCycle < mech.cycle) { } else if (mech.immuneCycle < mech.cycle) {
mech.immuneCycle = mech.cycle + mod.collisionImmuneCycles; mech.immuneCycle = mech.cycle + tech.collisionImmuneCycles;
mech.damage(damage) mech.damage(damage)
game.drawList.push({ //add dmg to draw queue simulation.drawList.push({ //add dmg to draw queue
x: player.position.x, x: player.position.x,
y: player.position.y, y: player.position.y,
radius: damage * 1500, radius: damage * 1500,
color: game.mobDmgColor, color: simulation.mobDmgColor,
time: 20 time: 20
}); });
} }

130
js/mob.js
View File

@@ -46,12 +46,12 @@ const mobs = {
statusSlow(who, cycles = 60) { statusSlow(who, cycles = 60) {
applySlow(who) applySlow(who)
//look for mobs near the target //look for mobs near the target
if (mod.isAoESlow) { if (tech.isAoESlow) {
const range = (320 + 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])
} }
game.drawList.push({ simulation.drawList.push({
x: who.position.x, x: who.position.x,
y: who.position.y, y: who.position.y,
radius: Math.sqrt(range), radius: Math.sqrt(range),
@@ -93,7 +93,7 @@ const mobs = {
who.isSlowed = false; who.isSlowed = false;
}, },
type: "slow", type: "slow",
endCycle: game.cycle + cycles, endCycle: simulation.cycle + cycles,
}) })
} }
} }
@@ -145,7 +145,7 @@ const mobs = {
who.isStunned = false who.isStunned = false
}, },
type: "stun", type: "stun",
endCycle: game.cycle + cycles * (who.isBoss ? 0.2 : 1), endCycle: simulation.cycle + cycles * (who.isBoss ? 0.2 : 1),
}) })
} }
}, },
@@ -153,15 +153,15 @@ const mobs = {
if (!who.isShielded && !mech.isBodiesAsleep && who.alive) { if (!who.isShielded && !mech.isBodiesAsleep && who.alive) {
who.status.push({ who.status.push({
effect() { effect() {
if ((game.cycle - this.startCycle) % 30 === 0) { if ((simulation.cycle - this.startCycle) % 30 === 0) {
let dmg = b.dmgScale * this.dmg let dmg = b.dmgScale * this.dmg
who.damage(dmg); who.damage(dmg);
game.drawList.push({ //add dmg to draw queue simulation.drawList.push({ //add dmg to draw queue
x: who.position.x + (Math.random() - 0.5) * who.radius * 0.5, x: who.position.x + (Math.random() - 0.5) * who.radius * 0.5,
y: who.position.y + (Math.random() - 0.5) * who.radius * 0.5, y: who.position.y + (Math.random() - 0.5) * who.radius * 0.5,
radius: Math.log(2 * dmg + 1.1) * 40, radius: Math.log(2 * dmg + 1.1) * 40,
color: "rgba(0,80,80,0.9)", color: "rgba(0,80,80,0.9)",
time: game.drawTime time: simulation.drawTime
}); });
} }
if (true) { if (true) {
@@ -172,8 +172,8 @@ const mobs = {
endEffect() {}, endEffect() {},
dmg: tickDamage, dmg: tickDamage,
type: "dot", type: "dot",
endCycle: game.cycle + cycles, endCycle: simulation.cycle + cycles,
startCycle: game.cycle startCycle: simulation.cycle
}) })
} }
}, },
@@ -186,21 +186,21 @@ const mobs = {
// } // }
// who.status.push({ // who.status.push({
// effect() { // effect() {
// if ((game.cycle - this.startCycle) % 15 === 0) { // if ((simulation.cycle - this.startCycle) % 15 === 0) {
// let dmg = b.dmgScale * tickDamage * 0.5 * (1 + Math.random()) // let dmg = b.dmgScale * tickDamage * 0.5 * (1 + Math.random())
// who.damage(dmg); // who.damage(dmg);
// game.drawList.push({ //add dmg to draw queue // simulation.drawList.push({ //add dmg to draw queue
// x: who.position.x, // x: who.position.x,
// y: who.position.y, // y: who.position.y,
// radius: Math.log(2 * dmg + 1.1) * 40, // radius: Math.log(2 * dmg + 1.1) * 40,
// color: `rgba(255,${Math.floor(200*Math.random())},0,0.9)`, // color: `rgba(255,${Math.floor(200*Math.random())},0,0.9)`,
// time: game.drawTime // time: simulation.drawTime
// }); // });
// } // }
// }, // },
// type: "burn", // type: "burn",
// endCycle: game.cycle + cycles, // endCycle: simulation.cycle + cycles,
// startCycle: game.cycle // startCycle: simulation.cycle
// }) // })
// } // }
// }, // },
@@ -225,9 +225,9 @@ const mobs = {
onHit: undefined, onHit: undefined,
alive: true, alive: true,
index: i, index: i,
health: mod.mobSpawnWithHealth, health: tech.mobSpawnWithHealth,
showHealthBar: true, showHealthBar: true,
accelMag: 0.001 * game.accelScale, accelMag: 0.001 * simulation.accelScale,
cd: 0, //game cycle when cooldown will be over cd: 0, //game cycle when cooldown will be over
delay: 60, //static: time between cooldowns delay: 60, //static: time between cooldowns
fill: color, fill: color,
@@ -250,7 +250,7 @@ const mobs = {
let j = this.status.length; let j = this.status.length;
while (j--) { while (j--) {
this.status[j].effect(); this.status[j].effect();
if (this.status[j].endCycle < game.cycle) { if (this.status[j].endCycle < simulation.cycle) {
this.status[j].endEffect(); this.status[j].endEffect();
this.status.splice(j, 1); this.status.splice(j, 1);
} }
@@ -272,7 +272,7 @@ const mobs = {
gravity() { gravity() {
this.force.y += this.mass * this.g; this.force.y += this.mass * this.g;
}, },
seePlayerFreq: Math.floor((30 + 30 * Math.random()) * game.lookFreqScale), //how often NPC checks to see where player is, lower numbers have better vision seePlayerFreq: Math.floor((30 + 30 * Math.random()) * simulation.lookFreqScale), //how often NPC checks to see where player is, lower numbers have better vision
foundPlayer() { foundPlayer() {
this.locatePlayer(); this.locatePlayer();
if (!this.seePlayer.yes) { if (!this.seePlayer.yes) {
@@ -307,7 +307,7 @@ const mobs = {
} }
}, },
seePlayerCheck() { seePlayerCheck() {
if (!(game.cycle % this.seePlayerFreq)) { if (!(simulation.cycle % this.seePlayerFreq)) {
if ( if (
this.distanceToPlayer2() < this.seeAtDistance2 && this.distanceToPlayer2() < this.seeAtDistance2 &&
Matter.Query.ray(map, this.position, this.mechPosRange()).length === 0 && Matter.Query.ray(map, this.position, this.mechPosRange()).length === 0 &&
@@ -321,7 +321,7 @@ const mobs = {
} }
}, },
seePlayerCheckByDistance() { seePlayerCheckByDistance() {
if (!(game.cycle % this.seePlayerFreq)) { if (!(simulation.cycle % this.seePlayerFreq)) {
if (this.distanceToPlayer2() < this.seeAtDistance2 && !mech.isCloak) { if (this.distanceToPlayer2() < this.seeAtDistance2 && !mech.isCloak) {
this.foundPlayer(); this.foundPlayer();
} else if (this.seePlayer.recall) { } else if (this.seePlayer.recall) {
@@ -330,7 +330,7 @@ const mobs = {
} }
}, },
seePlayerByDistOrLOS() { seePlayerByDistOrLOS() {
if (!(game.cycle % this.seePlayerFreq)) { if (!(simulation.cycle % this.seePlayerFreq)) {
if ( if (
(this.distanceToPlayer2() < this.seeAtDistance2 || (Matter.Query.ray(map, this.position, this.mechPosRange()).length === 0 && Matter.Query.ray(body, this.position, this.mechPosRange()).length === 0)) && (this.distanceToPlayer2() < this.seeAtDistance2 || (Matter.Query.ray(map, this.position, this.mechPosRange()).length === 0 && Matter.Query.ray(body, this.position, this.mechPosRange()).length === 0)) &&
!mech.isCloak !mech.isCloak
@@ -360,7 +360,7 @@ const mobs = {
lookRange: 0.2 + Math.random() * 0.2, lookRange: 0.2 + Math.random() * 0.2,
lookTorque: 0.0000004 * (Math.random() > 0.5 ? -1 : 1), lookTorque: 0.0000004 * (Math.random() > 0.5 ? -1 : 1),
seePlayerByLookingAt() { seePlayerByLookingAt() {
if (!(game.cycle % this.seePlayerFreq) && (this.seePlayer.recall || this.isLookingAtPlayer(this.lookRange))) { if (!(simulation.cycle % this.seePlayerFreq) && (this.seePlayer.recall || this.isLookingAtPlayer(this.lookRange))) {
if ( if (
this.distanceToPlayer2() < this.seeAtDistance2 && this.distanceToPlayer2() < this.seeAtDistance2 &&
Matter.Query.ray(map, this.position, this.mechPosRange()).length === 0 && Matter.Query.ray(map, this.position, this.mechPosRange()).length === 0 &&
@@ -392,7 +392,7 @@ const mobs = {
}, },
// hacked() { //set this.hackedTarget variable before running this method // hacked() { //set this.hackedTarget variable before running this method
// //find a new target // //find a new target
// if (!(game.cycle % this.seePlayerFreq)) { // if (!(simulation.cycle % this.seePlayerFreq)) {
// this.hackedTarget = null // this.hackedTarget = null
// for (let i = 0, len = mob.length; i < len; i++) { // for (let i = 0, len = mob.length; i < len; i++) {
// if (mob[i] !== this) { // if (mob[i] !== this) {
@@ -410,11 +410,11 @@ const mobs = {
// } // }
// }, // },
laserBeam() { laserBeam() {
if (game.cycle % 7 && this.seePlayer.yes) { if (simulation.cycle % 7 && this.seePlayer.yes) {
ctx.setLineDash([125 * Math.random(), 125 * Math.random()]); ctx.setLineDash([125 * Math.random(), 125 * Math.random()]);
// ctx.lineDashOffset = 6*(game.cycle % 215); // ctx.lineDashOffset = 6*(simulation.cycle % 215);
if (this.distanceToPlayer() < this.laserRange) { if (this.distanceToPlayer() < this.laserRange) {
if (mech.immuneCycle < mech.cycle) mech.damage(0.0003 * game.dmgScale); if (mech.immuneCycle < mech.cycle) mech.damage(0.0003 * simulation.dmgScale);
if (mech.energy > 0.1) mech.energy -= 0.003 if (mech.energy > 0.1) mech.energy -= 0.003
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(this.position.x, this.position.y); ctx.moveTo(this.position.x, this.position.y);
@@ -446,7 +446,7 @@ const mobs = {
let vertices = domain[i].vertices; let vertices = domain[i].vertices;
const len = vertices.length - 1; const len = vertices.length - 1;
for (let j = 0; j < len; j++) { for (let j = 0; j < len; j++) {
results = game.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]); results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
if (results.onLine1 && results.onLine2) { if (results.onLine1 && results.onLine2) {
const dx = v1.x - results.x; const dx = v1.x - results.x;
const dy = v1.y - results.y; const dy = v1.y - results.y;
@@ -463,7 +463,7 @@ const mobs = {
} }
} }
} }
results = game.checkLineIntersection(v1, v1End, vertices[0], vertices[len]); results = simulation.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
if (results.onLine1 && results.onLine2) { if (results.onLine1 && results.onLine2) {
const dx = v1.x - results.x; const dx = v1.x - results.x;
const dy = v1.y - results.y; const dy = v1.y - results.y;
@@ -503,7 +503,7 @@ const mobs = {
// hitting player // hitting player
if (best.who === player) { if (best.who === player) {
if (mech.immuneCycle < mech.cycle) { if (mech.immuneCycle < mech.cycle) {
const dmg = 0.0012 * game.dmgScale; const dmg = 0.0012 * simulation.dmgScale;
mech.damage(dmg); mech.damage(dmg);
//draw damage //draw damage
ctx.fillStyle = "#f00"; ctx.fillStyle = "#f00";
@@ -534,7 +534,7 @@ const mobs = {
ctx.fillStyle = "#222"; ctx.fillStyle = "#222";
ctx.fill(); ctx.fill();
if (!(game.cycle % this.seePlayerFreq)) { if (!(simulation.cycle % this.seePlayerFreq)) {
if ( if (
(this.seePlayer.recall || this.isLookingAtPlayer(this.lookRange)) && (this.seePlayer.recall || this.isLookingAtPlayer(this.lookRange)) &&
this.distanceToPlayer2() < this.seeAtDistance2 && this.distanceToPlayer2() < this.seeAtDistance2 &&
@@ -552,7 +552,7 @@ const mobs = {
// set new values of the ends of the spring constraints // set new values of the ends of the spring constraints
const stepRange = 600 const stepRange = 600
if (this.seePlayer.recall && Matter.Query.ray(map, this.position, player.position).length === 0) { if (this.seePlayer.recall && Matter.Query.ray(map, this.position, player.position).length === 0) {
if (!(game.cycle % (this.seePlayerFreq * 2))) { if (!(simulation.cycle % (this.seePlayerFreq * 2))) {
const unit = Vector.normalise(Vector.sub(this.seePlayer.position, this.position)) const unit = Vector.normalise(Vector.sub(this.seePlayer.position, this.position))
const goal = Vector.add(this.position, Vector.mult(unit, stepRange)) const goal = Vector.add(this.position, Vector.mult(unit, stepRange))
this.springTarget.x = goal.x; this.springTarget.x = goal.x;
@@ -561,7 +561,7 @@ const mobs = {
// this.springTarget.y = this.seePlayer.position.y; // this.springTarget.y = this.seePlayer.position.y;
this.cons.length = -200; this.cons.length = -200;
this.cons2.length = 100 + 1.5 * this.radius; this.cons2.length = 100 + 1.5 * this.radius;
} else if (!(game.cycle % this.seePlayerFreq)) { } else if (!(simulation.cycle % this.seePlayerFreq)) {
const unit = Vector.normalise(Vector.sub(this.seePlayer.position, this.position)) const unit = Vector.normalise(Vector.sub(this.seePlayer.position, this.position))
const goal = Vector.add(this.position, Vector.mult(unit, stepRange)) const goal = Vector.add(this.position, Vector.mult(unit, stepRange))
this.springTarget2.x = goal.x; this.springTarget2.x = goal.x;
@@ -586,7 +586,7 @@ const mobs = {
let vertices = domain[i].vertices; let vertices = domain[i].vertices;
const len = vertices.length - 1; const len = vertices.length - 1;
for (let j = 0; j < len; j++) { for (let j = 0; j < len; j++) {
results = game.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]); results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
if (results.onLine1 && results.onLine2) { if (results.onLine1 && results.onLine2) {
const dx = v1.x - results.x; const dx = v1.x - results.x;
const dy = v1.y - results.y; const dy = v1.y - results.y;
@@ -603,7 +603,7 @@ const mobs = {
} }
} }
} }
results = game.checkLineIntersection(v1, v1End, vertices[0], vertices[len]); results = simulation.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
if (results.onLine1 && results.onLine2) { if (results.onLine1 && results.onLine2) {
const dx = v1.x - results.x; const dx = v1.x - results.x;
const dy = v1.y - results.y; const dy = v1.y - results.y;
@@ -622,7 +622,7 @@ const mobs = {
} }
}; };
//move to a random location //move to a random location
if (!(game.cycle % (this.seePlayerFreq * 5))) { if (!(simulation.cycle % (this.seePlayerFreq * 5))) {
best = { best = {
x: null, x: null,
y: null, y: null,
@@ -661,7 +661,7 @@ const mobs = {
x: array[i].velocity.x * 0.94 + curlVector.x * 0.06, x: array[i].velocity.x * 0.94 + curlVector.x * 0.06,
y: array[i].velocity.y * 0.94 + curlVector.y * 0.06 y: array[i].velocity.y * 0.94 + curlVector.y * 0.06
}) })
if (isAntiGravity) array[i].force.y -= 0.8 * game.g * array[i].mass if (isAntiGravity) array[i].force.y -= 0.8 * simulation.g * array[i].mass
// //draw curl, for debugging // //draw curl, for debugging
// ctx.beginPath(); // ctx.beginPath();
// ctx.moveTo(array[i].position.x, array[i].position.y); // ctx.moveTo(array[i].position.x, array[i].position.y);
@@ -687,8 +687,8 @@ const mobs = {
pullPlayer() { pullPlayer() {
if (this.seePlayer.yes && Vector.magnitudeSquared(Vector.sub(this.position, player.position)) < 1000000) { if (this.seePlayer.yes && Vector.magnitudeSquared(Vector.sub(this.position, player.position)) < 1000000) {
const angle = Math.atan2(player.position.y - this.position.y, player.position.x - this.position.x); const angle = Math.atan2(player.position.y - this.position.y, player.position.x - this.position.x);
player.force.x -= game.accelScale * 0.00113 * player.mass * Math.cos(angle) * (mech.onGround ? 2 : 1); player.force.x -= simulation.accelScale * 0.00113 * player.mass * Math.cos(angle) * (mech.onGround ? 2 : 1);
player.force.y -= game.accelScale * 0.00084 * player.mass * Math.sin(angle); player.force.y -= simulation.accelScale * 0.00084 * player.mass * Math.sin(angle);
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(this.position.x, this.position.y); ctx.moveTo(this.position.x, this.position.y);
@@ -715,7 +715,7 @@ const mobs = {
ctx.moveTo(this.position.x, this.position.y); ctx.moveTo(this.position.x, this.position.y);
ctx.lineTo(bullet[i].position.x, bullet[i].position.y); ctx.lineTo(bullet[i].position.x, bullet[i].position.y);
const angle = Math.atan2(dy, dx); const angle = Math.atan2(dy, dx);
const mag = (1500 * bullet[i].mass * game.g) / dist; const mag = (1500 * bullet[i].mass * simulation.g) / dist;
bullet[i].force.x += mag * Math.cos(angle); bullet[i].force.x += mag * Math.cos(angle);
bullet[i].force.y += mag * Math.sin(angle); bullet[i].force.y += mag * Math.sin(angle);
} }
@@ -815,14 +815,14 @@ const mobs = {
newTarget(this); newTarget(this);
} }
//switch to a new target after a while //switch to a new target after a while
if (!(game.cycle % (this.seePlayerFreq * 15))) { if (!(simulation.cycle % (this.seePlayerFreq * 15))) {
newTarget(this); newTarget(this);
} }
} }
}, },
blink() { blink() {
//teleport towards player as a way to move //teleport towards player as a way to move
if (this.seePlayer.recall && !(game.cycle % this.blinkRate)) { if (this.seePlayer.recall && !(simulation.cycle % this.blinkRate)) {
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(this.position.x, this.position.y); ctx.moveTo(this.position.x, this.position.y);
const dist = Vector.sub(this.seePlayer.position, this.position); const dist = Vector.sub(this.seePlayer.position, this.position);
@@ -842,7 +842,7 @@ const mobs = {
}, },
drift() { drift() {
//teleport towards player as a way to move //teleport towards player as a way to move
if (this.seePlayer.recall && !(game.cycle % this.blinkRate)) { if (this.seePlayer.recall && !(simulation.cycle % this.blinkRate)) {
// && !mech.lookingAtMob(this,0.5)){ // && !mech.lookingAtMob(this,0.5)){
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(this.position.x, this.position.y); ctx.moveTo(this.position.x, this.position.y);
@@ -869,7 +869,7 @@ const mobs = {
bomb() { bomb() {
//throw a mob/bullet at player //throw a mob/bullet at player
if ( if (
!(game.cycle % this.fireFreq) && !(simulation.cycle % this.fireFreq) &&
Math.abs(this.position.x - this.seePlayer.position.x) < 400 && //above player Math.abs(this.position.x - this.seePlayer.position.x) < 400 && //above player
Matter.Query.ray(map, this.position, this.mechPosRange()).length === 0 && //see player Matter.Query.ray(map, this.position, this.mechPosRange()).length === 0 && //see player
Matter.Query.ray(body, this.position, this.mechPosRange()).length === 0 Matter.Query.ray(body, this.position, this.mechPosRange()).length === 0
@@ -895,7 +895,7 @@ const mobs = {
//throw a mob/bullet at player //throw a mob/bullet at player
if (this.seePlayer.recall) { if (this.seePlayer.recall) {
//set direction to turn to fire //set direction to turn to fire
if (!(game.cycle % this.seePlayerFreq)) { if (!(simulation.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) / 2500; //gives the bullet an arc //was / 1600 this.fireDir.y -= Math.abs(this.seePlayer.position.x - this.position.x) / 2500; //gives the bullet an arc //was / 1600
} }
@@ -971,7 +971,7 @@ const mobs = {
}, },
explode(mass = this.mass) { explode(mass = this.mass) {
if (mech.immuneCycle < mech.cycle) { if (mech.immuneCycle < mech.cycle) {
mech.damage(Math.min(Math.max(0.02 * Math.sqrt(mass), 0.01), 0.35) * game.dmgScale); mech.damage(Math.min(Math.max(0.02 * Math.sqrt(mass), 0.01), 0.35) * simulation.dmgScale);
this.dropPowerUp = false; this.dropPowerUp = false;
this.death(); //death with no power up or body this.death(); //death with no power up or body
} }
@@ -999,18 +999,18 @@ const mobs = {
}, },
damage(dmg, isBypassShield = false) { damage(dmg, isBypassShield = false) {
if ((!this.isShielded || isBypassShield) && this.alive) { if ((!this.isShielded || isBypassShield) && this.alive) {
dmg *= mod.damageFromMods() dmg *= tech.damageFromMods()
//mobs specific damage changes //mobs specific damage changes
if (mod.isFarAwayDmg) dmg *= 1 + Math.sqrt(Math.max(500, Math.min(3000, this.distanceToPlayer())) - 500) * 0.0067 //up to 50% dmg at max range of 3500 if (tech.isFarAwayDmg) dmg *= 1 + Math.sqrt(Math.max(500, Math.min(3000, this.distanceToPlayer())) - 500) * 0.0067 //up to 50% dmg at max range of 3500
if (this.shield) dmg *= 0.075 if (this.shield) dmg *= 0.075
//energy and heal drain should be calculated after damage boosts //energy and heal drain should be calculated after damage boosts
if (mod.energySiphon && dmg !== Infinity && this.dropPowerUp) { if (tech.energySiphon && dmg !== Infinity && this.dropPowerUp) {
mech.energy += Math.min(this.health, dmg) * mod.energySiphon mech.energy += Math.min(this.health, dmg) * tech.energySiphon
// if (mech.energy > mech.maxEnergy) mech.energy = mech.maxEnergy // if (mech.energy > mech.maxEnergy) mech.energy = mech.maxEnergy
} }
if (mod.healthDrain && dmg !== Infinity && this.dropPowerUp) { if (tech.healthDrain && dmg !== Infinity && this.dropPowerUp) {
mech.addHealth(Math.min(this.health, dmg) * mod.healthDrain) mech.addHealth(Math.min(this.health, dmg) * tech.healthDrain)
if (mech.health > mech.maxHealth) mech.health = mech.maxHealth if (mech.health > mech.maxHealth) mech.health = mech.maxHealth
} }
dmg /= Math.sqrt(this.mass) dmg /= Math.sqrt(this.mass)
@@ -1035,40 +1035,40 @@ const mobs = {
this.removeConsBB(); this.removeConsBB();
this.alive = false; //triggers mob removal in mob[i].replace(i) this.alive = false; //triggers mob removal in mob[i].replace(i)
if (this.dropPowerUp) { if (this.dropPowerUp) {
if (mod.isEnergyLoss) mech.energy *= 0.75; if (tech.isEnergyLoss) mech.energy *= 0.75;
powerUps.spawnRandomPowerUp(this.position.x, this.position.y); powerUps.spawnRandomPowerUp(this.position.x, this.position.y);
mech.lastKillCycle = mech.cycle; //tracks the last time a kill was made, mostly used in game.checks() mech.lastKillCycle = mech.cycle; //tracks the last time a kill was made, mostly used in simulation.checks()
if (Math.random() < mod.sporesOnDeath) { if (Math.random() < tech.sporesOnDeath) {
const len = Math.min(25, Math.floor(2 + this.mass * (0.5 + 0.5 * Math.random()))) const len = Math.min(25, Math.floor(2 + this.mass * (0.5 + 0.5 * Math.random())))
for (let i = 0; i < len; i++) { for (let i = 0; i < len; i++) {
b.spore(this.position) b.spore(this.position)
} }
} else if (mod.isExplodeMob) { } else if (tech.isExplodeMob) {
b.explosion(this.position, Math.min(600, Math.sqrt(this.mass + 2.75) * 55)) b.explosion(this.position, Math.min(600, Math.sqrt(this.mass + 2.75) * 55))
} else if (mod.nailsDeathMob) { } else if (tech.nailsDeathMob) {
b.targetedNail(this.position, mod.nailsDeathMob, 39 + 6 * Math.random()) b.targetedNail(this.position, tech.nailsDeathMob, 39 + 6 * Math.random())
} }
if (Math.random() < mod.isBotSpawner) { if (Math.random() < tech.isBotSpawner) {
b.randomBot(this.position, false) b.randomBot(this.position, false)
bullet[bullet.length - 1].endCycle = game.cycle + 1000 + Math.floor(400 * Math.random()) bullet[bullet.length - 1].endCycle = simulation.cycle + 1000 + Math.floor(400 * Math.random())
this.leaveBody = false; // no body since it turned into the bot this.leaveBody = false; // no body since it turned into the bot
} }
} else if (mod.isShieldAmmo && this.shield) { } else if (tech.isShieldAmmo && this.shield) {
let type = mod.isEnergyNoAmmo ? "heal" : "ammo" let type = tech.isEnergyNoAmmo ? "heal" : "ammo"
if (Math.random() < 0.4) { if (Math.random() < 0.4) {
type = "heal" type = "heal"
} else if (Math.random() < 0.3 && !mod.isSuperDeterminism) { } else if (Math.random() < 0.3 && !tech.isSuperDeterminism) {
type = "reroll" type = "reroll"
} }
for (let i = 0, len = Math.ceil(2 * Math.random()); i < len; i++) { for (let i = 0, len = Math.ceil(2 * Math.random()); i < len; i++) {
powerUps.spawn(this.position.x, this.position.y, type); powerUps.spawn(this.position.x, this.position.y, type);
} }
} }
if (mod.isRadioactive) { if (tech.isRadioactive) {
//look for dots and spread them //look for dots and spread them
let dmgTotal = 0 let dmgTotal = 0
for (let i = 0, len = this.status.length; i < len; i++) { for (let i = 0, len = this.status.length; i < len; i++) {
if (this.status[i].type === "dot") dmgTotal += this.status[i].dmg * (this.status[i].endCycle - game.cycle) if (this.status[i].type === "dot") dmgTotal += this.status[i].dmg * (this.status[i].endCycle - simulation.cycle)
} }
if (dmgTotal > 0) { //look for closest mob if (dmgTotal > 0) { //look for closest mob
let closestRadius = 500; let closestRadius = 500;
@@ -1090,7 +1090,7 @@ const mobs = {
ctx.stroke(); ctx.stroke();
} }
//draw AOE //draw AOE
// game.drawList.push({ //add dmg to draw queue // simulation.drawList.push({ //add dmg to draw queue
// x: this.position.x, // x: this.position.x,
// y: this.position.y, // y: this.position.y,
// radius: radius, // radius: radius,

View File

@@ -80,8 +80,8 @@ const mech = {
Fx: 0.016, //run Force on ground // Fx: 0.016, //run Force on ground //
jumpForce: 0.42, jumpForce: 0.42,
setMovement() { setMovement() {
mech.Fx = 0.016 * mod.squirrelFx * mod.fastTime; mech.Fx = 0.016 * tech.squirrelFx * tech.fastTime;
mech.jumpForce = 0.42 * mod.squirrelJump * mod.fastTimeJump; mech.jumpForce = 0.42 * tech.squirrelJump * tech.fastTimeJump;
}, },
FxAir: 0.016, // 0.4/5/5 run Force in Air FxAir: 0.016, // 0.4/5/5 run Force in Air
yOff: 70, yOff: 70,
@@ -184,13 +184,13 @@ const mech = {
look() { look() {
//always on mouse look //always on mouse look
mech.angle = Math.atan2( mech.angle = Math.atan2(
game.mouseInGame.y - mech.pos.y, simulation.mouseInGame.y - mech.pos.y,
game.mouseInGame.x - mech.pos.x simulation.mouseInGame.x - mech.pos.x
); );
//smoothed mouse look translations //smoothed mouse look translations
const scale = 0.8; const scale = 0.8;
mech.transSmoothX = canvas.width2 - mech.pos.x - (game.mouse.x - canvas.width2) * scale; mech.transSmoothX = canvas.width2 - mech.pos.x - (simulation.mouse.x - canvas.width2) * scale;
mech.transSmoothY = canvas.height2 - mech.pos.y - (game.mouse.y - canvas.height2) * scale; mech.transSmoothY = canvas.height2 - mech.pos.y - (simulation.mouse.y - canvas.height2) * scale;
mech.transX += (mech.transSmoothX - mech.transX) * 0.07; mech.transX += (mech.transSmoothX - mech.transX) * 0.07;
mech.transY += (mech.transSmoothY - mech.transY) * 0.07; mech.transY += (mech.transSmoothY - mech.transY) * 0.07;
@@ -324,38 +324,39 @@ const mech = {
}, },
alive: false, alive: false,
death() { death() {
if (mod.isImmortal) { //if player has the immortality buff, spawn on the same level with randomized damage if (tech.isImmortal) { //if player has the immortality buff, spawn on the same level with randomized damage
//count mods simulation.isTextLogOpen = false;
//count tech
let totalMods = 0; let totalMods = 0;
for (let i = 0; i < mod.mods.length; i++) { for (let i = 0; i < tech.tech.length; i++) {
if (!mod.mods[i].isNonRefundable) totalMods += mod.mods[i].count if (!tech.tech[i].isNonRefundable) totalMods += tech.tech[i].count
} }
if (mod.isDeterminism) totalMods -= 3 //remove the bonus mods if (tech.isDeterminism) totalMods -= 3 //remove the bonus tech
if (mod.isSuperDeterminism) totalMods -= 2 //remove the bonus mods if (tech.isSuperDeterminism) totalMods -= 2 //remove the bonus tech
totalMods = totalMods * 1.15 + 1 // a few extra to make it stronger totalMods = totalMods * 1.15 + 1 // a few extra to make it stronger
const totalGuns = b.inventory.length //count guns const totalGuns = b.inventory.length //count guns
function randomizeMods() { function randomizeMods() {
for (let i = 0; i < totalMods; i++) { for (let i = 0; i < totalMods; i++) {
//find what mods I don't have //find what tech I don't have
let options = []; let options = [];
for (let i = 0, len = mod.mods.length; i < len; i++) { for (let i = 0, len = tech.tech.length; i < len; i++) {
if (mod.mods[i].count < mod.mods[i].maxCount && if (tech.tech[i].count < tech.tech[i].maxCount &&
!mod.mods[i].isNonRefundable && !tech.tech[i].isNonRefundable &&
mod.mods[i].name !== "quantum immortality" && tech.tech[i].name !== "quantum immortality" &&
mod.mods[i].name !== "Born rule" && tech.tech[i].name !== "Born rule" &&
mod.mods[i].allowed() tech.tech[i].allowed()
) options.push(i); ) options.push(i);
} }
//add a new mod //add a new tech
if (options.length > 0) { if (options.length > 0) {
const choose = Math.floor(Math.random() * options.length) const choose = Math.floor(Math.random() * options.length)
let newMod = options[choose] let newMod = options[choose]
mod.giveMod(newMod) tech.giveMod(newMod)
options.splice(choose, 1); options.splice(choose, 1);
} }
} }
game.updateModHUD(); simulation.updateModHUD();
} }
function randomizeField() { function randomizeField() {
@@ -385,19 +386,19 @@ const mech = {
b.guns[b.inventory[i]].ammo = Math.max(0, Math.floor(6 * b.guns[b.inventory[i]].ammo * Math.sqrt(Math.random()))) b.guns[b.inventory[i]].ammo = Math.max(0, Math.floor(6 * b.guns[b.inventory[i]].ammo * Math.sqrt(Math.random())))
} }
} }
game.makeGunHUD(); //update gun HUD simulation.makeGunHUD(); //update gun HUD
} }
game.wipe = function() { //set wipe to have trails simulation.wipe = function() { //set wipe to have trails
ctx.fillStyle = "rgba(255,255,255,0)"; ctx.fillStyle = "rgba(255,255,255,0)";
ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillRect(0, 0, canvas.width, canvas.height);
} }
function randomizeEverything() { function randomizeEverything() {
spawn.setSpawnList(); //new mob types spawn.setSpawnList(); //new mob types
game.clearNow = true; //triggers a map reset simulation.clearNow = true; //triggers a map reset
mod.setupAllMods(); //remove all mods tech.setupAllMods(); //remove all tech
for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]); for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]);
bullet = []; //remove all bullets bullet = []; //remove all bullets
randomizeHealth() randomizeHealth()
@@ -411,9 +412,10 @@ const mech = {
for (let i = 0, len = 5; i < len; i++) { for (let i = 0, len = 5; i < len; i++) {
setTimeout(function() { setTimeout(function() {
randomizeEverything() randomizeEverything()
game.replaceTextLog = true; simulation.isTextLogOpen = true;
game.makeTextLog(`probability amplitude will synchronize in ${len-i-1} seconds`, swapPeriod); simulation.makeTextLog(`simulation.amplitude <span class='color-symbol'>=</span> 0.${len-i-1}`, swapPeriod);
game.wipe = function() { //set wipe to have trails simulation.isTextLogOpen = false;
simulation.wipe = function() { //set wipe to have trails
ctx.fillStyle = `rgba(255,255,255,${(i+1)*(i+1)*0.006})`; ctx.fillStyle = `rgba(255,255,255,${(i+1)*(i+1)*0.006})`;
ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillRect(0, 0, canvas.width, canvas.height);
// pixelWindows() // pixelWindows()
@@ -422,16 +424,17 @@ const mech = {
} }
setTimeout(function() { setTimeout(function() {
game.wipe = function() { //set wipe to normal simulation.wipe = function() { //set wipe to normal
ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.clearRect(0, 0, canvas.width, canvas.height);
} }
game.replaceTextLog = true; simulation.isTextLogOpen = true;
game.makeTextLog("your quantum probability has stabilized", 1000); simulation.makeTextLog("simulation.amplitude <span class='color-symbol'>=</span> null");
}, 6 * swapPeriod); }, 6 * swapPeriod);
} else if (mech.alive) { //normal death code here } else if (mech.alive) { //normal death code here
mech.alive = false; mech.alive = false;
game.paused = true; simulation.paused = true;
mech.health = 0; mech.health = 0;
mech.displayHealth(); mech.displayHealth();
document.getElementById("text-log").style.opacity = 0; //fade out any active text logs document.getElementById("text-log").style.opacity = 0; //fade out any active text logs
@@ -440,12 +443,12 @@ const mech = {
setTimeout(function() { setTimeout(function() {
World.clear(engine.world); World.clear(engine.world);
Engine.clear(engine); Engine.clear(engine);
game.splashReturn(); simulation.splashReturn();
}, 3000); }, 3000);
} }
}, },
health: 0, health: 0,
maxHealth: 1, //set in game.reset() maxHealth: 1, //set in simulation.reset()
drawHealth() { drawHealth() {
if (mech.health < 1) { if (mech.health < 1) {
ctx.fillStyle = "rgba(100, 100, 100, 0.5)"; ctx.fillStyle = "rgba(100, 100, 100, 0.5)";
@@ -471,15 +474,15 @@ const mech = {
} }
}, },
addHealth(heal) { addHealth(heal) {
if (!mod.isEnergyHealth) { if (!tech.isEnergyHealth) {
mech.health += heal * game.healScale; mech.health += heal * simulation.healScale;
if (mech.health > mech.maxHealth) mech.health = mech.maxHealth; if (mech.health > mech.maxHealth) mech.health = mech.maxHealth;
mech.displayHealth(); mech.displayHealth();
} }
}, },
baseHealth: 1, baseHealth: 1,
setMaxHealth() { setMaxHealth() {
mech.maxHealth = mech.baseHealth + mod.bonusHealth + mod.armorFromPowerUps mech.maxHealth = mech.baseHealth + tech.bonusHealth + tech.armorFromPowerUps
if (mech.health > mech.maxHealth) mech.health = mech.maxHealth; if (mech.health > mech.maxHealth) mech.health = mech.maxHealth;
mech.displayHealth(); mech.displayHealth();
}, },
@@ -489,33 +492,33 @@ const mech = {
harmReduction() { harmReduction() {
let dmg = 1 let dmg = 1
dmg *= mech.fieldHarmReduction dmg *= mech.fieldHarmReduction
if (mod.isSpeedHarm) dmg *= 1 - Math.min(player.speed * 0.0185, 0.55) if (tech.isSpeedHarm) dmg *= 1 - Math.min(player.speed * 0.0185, 0.55)
if (mod.isSlowFPS) dmg *= 0.85 if (tech.isSlowFPS) dmg *= 0.85
if (mod.isPiezo) dmg *= 0.85 if (tech.isPiezo) dmg *= 0.85
if (mod.isHarmReduce && mech.fieldUpgrades[mech.fieldMode].name === "negative mass field" && mech.isFieldActive) dmg *= 0.6 if (tech.isHarmReduce && mech.fieldUpgrades[mech.fieldMode].name === "negative mass field" && mech.isFieldActive) dmg *= 0.6
if (mod.isBotArmor) dmg *= 0.97 ** mod.totalBots() if (tech.isBotArmor) dmg *= 0.97 ** tech.totalBots()
if (mod.isHarmArmor && mech.lastHarmCycle + 600 > mech.cycle) dmg *= 0.33; if (tech.isHarmArmor && mech.lastHarmCycle + 600 > mech.cycle) dmg *= 0.33;
if (mod.isNoFireDefense && mech.cycle > mech.fireCDcycle + 120) dmg *= 0.6 if (tech.isNoFireDefense && mech.cycle > mech.fireCDcycle + 120) dmg *= 0.6
if (mod.energyRegen === 0) dmg *= 0.4 if (tech.energyRegen === 0) dmg *= 0.4
if (mod.isTurret && mech.crouch) dmg *= 0.5; if (tech.isTurret && mech.crouch) dmg *= 0.5;
if (mod.isEntanglement && b.inventory[0] === b.activeGun) { if (tech.isEntanglement && b.inventory[0] === b.activeGun) {
for (let i = 0, len = b.inventory.length; i < len; i++) dmg *= 0.87 // 1 - 0.15 for (let i = 0, len = b.inventory.length; i < len; i++) dmg *= 0.87 // 1 - 0.15
} }
return dmg return dmg
}, },
rewind(steps) { // mech.rewind(Math.floor(Math.min(599, 137 * mech.energy))) rewind(steps) { // mech.rewind(Math.floor(Math.min(599, 137 * mech.energy)))
if (mod.isRewindGrenade) { if (tech.isRewindGrenade) {
for (let i = 1, len = Math.floor(2 + steps / 40); i < len; i++) { for (let i = 1, len = Math.floor(2 + steps / 40); i < len; i++) {
b.grenade(Vector.add(mech.pos, { x: 10 * (Math.random() - 0.5), y: 10 * (Math.random() - 0.5) }), -i * Math.PI / len) //fire different angles for each grenade b.grenade(Vector.add(mech.pos, { x: 10 * (Math.random() - 0.5), y: 10 * (Math.random() - 0.5) }), -i * Math.PI / len) //fire different angles for each grenade
const who = bullet[bullet.length - 1] const who = bullet[bullet.length - 1]
if (mod.isVacuumBomb) { if (tech.isVacuumBomb) {
Matter.Body.setVelocity(who, { Matter.Body.setVelocity(who, {
x: who.velocity.x * 0.5, x: who.velocity.x * 0.5,
y: who.velocity.y * 0.5 y: who.velocity.y * 0.5
}); });
} else if (mod.isRPG) { } else if (tech.isRPG) {
who.endCycle = (who.endCycle - game.cycle) * 0.2 + game.cycle who.endCycle = (who.endCycle - simulation.cycle) * 0.2 + simulation.cycle
} else if (mod.isNeutronBomb) { } else if (tech.isNeutronBomb) {
Matter.Body.setVelocity(who, { Matter.Body.setVelocity(who, {
x: who.velocity.x * 0.3, x: who.velocity.x * 0.3,
y: who.velocity.y * 0.3 y: who.velocity.y * 0.3
@@ -525,19 +528,21 @@ const mech = {
x: who.velocity.x * 0.5, x: who.velocity.x * 0.5,
y: who.velocity.y * 0.5 y: who.velocity.y * 0.5
}); });
who.endCycle = (who.endCycle - game.cycle) * 0.5 + game.cycle who.endCycle = (who.endCycle - simulation.cycle) * 0.5 + simulation.cycle
} }
} }
} }
let history = mech.history[(mech.cycle - steps) % 600] let history = mech.history[(mech.cycle - steps) % 600]
Matter.Body.setPosition(player, history.position); Matter.Body.setPosition(player, history.position);
Matter.Body.setVelocity(player, { x: history.velocity.x, y: history.velocity.y }); Matter.Body.setVelocity(player, { x: history.velocity.x, y: history.velocity.y });
b.activeGun = history.activeGun
for (let i = 0; i < b.inventory.length; i++) { // b.activeGun = history.activeGun
if (b.inventory[i] === b.activeGun) b.inventoryGun = i // for (let i = 0; i < b.inventory.length; i++) {
} // if (b.inventory[i] === b.activeGun) b.inventoryGun = i
game.updateGunHUD(); // }
game.boldActiveGunHUD(); // simulation.updateGunHUD();
// simulation.boldActiveGunHUD();
// 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].botType) { if (bullet[i].botType) {
@@ -557,8 +562,8 @@ const mech = {
let isDrawPlayer = true let isDrawPlayer = true
const shortPause = function() { const shortPause = function() {
if (mech.defaultFPSCycle < mech.cycle) { //back to default values if (mech.defaultFPSCycle < mech.cycle) { //back to default values
game.fpsCap = game.fpsCapDefault simulation.fpsCap = simulation.fpsCapDefault
game.fpsInterval = 1000 / game.fpsCap; simulation.fpsInterval = 1000 / simulation.fpsCap;
document.getElementById("dmg").style.transition = "opacity 1s"; document.getElementById("dmg").style.transition = "opacity 1s";
document.getElementById("dmg").style.opacity = "0"; document.getElementById("dmg").style.opacity = "0";
} else { } else {
@@ -567,7 +572,7 @@ const mech = {
isDrawPlayer = false isDrawPlayer = false
ctx.save(); ctx.save();
ctx.translate(canvas.width2, canvas.height2); //center ctx.translate(canvas.width2, canvas.height2); //center
ctx.scale(game.zoom / game.edgeZoomOutSmooth, game.zoom / game.edgeZoomOutSmooth); //zoom in once centered ctx.scale(simulation.zoom / simulation.edgeZoomOutSmooth, simulation.zoom / simulation.edgeZoomOutSmooth); //zoom in once centered
ctx.translate(-canvas.width2 + mech.transX, -canvas.height2 + mech.transY); //translate ctx.translate(-canvas.width2 + mech.transX, -canvas.height2 + mech.transY); //translate
for (let i = 1; i < steps; i++) { for (let i = 1; i < steps; i++) {
history = mech.history[(mech.cycle - i) % 600] history = mech.history[(mech.cycle - i) % 600]
@@ -582,52 +587,53 @@ const mech = {
}; };
if (mech.defaultFPSCycle < mech.cycle) requestAnimationFrame(shortPause); if (mech.defaultFPSCycle < mech.cycle) requestAnimationFrame(shortPause);
game.fpsCap = 3 //1 is longest pause, 4 is standard simulation.fpsCap = 3 //1 is longest pause, 4 is standard
game.fpsInterval = 1000 / game.fpsCap; simulation.fpsInterval = 1000 / simulation.fpsCap;
mech.defaultFPSCycle = mech.cycle mech.defaultFPSCycle = mech.cycle
if (mod.isRewindBot) { if (tech.isRewindBot) {
const len = steps * 0.042 * mod.isRewindBot const len = steps * 0.042 * tech.isRewindBot
for (let i = 0; i < len; i++) { for (let i = 0; i < len; i++) {
const where = mech.history[Math.abs(mech.cycle - i * 40) % 600].position //spread out spawn locations along past history const where = mech.history[Math.abs(mech.cycle - i * 40) % 600].position //spread out spawn locations along past history
b.randomBot({ b.randomBot({
x: where.x + 100 * (Math.random() - 0.5), x: where.x + 100 * (Math.random() - 0.5),
y: where.y + 100 * (Math.random() - 0.5) y: where.y + 100 * (Math.random() - 0.5)
}, false, false) }, false, false)
bullet[bullet.length - 1].endCycle = game.cycle + 360 + Math.floor(180 * Math.random()) //6-9 seconds bullet[bullet.length - 1].endCycle = simulation.cycle + 360 + Math.floor(180 * Math.random()) //6-9 seconds
} }
} }
}, },
damage(dmg) { damage(dmg) {
if (mod.isRewindAvoidDeath && mech.energy > 0.66) { if (tech.isRewindAvoidDeath && mech.energy > 0.66) {
mech.rewind(Math.floor(Math.min(299, 137 * mech.energy))) mech.rewind(Math.floor(Math.min(299, 137 * mech.energy)))
return return
} }
mech.lastHarmCycle = mech.cycle mech.lastHarmCycle = mech.cycle
if (mod.isDroneOnDamage) { //chance to build a drone on damage from mod if (tech.isDroneOnDamage) { //chance to build a drone on damage from tech
const len = Math.min((dmg - 0.06 * Math.random()) * 40, 40) const len = Math.min((dmg - 0.06 * Math.random()) * 40, 40)
for (let i = 0; i < len; i++) { for (let i = 0; i < len; i++) {
if (Math.random() < 0.5) b.drone() //spawn drone if (Math.random() < 0.5) b.drone() //spawn drone
} }
} }
if (mod.isEnergyHealth) { if (tech.isEnergyHealth) {
mech.energy -= dmg; mech.energy -= dmg;
if (mech.energy < 0 || isNaN(mech.energy)) { //taking deadly damage if (mech.energy < 0 || isNaN(mech.energy)) { //taking deadly damage
if (mod.isDeathAvoid && powerUps.reroll.rerolls && !mod.isDeathAvoidedThisLevel) { if (tech.isDeathAvoid && powerUps.reroll.rerolls && !tech.isDeathAvoidedThisLevel) {
mod.isDeathAvoidedThisLevel = true tech.isDeathAvoidedThisLevel = true
powerUps.reroll.changeRerolls(-1) powerUps.reroll.changeRerolls(-1)
game.makeTextLog(`<span style='font-size:115%;'> <strong>death</strong> avoided<br><strong>${powerUps.reroll.rerolls}</strong> <strong class='color-r'>rerolls</strong> left</span>`, 420) simulation.makeTextLog(`<span class='color-var'>mech</span>.<span class='color-r'>rerolls</span><span class='color-symbol'>--</span>
<br>${powerUps.reroll.rerolls}`)
for (let i = 0; i < 6; i++) { for (let i = 0; i < 6; i++) {
powerUps.spawn(mech.pos.x, mech.pos.y, "heal", false); powerUps.spawn(mech.pos.x, mech.pos.y, "heal", false);
} }
mech.energy = mech.maxEnergy mech.energy = mech.maxEnergy
mech.immuneCycle = mech.cycle + 360 //disable this.immuneCycle bonus seconds mech.immuneCycle = mech.cycle + 360 //disable this.immuneCycle bonus seconds
game.wipe = function() { //set wipe to have trails simulation.wipe = function() { //set wipe to have trails
ctx.fillStyle = "rgba(255,255,255,0.03)"; ctx.fillStyle = "rgba(255,255,255,0.03)";
ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillRect(0, 0, canvas.width, canvas.height);
} }
setTimeout(function() { setTimeout(function() {
game.wipe = function() { //set wipe to normal simulation.wipe = function() { //set wipe to normal
ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.clearRect(0, 0, canvas.width, canvas.height);
} }
}, 3000); }, 3000);
@@ -643,23 +649,22 @@ const mech = {
dmg *= mech.harmReduction() dmg *= mech.harmReduction()
mech.health -= dmg; mech.health -= dmg;
if (mech.health < 0 || isNaN(mech.health)) { if (mech.health < 0 || isNaN(mech.health)) {
if (mod.isDeathAvoid && powerUps.reroll.rerolls > 0 && !mod.isDeathAvoidedThisLevel) { //&& Math.random() < 0.5 if (tech.isDeathAvoid && powerUps.reroll.rerolls > 0 && !tech.isDeathAvoidedThisLevel) { //&& Math.random() < 0.5
mod.isDeathAvoidedThisLevel = true tech.isDeathAvoidedThisLevel = true
mech.health = 0.05 mech.health = 0.05
powerUps.reroll.changeRerolls(-1) powerUps.reroll.changeRerolls(-1)
game.makeTextLog(`<span style='font-size:115%;'> <strong>death</strong> avoided<br><strong>${powerUps.reroll.rerolls}</strong> <strong class='color-r'>rerolls</strong> left</span>`, 420) simulation.makeTextLog(`<span class='color-var'>mech</span>.<span class='color-r'>rerolls</span><span class='color-symbol'>--</span>
<br>${powerUps.reroll.rerolls}`)
for (let i = 0; i < 6; i++) { for (let i = 0; i < 6; i++) {
powerUps.spawn(mech.pos.x, mech.pos.y, "heal", false); powerUps.spawn(mech.pos.x, mech.pos.y, "heal", false);
} }
mech.immuneCycle = mech.cycle + 360 //disable this.immuneCycle bonus seconds mech.immuneCycle = mech.cycle + 360 //disable this.immuneCycle bonus seconds
// game.makeTextLog("<span style='font-size:115%;'> <strong>death</strong> avoided<br><strong>1</strong> <strong class='color-r'>reroll</strong> consumed</span>", 420) simulation.wipe = function() { //set wipe to have trails
game.wipe = function() { //set wipe to have trails
ctx.fillStyle = "rgba(255,255,255,0.03)"; ctx.fillStyle = "rgba(255,255,255,0.03)";
ctx.fillRect(0, 0, canvas.width, canvas.height); ctx.fillRect(0, 0, canvas.width, canvas.height);
} }
setTimeout(function() { setTimeout(function() {
game.wipe = function() { //set wipe to normal simulation.wipe = function() { //set wipe to normal
ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.clearRect(0, 0, canvas.width, canvas.height);
} }
}, 3000); }, 3000);
@@ -677,8 +682,8 @@ const mech = {
if (dmg > 0.06 / mech.holdingMassScale) mech.drop(); //drop block if holding if (dmg > 0.06 / mech.holdingMassScale) mech.drop(); //drop block if holding
const normalFPS = function() { const normalFPS = function() {
if (mech.defaultFPSCycle < mech.cycle) { //back to default values if (mech.defaultFPSCycle < mech.cycle) { //back to default values
game.fpsCap = game.fpsCapDefault simulation.fpsCap = simulation.fpsCapDefault
game.fpsInterval = 1000 / game.fpsCap; simulation.fpsInterval = 1000 / simulation.fpsCap;
document.getElementById("dmg").style.transition = "opacity 1s"; document.getElementById("dmg").style.transition = "opacity 1s";
document.getElementById("dmg").style.opacity = "0"; document.getElementById("dmg").style.opacity = "0";
} else { } else {
@@ -687,23 +692,23 @@ const mech = {
}; };
if (mech.defaultFPSCycle < mech.cycle) requestAnimationFrame(normalFPS); if (mech.defaultFPSCycle < mech.cycle) requestAnimationFrame(normalFPS);
if (mod.isSlowFPS) { // slow game if (tech.isSlowFPS) { // slow game
game.fpsCap = 30 //new fps simulation.fpsCap = 30 //new fps
game.fpsInterval = 1000 / game.fpsCap; simulation.fpsInterval = 1000 / simulation.fpsCap;
//how long to wait to return to normal fps //how long to wait to return to normal fps
mech.defaultFPSCycle = mech.cycle + 20 + Math.min(90, Math.floor(200 * dmg)) mech.defaultFPSCycle = mech.cycle + 20 + Math.min(90, Math.floor(200 * dmg))
if (mod.isHarmFreeze) { //freeze all mobs if (tech.isHarmFreeze) { //freeze all mobs
for (let i = 0, len = mob.length; i < len; i++) { for (let i = 0, len = mob.length; i < len; i++) {
mobs.statusSlow(mob[i], 300) mobs.statusSlow(mob[i], 300)
} }
} }
} else { } else {
if (dmg > 0.05) { // freeze game for high damage hits if (dmg > 0.05) { // freeze game for high damage hits
game.fpsCap = 4 //40 - Math.min(25, 100 * dmg) simulation.fpsCap = 4 //40 - Math.min(25, 100 * dmg)
game.fpsInterval = 1000 / game.fpsCap; simulation.fpsInterval = 1000 / simulation.fpsCap;
} else { } else {
game.fpsCap = game.fpsCapDefault simulation.fpsCap = simulation.fpsCapDefault
game.fpsInterval = 1000 / game.fpsCap; simulation.fpsInterval = 1000 / simulation.fpsCap;
} }
mech.defaultFPSCycle = mech.cycle mech.defaultFPSCycle = mech.cycle
} }
@@ -718,7 +723,7 @@ const mech = {
}, },
buttonCD: 0, //cool down for player buttons buttonCD: 0, //cool down for player buttons
drawLeg(stroke) { drawLeg(stroke) {
// if (game.mouseInGame.x > mech.pos.x) { // if (simulation.mouseInGame.x > mech.pos.x) {
if (mech.angle > -Math.PI / 2 && mech.angle < Math.PI / 2) { if (mech.angle > -Math.PI / 2 && mech.angle < Math.PI / 2) {
mech.flipLegs = 1; mech.flipLegs = 1;
} else { } else {
@@ -822,7 +827,7 @@ const mech = {
fireCDcycle: 0, fireCDcycle: 0,
fieldCDcycle: 0, fieldCDcycle: 0,
fieldMode: 0, //basic field mode before upgrades fieldMode: 0, //basic field mode before upgrades
maxEnergy: 1, //can be increased by a mod maxEnergy: 1, //can be increased by a tech
holdingTarget: null, holdingTarget: null,
timeSkipLastCycle: 0, timeSkipLastCycle: 0,
// these values are set on reset by setHoldDefaults() // these values are set on reset by setHoldDefaults()
@@ -857,14 +862,14 @@ const mech = {
}, },
setHoldDefaults() { setHoldDefaults() {
if (mech.energy < mech.maxEnergy) mech.energy = mech.maxEnergy; if (mech.energy < mech.maxEnergy) mech.energy = mech.maxEnergy;
mech.fieldRegen = mod.energyRegen; //0.001 mech.fieldRegen = tech.energyRegen; //0.001
mech.fieldMeterColor = "#0cf" mech.fieldMeterColor = "#0cf"
mech.fieldShieldingScale = 1; mech.fieldShieldingScale = 1;
mech.fieldBlockCD = 10; mech.fieldBlockCD = 10;
mech.fieldHarmReduction = 1; mech.fieldHarmReduction = 1;
mech.fieldDamage = 1 mech.fieldDamage = 1
mech.duplicateChance = 0 mech.duplicateChance = 0
if (mod.duplicationChance() === 0) game.draw.powerUp = game.draw.powerUpNormal if (tech.duplicationChance() === 0) simulation.draw.powerUp = simulation.draw.powerUpNormal
mech.grabPowerUpRange2 = 156000; mech.grabPowerUpRange2 = 156000;
mech.fieldRange = 155; mech.fieldRange = 155;
mech.fieldFire = false; mech.fieldFire = false;
@@ -894,7 +899,7 @@ const mech = {
} }
}, },
setMaxEnergy() { setMaxEnergy() {
mech.maxEnergy = (mod.isMaxEnergyMod ? 0.5 : 1) + mod.bonusEnergy + mod.healMaxEnergyBonus mech.maxEnergy = (tech.isMaxEnergyMod ? 0.5 : 1) + tech.bonusEnergy + tech.healMaxEnergyBonus
}, },
fieldMeterColor: "#0cf", fieldMeterColor: "#0cf",
drawFieldMeter(bgColor = "rgba(0, 0, 0, 0.4)", range = 60) { drawFieldMeter(bgColor = "rgba(0, 0, 0, 0.4)", range = 60) {
@@ -950,7 +955,7 @@ const mech = {
definePlayerMass(mass = mech.defaultMass) { definePlayerMass(mass = mech.defaultMass) {
Matter.Body.setMass(player, mass); Matter.Body.setMass(player, mass);
//reduce air and ground move forces //reduce air and ground move forces
mech.Fx = 0.08 / mass * mod.squirrelFx //base player mass is 5 mech.Fx = 0.08 / mass * tech.squirrelFx //base player mass is 5
mech.FxAir = 0.4 / mass / mass //base player mass is 5 mech.FxAir = 0.4 / mass / mass //base player mass is 5
//make player stand a bit lower when holding heavy masses //make player stand a bit lower when holding heavy masses
mech.yOffWhen.stand = Math.max(mech.yOffWhen.crouch, Math.min(49, 49 - (mass - 5) * 6)) mech.yOffWhen.stand = Math.max(mech.yOffWhen.crouch, Math.min(49, 49 - (mass - 5) * 6))
@@ -1005,8 +1010,8 @@ const mech = {
if (input.field) { if (input.field) {
if (mech.energy > 0.001) { if (mech.energy > 0.001) {
if (mech.fireCDcycle < mech.cycle) mech.fireCDcycle = mech.cycle if (mech.fireCDcycle < mech.cycle) mech.fireCDcycle = mech.cycle
mech.energy -= 0.001 / mod.throwChargeRate; mech.energy -= 0.001 / tech.throwChargeRate;
mech.throwCharge += 0.5 * mod.throwChargeRate / mech.holdingTarget.mass mech.throwCharge += 0.5 * tech.throwChargeRate / mech.holdingTarget.mass
//draw charge //draw charge
const x = mech.pos.x + 15 * Math.cos(mech.angle); const x = mech.pos.x + 15 * Math.cos(mech.angle);
const y = mech.pos.y + 15 * Math.sin(mech.angle); const y = mech.pos.y + 15 * Math.sin(mech.angle);
@@ -1086,7 +1091,7 @@ const mech = {
ctx.fillStyle = "rgba(110,170,200," + (0.02 + mech.energy * (0.15 + 0.15 * Math.random())) + ")"; ctx.fillStyle = "rgba(110,170,200," + (0.02 + mech.energy * (0.15 + 0.15 * Math.random())) + ")";
ctx.strokeStyle = "rgba(110, 200, 235, " + (0.6 + 0.2 * Math.random()) + ")" //"#9bd" //"rgba(110, 200, 235, " + (0.5 + 0.1 * Math.random()) + ")" ctx.strokeStyle = "rgba(110, 200, 235, " + (0.6 + 0.2 * Math.random()) + ")" //"#9bd" //"rgba(110, 200, 235, " + (0.5 + 0.1 * Math.random()) + ")"
} }
// const off = 2 * Math.cos(game.cycle * 0.1) // const off = 2 * Math.cos(simulation.cycle * 0.1)
const range = mech.fieldRange; const range = mech.fieldRange;
ctx.beginPath(); ctx.beginPath();
ctx.arc(mech.pos.x, mech.pos.y, range, mech.angle - Math.PI * mech.fieldArc, mech.angle + Math.PI * mech.fieldArc, false); ctx.arc(mech.pos.x, mech.pos.y, range, mech.angle - Math.PI * mech.fieldArc, mech.angle + Math.PI * mech.fieldArc, false);
@@ -1129,13 +1134,13 @@ const mech = {
Matter.Query.ray(map, powerUp[i].position, mech.pos).length === 0 Matter.Query.ray(map, powerUp[i].position, mech.pos).length === 0
) { ) {
powerUp[i].force.x += 0.05 * (dxP / Math.sqrt(dist2)) * powerUp[i].mass; powerUp[i].force.x += 0.05 * (dxP / Math.sqrt(dist2)) * powerUp[i].mass;
powerUp[i].force.y += 0.05 * (dyP / Math.sqrt(dist2)) * powerUp[i].mass - powerUp[i].mass * game.g; //negate gravity powerUp[i].force.y += 0.05 * (dyP / Math.sqrt(dist2)) * powerUp[i].mass - powerUp[i].mass * simulation.g; //negate gravity
//extra friction //extra friction
Matter.Body.setVelocity(powerUp[i], { Matter.Body.setVelocity(powerUp[i], {
x: powerUp[i].velocity.x * 0.11, x: powerUp[i].velocity.x * 0.11,
y: powerUp[i].velocity.y * 0.11 y: powerUp[i].velocity.y * 0.11
}); });
if (dist2 < 5000 && !game.isChoosing) { //use power up if it is close enough if (dist2 < 5000 && !simulation.isChoosing) { //use power up if it is close enough
powerUps.onPickUp(mech.pos); powerUps.onPickUp(mech.pos);
Matter.Body.setVelocity(player, { //player knock back, after grabbing power up Matter.Body.setVelocity(player, { //player knock back, after grabbing power up
x: player.velocity.x + powerUp[i].velocity.x / player.mass * 5, x: player.velocity.x + powerUp[i].velocity.x / player.mass * 5,
@@ -1161,12 +1166,12 @@ const mech = {
} }
// if (mech.energy > mech.maxEnergy) mech.energy = mech.maxEnergy; // if (mech.energy > mech.maxEnergy) mech.energy = mech.maxEnergy;
if (mod.blockDmg) { if (tech.blockDmg) {
who.damage(mod.blockDmg * b.dmgScale) who.damage(tech.blockDmg * b.dmgScale)
//draw electricity //draw electricity
const step = 40 const step = 40
ctx.beginPath(); ctx.beginPath();
for (let i = 0, len = 2.5 * mod.blockDmg; i < len; i++) { for (let i = 0, len = 2.5 * tech.blockDmg; i < len; i++) {
let x = mech.pos.x - 20 * unit.x; let x = mech.pos.x - 20 * unit.x;
let y = mech.pos.y - 20 * unit.y; let y = mech.pos.y - 20 * unit.y;
ctx.moveTo(x, y); ctx.moveTo(x, y);
@@ -1182,7 +1187,7 @@ const mech = {
} else { } else {
mech.drawHold(who); mech.drawHold(who);
} }
// if (mod.isFreezeMobs) mobs.statusSlow(who, 60) //this works but doesn't have a fun effect // if (tech.isFreezeMobs) mobs.statusSlow(who, 60) //this works but doesn't have a fun effect
// mech.holdingTarget = null // mech.holdingTarget = null
//knock backs //knock backs
@@ -1205,8 +1210,8 @@ const mech = {
}); });
} }
} else { } else {
if (mod.isStunField && mech.fieldUpgrades[mech.fieldMode].name === "perfect diamagnetism") mobs.statusStun(who, mod.isStunField) if (tech.isStunField && mech.fieldUpgrades[mech.fieldMode].name === "perfect diamagnetism") mobs.statusStun(who, tech.isStunField)
// mobs.statusSlow(who, mod.isStunField) // mobs.statusSlow(who, tech.isStunField)
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, {
x: player.velocity.x - (20 * unit.x) / massRoot, x: player.velocity.x - (20 * unit.x) / massRoot,
@@ -1314,7 +1319,7 @@ const mech = {
} }
} }
} }
if (mod.isFreezeMobs) { if (tech.isFreezeMobs) {
for (let i = 0, len = mob.length; i < len; ++i) { for (let i = 0, len = mob.length; i < len; ++i) {
Matter.Sleeping.set(mob[i], false) Matter.Sleeping.set(mob[i], false)
mobs.statusSlow(mob[i], 60) mobs.statusSlow(mob[i], 60)
@@ -1352,9 +1357,8 @@ const mech = {
}, },
fieldUpgrades: [{ fieldUpgrades: [{
name: "field emitter", name: "field emitter",
description: "using the field drains <strong class='color-f'>energy</strong><br><strong>block</strong> mobs, <strong>grab</strong> power ups<br><strong>pick up</strong> and <strong>throw</strong> blocks", description: "use <strong class='color-f'>energy</strong> to <strong>block</strong> mobs,<br><strong>grab</strong> power ups, and <strong>throw</strong> blocks",
effect: () => { effect: () => {
game.replaceTextLog = true; //allow text over write
mech.hold = function() { mech.hold = function() {
if (mech.isHolding) { if (mech.isHolding) {
mech.drawHold(mech.holdingTarget); mech.drawHold(mech.holdingTarget);
@@ -1470,7 +1474,7 @@ const mech = {
} }
mech.drawFieldMeter() mech.drawFieldMeter()
if (mod.isPerfectBrake) { //cap mob speed around player if (tech.isPerfectBrake) { //cap mob speed around player
const range = 160 + 140 * wave + 150 * mech.energy const range = 160 + 140 * wave + 150 * mech.energy
for (let i = 0; i < mob.length; i++) { for (let i = 0; i < mob.length; i++) {
const distance = Vector.magnitude(Vector.sub(mech.pos, mob[i].position)) const distance = Vector.magnitude(Vector.sub(mech.pos, mob[i].position))
@@ -1495,16 +1499,16 @@ const mech = {
effect: () => { effect: () => {
mech.hold = function() { mech.hold = function() {
if (mech.energy > mech.maxEnergy - 0.02 && mech.fieldCDcycle < mech.cycle && !input.field) { if (mech.energy > mech.maxEnergy - 0.02 && mech.fieldCDcycle < mech.cycle && !input.field) {
if (mod.isSporeField) { if (tech.isSporeField) {
const len = Math.floor(5 + 4 * Math.random()) const len = Math.floor(5 + 4 * Math.random())
mech.energy -= len * 0.105; mech.energy -= len * 0.105;
for (let i = 0; i < len; i++) { for (let i = 0; i < len; i++) {
b.spore(mech.pos) b.spore(mech.pos)
} }
} else if (mod.isMissileField) { } else if (tech.isMissileField) {
mech.energy -= 0.55; mech.energy -= 0.55;
b.missile({ x: mech.pos.x, y: mech.pos.y - 40 }, -Math.PI / 2, 0, 1, mod.recursiveMissiles) b.missile({ x: mech.pos.x, y: mech.pos.y - 40 }, -Math.PI / 2, 0, 1, tech.recursiveMissiles)
} else if (mod.isIceField) { } else if (tech.isIceField) {
mech.energy -= 0.057; mech.energy -= 0.057;
b.iceIX(1) b.iceIX(1)
} else { } else {
@@ -1558,7 +1562,7 @@ const mech = {
mech.lookForPickUp(); mech.lookForPickUp();
const DRAIN = 0.00035 const DRAIN = 0.00035
if (mech.energy > DRAIN) { if (mech.energy > DRAIN) {
mech.isFieldActive = true; //used with mod.isHarmReduce mech.isFieldActive = true; //used with tech.isHarmReduce
mech.airSpeedLimit = 400 // 7* player.mass * player.mass mech.airSpeedLimit = 400 // 7* player.mass * player.mass
mech.FxAir = 0.005 mech.FxAir = 0.005
// mech.pushMobs360(); // mech.pushMobs360();
@@ -1579,7 +1583,7 @@ const mech = {
sub = Vector.sub(who[i].position, mech.pos); sub = Vector.sub(who[i].position, mech.pos);
dist = Vector.magnitude(sub); dist = Vector.magnitude(sub);
if (dist < range) { if (dist < range) {
who[i].force.y -= who[i].mass * (game.g * mag); //add a bit more then standard gravity who[i].force.y -= who[i].mass * (simulation.g * mag); //add a bit more then standard gravity
} }
} }
} }
@@ -1587,20 +1591,20 @@ const mech = {
// zeroG(mob); //mobs are too irregular to make this work? // zeroG(mob); //mobs are too irregular to make this work?
if (input.down) { //down if (input.down) { //down
player.force.y -= 0.5 * player.mass * game.g; player.force.y -= 0.5 * player.mass * simulation.g;
this.fieldDrawRadius = this.fieldDrawRadius * 0.97 + 400 * 0.03; this.fieldDrawRadius = this.fieldDrawRadius * 0.97 + 400 * 0.03;
zeroG(powerUp, this.fieldDrawRadius, 0.7); zeroG(powerUp, this.fieldDrawRadius, 0.7);
zeroG(body, this.fieldDrawRadius, 0.7); zeroG(body, this.fieldDrawRadius, 0.7);
} else if (input.up) { //up } else if (input.up) { //up
mech.energy -= 5 * DRAIN; mech.energy -= 5 * DRAIN;
this.fieldDrawRadius = this.fieldDrawRadius * 0.97 + 850 * 0.03; this.fieldDrawRadius = this.fieldDrawRadius * 0.97 + 850 * 0.03;
player.force.y -= 1.45 * player.mass * game.g; player.force.y -= 1.45 * player.mass * simulation.g;
zeroG(powerUp, this.fieldDrawRadius, 1.38); zeroG(powerUp, this.fieldDrawRadius, 1.38);
zeroG(body, this.fieldDrawRadius, 1.38); zeroG(body, this.fieldDrawRadius, 1.38);
} else { } else {
mech.energy -= DRAIN; mech.energy -= DRAIN;
this.fieldDrawRadius = this.fieldDrawRadius * 0.97 + 650 * 0.03; this.fieldDrawRadius = this.fieldDrawRadius * 0.97 + 650 * 0.03;
player.force.y -= 1.07 * player.mass * game.g; // slow upward drift player.force.y -= 1.07 * player.mass * simulation.g; // slow upward drift
zeroG(powerUp, this.fieldDrawRadius); zeroG(powerUp, this.fieldDrawRadius);
zeroG(body, this.fieldDrawRadius); zeroG(body, this.fieldDrawRadius);
} }
@@ -1620,7 +1624,7 @@ const mech = {
y: player.velocity.y * 0.98 y: player.velocity.y * 0.98
}); });
} }
if (mod.isFreezeMobs) { if (tech.isFreezeMobs) {
const ICE_DRAIN = 0.0005 const ICE_DRAIN = 0.0005
for (let i = 0, len = mob.length; i < len; i++) { for (let i = 0, len = mob.length; i < len; i++) {
if (mob[i].distanceToPlayer() + mob[i].radius < this.fieldDrawRadius && !mob[i].shield && !mob[i].isShielded) { if (mob[i].distanceToPlayer() + mob[i].radius < this.fieldDrawRadius && !mob[i].shield && !mob[i].isShielded) {
@@ -1668,7 +1672,7 @@ const mech = {
} else if (input.field && mech.fieldCDcycle < mech.cycle) { //not hold but field button is pressed } else if (input.field && mech.fieldCDcycle < mech.cycle) { //not hold but field button is pressed
mech.grabPowerUp(); mech.grabPowerUp();
mech.lookForPickUp(); mech.lookForPickUp();
if (mod.isExtruder) { if (tech.isExtruder) {
b.extruder(); b.extruder();
} else { } else {
b.plasma(); b.plasma();
@@ -1680,7 +1684,7 @@ const mech = {
} }
mech.drawFieldMeter("rgba(0, 0, 0, 0.2)") mech.drawFieldMeter("rgba(0, 0, 0, 0.2)")
if (mod.isExtruder) { if (tech.isExtruder) {
if (input.field) { if (input.field) {
b.wasExtruderOn = true b.wasExtruderOn = true
} else { } else {
@@ -1759,17 +1763,17 @@ const mech = {
} }
} }
game.cycle--; //pause all functions that depend on game cycle increasing simulation.cycle--; //pause all functions that depend on game cycle increasing
if (mod.isTimeSkip) { if (tech.isTimeSkip) {
mech.immuneCycle = mech.cycle + 10; mech.immuneCycle = mech.cycle + 10;
game.isTimeSkipping = true; simulation.isTimeSkipping = true;
mech.cycle++; mech.cycle++;
game.gravity(); simulation.gravity();
Engine.update(engine, game.delta); Engine.update(engine, simulation.delta);
// level.checkZones(); // level.checkZones();
// level.checkQuery(); // level.checkQuery();
mech.move(); mech.move();
game.checks(); simulation.checks();
// mobs.loop(); // mobs.loop();
// mech.draw(); // mech.draw();
mech.walk_cycle += mech.flipLegs * mech.Vx; mech.walk_cycle += mech.flipLegs * mech.Vx;
@@ -1778,11 +1782,11 @@ const mech = {
b.fire(); b.fire();
// b.bulletRemove(); // b.bulletRemove();
b.bulletDo(); b.bulletDo();
game.isTimeSkipping = false; simulation.isTimeSkipping = false;
} }
// game.cycle--; //pause all functions that depend on game cycle increasing // simulation.cycle--; //pause all functions that depend on game cycle increasing
// if (mod.isTimeSkip && !game.isTimeSkipping) { //speed up the rate of time // if (tech.isTimeSkip && !simulation.isTimeSkipping) { //speed up the rate of time
// game.timeSkip(1) // simulation.timeSkip(1)
// mech.energy += 1.5 * DRAIN; //x1 to undo the energy drain from time speed up, x1.5 to cut energy drain in half // mech.energy += 1.5 * DRAIN; //x1 to undo the energy drain from time speed up, x1.5 to cut energy drain in half
// } // }
} }
@@ -1828,7 +1832,7 @@ const mech = {
if (mech.fireCDcycle + 50 < mech.cycle) { if (mech.fireCDcycle + 50 < mech.cycle) {
if (!mech.isCloak) { if (!mech.isCloak) {
mech.isCloak = true //enter cloak mech.isCloak = true //enter cloak
if (mod.isIntangible) { if (tech.isIntangible) {
for (let i = 0; i < bullet.length; i++) { for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType && bullet[i].botType !== "orbit") bullet[i].collisionFilter.mask = cat.map | cat.bullet | cat.mobBullet | cat.mobShield if (bullet[i].botType && bullet[i].botType !== "orbit") bullet[i].collisionFilter.mask = cat.map | cat.bullet | cat.mobBullet | cat.mobShield
} }
@@ -1836,12 +1840,12 @@ const mech = {
} }
} else if (mech.isCloak) { //exit cloak } else if (mech.isCloak) { //exit cloak
mech.isCloak = false mech.isCloak = false
if (mod.isIntangible) { if (tech.isIntangible) {
for (let i = 0; i < bullet.length; i++) { for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType && bullet[i].botType !== "orbit") bullet[i].collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield if (bullet[i].botType && bullet[i].botType !== "orbit") bullet[i].collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield
} }
} }
if (mod.isCloakStun) { //stun nearby mobs after exiting cloak if (tech.isCloakStun) { //stun nearby mobs after exiting cloak
let isMobsAround = false let isMobsAround = false
const stunRange = mech.fieldDrawRadius * 1.15 const stunRange = mech.fieldDrawRadius * 1.15
const drain = 0.3 * mech.energy const drain = 0.3 * mech.energy
@@ -1856,7 +1860,7 @@ const mech = {
} }
if (isMobsAround && mech.energy > drain) { if (isMobsAround && mech.energy > drain) {
mech.energy -= drain mech.energy -= drain
game.drawList.push({ simulation.drawList.push({
x: mech.pos.x, x: mech.pos.x,
y: mech.pos.y, y: mech.pos.y,
radius: stunRange, radius: stunRange,
@@ -1900,7 +1904,7 @@ const mech = {
drawField() drawField()
} }
} }
if (mod.isIntangible) { if (tech.isIntangible) {
if (mech.isCloak) { if (mech.isCloak) {
player.collisionFilter.mask = cat.map player.collisionFilter.mask = cat.map
let inPlayer = Matter.Query.region(mob, player.bounds) let inPlayer = Matter.Query.region(mob, player.bounds)
@@ -1981,8 +1985,8 @@ const mech = {
// mech.lookForPickUp(); // mech.lookForPickUp();
// if (mech.fieldCDcycle < mech.cycle) { // if (mech.fieldCDcycle < mech.cycle) {
// // game.draw.bodyFill = "transparent" // // simulation.draw.bodyFill = "transparent"
// // game.draw.bodyStroke = "transparent" // // simulation.draw.bodyStroke = "transparent"
// const DRAIN = 0.00013 + (mech.fireCDcycle > mech.cycle ? 0.005 : 0) // const DRAIN = 0.00013 + (mech.fireCDcycle > mech.cycle ? 0.005 : 0)
// if (mech.energy > DRAIN) { // if (mech.energy > DRAIN) {
@@ -2007,7 +2011,7 @@ const mech = {
// //draw outline of shield // //draw outline of shield
// ctx.fillStyle = `rgba(140,217,255,0.5)` // ctx.fillStyle = `rgba(140,217,255,0.5)`
// ctx.fill() // ctx.fill()
// } else if (mod.superposition && inPlayer[i].dropPowerUp) { // } else if (tech.superposition && inPlayer[i].dropPowerUp) {
// // inPlayer[i].damage(0.4 * b.dmgScale); //damage mobs inside the player // // inPlayer[i].damage(0.4 * b.dmgScale); //damage mobs inside the player
// // mech.energy += 0.005; // // mech.energy += 0.005;
@@ -2073,17 +2077,16 @@ 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><br>allows <strong class='color-m'>mods</strong> that normally require other <strong class='color-f'>fields</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><br>allows <strong class='color-m'>tech</strong> that normally require other <strong class='color-f'>fields</strong>",
effect: () => { effect: () => {
game.replaceTextLog = true; //allow text over write
mech.fieldPhase = 0; mech.fieldPhase = 0;
mech.fieldPosition = { mech.fieldPosition = {
x: game.mouseInGame.x, x: simulation.mouseInGame.x,
y: game.mouseInGame.y y: simulation.mouseInGame.y
} }
mech.lastFieldPosition = { mech.lastFieldPosition = {
x: game.mouseInGame.x, x: simulation.mouseInGame.x,
y: game.mouseInGame.y y: simulation.mouseInGame.y
} }
mech.fieldOn = false; mech.fieldOn = false;
mech.fieldRadius = 0; mech.fieldRadius = 0;
@@ -2108,8 +2111,8 @@ const mech = {
if (!mech.fieldOn) { // if field was off, and it starting up, teleport to new mouse location if (!mech.fieldOn) { // if field was off, and it starting up, teleport to new mouse location
mech.fieldOn = true; mech.fieldOn = true;
mech.fieldPosition = { //smooth the mouse position mech.fieldPosition = { //smooth the mouse position
x: game.mouseInGame.x, x: simulation.mouseInGame.x,
y: game.mouseInGame.y y: simulation.mouseInGame.y
} }
mech.lastFieldPosition = { //used to find velocity of field changes mech.lastFieldPosition = { //used to find velocity of field changes
x: mech.fieldPosition.x, x: mech.fieldPosition.x,
@@ -2122,8 +2125,8 @@ const mech = {
} }
const smooth = isInMap ? 0.985 : 0.96; const smooth = isInMap ? 0.985 : 0.96;
mech.fieldPosition = { //smooth the mouse position mech.fieldPosition = { //smooth the mouse position
x: mech.fieldPosition.x * smooth + game.mouseInGame.x * (1 - smooth), x: mech.fieldPosition.x * smooth + simulation.mouseInGame.x * (1 - smooth),
y: mech.fieldPosition.y * smooth + game.mouseInGame.y * (1 - smooth), y: mech.fieldPosition.y * smooth + simulation.mouseInGame.y * (1 - smooth),
} }
} }
@@ -2135,13 +2138,13 @@ const mech = {
// float towards field if looking at and in range or if very close to player // float towards field if looking at and in range or if very close to player
if (dist2 < mech.fieldRadius * mech.fieldRadius && (mech.lookingAt(powerUp[i]) || dist2 < 16000) && !(mech.health === mech.maxHealth && powerUp[i].name === "heal")) { if (dist2 < mech.fieldRadius * mech.fieldRadius && (mech.lookingAt(powerUp[i]) || dist2 < 16000) && !(mech.health === mech.maxHealth && powerUp[i].name === "heal")) {
powerUp[i].force.x += 7 * (dxP / dist2) * powerUp[i].mass; powerUp[i].force.x += 7 * (dxP / dist2) * powerUp[i].mass;
powerUp[i].force.y += 7 * (dyP / dist2) * powerUp[i].mass - powerUp[i].mass * game.g; //negate gravity powerUp[i].force.y += 7 * (dyP / dist2) * powerUp[i].mass - powerUp[i].mass * simulation.g; //negate gravity
//extra friction //extra friction
Matter.Body.setVelocity(powerUp[i], { Matter.Body.setVelocity(powerUp[i], {
x: powerUp[i].velocity.x * 0.11, x: powerUp[i].velocity.x * 0.11,
y: powerUp[i].velocity.y * 0.11 y: powerUp[i].velocity.y * 0.11
}); });
if (dist2 < 5000 && !game.isChoosing) { //use power up if it is close enough if (dist2 < 5000 && !simulation.isChoosing) { //use power up if it is close enough
powerUps.onPickUp(powerUp[i].position); powerUps.onPickUp(powerUp[i].position);
powerUp[i].effect(); powerUp[i].effect();
Matter.World.remove(engine.world, powerUp[i]); Matter.World.remove(engine.world, powerUp[i]);
@@ -2176,12 +2179,12 @@ const mech = {
mech.energy -= DRAIN; mech.energy -= DRAIN;
Matter.Body.setVelocity(body[i], velocity); //give block mouse velocity Matter.Body.setVelocity(body[i], velocity); //give block mouse velocity
Matter.Body.setAngularVelocity(body[i], body[i].angularVelocity * 0.8) Matter.Body.setAngularVelocity(body[i], body[i].angularVelocity * 0.8)
// body[i].force.y -= body[i].mass * game.g; //remove gravity effects // body[i].force.y -= body[i].mass * simulation.g; //remove gravity effects
//blocks drift towards center of pilot wave //blocks drift towards center of pilot wave
const sub = Vector.sub(mech.fieldPosition, body[i].position) const sub = Vector.sub(mech.fieldPosition, body[i].position)
const unit = Vector.mult(Vector.normalise(sub), 0.00005 * Vector.magnitude(sub)) const unit = Vector.mult(Vector.normalise(sub), 0.00005 * Vector.magnitude(sub))
body[i].force.x += unit.x body[i].force.x += unit.x
body[i].force.y += unit.y - body[i].mass * game.g //remove gravity effects body[i].force.y += unit.y - body[i].mass * simulation.g //remove gravity effects
} else { } else {
mech.fieldCDcycle = mech.cycle + 120; mech.fieldCDcycle = mech.cycle + 120;
mech.fieldOn = false mech.fieldOn = false
@@ -2191,7 +2194,7 @@ const mech = {
} }
} }
if (mod.isFreezeMobs) { if (tech.isFreezeMobs) {
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, mech.fieldPosition)) < mech.fieldRadius) { if (Vector.magnitude(Vector.sub(mob[i].position, mech.fieldPosition)) < mech.fieldRadius) {
mobs.statusSlow(mob[i], 120) mobs.statusSlow(mob[i], 120)
@@ -2235,12 +2238,11 @@ const mech = {
name: "wormhole", name: "wormhole",
description: "use <strong class='color-f'>energy</strong> to <strong>tunnel</strong> through a <strong class='color-worm'>wormhole</strong><br><strong class='color-worm'>wormholes</strong> attract blocks and power ups<br><strong>10%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong>", //<br>bullets may also traverse <strong class='color-worm'>wormholes</strong> description: "use <strong class='color-f'>energy</strong> to <strong>tunnel</strong> through a <strong class='color-worm'>wormhole</strong><br><strong class='color-worm'>wormholes</strong> attract blocks and power ups<br><strong>10%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong>", //<br>bullets may also traverse <strong class='color-worm'>wormholes</strong>
effect: function() { effect: function() {
game.replaceTextLog = true; //allow text over write
mech.drop(); mech.drop();
mech.duplicateChance = 0.1 mech.duplicateChance = 0.1
game.draw.powerUp = game.draw.powerUpBonus //change power up draw simulation.draw.powerUp = simulation.draw.powerUpBonus //change power up draw
// if (mod.isRewindGun) { // if (tech.isRewindGun) {
// mech.hold = this.rewind // mech.hold = this.rewind
// } else { // } else {
mech.hold = this.teleport mech.hold = this.teleport
@@ -2258,8 +2260,8 @@ const mech = {
// if (this.rewindCount === 0) { // if (this.rewindCount === 0) {
// const shortPause = function() { // const shortPause = function() {
// if (mech.defaultFPSCycle < mech.cycle) { //back to default values // if (mech.defaultFPSCycle < mech.cycle) { //back to default values
// game.fpsCap = game.fpsCapDefault // simulation.fpsCap = simulation.fpsCapDefault
// game.fpsInterval = 1000 / game.fpsCap; // simulation.fpsInterval = 1000 / simulation.fpsCap;
// // document.getElementById("dmg").style.transition = "opacity 1s"; // // document.getElementById("dmg").style.transition = "opacity 1s";
// // document.getElementById("dmg").style.opacity = "0"; // // document.getElementById("dmg").style.opacity = "0";
// } else { // } else {
@@ -2267,14 +2269,14 @@ const mech = {
// } // }
// }; // };
// if (mech.defaultFPSCycle < mech.cycle) requestAnimationFrame(shortPause); // if (mech.defaultFPSCycle < mech.cycle) requestAnimationFrame(shortPause);
// game.fpsCap = 4 //1 is longest pause, 4 is standard // simulation.fpsCap = 4 //1 is longest pause, 4 is standard
// game.fpsInterval = 1000 / game.fpsCap; // simulation.fpsInterval = 1000 / simulation.fpsCap;
// mech.defaultFPSCycle = mech.cycle // mech.defaultFPSCycle = mech.cycle
// } // }
// this.rewindCount += 10; // this.rewindCount += 10;
// game.wipe = function() { //set wipe to have trails // simulation.wipe = function() { //set wipe to have trails
// // ctx.fillStyle = "rgba(255,255,255,0)"; // // ctx.fillStyle = "rgba(255,255,255,0)";
// ctx.fillStyle = `rgba(221,221,221,${0.004})`; // ctx.fillStyle = `rgba(221,221,221,${0.004})`;
// ctx.fillRect(0, 0, canvas.width, canvas.height); // ctx.fillRect(0, 0, canvas.width, canvas.height);
@@ -2290,15 +2292,15 @@ const mech = {
// for (let i = 0, len = powerUp.length; i < len; ++i) { // for (let i = 0, len = powerUp.length; i < len; ++i) {
// const dxP = player.position.x - powerUp[i].position.x; // const dxP = player.position.x - powerUp[i].position.x;
// const dyP = player.position.y - powerUp[i].position.y; // const dyP = player.position.y - powerUp[i].position.y;
// if (dxP * dxP + dyP * dyP < 50000 && !game.isChoosing && !(mech.health === mech.maxHealth && powerUp[i].name === "heal")) { // if (dxP * dxP + dyP * dyP < 50000 && !simulation.isChoosing && !(mech.health === mech.maxHealth && powerUp[i].name === "heal")) {
// powerUps.onPickUp(player.position); // powerUps.onPickUp(player.position);
// powerUp[i].effect(); // powerUp[i].effect();
// Matter.World.remove(engine.world, powerUp[i]); // Matter.World.remove(engine.world, powerUp[i]);
// powerUp.splice(i, 1); // powerUp.splice(i, 1);
// const shortPause = function() { // const shortPause = function() {
// if (mech.defaultFPSCycle < mech.cycle) { //back to default values // if (mech.defaultFPSCycle < mech.cycle) { //back to default values
// game.fpsCap = game.fpsCapDefault // simulation.fpsCap = simulation.fpsCapDefault
// game.fpsInterval = 1000 / game.fpsCap; // simulation.fpsInterval = 1000 / simulation.fpsCap;
// // document.getElementById("dmg").style.transition = "opacity 1s"; // // document.getElementById("dmg").style.transition = "opacity 1s";
// // document.getElementById("dmg").style.opacity = "0"; // // document.getElementById("dmg").style.opacity = "0";
// } else { // } else {
@@ -2306,8 +2308,8 @@ const mech = {
// } // }
// }; // };
// if (mech.defaultFPSCycle < mech.cycle) requestAnimationFrame(shortPause); // if (mech.defaultFPSCycle < mech.cycle) requestAnimationFrame(shortPause);
// game.fpsCap = 3 //1 is longest pause, 4 is standard // simulation.fpsCap = 3 //1 is longest pause, 4 is standard
// game.fpsInterval = 1000 / game.fpsCap; // simulation.fpsInterval = 1000 / simulation.fpsCap;
// mech.defaultFPSCycle = mech.cycle // mech.defaultFPSCycle = mech.cycle
// break; //because the array order is messed up after splice // break; //because the array order is messed up after splice
// } // }
@@ -2322,7 +2324,7 @@ const mech = {
// mech.fieldCDcycle = mech.cycle + 30; // mech.fieldCDcycle = mech.cycle + 30;
// mech.resetHistory(); // mech.resetHistory();
// this.rewindCount = 0; // this.rewindCount = 0;
// game.wipe = function() { //set wipe to normal // simulation.wipe = function() { //set wipe to normal
// ctx.clearRect(0, 0, canvas.width, canvas.height); // ctx.clearRect(0, 0, canvas.width, canvas.height);
// } // }
// } // }
@@ -2342,7 +2344,7 @@ const mech = {
// } // }
if (mech.hole.isOn) { if (mech.hole.isOn) {
// draw holes // draw holes
mech.fieldRange = 0.97 * mech.fieldRange + 0.03 * (50 + 10 * Math.sin(game.cycle * 0.025)) mech.fieldRange = 0.97 * mech.fieldRange + 0.03 * (50 + 10 * Math.sin(simulation.cycle * 0.025))
const semiMajorAxis = mech.fieldRange + 30 const semiMajorAxis = mech.fieldRange + 30
const edge1a = Vector.add(Vector.mult(mech.hole.unit, semiMajorAxis), mech.hole.pos1) const edge1a = Vector.add(Vector.mult(mech.hole.unit, semiMajorAxis), mech.hole.pos1)
const edge1b = Vector.add(Vector.mult(mech.hole.unit, -semiMajorAxis), mech.hole.pos1) const edge1b = Vector.add(Vector.mult(mech.hole.unit, -semiMajorAxis), mech.hole.pos1)
@@ -2379,12 +2381,12 @@ const mech = {
dist2 = dxP * dxP + dyP * dyP; dist2 = dxP * dxP + dyP * dyP;
if (dist2 < 600000 && !(mech.health === mech.maxHealth && powerUp[i].name === "heal")) { if (dist2 < 600000 && !(mech.health === mech.maxHealth && powerUp[i].name === "heal")) {
powerUp[i].force.x += 4 * (dxP / dist2) * powerUp[i].mass; // float towards hole powerUp[i].force.x += 4 * (dxP / dist2) * powerUp[i].mass; // float towards hole
powerUp[i].force.y += 4 * (dyP / dist2) * powerUp[i].mass - powerUp[i].mass * game.g; //negate gravity powerUp[i].force.y += 4 * (dyP / dist2) * powerUp[i].mass - powerUp[i].mass * simulation.g; //negate gravity
Matter.Body.setVelocity(powerUp[i], { //extra friction Matter.Body.setVelocity(powerUp[i], { //extra friction
x: powerUp[i].velocity.x * 0.05, x: powerUp[i].velocity.x * 0.05,
y: powerUp[i].velocity.y * 0.05 y: powerUp[i].velocity.y * 0.05
}); });
if (dist2 < 1000 && !game.isChoosing) { //use power up if it is close enough if (dist2 < 1000 && !simulation.isChoosing) { //use power up if it is close enough
mech.fieldRange *= 0.8 mech.fieldRange *= 0.8
powerUps.onPickUp(powerUp[i].position); powerUps.onPickUp(powerUp[i].position);
powerUp[i].effect(); powerUp[i].effect();
@@ -2415,8 +2417,8 @@ const mech = {
Matter.World.remove(engine.world, body[i]); Matter.World.remove(engine.world, body[i]);
body.splice(i, 1); body.splice(i, 1);
mech.fieldRange *= 0.8 mech.fieldRange *= 0.8
if (mod.isWormholeEnergy) mech.energy += 0.5 if (tech.isWormholeEnergy) mech.energy += 0.5
if (mod.isWormSpores) { //pandimensionalspermia if (tech.isWormSpores) { //pandimensionalspermia
for (let i = 0, len = Math.ceil(3 * Math.random()); i < len; i++) { for (let i = 0, len = Math.ceil(3 * Math.random()); i < len; i++) {
b.spore(Vector.add(mech.hole.pos2, Vector.rotate({ b.spore(Vector.add(mech.hole.pos2, Vector.rotate({
x: mech.fieldRange * 0.4, x: mech.fieldRange * 0.4,
@@ -2440,9 +2442,9 @@ const mech = {
Matter.World.remove(engine.world, body[i]); Matter.World.remove(engine.world, body[i]);
body.splice(i, 1); body.splice(i, 1);
mech.fieldRange *= 0.8 mech.fieldRange *= 0.8
// if (mod.isWormholeEnergy && mech.energy < mech.maxEnergy * 2) mech.energy = mech.maxEnergy * 2 // if (tech.isWormholeEnergy && mech.energy < mech.maxEnergy * 2) mech.energy = mech.maxEnergy * 2
if (mod.isWormholeEnergy) mech.energy += 0.5 if (tech.isWormholeEnergy) mech.energy += 0.5
if (mod.isWormSpores) { //pandimensionalspermia if (tech.isWormSpores) { //pandimensionalspermia
for (let i = 0, len = Math.ceil(3 * Math.random()); i < len; i++) { for (let i = 0, len = Math.ceil(3 * Math.random()); i < len; i++) {
b.spore(Vector.add(mech.hole.pos1, Vector.rotate({ b.spore(Vector.add(mech.hole.pos1, Vector.rotate({
x: mech.fieldRange * 0.4, x: mech.fieldRange * 0.4,
@@ -2457,7 +2459,7 @@ const mech = {
} }
} }
} }
if (mod.isWormBullets) { if (tech.isWormBullets) {
//teleport bullets //teleport bullets
for (let i = 0, len = bullet.length; i < len; ++i) { //teleport bullets from hole1 to hole2 for (let i = 0, len = bullet.length; i < len; ++i) { //teleport bullets from hole1 to hole2
if (!bullet[i].botType && !bullet[i].isInHole) { //don't teleport bots if (!bullet[i].botType && !bullet[i].isInHole) { //don't teleport bots
@@ -2487,35 +2489,35 @@ const mech = {
} }
if (input.field && mech.fieldCDcycle < mech.cycle) { //not hold but field button is pressed if (input.field && mech.fieldCDcycle < mech.cycle) { //not hold but field button is pressed
const justPastMouse = Vector.add(Vector.mult(Vector.normalise(Vector.sub(game.mouseInGame, mech.pos)), 50), game.mouseInGame) const justPastMouse = Vector.add(Vector.mult(Vector.normalise(Vector.sub(simulation.mouseInGame, mech.pos)), 50), simulation.mouseInGame)
const scale = 60 const scale = 60
// console.log(Matter.Query.region(map, bounds)) // console.log(Matter.Query.region(map, bounds))
if (mech.hole.isReady && if (mech.hole.isReady &&
( (
Matter.Query.region(map, { Matter.Query.region(map, {
min: { min: {
x: game.mouseInGame.x - scale, x: simulation.mouseInGame.x - scale,
y: game.mouseInGame.y - scale y: simulation.mouseInGame.y - scale
}, },
max: { max: {
x: game.mouseInGame.x + scale, x: simulation.mouseInGame.x + scale,
y: game.mouseInGame.y + scale y: simulation.mouseInGame.y + scale
} }
}).length === 0 && }).length === 0 &&
Matter.Query.ray(map, mech.pos, justPastMouse).length === 0 Matter.Query.ray(map, mech.pos, justPastMouse).length === 0
// Matter.Query.ray(map, mech.pos, game.mouseInGame).length === 0 && // Matter.Query.ray(map, mech.pos, simulation.mouseInGame).length === 0 &&
// Matter.Query.ray(map, player.position, game.mouseInGame).length === 0 && // Matter.Query.ray(map, player.position, simulation.mouseInGame).length === 0 &&
// Matter.Query.ray(map, player.position, justPastMouse).length === 0 // Matter.Query.ray(map, player.position, justPastMouse).length === 0
) )
) { ) {
const sub = Vector.sub(game.mouseInGame, mech.pos) const sub = Vector.sub(simulation.mouseInGame, mech.pos)
const mag = Vector.magnitude(sub) const mag = Vector.magnitude(sub)
const drain = 0.03 + 0.005 * Math.sqrt(mag) const drain = 0.03 + 0.005 * Math.sqrt(mag)
if (mech.energy > drain && mag > 300) { if (mech.energy > drain && mag > 300) {
mech.energy -= drain mech.energy -= drain
mech.hole.isReady = false; mech.hole.isReady = false;
mech.fieldRange = 0 mech.fieldRange = 0
Matter.Body.setPosition(player, game.mouseInGame); Matter.Body.setPosition(player, simulation.mouseInGame);
mech.buttonCD_jump = 0 //this might fix a bug with jumping mech.buttonCD_jump = 0 //this might fix a bug with jumping
const velocity = Vector.mult(Vector.normalise(sub), 18) const velocity = Vector.mult(Vector.normalise(sub), 18)
Matter.Body.setVelocity(player, { Matter.Body.setVelocity(player, {
@@ -2546,8 +2548,8 @@ const mech = {
mech.hole.angle = Math.atan2(sub.y, sub.x) mech.hole.angle = Math.atan2(sub.y, sub.x)
mech.hole.unit = Vector.perp(Vector.normalise(sub)) mech.hole.unit = Vector.perp(Vector.normalise(sub))
if (mod.isWormholeDamage) { if (tech.isWormholeDamage) {
who = Matter.Query.ray(mob, mech.pos, game.mouseInGame, 80) who = Matter.Query.ray(mob, mech.pos, simulation.mouseInGame, 80)
for (let i = 0; i < who.length; i++) { for (let i = 0; i < who.length; i++) {
if (who[i].body.alive) { if (who[i].body.alive) {
mobs.statusDoT(who[i].body, 0.6, 420) mobs.statusDoT(who[i].body, 0.6, 420)

View File

@@ -1,23 +1,22 @@
let powerUp = []; let powerUp = [];
const powerUps = { const powerUps = {
totalPowerUps: 0, //used for mods that count power ups at the end of a level totalPowerUps: 0, //used for tech that count power ups at the end of a level
choose(type, index) { choose(type, index) {
if (type === "gun") { if (type === "gun") {
b.giveGuns(index) b.giveGuns(index)
// game.replaceTextLog = true; let text = `b.giveGuns("<span class='color-text'>${b.guns[index].name}</span>")`
// game.makeTextLog(`${game.SVGleftMouse} <strong style='font-size:30px;'>${b.guns[index].name}</strong><br><br>${b.guns[index].description}`, 500); if (b.inventory.length === 1) text += `<br>input.key.gun <span class='color-symbol'>=</span> ["<span class='color-text'>MouseLeft</span>"]`
// game.replaceTextLog = false; if (b.inventory.length === 2) text += `
<br>input.key.nextGun <span class='color-symbol'>=</span> ["<span class='color-text'>${input.key.nextGun}</span>","<span class='color-text'>MouseWheel</span>"]
<br>input.key.previousGun <span class='color-symbol'>=</span> ["<span class='color-text'>${input.key.previousGun}</span>","<span class='color-text'>MouseWheel</span>"]`
simulation.makeTextLog(text);
} else if (type === "field") { } else if (type === "field") {
mech.setField(index) mech.setField(index)
// game.replaceTextLog = true; simulation.makeTextLog(`<span class='color-var'>mech</span>.setField("<span class='color-text'>${mech.fieldUpgrades[mech.fieldMode].name}</span>")`);
// game.makeTextLog(`${game.SVGrightMouse}<strong style='font-size:30px;'> ${mech.fieldUpgrades[mech.fieldMode].name}</strong><br><span class='faded'></span><br>${mech.fieldUpgrades[mech.fieldMode].description}`, 600); } else if (type === "tech") {
// game.replaceTextLog = false; tech.giveMod(index)
} else if (type === "mod") { simulation.makeTextLog(`<span class='color-var'>tech</span>.giveMod("<span class='color-text'>${tech.tech[index].name}</span>")`);
mod.giveMod(index)
// game.replaceTextLog = true;
// game.makeTextLog(`<div class="circle mod"></div> &nbsp; <strong style='font-size:30px;'>${mod.mods[index].name}</strong><br><br> ${mod.mods[index].description}`, 500);
// game.replaceTextLog = false;
} }
powerUps.endDraft(type); powerUps.endDraft(type);
}, },
@@ -27,45 +26,45 @@ const powerUps = {
document.getElementById("choose-background").style.display = "inline" document.getElementById("choose-background").style.display = "inline"
document.body.style.cursor = "auto"; document.body.style.cursor = "auto";
if (mod.isExtraChoice) { if (tech.isExtraChoice) {
document.body.style.overflowY = "scroll"; document.body.style.overflowY = "scroll";
document.body.style.overflowX = "hidden"; document.body.style.overflowX = "hidden";
} }
game.paused = true; simulation.paused = true;
game.isChoosing = true; //stops p from un pausing on key down simulation.isChoosing = true; //stops p from un pausing on key down
build.pauseGrid(true) build.pauseGrid(true)
}, },
endDraft(type, isCanceled = false) { endDraft(type, isCanceled = false) {
if (isCanceled) { if (isCanceled) {
if (mod.isCancelDuplication) mod.cancelCount++ if (tech.isCancelDuplication) tech.cancelCount++
if (mod.isCancelRerolls) { if (tech.isCancelRerolls) {
let spawnType = (mech.health < 0.25 || mod.isEnergyNoAmmo) ? "heal" : "ammo" let spawnType = (mech.health < 0.25 || tech.isEnergyNoAmmo) ? "heal" : "ammo"
if (Math.random() < 0.33) { if (Math.random() < 0.33) {
spawnType = "heal" spawnType = "heal"
} else if (Math.random() < 0.5 && !mod.isSuperDeterminism) { } else if (Math.random() < 0.5 && !tech.isSuperDeterminism) {
spawnType = "reroll" spawnType = "reroll"
} }
for (let i = 0; i < 6; i++) powerUps.spawn(mech.pos.x + 40 * (Math.random() - 0.5), mech.pos.y + 40 * (Math.random() - 0.5), spawnType, false); for (let i = 0; i < 6; i++) powerUps.spawn(mech.pos.x + 40 * (Math.random() - 0.5), mech.pos.y + 40 * (Math.random() - 0.5), spawnType, false);
} }
if (mod.isBanish && type === 'mod') { // banish rerolled mods by adding them to the list of banished mods if (tech.isBanish && type === 'tech') { // banish rerolled tech by adding them to the list of banished tech
const banishLength = mod.isDeterminism ? 1 : 3 + mod.isExtraChoice * 2 const banishLength = tech.isDeterminism ? 1 : 3 + tech.isExtraChoice * 2
if (powerUps.mod.choiceLog.length > banishLength || powerUps.mod.choiceLog.length === banishLength) { //I'm not sure this check is needed if (powerUps.tech.choiceLog.length > banishLength || powerUps.tech.choiceLog.length === banishLength) { //I'm not sure this check is needed
for (let i = 0; i < banishLength; i++) { for (let i = 0; i < banishLength; i++) {
powerUps.mod.banishLog.push(powerUps.mod.choiceLog[powerUps.mod.choiceLog.length - 1 - i]) powerUps.tech.banishLog.push(powerUps.tech.choiceLog[powerUps.tech.choiceLog.length - 1 - i])
} }
} }
game.makeTextLog(`about ${Math.max(0,powerUps.mod.lastTotalChoices - powerUps.mod.banishLog.length)} estimated <strong class='color-m'>mods</strong> left`, 300) simulation.makeTextLog(`${Math.max(0,powerUps.tech.lastTotalChoices - powerUps.tech.banishLog.length)} estimated <strong class='color-m'>tech</strong> choices remaining`)
} }
} }
if (mod.manyWorlds && powerUps.reroll.rerolls === 0) { if (tech.manyWorlds && powerUps.reroll.rerolls === 0) {
for (let i = 0; i < 2; i++) powerUps.spawn(mech.pos.x + 40 * (Math.random() - 0.5), mech.pos.y + 40 * (Math.random() - 0.5), "reroll", false); for (let i = 0; i < 2; i++) powerUps.spawn(mech.pos.x + 40 * (Math.random() - 0.5), mech.pos.y + 40 * (Math.random() - 0.5), "reroll", false);
} }
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"
document.body.style.cursor = "none"; document.body.style.cursor = "none";
document.body.style.overflow = "hidden" document.body.style.overflow = "hidden"
game.paused = false; simulation.paused = false;
game.isChoosing = false; //stops p from un pausing on key down simulation.isChoosing = false; //stops p from un pausing on key down
mech.immuneCycle = mech.cycle + 60; //player is immune to collision damage for 30 cycles mech.immuneCycle = mech.cycle + 60; //player is immune to collision damage for 30 cycles
build.unPauseGrid() build.unPauseGrid()
requestAnimationFrame(cycle); requestAnimationFrame(cycle);
@@ -79,17 +78,21 @@ const powerUps = {
}, },
effect() { effect() {
powerUps.reroll.changeRerolls(1) powerUps.reroll.changeRerolls(1)
game.makeTextLog(`<div class='circle reroll'></div> &nbsp; <span style='font-size:115%;'><strong>rerolls:</strong> ${powerUps.reroll.rerolls}</span>`, 300)
}, },
changeRerolls(amount) { changeRerolls(amount) {
powerUps.reroll.rerolls += amount powerUps.reroll.rerolls += amount
if (powerUps.reroll.rerolls < 0) powerUps.reroll.rerolls = 0 if (powerUps.reroll.rerolls < 0) {
powerUps.reroll.rerolls = 0
} else {
simulation.makeTextLog(`powerUps.reroll.rerolls <span class='color-symbol'>+=</span> ${amount}`) // <br>${powerUps.reroll.rerolls}
}
if (mod.isRerollBots) {
if (tech.isRerollBots) {
const limit = 5 const limit = 5
for (; powerUps.reroll.rerolls > limit - 1; powerUps.reroll.rerolls -= limit) { for (; powerUps.reroll.rerolls > limit - 1; powerUps.reroll.rerolls -= limit) {
b.randomBot() b.randomBot()
if (mod.renormalization) { if (tech.renormalization) {
for (let i = 0; i < limit; i++) { for (let i = 0; i < limit; i++) {
if (Math.random() < 0.37) { if (Math.random() < 0.37) {
mech.fieldCDcycle = mech.cycle + 30; mech.fieldCDcycle = mech.cycle + 30;
@@ -99,54 +102,32 @@ const powerUps = {
} }
} }
} }
if (mod.isDeathAvoid && document.getElementById("mod-anthropic")) { if (tech.isDeathAvoid && document.getElementById("tech-anthropic")) {
document.getElementById("mod-anthropic").innerHTML = `-${powerUps.reroll.rerolls}` document.getElementById("tech-anthropic").innerHTML = `-${powerUps.reroll.rerolls}`
} }
if (mod.renormalization && Math.random() < 0.37 && amount < 0) powerUps.spawn(mech.pos.x, mech.pos.y, "reroll"); if (tech.renormalization && Math.random() < 0.37 && amount < 0) powerUps.spawn(mech.pos.x, mech.pos.y, "reroll");
if (mod.isRerollHaste) { if (tech.isRerollHaste) {
if (powerUps.reroll.rerolls === 0) { if (powerUps.reroll.rerolls === 0) {
mod.rerollHaste = 0.66; tech.rerollHaste = 0.66;
b.setFireCD(); b.setFireCD();
} else { } else {
mod.rerollHaste = 1; tech.rerollHaste = 1;
b.setFireCD(); b.setFireCD();
} }
} }
}, },
diceText() { use(type) { //runs when you actually reroll a list of selections, type can be field, gun, or tech
const diceLimit = 5
const r = powerUps.reroll.rerolls
const fullDice = Math.min(Math.floor(r / 6), diceLimit)
const lastDice = r % 6
let out = ''
if (Math.floor(r / 6) > diceLimit) out += "+"
for (let i = 0; i < fullDice; i++) {
out += '⚅'
}
if (lastDice === 1) {
out += '⚀'
} else if (lastDice === 2) {
out += '⚁'
} else if (lastDice === 3) {
out += '⚂'
} else if (lastDice === 4) {
out += '⚃'
} else if (lastDice === 5) {
out += '⚄'
}
return out
},
use(type) { //runs when you actually reroll a list of selections, type can be field, gun, or mod
powerUps.reroll.changeRerolls(-1) powerUps.reroll.changeRerolls(-1)
// simulation.makeTextLog(`<span class='color-var'>mech</span>.<span class='color-r'>rerolls</span><span class='color-symbol'>--</span>
if (mod.isBanish && type === 'mod') { // banish rerolled mods // <br>${powerUps.reroll.rerolls}`)
const banishLength = mod.isDeterminism ? 1 : 3 + mod.isExtraChoice * 2 if (tech.isBanish && type === 'tech') { // banish rerolled tech
if (powerUps.mod.choiceLog.length > banishLength || powerUps.mod.choiceLog.length === banishLength) { //I'm not sure this check is needed const banishLength = tech.isDeterminism ? 1 : 3 + tech.isExtraChoice * 2
if (powerUps.tech.choiceLog.length > banishLength || powerUps.tech.choiceLog.length === banishLength) { //I'm not sure this check is needed
for (let i = 0; i < banishLength; i++) { for (let i = 0; i < banishLength; i++) {
powerUps.mod.banishLog.push(powerUps.mod.choiceLog[powerUps.mod.choiceLog.length - 1 - i]) powerUps.tech.banishLog.push(powerUps.tech.choiceLog[powerUps.tech.choiceLog.length - 1 - i])
} }
} }
game.makeTextLog(`about ${Math.max(0,powerUps.mod.lastTotalChoices - powerUps.mod.banishLog.length)} estimated <strong class='color-m'>mods</strong> left`, 300) simulation.makeTextLog(`${Math.max(0,powerUps.tech.lastTotalChoices - powerUps.tech.banishLog.length)} estimated <strong class='color-m'>tech</strong> choices remaining`)
} }
powerUps[type].effect(); powerUps[type].effect();
}, },
@@ -155,24 +136,26 @@ const powerUps = {
name: "heal", name: "heal",
color: "#0eb", color: "#0eb",
size() { size() {
return 40 * (game.healScale ** 0.25) * Math.sqrt(mod.largerHeals) * Math.sqrt(0.1 + Math.random() * 0.5); //(game.healScale ** 0.25) gives a smaller radius as heal scale goes down return 40 * (simulation.healScale ** 0.25) * Math.sqrt(tech.largerHeals) * Math.sqrt(0.1 + Math.random() * 0.5); //(simulation.healScale ** 0.25) gives a smaller radius as heal scale goes down
}, },
effect() { effect() {
if (!mod.isEnergyHealth && mech.alive) { if (!tech.isEnergyHealth && mech.alive) {
const heal = mod.largerHeals * (this.size / 40 / Math.sqrt(mod.largerHeals) / (game.healScale ** 0.25)) ** 2 //heal scale is undone here because heal scale is properly affected on mech.addHealth() const heal = tech.largerHeals * (this.size / 40 / Math.sqrt(tech.largerHeals) / (simulation.healScale ** 0.25)) ** 2 //heal scale is undone here because heal scale is properly affected on mech.addHealth()
if (heal > 0) { if (heal > 0) {
game.makeTextLog("<div class='circle heal'></div> &nbsp; <span style='font-size:115%;'> <strong style = 'letter-spacing: 2px;'>heal</strong> " + (Math.min(mech.maxHealth - mech.health, heal) * game.healScale * 100).toFixed(0) + "%</span>", 300) const healOutput = Math.min(mech.maxHealth - mech.health, heal) * simulation.healScale
mech.addHealth(heal); mech.addHealth(heal);
simulation.makeTextLog(`<span class='color-var'>mech</span>.health <span class='color-symbol'>+=</span> ${(healOutput).toFixed(3)}`) // <br>${mech.health.toFixed(3)}
// simulation.makeTextLog("<div class='circle heal'></div> &nbsp; <span style='font-size:115%;'> <strong style = 'letter-spacing: 2px;'>heal</strong> " + (Math.min(mech.maxHealth - mech.health, heal) * simulation.healScale * 100).toFixed(0) + "%</span>", 300)
} }
} }
if (mod.healGiveMaxEnergy) { if (tech.healGiveMaxEnergy) {
mod.healMaxEnergyBonus += 0.04 tech.healMaxEnergyBonus += 0.04
mech.setMaxEnergy(); mech.setMaxEnergy();
} }
}, },
spawn(x, y, size) { //used to spawn a heal with a specific size / heal amount, not normally used spawn(x, y, size) { //used to spawn a heal with a specific size / heal amount, not normally used
powerUps.directSpawn(x, y, "heal", false, null, size) powerUps.directSpawn(x, y, "heal", false, null, size)
if (Math.random() < mod.duplicationChance()) { if (Math.random() < tech.duplicationChance()) {
powerUps.directSpawn(x, y, "heal", false, null, size) powerUps.directSpawn(x, y, "heal", false, null, size)
powerUp[powerUp.length - 1].isBonus = true powerUp[powerUp.length - 1].isBonus = true
} }
@@ -186,20 +169,27 @@ const powerUps = {
}, },
effect() { effect() {
//give ammo to all guns in inventory //give ammo to all guns in inventory
if (mod.isAmmoForGun && b.inventory.length > 0) { if (tech.isAmmoForGun && b.inventory.length > 0) {
const target = b.guns[b.activeGun] const target = b.guns[b.activeGun]
const ammoAdded = Math.ceil(Math.random() * target.ammoPack) + Math.ceil(Math.random() * target.ammoPack) const ammoAdded = Math.ceil(Math.random() * target.ammoPack) + Math.ceil(Math.random() * target.ammoPack)
target.ammo += ammoAdded target.ammo += ammoAdded
// game.makeTextLog(`<div class='circle gun'></div> &nbsp; ${ammoAdded} ammo added`, 300) // simulation.makeTextLog(`<div class='circle gun'></div> &nbsp; ${ammoAdded} ammo added`, 300)
simulation.makeTextLog(`${target.name}.<span class='color-gun'>ammo</span> <span class='color-symbol'>+=</span> ${ammoAdded}
<br>${target.ammo}`)
} else { } else {
let text = '';
for (let i = 0, len = b.inventory.length; i < len; i++) { for (let i = 0, len = b.inventory.length; i < len; i++) {
const target = b.guns[b.inventory[i]] const target = b.guns[b.inventory[i]]
if (target.ammo !== Infinity) { if (target.ammo !== Infinity) {
target.ammo += Math.ceil(Math.random() * target.ammoPack) const ammoAdded = Math.ceil(Math.random() * target.ammoPack)
target.ammo += ammoAdded
if (i !== 0) text += "<br>"
text += `${target.name}.<span class='color-gun'>ammo</span> <span class='color-symbol'>+=</span> ${ammoAdded}`
} }
} }
simulation.makeTextLog(text)
} }
game.updateGunHUD(); simulation.updateGunHUD();
} }
}, },
field: { field: {
@@ -216,7 +206,7 @@ const powerUps = {
if (i !== mech.fieldMode && 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 = tech.isDeterminism ? 1 : 3 + tech.isExtraChoice * 2
if (powerUps.field.choiceLog.length > totalChoices || powerUps.field.choiceLog.length === totalChoices) { //make sure this isn't the first time getting a power up and there are previous choices to remove if (powerUps.field.choiceLog.length > totalChoices || powerUps.field.choiceLog.length === totalChoices) { //make sure this isn't the first time getting a power up and there are previous choices to remove
for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection
if (options.length > totalChoices) { if (options.length > totalChoices) {
@@ -239,16 +229,16 @@ const powerUps = {
let choice3 = -1 let choice3 = -1
if (choice1 > -1) { if (choice1 > -1) {
let text = "" let text = ""
if (!mod.isDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("field",true)'>✕</div>` if (!tech.isDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("field",true)'>✕</div>`
text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>choose a field</h3>` text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>field</h3>`
text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice1})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${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> &nbsp; ${mech.fieldUpgrades[choice1].name}</div> ${mech.fieldUpgrades[choice1].description}</div>`
if (!mod.isDeterminism) { if (!tech.isDeterminism) {
choice2 = pick(mech.fieldUpgrades, choice1) choice2 = pick(mech.fieldUpgrades, choice1)
if (choice2 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice2})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${mech.fieldUpgrades[choice2].name}</div> ${mech.fieldUpgrades[choice2].description}</div>` if (choice2 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice2})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${mech.fieldUpgrades[choice2].name}</div> ${mech.fieldUpgrades[choice2].description}</div>`
choice3 = pick(mech.fieldUpgrades, choice1, choice2) choice3 = pick(mech.fieldUpgrades, choice1, choice2)
if (choice3 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice3})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${mech.fieldUpgrades[choice3].name}</div> ${mech.fieldUpgrades[choice3].description}</div>` if (choice3 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice3})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${mech.fieldUpgrades[choice3].name}</div> ${mech.fieldUpgrades[choice3].description}</div>`
} }
if (mod.isExtraChoice) { if (tech.isExtraChoice) {
let choice4 = pick(mech.fieldUpgrades, choice1, choice2, choice3) let choice4 = pick(mech.fieldUpgrades, choice1, choice2, choice3)
if (choice4 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice4})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${mech.fieldUpgrades[choice4].name}</div> ${mech.fieldUpgrades[choice4].description}</div>` if (choice4 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice4})"><div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${mech.fieldUpgrades[choice4].name}</div> ${mech.fieldUpgrades[choice4].description}</div>`
let choice5 = pick(mech.fieldUpgrades, choice1, choice2, choice3, choice4) let choice5 = pick(mech.fieldUpgrades, choice1, choice2, choice3, choice4)
@@ -260,9 +250,13 @@ const powerUps = {
powerUps.field.choiceLog.push(choice2) powerUps.field.choiceLog.push(choice2)
powerUps.field.choiceLog.push(choice3) powerUps.field.choiceLog.push(choice3)
if (powerUps.reroll.rerolls) text += `<div class="choose-grid-module" onclick="powerUps.reroll.use('field')"><div class="grid-title"><div class="circle-grid reroll"></div> &nbsp; reroll <span class='dice'>${powerUps.reroll.diceText()}</span></div></div>` if (powerUps.reroll.rerolls) {
text += `<div class="choose-grid-module" onclick="powerUps.reroll.use('field')"><div class="grid-title"> <span style="position:relative;">`
// text += `<div style = 'color:#fff'>${game.SVGrightMouse} activate the shield with the right mouse<br>fields shield you from damage <br>and let you pick up and throw blocks</div>` for (let i = 0, len = Math.min(powerUps.reroll.rerolls, 30); i < len; i++) text += `<div class="circle-grid reroll" style="position:absolute; top:0; left:${(18 - len*0.3)*i}px ;opacity:0.8; border: 1px #fff solid;"></div>`
text += `</span><span class='reroll-select'>reroll</span></div></div>`
}
//(${powerUps.reroll.rerolls})
// text += `<div style = 'color:#fff'>${simulation.SVGrightMouse} activate the shield with the right mouse<br>fields shield you from damage <br>and let you pick up and throw blocks</div>`
document.getElementById("choose-grid").innerHTML = text document.getElementById("choose-grid").innerHTML = text
powerUps.showDraft(); powerUps.showDraft();
} else { } else {
@@ -270,42 +264,42 @@ const powerUps = {
} }
} }
}, },
mod: { tech: {
name: "mod", name: "tech",
color: "hsl(246,100%,77%)", //"#a8f", color: "hsl(246,100%,77%)", //"#a8f",
size() { size() {
return 42; return 42;
}, },
choiceLog: [], //records all previous choice options choiceLog: [], //records all previous choice options
lastTotalChoices: 0, //tracks how many mods were available for random selection last time a mod was picked up lastTotalChoices: 0, //tracks how many tech were available for random selection last time a tech was picked up
banishLog: [], //records all mods permanently removed from the selection pool banishLog: [], //records all tech permanently removed from the selection pool
effect() { effect() {
if (mech.alive) { if (mech.alive) {
function pick(skip1 = -1, skip2 = -1, skip3 = -1, skip4 = -1) { function pick(skip1 = -1, skip2 = -1, skip3 = -1, skip4 = -1) {
let options = []; let options = [];
for (let i = 0; i < mod.mods.length; i++) { for (let i = 0; i < tech.tech.length; i++) {
if (mod.mods[i].count < mod.mods[i].maxCount && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4 && mod.mods[i].allowed()) { if (tech.tech[i].count < tech.tech[i].maxCount && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4 && tech.tech[i].allowed()) {
options.push(i); options.push(i);
} }
} }
powerUps.mod.lastTotalChoices = options.length //this is recorded so that banish can know how many mods were available powerUps.tech.lastTotalChoices = options.length //this is recorded so that banish can know how many tech were available
if (mod.isBanish) { //remove banished mods from last selection if (tech.isBanish) { //remove banished tech from last selection
for (let i = 0; i < powerUps.mod.banishLog.length; i++) { for (let i = 0; i < powerUps.tech.banishLog.length; i++) {
for (let j = 0; j < options.length; j++) { for (let j = 0; j < options.length; j++) {
if (powerUps.mod.banishLog[i] === options[j]) { if (powerUps.tech.banishLog[i] === options[j]) {
options.splice(j, 1) options.splice(j, 1)
break break
} }
} }
} }
} else { //remove repeats from last selection } else { //remove repeats from last selection
const totalChoices = mod.isDeterminism ? 1 : 3 + mod.isExtraChoice * 2 const totalChoices = tech.isDeterminism ? 1 : 3 + tech.isExtraChoice * 2
if (powerUps.mod.choiceLog.length > totalChoices || powerUps.mod.choiceLog.length === totalChoices) { //make sure this isn't the first time getting a power up and there are previous choices to remove if (powerUps.tech.choiceLog.length > totalChoices || powerUps.tech.choiceLog.length === totalChoices) { //make sure this isn't the first time getting a power up and there are previous choices to remove
for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection
if (options.length > totalChoices) { if (options.length > totalChoices) {
for (let j = 0, len = options.length; j < len; j++) { for (let j = 0, len = options.length; j < len; j++) {
if (powerUps.mod.choiceLog[powerUps.mod.choiceLog.length - 1 - i] === options[j]) { if (powerUps.tech.choiceLog[powerUps.tech.choiceLog.length - 1 - i] === options[j]) {
options.splice(j, 1) //remove previous choice from option pool options.splice(j, 1) //remove previous choice from option pool
break break
} }
@@ -317,67 +311,73 @@ const powerUps = {
if (options.length > 0) { if (options.length > 0) {
const choose = options[Math.floor(Math.random() * options.length)] const choose = options[Math.floor(Math.random() * options.length)]
const isCount = mod.mods[choose].count > 0 ? `(${mod.mods[choose].count+1}x)` : ""; const isCount = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count+1}x)` : "";
if (mod.mods[choose].isFieldMod) { if (tech.tech[choose].isFieldMod) {
text += `<div class="choose-grid-module" onclick="powerUps.choose('mod',${choose})"><div class="grid-title"> text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title">
<span style="position:relative;"> <span style="position:relative;">
<div class="circle-grid mod" style="position:absolute; top:0; left:0;opacity:0.8;"></div> <div class="circle-grid tech" style="position:absolute; top:0; left:0;opacity:0.8;"></div>
<div class="circle-grid field" style="position:absolute; top:0; left:10px;opacity:0.65;"></div> <div class="circle-grid field" style="position:absolute; top:0; left:10px;opacity:0.65;"></div>
</span> </span>
&nbsp; &nbsp; &nbsp; &nbsp; ${mod.mods[choose].name} ${isCount}</div>${mod.mods[choose].description}</div></div>` &nbsp; &nbsp; &nbsp; &nbsp; ${tech.tech[choose].name} ${isCount}</div>${tech.tech[choose].description}</div></div>`
} else if (mod.mods[choose].isGunMod) { } else if (tech.tech[choose].isGunMod) {
text += `<div class="choose-grid-module" onclick="powerUps.choose('mod',${choose})"><div class="grid-title"> text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title">
<span style="position:relative;"> <span style="position:relative;">
<div class="circle-grid mod" style="position:absolute; top:0; left:0;opacity:0.8;"></div> <div class="circle-grid tech" style="position:absolute; top:0; left:0;opacity:0.8;"></div>
<div class="circle-grid gun" style="position:absolute; top:0; left:10px; opacity:0.65;"></div> <div class="circle-grid gun" style="position:absolute; top:0; left:10px; opacity:0.65;"></div>
</span> </span>
&nbsp; &nbsp; &nbsp; &nbsp; ${mod.mods[choose].name} ${isCount}</div>${mod.mods[choose].description}</div></div>` &nbsp; &nbsp; &nbsp; &nbsp; ${tech.tech[choose].name} ${isCount}</div>${tech.tech[choose].description}</div></div>`
} else { } else {
text += `<div class="choose-grid-module" onclick="powerUps.choose('mod',${choose})"><div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${mod.mods[choose].name} ${isCount}</div>${mod.mods[choose].description}</div>` text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[choose].name} ${isCount}</div>${tech.tech[choose].description}</div>`
} }
// text += `<div class="choose-grid-module" onclick="powerUps.choose('mod',${choose})"><div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${mod.mods[choose].name}</div> ${mod.mods[choose].description}</div>` // text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[choose].name}</div> ${tech.tech[choose].description}</div>`
return choose return choose
} }
} }
let text = "" let text = ""
if (!mod.isDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("mod",true)'>✕</div>` if (!tech.isDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("tech",true)'>✕</div>`
text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>choose a mod</h3>` text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>tech</h3>`
let choice1 = pick() let choice1 = pick()
let choice2 = -1 let choice2 = -1
let choice3 = -1 let choice3 = -1
if (choice1 > -1) { if (choice1 > -1) {
if (!mod.isDeterminism) { if (!tech.isDeterminism) {
choice2 = pick(choice1) choice2 = pick(choice1)
// if (choice2 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('mod',${choice2})"><div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${mod.mods[choice2].name}</div> ${mod.mods[choice2].description}</div>` // if (choice2 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choice2})"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[choice2].name}</div> ${tech.tech[choice2].description}</div>`
choice3 = pick(choice1, choice2) choice3 = pick(choice1, choice2)
// if (choice3 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('mod',${choice3})"><div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${mod.mods[choice3].name}</div> ${mod.mods[choice3].description}</div>` // if (choice3 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choice3})"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[choice3].name}</div> ${tech.tech[choice3].description}</div>`
} }
if (mod.isExtraChoice) { if (tech.isExtraChoice) {
let choice4 = pick(choice1, choice2, choice3) let choice4 = pick(choice1, choice2, choice3)
// if (choice4 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('mod',${choice4})"><div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${mod.mods[choice4].name}</div> ${mod.mods[choice4].description}</div>` // if (choice4 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choice4})"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[choice4].name}</div> ${tech.tech[choice4].description}</div>`
let choice5 = pick(choice1, choice2, choice3, choice4) let choice5 = pick(choice1, choice2, choice3, choice4)
// if (choice5 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('mod',${choice5})"><div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${mod.mods[choice5].name}</div> ${mod.mods[choice5].description}</div>` // if (choice5 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choice5})"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[choice5].name}</div> ${tech.tech[choice5].description}</div>`
powerUps.mod.choiceLog.push(choice4) powerUps.tech.choiceLog.push(choice4)
powerUps.mod.choiceLog.push(choice5) powerUps.tech.choiceLog.push(choice5)
}
powerUps.tech.choiceLog.push(choice1)
powerUps.tech.choiceLog.push(choice2)
powerUps.tech.choiceLog.push(choice3)
// if (powerUps.reroll.rerolls) text += `<div class="choose-grid-module" onclick="powerUps.reroll.use('tech')"><div class="grid-title"><div class="circle-grid reroll"></div> &nbsp; reroll <span class="reroll-select">${powerUps.reroll.rerolls}</span></div></div>`
if (powerUps.reroll.rerolls) {
text += `<div class="choose-grid-module" onclick="powerUps.reroll.use('tech')"><div class="grid-title"> <span style="position:relative;">`
for (let i = 0, len = Math.min(powerUps.reroll.rerolls, 30); i < len; i++) text += `<div class="circle-grid reroll" style="position:absolute; top:0; left:${(18 - len*0.3)*i}px ;opacity:0.8; border: 1px #fff solid;"></div>`
text += `</span><span class='reroll-select'>reroll</span></div></div>`
} }
powerUps.mod.choiceLog.push(choice1)
powerUps.mod.choiceLog.push(choice2)
powerUps.mod.choiceLog.push(choice3)
if (powerUps.reroll.rerolls) text += `<div class="choose-grid-module" onclick="powerUps.reroll.use('mod')"><div class="grid-title"><div class="circle-grid reroll"></div> &nbsp; reroll <span class='dice'>${powerUps.reroll.diceText()}</span></div></div>`
document.getElementById("choose-grid").innerHTML = text document.getElementById("choose-grid").innerHTML = text
powerUps.showDraft(); powerUps.showDraft();
} else { } else {
if (mod.isBanish) { if (tech.isBanish) {
for (let i = 0, len = mod.mods.length; i < len; i++) { for (let i = 0, len = tech.tech.length; i < len; i++) {
if (mod.mods[i].name === "erase") powerUps.ejectMod(i) if (tech.tech[i].name === "erase") powerUps.ejectMod(i)
} }
game.makeTextLog(`No <strong class='color-m'>mods</strong> left<br>erased <strong class='color-m'>mods</strong> have been recovered`, 300) simulation.makeTextLog(`No <strong class='color-m'>tech</strong> left<br>erased <strong class='color-m'>tech</strong> have been recovered`)
powerUps.spawn(mech.pos.x, mech.pos.y, "mod"); powerUps.spawn(mech.pos.x, mech.pos.y, "tech");
powerUps.endDraft("mod"); powerUps.endDraft("tech");
} else { } else {
powerUps.giveRandomAmmo() powerUps.giveRandomAmmo()
} }
@@ -402,7 +402,7 @@ const powerUps = {
} }
//remove repeats from last selection //remove repeats from last selection
const totalChoices = mod.isDeterminism ? 1 : 3 + mod.isExtraChoice * 2 const totalChoices = tech.isDeterminism ? 1 : 3 + tech.isExtraChoice * 2
if (powerUps.gun.choiceLog.length > totalChoices || powerUps.gun.choiceLog.length === totalChoices) { //make sure this isn't the first time getting a power up and there are previous choices to remove if (powerUps.gun.choiceLog.length > totalChoices || powerUps.gun.choiceLog.length === totalChoices) { //make sure this isn't the first time getting a power up and there are previous choices to remove
for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection
if (options.length > totalChoices) { if (options.length > totalChoices) {
@@ -425,16 +425,16 @@ const powerUps = {
let choice3 = -1 let choice3 = -1
if (choice1 > -1) { if (choice1 > -1) {
let text = "" let text = ""
if (!mod.isDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("gun",true)'>✕</div>` if (!tech.isDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("gun",true)'>✕</div>`
text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>choose a gun</h3>` text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>gun</h3>`
text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice1})"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${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> &nbsp; ${b.guns[choice1].name}</div> ${b.guns[choice1].description}</div>`
if (!mod.isDeterminism) { if (!tech.isDeterminism) {
choice2 = pick(b.guns, choice1) choice2 = pick(b.guns, choice1)
if (choice2 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice2})"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[choice2].name}</div> ${b.guns[choice2].description}</div>` if (choice2 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice2})"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[choice2].name}</div> ${b.guns[choice2].description}</div>`
choice3 = pick(b.guns, choice1, choice2) choice3 = pick(b.guns, choice1, choice2)
if (choice3 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice3})"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[choice3].name}</div> ${b.guns[choice3].description}</div>` if (choice3 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice3})"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[choice3].name}</div> ${b.guns[choice3].description}</div>`
} }
if (mod.isExtraChoice) { if (tech.isExtraChoice) {
let choice4 = pick(b.guns, choice1, choice2, choice3) let choice4 = pick(b.guns, choice1, choice2, choice3)
if (choice4 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice4})"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[choice4].name}</div> ${b.guns[choice4].description}</div>` if (choice4 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice4})"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${b.guns[choice4].name}</div> ${b.guns[choice4].description}</div>`
let choice5 = pick(b.guns, choice1, choice2, choice3, choice4) let choice5 = pick(b.guns, choice1, choice2, choice3, choice4)
@@ -446,11 +446,15 @@ const powerUps = {
powerUps.gun.choiceLog.push(choice1) powerUps.gun.choiceLog.push(choice1)
powerUps.gun.choiceLog.push(choice2) powerUps.gun.choiceLog.push(choice2)
powerUps.gun.choiceLog.push(choice3) powerUps.gun.choiceLog.push(choice3)
if (powerUps.reroll.rerolls) text += `<div class="choose-grid-module" onclick="powerUps.reroll.use('gun')"><div class="grid-title"><div class="circle-grid reroll"></div> &nbsp; reroll <span class='dice'>${powerUps.reroll.diceText()}</span></div></div>` // if (powerUps.reroll.rerolls) text += `<div class="choose-grid-module" onclick="powerUps.reroll.use('gun')"><div class="grid-title"><div class="circle-grid reroll"></div> &nbsp; reroll <span class="reroll-select">${powerUps.reroll.rerolls}</span></div></div>`
if (powerUps.reroll.rerolls) {
text += `<div class="choose-grid-module" onclick="powerUps.reroll.use('gun')"><div class="grid-title"> <span style="position:relative;">`
for (let i = 0, len = Math.min(powerUps.reroll.rerolls, 30); i < len; i++) text += `<div class="circle-grid reroll" style="position:absolute; top:0; left:${(18 - len*0.3)*i}px ;opacity:0.8; border: 1px #fff solid;"></div>`
text += `</span><span class='reroll-select'>reroll</span></div></div>`
}
// console.log(powerUps.gun.choiceLog) // console.log(powerUps.gun.choiceLog)
// console.log(choice1, choice2, choice3) // console.log(choice1, choice2, choice3)
if (mod.isOneGun) text += `<div style = "color: #f24">replaces your current gun</div>` if (tech.isOneGun) text += `<div style = "color: #f24">replaces your current gun</div>`
document.getElementById("choose-grid").innerHTML = text document.getElementById("choose-grid").innerHTML = text
powerUps.showDraft(); powerUps.showDraft();
} else { } else {
@@ -459,29 +463,26 @@ const powerUps = {
} }
}, },
onPickUp(where) { onPickUp(where) {
if (mod.isMassEnergy) mech.energy += 2.5; if (tech.isMassEnergy) mech.energy += 2.5;
if (mod.isMineDrop) b.mine({ if (tech.isMineDrop) b.mine({
x: where.x, x: where.x,
y: where.y y: where.y
}, { }, {
x: 0, x: 0,
y: 0 y: 0
}, 0, mod.isMineAmmoBack) }, 0, tech.isMineAmmoBack)
}, },
giveRandomAmmo() { giveRandomAmmo() {
const ammoTarget = Math.floor(Math.random() * (b.guns.length)); const ammoTarget = Math.floor(Math.random() * (b.guns.length));
const ammo = Math.ceil(b.guns[ammoTarget].ammoPack * 6); const ammo = Math.ceil(b.guns[ammoTarget].ammoPack * 6);
if (ammo === Infinity) { if (ammo !== Infinity) {
b.guns[ammoTarget].ammo += ammo; b.guns[ammoTarget].ammo += ammo;
game.makeTextLog("<span style='font-size:115%;'><span class='color-f'>+energy</span></span>", 300); simulation.updateGunHUD();
} else { simulation.makeTextLog(`${b.guns[ammoTarget].name}.<span class='color-gun'>ammo</span> <span class='color-symbol'>+=</span> ${ammo}`);
b.guns[ammoTarget].ammo += ammo;
game.updateGunHUD();
game.makeTextLog("<span style='font-size:110%;'>+" + ammo + " ammo for " + b.guns[ammoTarget].name + "</span>", 300);
} }
}, },
spawnRandomPowerUp(x, y) { //mostly used after mob dies, doesn't always return a power up spawnRandomPowerUp(x, y) { //mostly used after mob dies, doesn't always return a power up
if ((Math.random() * Math.random() - 0.3 > Math.sqrt(mech.health) && !mod.isEnergyHealth) || Math.random() < 0.04) { //spawn heal chance is higher at low health if ((Math.random() * Math.random() - 0.3 > Math.sqrt(mech.health) && !tech.isEnergyHealth) || Math.random() < 0.04) { //spawn heal chance is higher at low health
powerUps.spawn(x, y, "heal"); powerUps.spawn(x, y, "heal");
return; return;
} }
@@ -493,8 +494,8 @@ const powerUps = {
powerUps.spawn(x, y, "gun"); powerUps.spawn(x, y, "gun");
return; return;
} }
if (Math.random() < 0.0027 * (25 - mod.totalCount)) { //a new mod has a low chance for each not acquired mod up to 15 if (Math.random() < 0.0027 * (25 - tech.totalCount)) { //a new tech has a low chance for each not acquired tech up to 15
powerUps.spawn(x, y, "mod"); powerUps.spawn(x, y, "tech");
return; return;
} }
if (Math.random() < 0.006) { if (Math.random() < 0.006) {
@@ -507,7 +508,7 @@ const powerUps = {
// } // }
}, },
randomPowerUpCounter: 0, randomPowerUpCounter: 0,
spawnBossPowerUp(x, y) { //boss spawns field and gun mod upgrades spawnBossPowerUp(x, y) { //boss spawns field and gun tech upgrades
level.bossKilled = true; level.bossKilled = true;
if (mech.fieldMode === 0) { if (mech.fieldMode === 0) {
@@ -523,12 +524,12 @@ const powerUps = {
if (Math.random() * chanceToFail < powerUps.randomPowerUpCounter) { if (Math.random() * chanceToFail < powerUps.randomPowerUpCounter) {
powerUps.randomPowerUpCounter = 0; powerUps.randomPowerUpCounter = 0;
if (Math.random() < 0.95) { if (Math.random() < 0.95) {
powerUps.spawn(x, y, "mod") powerUps.spawn(x, y, "tech")
} else { } else {
powerUps.spawn(x, y, "gun") powerUps.spawn(x, y, "gun")
} }
} else { } else {
if (mech.health < 0.65 && !mod.isEnergyHealth) { if (mech.health < 0.65 && !tech.isEnergyHealth) {
powerUps.spawn(x, y, "heal"); powerUps.spawn(x, y, "heal");
powerUps.spawn(x, y, "heal"); powerUps.spawn(x, y, "heal");
} else { } else {
@@ -553,20 +554,20 @@ const powerUps = {
}, },
spawnStartingPowerUps(x, y) { //used for map specific power ups, mostly to give player a starting gun spawnStartingPowerUps(x, y) { //used for map specific power ups, mostly to give player a starting gun
if (level.levelsCleared < 4) { //runs 4 times on all difficulty levels if (level.levelsCleared < 4) { //runs 4 times on all difficulty levels
if (level.levelsCleared > 1) powerUps.spawn(x, y, "mod") if (level.levelsCleared > 1) powerUps.spawn(x, y, "tech")
//bonus power ups for clearing runs in the last game //bonus power ups for clearing runs in the last game
if (level.levelsCleared === 0 && !game.isCheating) { if (level.levelsCleared === 0 && !simulation.isCheating) {
for (let i = 0; i < localSettings.levelsClearedLastGame / 4 - 1; i++) { for (let i = 0; i < localSettings.levelsClearedLastGame / 4 - 1; i++) {
powerUps.spawn(mech.pos.x, mech.pos.y, "mod", false); //spawn a mod for levels cleared in last game powerUps.spawn(mech.pos.x, mech.pos.y, "tech", false); //spawn a tech for levels cleared in last game
} }
localSettings.levelsClearedLastGame = 0 //after getting bonus power ups reset run history localSettings.levelsClearedLastGame = 0 //after getting bonus power ups reset run history
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
} }
if (b.inventory.length === 0) { if (b.inventory.length === 0) {
powerUps.spawn(x, y, "gun", false); //first gun powerUps.spawn(x, y, "gun", false); //first gun
} else if (mod.totalCount === 0) { //first mod } else if (tech.totalCount === 0) { //first tech
powerUps.spawn(x, y, "mod", false); powerUps.spawn(x, y, "tech", false);
} else if (b.inventory.length < 2) { //second gun or extra ammo } else if (b.inventory.length < 2) { //second gun or extra ammo
if (Math.random() < 0.5) { if (Math.random() < 0.5) {
powerUps.spawn(x, y, "gun", false); powerUps.spawn(x, y, "gun", false);
@@ -589,38 +590,48 @@ const powerUps = {
} }
}, },
ejectMod(choose = 'random') { ejectMod(choose = 'random') {
//find which mods you have //find which tech you have
if (choose === 'random') { if (choose === 'random') {
const have = [] const have = []
for (let i = 0; i < mod.mods.length; i++) { for (let i = 0; i < tech.tech.length; i++) {
if (mod.mods[i].count > 0) have.push(i) if (tech.tech[i].count > 0 && !tech.tech[i].isNonRefundable) have.push(i)
} }
if (have.length === 0) {
for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].count > 0) have.push(i)
}
}
if (have.length) { if (have.length) {
choose = have[Math.floor(Math.random() * have.length)] choose = have[Math.floor(Math.random() * have.length)]
game.makeTextLog(`<div class='circle mod'></div> &nbsp; <strong>${mod.mods[choose].name}</strong> was ejected`, 600) //message about what mod was lost // simulation.makeTextLog(`<div class='circle tech'></div> &nbsp; <strong>${tech.tech[choose].name}</strong> was ejected`, 600) //message about what tech was lost
for (let i = 0; i < mod.mods[choose].count; i++) { simulation.makeTextLog(`<span class='color-var'>tech</span>.remove("<span class='color-text'>${tech.tech[choose].name}</span>")`)
powerUps.directSpawn(mech.pos.x, mech.pos.y, "mod");
for (let i = 0; i < tech.tech[choose].count; i++) {
powerUps.directSpawn(mech.pos.x, mech.pos.y, "tech");
powerUp[powerUp.length - 1].isBonus = true powerUp[powerUp.length - 1].isBonus = true
} }
// remove a random mod from the list of mods you have // remove a random tech from the list of tech you have
mod.mods[choose].remove(); tech.tech[choose].remove();
mod.mods[choose].count = 0; tech.tech[choose].count = 0;
mod.mods[choose].isLost = true; tech.tech[choose].isLost = true;
game.updateModHUD(); simulation.updateModHUD();
mech.fieldCDcycle = mech.cycle + 30; //disable field so you can't pick up the ejected mod mech.fieldCDcycle = mech.cycle + 30; //disable field so you can't pick up the ejected tech
} }
} else { } else {
game.makeTextLog(`<div class='circle mod'></div> &nbsp; <strong>${mod.mods[choose].name}</strong> was ejected`, 600) //message about what mod was lost // simulation.makeTextLog(`<div class='circle tech'></div> &nbsp; <strong>${tech.tech[choose].name}</strong> was ejected`, 600) //message about what tech was lost
for (let i = 0; i < mod.mods[choose].count; i++) { simulation.makeTextLog(`<span class='color-var'>tech</span>.remove("<span class='color-text'>${tech.tech[choose].name}</span>")`)
powerUps.directSpawn(mech.pos.x, mech.pos.y, "mod");
for (let i = 0; i < tech.tech[choose].count; i++) {
powerUps.directSpawn(mech.pos.x, mech.pos.y, "tech");
powerUp[powerUp.length - 1].isBonus = true powerUp[powerUp.length - 1].isBonus = true
} }
// remove a random mod from the list of mods you have // remove a random tech from the list of tech you have
mod.mods[choose].remove(); tech.tech[choose].remove();
mod.mods[choose].count = 0; tech.tech[choose].count = 0;
mod.mods[choose].isLost = true; tech.tech[choose].isLost = true;
game.updateModHUD(); simulation.updateModHUD();
mech.fieldCDcycle = mech.cycle + 30; //disable field so you can't pick up the ejected mod mech.fieldCDcycle = mech.cycle + 30; //disable field so you can't pick up the ejected tech
} }
}, },
directSpawn(x, y, target, moving = true, mode = null, size = powerUps[target].size()) { directSpawn(x, y, target, moving = true, mode = null, size = powerUps[target].size()) {
@@ -654,12 +665,12 @@ const powerUps = {
}, },
spawn(x, y, target, moving = true, mode = null, size = powerUps[target].size()) { spawn(x, y, target, moving = true, mode = null, size = powerUps[target].size()) {
if ( if (
(!mod.isSuperDeterminism || (target === 'mod' || target === 'heal' || target === 'ammo')) && (!tech.isSuperDeterminism || (target === 'tech' || target === 'heal' || target === 'ammo')) &&
!(mod.isEnergyNoAmmo && target === 'ammo') && !(tech.isEnergyNoAmmo && target === 'ammo') &&
(!game.isNoPowerUps || (target === 'reroll' || target === 'heal' || target === 'ammo')) (!simulation.isNoPowerUps || (target === 'reroll' || target === 'heal' || target === 'ammo'))
) { ) {
powerUps.directSpawn(x, y, target, moving, mode, size) powerUps.directSpawn(x, y, target, moving, mode, size)
if (Math.random() < mod.duplicationChance()) { if (Math.random() < tech.duplicationChance()) {
powerUps.directSpawn(x, y, target, moving, mode, size) powerUps.directSpawn(x, y, target, moving, mode, size)
powerUp[powerUp.length - 1].isBonus = true powerUp[powerUp.length - 1].isBonus = true
} }

View File

@@ -1,12 +1,12 @@
// game Object ******************************************************** // game Object ********************************************************
//********************************************************************* //*********************************************************************
const game = { const simulation = {
loop() {}, //main game loop, gets se tto normal or testing loop loop() {}, //main game loop, gets se tto normal or testing loop
normalLoop() { normalLoop() {
game.gravity(); simulation.gravity();
Engine.update(engine, game.delta); Engine.update(engine, simulation.delta);
game.wipe(); simulation.wipe();
game.textLog(); simulation.textLog();
if (mech.onGround) { if (mech.onGround) {
mech.groundControl() mech.groundControl()
} else { } else {
@@ -16,17 +16,17 @@ const game = {
level.checkQuery(); level.checkQuery();
mech.move(); mech.move();
mech.look(); mech.look();
game.checks(); simulation.checks();
ctx.save(); ctx.save();
game.camera(); simulation.camera();
level.drawFillBGs(); level.drawFillBGs();
level.exit.draw(); level.exit.draw();
level.enter.draw(); level.enter.draw();
level.custom(); level.custom();
game.draw.powerUp(); simulation.draw.powerUp();
mobs.draw(); mobs.draw();
game.draw.cons(); simulation.draw.cons();
game.draw.body(); simulation.draw.body();
mobs.loop(); mobs.loop();
mobs.healthBar(); mobs.healthBar();
mech.draw(); mech.draw();
@@ -34,22 +34,22 @@ const game = {
// v.draw(); //working on visibility work in progress // v.draw(); //working on visibility work in progress
level.drawFills(); level.drawFills();
level.customTopLayer(); level.customTopLayer();
game.draw.drawMapPath(); simulation.draw.drawMapPath();
b.fire(); b.fire();
b.bulletRemove(); b.bulletRemove();
b.bulletDraw(); b.bulletDraw();
b.bulletDo(); b.bulletDo();
game.drawCircle(); simulation.drawCircle();
// game.clip(); // simulation.clip();
ctx.restore(); ctx.restore();
game.drawCursor(); simulation.drawCursor();
// game.pixelGraphics(); // simulation.pixelGraphics();
}, },
testingLoop() { testingLoop() {
game.gravity(); simulation.gravity();
Engine.update(engine, game.delta); Engine.update(engine, simulation.delta);
game.wipe(); simulation.wipe();
game.textLog(); simulation.textLog();
if (mech.onGround) { if (mech.onGround) {
mech.groundControl() mech.groundControl()
} else { } else {
@@ -60,28 +60,28 @@ const game = {
level.checkQuery(); level.checkQuery();
mech.move(); mech.move();
mech.look(); mech.look();
game.checks(); simulation.checks();
ctx.save(); ctx.save();
game.camera(); simulation.camera();
mech.draw(); mech.draw();
level.customTopLayer(); level.customTopLayer();
game.draw.wireFrame(); simulation.draw.wireFrame();
game.draw.cons(); simulation.draw.cons();
game.draw.testing(); simulation.draw.testing();
game.drawCircle(); simulation.drawCircle();
game.constructCycle() simulation.constructCycle()
ctx.restore(); ctx.restore();
game.testingOutput(); simulation.testingOutput();
game.drawCursor(); simulation.drawCursor();
}, },
isTimeSkipping: false, isTimeSkipping: false,
timeSkip(cycles = 60) { timeSkip(cycles = 60) {
game.isTimeSkipping = true; simulation.isTimeSkipping = true;
for (let i = 0; i < cycles; i++) { for (let i = 0; i < cycles; i++) {
game.cycle++; simulation.cycle++;
mech.cycle++; mech.cycle++;
game.gravity(); simulation.gravity();
Engine.update(engine, game.delta); Engine.update(engine, simulation.delta);
if (mech.onGround) { if (mech.onGround) {
mech.groundControl() mech.groundControl()
} else { } else {
@@ -91,7 +91,7 @@ const game = {
level.checkZones(); level.checkZones();
level.checkQuery(); level.checkQuery();
mech.move(); mech.move();
game.checks(); simulation.checks();
mobs.loop(); mobs.loop();
// mech.draw(); // mech.draw();
mech.walk_cycle += mech.flipLegs * mech.Vx; mech.walk_cycle += mech.flipLegs * mech.Vx;
@@ -101,7 +101,7 @@ const game = {
b.bulletRemove(); b.bulletRemove();
b.bulletDo(); b.bulletDo();
} }
game.isTimeSkipping = false; simulation.isTimeSkipping = false;
}, },
mouse: { mouse: {
x: canvas.width / 2, x: canvas.width / 2,
@@ -136,13 +136,13 @@ const game = {
lookFreqScale: null, //set in levels.setDifficulty lookFreqScale: null, //set in levels.setDifficulty
isNoPowerUps: false, isNoPowerUps: false,
// dropFPS(cap = 40, time = 15) { // dropFPS(cap = 40, time = 15) {
// game.fpsCap = cap // simulation.fpsCap = cap
// game.fpsInterval = 1000 / game.fpsCap; // simulation.fpsInterval = 1000 / simulation.fpsCap;
// game.defaultFPSCycle = game.cycle + time // simulation.defaultFPSCycle = simulation.cycle + time
// const normalFPS = function () { // const normalFPS = function () {
// if (game.defaultFPSCycle < game.cycle) { // if (simulation.defaultFPSCycle < simulation.cycle) {
// game.fpsCap = 72 // simulation.fpsCap = 72
// game.fpsInterval = 1000 / game.fpsCap; // simulation.fpsInterval = 1000 / simulation.fpsCap;
// } else { // } else {
// requestAnimationFrame(normalFPS); // requestAnimationFrame(normalFPS);
// } // }
@@ -233,10 +233,10 @@ const game = {
drawCursor() { drawCursor() {
const size = 10; const size = 10;
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(game.mouse.x - size, game.mouse.y); ctx.moveTo(simulation.mouse.x - size, simulation.mouse.y);
ctx.lineTo(game.mouse.x + size, game.mouse.y); ctx.lineTo(simulation.mouse.x + size, simulation.mouse.y);
ctx.moveTo(game.mouse.x, game.mouse.y - size); ctx.moveTo(simulation.mouse.x, simulation.mouse.y - size);
ctx.lineTo(game.mouse.x, game.mouse.y + size); ctx.lineTo(simulation.mouse.x, simulation.mouse.y + size);
ctx.lineWidth = 2; ctx.lineWidth = 2;
ctx.strokeStyle = "#000"; //'rgba(0,0,0,0.4)' ctx.strokeStyle = "#000"; //'rgba(0,0,0,0.4)'
ctx.stroke(); // Draw it ctx.stroke(); // Draw it
@@ -247,17 +247,17 @@ const game = {
playerDmgColor: "rgba(0,0,0,0.7)", //used top push into drawList.color playerDmgColor: "rgba(0,0,0,0.7)", //used top push into drawList.color
drawCircle() { drawCircle() {
//draws a circle for two cycles, used for showing damage mostly //draws a circle for two cycles, used for showing damage mostly
let i = game.drawList.length; let i = simulation.drawList.length;
while (i--) { while (i--) {
ctx.beginPath(); //draw circle ctx.beginPath(); //draw circle
ctx.arc(game.drawList[i].x, game.drawList[i].y, game.drawList[i].radius, 0, 2 * Math.PI); ctx.arc(simulation.drawList[i].x, simulation.drawList[i].y, simulation.drawList[i].radius, 0, 2 * Math.PI);
ctx.fillStyle = game.drawList[i].color; ctx.fillStyle = simulation.drawList[i].color;
ctx.fill(); ctx.fill();
if (game.drawList[i].time) { if (simulation.drawList[i].time) {
//remove when timer runs out //remove when timer runs out
game.drawList[i].time--; simulation.drawList[i].time--;
} else { } else {
game.drawList.splice(i, 1); simulation.drawList.splice(i, 1);
} }
} }
}, },
@@ -273,15 +273,15 @@ const game = {
if (document.getElementById(b.activeGun)) document.getElementById(b.activeGun).style.opacity = "1"; if (document.getElementById(b.activeGun)) document.getElementById(b.activeGun).style.opacity = "1";
} }
if (mod.isEntanglement && document.getElementById("mod-entanglement")) { if (tech.isEntanglement && document.getElementById("tech-entanglement")) {
if (b.inventory[0] === b.activeGun) { if (b.inventory[0] === b.activeGun) {
let lessDamage = 1 let lessDamage = 1
for (let i = 0, len = b.inventory.length; i < len; i++) { for (let i = 0, len = b.inventory.length; i < len; i++) {
lessDamage *= 0.87 // 1 - 0.13 lessDamage *= 0.87 // 1 - 0.13
} }
document.getElementById("mod-entanglement").innerHTML = " " + ((1 - lessDamage) * 100).toFixed(0) + "%" document.getElementById("tech-entanglement").innerHTML = " " + ((1 - lessDamage) * 100).toFixed(0) + "%"
} else { } else {
document.getElementById("mod-entanglement").innerHTML = " 0%" document.getElementById("tech-entanglement").innerHTML = " 0%"
} }
} }
}, },
@@ -304,115 +304,119 @@ const game = {
node.appendChild(textnode); node.appendChild(textnode);
document.getElementById("guns").appendChild(node); document.getElementById("guns").appendChild(node);
} }
game.boldActiveGunHUD(); simulation.boldActiveGunHUD();
}, },
updateModHUD() { updateModHUD() {
let text = "" let text = ""
for (let i = 0, len = mod.mods.length; i < len; i++) { //add mods for (let i = 0, len = tech.tech.length; i < len; i++) { //add tech
if (mod.mods[i].isLost) { if (tech.tech[i].isLost) {
if (text) text += "<br>" //add a new line, but not on the first line if (text) text += "<br>" //add a new line, but not on the first line
text += `<span style="text-decoration: line-through;">${mod.mods[i].name}</span>` text += `<span style="text-decoration: line-through;">${tech.tech[i].name}</span>`
} else if (mod.mods[i].count > 0) { } else if (tech.tech[i].count > 0) {
if (text) text += "<br>" //add a new line, but not on the first line if (text) text += "<br>" //add a new line, but not on the first line
text += mod.mods[i].name text += tech.tech[i].name
if (mod.mods[i].nameInfo) { if (tech.tech[i].nameInfo) {
text += mod.mods[i].nameInfo text += tech.tech[i].nameInfo
mod.mods[i].addNameInfo(); tech.tech[i].addNameInfo();
} }
if (mod.mods[i].count > 1) text += ` (${mod.mods[i].count}x)` if (tech.tech[i].count > 1) text += ` (${tech.tech[i].count}x)`
} }
} }
document.getElementById("mods").innerHTML = text document.getElementById("tech").innerHTML = text
}, },
replaceTextLog: true, isTextLogOpen: true,
// <!-- <path d="M832.41,106.64 V323.55 H651.57 V256.64 c0-82.5,67.5-150,150-150 Z" fill="#789" stroke="none" /> // <!-- <path d="M832.41,106.64 V323.55 H651.57 V256.64 c0-82.5,67.5-150,150-150 Z" fill="#789" stroke="none" />
// <path d="M827,112 h30 a140,140,0,0,1,140,140 v68 h-167 z" fill="#7ce" stroke="none" /> --> // <path d="M827,112 h30 a140,140,0,0,1,140,140 v68 h-167 z" fill="#7ce" stroke="none" /> -->
// SVGleftMouse: '<svg viewBox="750 0 200 765" class="mouse-icon" width="40px" height = "60px" stroke-linecap="round" stroke-linejoin="round" stroke-width="25px" stroke="#000" fill="none"> <path fill="#fff" stroke="none" d="M827,112 h30 a140,140,0,0,1,140,140 v268 a140,140,0,0,1-140,140 h-60 a140,140,0,0,1-140-140v-268 a140,140,0,0,1,140-140h60" /> <path d="M832.41,106.64 V323.55 H651.57 V256.64 c0-82.5,67.5-150,150-150 Z" fill="#149" stroke="none" /> <path fill="none" d="M827,112 h30 a140,140,0,0,1,140,140 v268 a140,140,0,0,1-140,140 h-60 a140,140,0,0,1-140-140v-268 a140,140,0,0,1,140-140h60" /> <path d="M657 317 h 340 h-170 v-207" /> <ellipse fill="#fff" cx="827.57" cy="218.64" rx="29" ry="68" /> </svg>', // SVGleftMouse: '<svg viewBox="750 0 200 765" class="mouse-icon" width="40px" height = "60px" stroke-linecap="round" stroke-linejoin="round" stroke-width="25px" stroke="#000" fill="none"> <path fill="#fff" stroke="none" d="M827,112 h30 a140,140,0,0,1,140,140 v268 a140,140,0,0,1-140,140 h-60 a140,140,0,0,1-140-140v-268 a140,140,0,0,1,140-140h60" /> <path d="M832.41,106.64 V323.55 H651.57 V256.64 c0-82.5,67.5-150,150-150 Z" fill="#149" stroke="none" /> <path fill="none" d="M827,112 h30 a140,140,0,0,1,140,140 v268 a140,140,0,0,1-140,140 h-60 a140,140,0,0,1-140-140v-268 a140,140,0,0,1,140-140h60" /> <path d="M657 317 h 340 h-170 v-207" /> <ellipse fill="#fff" cx="827.57" cy="218.64" rx="29" ry="68" /> </svg>',
SVGrightMouse: '<svg viewBox="750 0 200 765" class="mouse-icon" width="40px" height = "60px" stroke-linecap="round" stroke-linejoin="round" stroke-width="25px" stroke="#000" fill="none"> <path fill="#fff" stroke="none" d="M827,112 h30 a140,140,0,0,1,140,140 v268 a140,140,0,0,1-140,140 h-60 a140,140,0,0,1-140-140v-268 a140,140,0,0,1,140-140h60" /> <path d="M827,112 h30 a140,140,0,0,1,140,140 v68 h-167 z" fill="#0cf" stroke="none" /> <path fill="none" d="M827,112 h30 a140,140,0,0,1,140,140 v268 a140,140,0,0,1-140,140 h-60 a140,140,0,0,1-140-140v-268 a140,140,0,0,1,140-140h60" /> <path d="M657 317 h 340 h-170 v-207" /> <ellipse fill="#fff" cx="827.57" cy="218.64" rx="29" ry="68" /> </svg>', // SVGrightMouse: '<svg viewBox="750 0 200 765" class="mouse-icon" width="40px" height = "60px" stroke-linecap="round" stroke-linejoin="round" stroke-width="25px" stroke="#000" fill="none"> <path fill="#fff" stroke="none" d="M827,112 h30 a140,140,0,0,1,140,140 v268 a140,140,0,0,1-140,140 h-60 a140,140,0,0,1-140-140v-268 a140,140,0,0,1,140-140h60" /> <path d="M827,112 h30 a140,140,0,0,1,140,140 v68 h-167 z" fill="#0cf" stroke="none" /> <path fill="none" d="M827,112 h30 a140,140,0,0,1,140,140 v268 a140,140,0,0,1-140,140 h-60 a140,140,0,0,1-140-140v-268 a140,140,0,0,1,140-140h60" /> <path d="M657 317 h 340 h-170 v-207" /> <ellipse fill="#fff" cx="827.57" cy="218.64" rx="29" ry="68" /> </svg>',
makeTextLog(text, time = 180) { makeTextLog(text, time = 120) {
if (game.replaceTextLog) { if (simulation.isTextLogOpen && !build.isCustomSelection) {
if (simulation.lastLogTime > mech.cycle) { //if there is an older message
document.getElementById("text-log").innerHTML = document.getElementById("text-log").innerHTML + '<br>' + text;
simulation.lastLogTime = mech.cycle + time;
} else {
document.getElementById("text-log").innerHTML = text; document.getElementById("text-log").innerHTML = text;
document.getElementById("text-log").style.opacity = 1; document.getElementById("text-log").style.opacity = 1;
game.lastLogTime = mech.cycle + time; simulation.lastLogTime = mech.cycle + time;
}
} }
}, },
textLog() { textLog() {
if (game.lastLogTime && game.lastLogTime < mech.cycle) { if (simulation.lastLogTime && simulation.lastLogTime < mech.cycle) {
game.lastLogTime = 0; simulation.lastLogTime = 0;
game.replaceTextLog = true
// document.getElementById("text-log").innerHTML = " "; // document.getElementById("text-log").innerHTML = " ";
document.getElementById("text-log").style.opacity = 0; document.getElementById("text-log").style.opacity = 0;
} }
}, },
nextGun() { nextGun() {
if (b.inventory.length > 0 && !mod.isGunCycle) { if (b.inventory.length > 0 && !tech.isGunCycle) {
b.inventoryGun++; b.inventoryGun++;
if (b.inventoryGun > b.inventory.length - 1) b.inventoryGun = 0; if (b.inventoryGun > b.inventory.length - 1) b.inventoryGun = 0;
game.switchGun(); simulation.switchGun();
} }
}, },
previousGun() { previousGun() {
if (b.inventory.length > 0 && !mod.isGunCycle) { if (b.inventory.length > 0 && !tech.isGunCycle) {
b.inventoryGun--; b.inventoryGun--;
if (b.inventoryGun < 0) b.inventoryGun = b.inventory.length - 1; if (b.inventoryGun < 0) b.inventoryGun = b.inventory.length - 1;
game.switchGun(); simulation.switchGun();
} }
}, },
switchGun() { switchGun() {
if (mod.isCrouchAmmo) mod.isCrouchAmmo = 1 //this prevents hacking the mod by switching guns if (tech.isCrouchAmmo) tech.isCrouchAmmo = 1 //this prevents hacking the tech by switching guns
b.activeGun = b.inventory[b.inventoryGun]; b.activeGun = b.inventory[b.inventoryGun];
game.updateGunHUD(); simulation.updateGunHUD();
game.boldActiveGunHUD(); simulation.boldActiveGunHUD();
// mech.drop(); // mech.drop();
}, },
zoom: null, zoom: null,
zoomScale: 1000, zoomScale: 1000,
isAutoZoom: true, isAutoZoom: true,
setZoom(zoomScale = game.zoomScale) { //use in window resize in index.js setZoom(zoomScale = simulation.zoomScale) { //use in window resize in index.js
game.zoomScale = zoomScale simulation.zoomScale = zoomScale
game.zoom = canvas.height / zoomScale; //sets starting zoom scale simulation.zoom = canvas.height / zoomScale; //sets starting zoom scale
}, },
zoomTransition(newZoomScale, step = 2) { zoomTransition(newZoomScale, step = 2) {
if (game.isAutoZoom) { if (simulation.isAutoZoom) {
const isBigger = (newZoomScale - game.zoomScale > 0) ? true : false; const isBigger = (newZoomScale - simulation.zoomScale > 0) ? true : false;
requestAnimationFrame(zLoop); requestAnimationFrame(zLoop);
const currentLevel = level.onLevel const currentLevel = level.onLevel
function zLoop() { function zLoop() {
if (currentLevel !== level.onLevel || game.isAutoZoom === false) return //stop the zoom if player goes to a new level if (currentLevel !== level.onLevel || simulation.isAutoZoom === false) return //stop the zoom if player goes to a new level
if (isBigger) { if (isBigger) {
game.zoomScale += step simulation.zoomScale += step
if (game.zoomScale >= newZoomScale) { if (simulation.zoomScale >= newZoomScale) {
game.setZoom(newZoomScale); simulation.setZoom(newZoomScale);
return return
} }
} else { } else {
game.zoomScale -= step simulation.zoomScale -= step
if (game.zoomScale <= newZoomScale) { if (simulation.zoomScale <= newZoomScale) {
game.setZoom(newZoomScale); simulation.setZoom(newZoomScale);
return return
} }
} }
game.setZoom(); simulation.setZoom();
requestAnimationFrame(zLoop); requestAnimationFrame(zLoop);
} }
} }
}, },
zoomInFactor: 0, zoomInFactor: 0,
startZoomIn(time = 180) { startZoomIn(time = 180) {
game.zoom = 0; simulation.zoom = 0;
let count = 0; let count = 0;
requestAnimationFrame(zLoop); requestAnimationFrame(zLoop);
function zLoop() { function zLoop() {
game.zoom += canvas.height / game.zoomScale / time; simulation.zoom += canvas.height / simulation.zoomScale / time;
count++; count++;
if (count < time) { if (count < time) {
requestAnimationFrame(zLoop); requestAnimationFrame(zLoop);
} else { } else {
game.setZoom(); simulation.setZoom();
} }
} }
}, },
@@ -421,27 +425,27 @@ const game = {
mech.pos.x = player.position.x; mech.pos.x = player.position.x;
mech.pos.y = playerBody.position.y - mech.yOff; mech.pos.y = playerBody.position.y - mech.yOff;
const scale = 0.8; const scale = 0.8;
mech.transSmoothX = canvas.width2 - mech.pos.x - (game.mouse.x - canvas.width2) * scale; mech.transSmoothX = canvas.width2 - mech.pos.x - (simulation.mouse.x - canvas.width2) * scale;
mech.transSmoothY = canvas.height2 - mech.pos.y - (game.mouse.y - canvas.height2) * scale; mech.transSmoothY = canvas.height2 - mech.pos.y - (simulation.mouse.y - canvas.height2) * scale;
mech.transX += (mech.transSmoothX - mech.transX) * 1; mech.transX += (mech.transSmoothX - mech.transX) * 1;
mech.transY += (mech.transSmoothY - mech.transY) * 1; mech.transY += (mech.transSmoothY - mech.transY) * 1;
}, },
edgeZoomOutSmooth: 1, edgeZoomOutSmooth: 1,
camera() { camera() {
//zoom out when mouse gets near the edge of the window //zoom out when mouse gets near the edge of the window
const dx = game.mouse.x / window.innerWidth - 0.5 //x distance from mouse to window center scaled by window width const dx = simulation.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 = simulation.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.04 + game.edgeZoomOutSmooth * 0.96 simulation.edgeZoomOutSmooth = (1 + 4 * d * d) * 0.04 + simulation.edgeZoomOutSmooth * 0.96
ctx.save(); ctx.save();
ctx.translate(canvas.width2, canvas.height2); //center ctx.translate(canvas.width2, canvas.height2); //center
ctx.scale(game.zoom / game.edgeZoomOutSmooth, game.zoom / game.edgeZoomOutSmooth); //zoom in once centered ctx.scale(simulation.zoom / simulation.edgeZoomOutSmooth, simulation.zoom / simulation.edgeZoomOutSmooth); //zoom in once centered
ctx.translate(-canvas.width2 + mech.transX, -canvas.height2 + mech.transY); //translate ctx.translate(-canvas.width2 + mech.transX, -canvas.height2 + mech.transY); //translate
//calculate in game mouse position by undoing the zoom and translations //calculate in game mouse position by undoing the zoom and translations
game.mouseInGame.x = (game.mouse.x - canvas.width2) / game.zoom * game.edgeZoomOutSmooth + canvas.width2 - mech.transX; simulation.mouseInGame.x = (simulation.mouse.x - canvas.width2) / simulation.zoom * simulation.edgeZoomOutSmooth + canvas.width2 - mech.transX;
game.mouseInGame.y = (game.mouse.y - canvas.height2) / game.zoom * game.edgeZoomOutSmooth + canvas.height2 - mech.transY; simulation.mouseInGame.y = (simulation.mouse.y - canvas.height2) / simulation.zoom * simulation.edgeZoomOutSmooth + canvas.height2 - mech.transY;
}, },
restoreCamera() { restoreCamera() {
ctx.restore(); ctx.restore();
@@ -455,15 +459,15 @@ const game = {
bodies[i].force.y += bodies[i].mass * magnitude; bodies[i].force.y += bodies[i].mass * magnitude;
} }
} }
addGravity(powerUp, game.g); addGravity(powerUp, simulation.g);
addGravity(body, game.g); addGravity(body, simulation.g);
player.force.y += player.mass * game.g; player.force.y += player.mass * simulation.g;
}, },
firstRun: true, firstRun: true,
splashReturn() { splashReturn() {
game.onTitlePage = true; simulation.onTitlePage = true;
document.getElementById("splash").onclick = function() { document.getElementById("splash").onclick = function() {
game.startGame(); simulation.startGame();
}; };
document.getElementById("choose-grid").style.display = "none" document.getElementById("choose-grid").style.display = "none"
document.getElementById("info").style.display = "inline"; document.getElementById("info").style.display = "inline";
@@ -483,7 +487,7 @@ const game = {
document.body.style.cursor = "none"; document.body.style.cursor = "none";
document.body.style.overflow = "hidden" document.body.style.overflow = "hidden"
} }
game.onTitlePage = false; simulation.onTitlePage = false;
document.getElementById("choose-grid").style.display = "none" document.getElementById("choose-grid").style.display = "none"
document.getElementById("build-grid").style.display = "none" document.getElementById("build-grid").style.display = "none"
document.getElementById("info").style.display = "none"; document.getElementById("info").style.display = "none";
@@ -496,7 +500,7 @@ const game = {
mech.spawn(); //spawns the player mech.spawn(); //spawns the player
level.levels = level.playableLevels.slice(0) //copy array, not by just by assignment level.levels = level.playableLevels.slice(0) //copy array, not by just by assignment
if (game.isCommunityMaps) { if (simulation.isCommunityMaps) {
level.levels.push("stronghold"); level.levels.push("stronghold");
level.levels.push("basement"); level.levels.push("basement");
level.levels.push("detours"); level.levels.push("detours");
@@ -505,14 +509,22 @@ const game = {
level.levels = shuffle(level.levels); //shuffles order of maps level.levels = shuffle(level.levels); //shuffles order of maps
level.levels.unshift("intro"); //add level to the start of the randomized levels list level.levels.unshift("intro"); //add level to the start of the randomized levels list
level.levels.push("gauntlet"); //add level to the end of the randomized levels list level.levels.push("gauntlet"); //add level to the end of the randomized levels list
level.levels.push("finalBoss"); //add level to the end of the randomized levels list level.levels.push("final"); //add level to the end of the randomized levels list
input.endKeySensing(); input.endKeySensing();
b.removeAllGuns(); b.removeAllGuns();
game.isNoPowerUps = false; simulation.isNoPowerUps = false;
mod.setupAllMods(); //sets mods to default values
tech.setupAllMods(); //sets tech to default values
tech.laserBotCount = 0;
tech.orbitBotCount = 0;
tech.nailBotCount = 0;
tech.foamBotCount = 0;
tech.boomBotCount = 0;
tech.plasmaBotCount = 0;
b.setFireCD(); b.setFireCD();
game.updateModHUD(); simulation.updateModHUD();
powerUps.totalPowerUps = 0; powerUps.totalPowerUps = 0;
powerUps.reroll.rerolls = 0; powerUps.reroll.rerolls = 0;
mech.setFillColors(); mech.setFillColors();
@@ -520,11 +532,11 @@ const game = {
mech.maxEnergy = 1 mech.maxEnergy = 1
mech.energy = 1 mech.energy = 1
mech.hole.isOn = false mech.hole.isOn = false
game.paused = false; simulation.paused = false;
engine.timing.timeScale = 1; engine.timing.timeScale = 1;
game.fpsCap = game.fpsCapDefault; simulation.fpsCap = simulation.fpsCapDefault;
game.isAutoZoom = true; simulation.isAutoZoom = true;
game.makeGunHUD(); simulation.makeGunHUD();
mech.drop(); mech.drop();
mech.holdingTarget = null mech.holdingTarget = null
mech.health = 0.25; mech.health = 0.25;
@@ -534,58 +546,98 @@ const game = {
level.levelsCleared = 0; level.levelsCleared = 0;
//resetting difficulty //resetting difficulty
game.dmgScale = 0; //increases in level.difficultyIncrease simulation.dmgScale = 0; //increases in level.difficultyIncrease
b.dmgScale = 1; //decreases in level.difficultyIncrease b.dmgScale = 1; //decreases in level.difficultyIncrease
game.accelScale = 1; simulation.accelScale = 1;
game.lookFreqScale = 1; simulation.lookFreqScale = 1;
game.CDScale = 1; simulation.CDScale = 1;
game.difficulty = 0; simulation.difficulty = 0;
game.difficultyMode = Number(document.getElementById("difficulty-select").value) simulation.difficultyMode = Number(document.getElementById("difficulty-select").value)
build.isCustomSelection = false; build.isCustomSelection = false;
game.clearNow = true; simulation.clearNow = true;
document.getElementById("text-log").style.opacity = 0; document.getElementById("text-log").style.opacity = 0;
document.getElementById("fade-out").style.opacity = 0; document.getElementById("fade-out").style.opacity = 0;
document.title = "n-gon"; document.title = "n-gon";
//set to default field //set to default field
mech.fieldMode = 0; mech.fieldMode = 0;
game.replaceTextLog = true; // simulation.makeTextLog(`${simulation.SVGrightMouse}<strong style='font-size:30px;'> ${mech.fieldUpgrades[mech.fieldMode].name}</strong><br><span class='faded'></span><br>${mech.fieldUpgrades[mech.fieldMode].description}`, 600);
game.makeTextLog(`${game.SVGrightMouse}<strong style='font-size:30px;'> ${mech.fieldUpgrades[mech.fieldMode].name}</strong><br><span class='faded'></span><br>${mech.fieldUpgrades[mech.fieldMode].description}`, 600); // simulation.makeTextLog(`
// input.key.up <span class='color-symbol'>=</span> ["<span class='color-text'>${input.key.up}</span>", "<span class='color-text'>ArrowUp</span>"]
// <br>input.key.left <span class='color-symbol'>=</span> ["<span class='color-text'>${input.key.left}</span>", "<span class='color-text'>ArrowLeft</span>"]
// <br>input.key.down <span class='color-symbol'>=</span> ["<span class='color-text'>${input.key.down}</span>", "<span class='color-text'>ArrowDown</span>"]
// <br>input.key.right <span class='color-symbol'>=</span> ["<span class='color-text'>${input.key.right}</span>", "<span class='color-text'>ArrowRight</span>"]
// <br>
// <br><span class='color-var'>mech</span>.fieldMode <span class='color-symbol'>=</span> "<span class='color-text'>${mech.fieldUpgrades[mech.fieldMode].name}</span>"
// <br>input.key.field <span class='color-symbol'>=</span> ["<span class='color-text'>${input.key.field}</span>", "<span class='color-text'>right mouse</span>"]
// <br><span class='color-var'>mech</span>.field.description <span class='color-symbol'>=</span> "<span class='color-text'>${mech.fieldUpgrades[mech.fieldMode].description}</span>"
// `, 800);
let delay = 500
const step = 150
setTimeout(function() {
simulation.makeTextLog(`input.key.up <span class='color-symbol'>=</span> ["<span class='color-text'>${input.key.up}</span>", "<span class='color-text'>ArrowUp</span>"]`);
}, delay);
delay += step
setTimeout(function() {
simulation.makeTextLog(`input.key.left <span class='color-symbol'>=</span> ["<span class='color-text'>${input.key.left}</span>", "<span class='color-text'>ArrowLeft</span>"]`);
}, delay);
delay += step
setTimeout(function() {
simulation.makeTextLog(`input.key.down <span class='color-symbol'>=</span> ["<span class='color-text'>${input.key.down}</span>", "<span class='color-text'>ArrowDown</span>"]`);
}, delay);
delay += step
setTimeout(function() {
simulation.makeTextLog(`input.key.right <span class='color-symbol'>=</span> ["<span class='color-text'>${input.key.right}</span>", "<span class='color-text'>ArrowRight</span>"]`);
}, delay);
delay += 1000
setTimeout(function() {
simulation.makeTextLog(`<br><span class='color-var'>mech</span>.fieldMode <span class='color-symbol'>=</span> "<span class='color-text'>${mech.fieldUpgrades[mech.fieldMode].name}</span>"`);
}, delay);
delay += step
setTimeout(function() {
simulation.makeTextLog(`input.key.field <span class='color-symbol'>=</span> ["<span class='color-text'>${input.key.field}</span>", "<span class='color-text'>MouseRight</span>"]`);
}, delay);
// delay += step
// setTimeout(function() {
// simulation.makeTextLog(`<span class='color-var'>mech</span>.field.description<br>"<span class='color-text'>${mech.fieldUpgrades[mech.fieldMode].description}</span>"`);
// }, delay);
mech.setField(mech.fieldMode) mech.setField(mech.fieldMode)
//exit testing //exit testing
if (game.testing) { if (simulation.testing) {
game.testing = false; simulation.testing = false;
game.loop = game.normalLoop simulation.loop = simulation.normalLoop
if (game.isConstructionMode) { if (simulation.isConstructionMode) {
document.getElementById("construct").style.display = 'none' document.getElementById("construct").style.display = 'none'
} }
} }
game.isCheating = false simulation.isCheating = false
game.firstRun = false; simulation.firstRun = false;
//setup FPS cap //setup FPS cap
game.fpsInterval = 1000 / game.fpsCap; simulation.fpsInterval = 1000 / simulation.fpsCap;
game.then = Date.now(); simulation.then = Date.now();
requestAnimationFrame(cycle); //starts game loop requestAnimationFrame(cycle); //starts game loop
}, },
clearNow: false, clearNow: false,
clearMap() { clearMap() {
if (mod.isMineAmmoBack) { if (tech.isMineAmmoBack) {
let count = 0; let count = 0;
for (i = 0, len = bullet.length; i < len; i++) { //count mines left on map for (i = 0, len = bullet.length; i < len; i++) { //count mines left on map
if (bullet[i].bulletType === "mine") count++ if (bullet[i].bulletType === "mine") count++
} }
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun is mine for (i = 0, len = b.guns.length; i < len; i++) { //find which gun is mine
if (b.guns[i].name === "mine") { if (b.guns[i].name === "mine") {
if (mod.isCrouchAmmo) count = Math.ceil(count / 2) if (tech.isCrouchAmmo) count = Math.ceil(count / 2)
b.guns[i].ammo += count b.guns[i].ammo += count
game.updateGunHUD(); simulation.updateGunHUD();
break; break;
} }
} }
} }
if (mod.isMutualism && !mod.isEnergyHealth) { if (tech.isMutualism && !tech.isEnergyHealth) {
for (let i = 0; i < bullet.length; i++) { for (let i = 0; i < bullet.length; i++) {
if (bullet[i].isMutualismActive) { if (bullet[i].isMutualismActive) {
mech.health += 0.005 mech.health += 0.005
@@ -595,12 +647,12 @@ const game = {
} }
} }
if (mod.isEndLevelPowerUp) { if (tech.isEndLevelPowerUp) {
for (let i = 0; i < powerUp.length; i++) { for (let i = 0; i < powerUp.length; i++) {
if (powerUp[i].name === "mod") { if (powerUp[i].name === "tech") {
mod.giveMod() tech.giveMod()
} else if (powerUp[i].name === "gun") { } else if (powerUp[i].name === "gun") {
if (!mod.isOneGun) b.giveGuns("random") if (!tech.isOneGun) b.giveGuns("random")
} else if (powerUp[i].name === "field") { } else if (powerUp[i].name === "field") {
if (mech.fieldMode === 0) mech.setField(Math.ceil(Math.random() * (mech.fieldUpgrades.length - 1))) //pick a random field, but not field 0 if (mech.fieldMode === 0) mech.setField(Math.ceil(Math.random() * (mech.fieldUpgrades.length - 1))) //pick a random field, but not field 0
} else { } else {
@@ -620,7 +672,7 @@ const game = {
level.fillBG = []; level.fillBG = [];
level.zones = []; level.zones = [];
level.queryList = []; level.queryList = [];
game.drawList = []; simulation.drawList = [];
function removeAll(array) { function removeAll(array) {
for (let i = 0; i < array.length; ++i) Matter.World.remove(engine.world, array[i]); for (let i = 0; i < array.length; ++i) Matter.World.remove(engine.world, array[i]);
@@ -656,8 +708,8 @@ const game = {
mech.holdingTarget.collisionFilter.mask = 0; mech.holdingTarget.collisionFilter.mask = 0;
} }
//set fps back to default //set fps back to default
game.fpsCap = game.fpsCapDefault simulation.fpsCap = simulation.fpsCapDefault
game.fpsInterval = 1000 / game.fpsCap; simulation.fpsInterval = 1000 / simulation.fpsCap;
}, },
// getCoords: { // getCoords: {
// //used when building maps, outputs a draw rect command to console, only works in testing mode // //used when building maps, outputs a draw rect command to console, only works in testing mode
@@ -671,20 +723,20 @@ const game = {
// }, // },
// out() { // out() {
// if (keys[49]) { // if (keys[49]) {
// game.getCoords.pos1.x = Math.round(game.mouseInGame.x / 25) * 25; // simulation.getCoords.pos1.x = Math.round(simulation.mouseInGame.x / 25) * 25;
// game.getCoords.pos1.y = Math.round(game.mouseInGame.y / 25) * 25; // simulation.getCoords.pos1.y = Math.round(simulation.mouseInGame.y / 25) * 25;
// } // }
// if (keys[50]) { // if (keys[50]) {
// //press 1 in the top left; press 2 in the bottom right;copy command from console // //press 1 in the top left; press 2 in the bottom right;copy command from console
// game.getCoords.pos2.x = Math.round(game.mouseInGame.x / 25) * 25; // simulation.getCoords.pos2.x = Math.round(simulation.mouseInGame.x / 25) * 25;
// game.getCoords.pos2.y = Math.round(game.mouseInGame.y / 25) * 25; // simulation.getCoords.pos2.y = Math.round(simulation.mouseInGame.y / 25) * 25;
// window.getSelection().removeAllRanges(); // window.getSelection().removeAllRanges();
// var range = document.createRange(); // var range = document.createRange();
// range.selectNode(document.getElementById("test")); // range.selectNode(document.getElementById("test"));
// window.getSelection().addRange(range); // window.getSelection().addRange(range);
// document.execCommand("copy"); // document.execCommand("copy");
// window.getSelection().removeAllRanges(); // window.getSelection().removeAllRanges();
// console.log(`spawn.mapRect(${game.getCoords.pos1.x}, ${game.getCoords.pos1.y}, ${game.getCoords.pos2.x - game.getCoords.pos1.x}, ${game.getCoords.pos2.y - game.getCoords.pos1.y}); //`); // console.log(`spawn.mapRect(${simulation.getCoords.pos1.x}, ${simulation.getCoords.pos1.y}, ${simulation.getCoords.pos2.x - simulation.getCoords.pos1.x}, ${simulation.getCoords.pos2.y - simulation.getCoords.pos1.y}); //`);
// } // }
// } // }
// }, // },
@@ -692,9 +744,9 @@ const game = {
if (!(mech.cycle % 60)) { //once a second if (!(mech.cycle % 60)) { //once a second
//energy overfill //energy overfill
if (mech.energy > mech.maxEnergy) mech.energy = mech.maxEnergy + (mech.energy - mech.maxEnergy) * mod.overfillDrain //every second energy above max energy loses 25% if (mech.energy > mech.maxEnergy) mech.energy = mech.maxEnergy + (mech.energy - mech.maxEnergy) * tech.overfillDrain //every second energy above max energy loses 25%
if (mech.pos.y > game.fallHeight) { // if 4000px deep if (mech.pos.y > simulation.fallHeight) { // if 4000px deep
Matter.Body.setVelocity(player, { Matter.Body.setVelocity(player, {
x: 0, x: 0,
y: 0 y: 0
@@ -716,31 +768,31 @@ const game = {
}); });
} }
} }
mech.damage(0.1 * game.difficultyMode); mech.damage(0.1 * simulation.difficultyMode);
mech.energy -= 0.1 * game.difficultyMode mech.energy -= 0.1 * simulation.difficultyMode
} }
// if (mod.isEnergyDamage) { // if (tech.isEnergyDamage) {
// document.getElementById("mod-capacitor").innerHTML = `(+${(mech.energy/0.05).toFixed(0)}%)` // document.getElementById("tech-capacitor").innerHTML = `(+${(mech.energy/0.05).toFixed(0)}%)`
// } // }
// if (mod.restDamage) { // if (tech.restDamage) {
// if (player.speed < 1) { // if (player.speed < 1) {
// document.getElementById("mod-rest").innerHTML = `(+20%)` // document.getElementById("tech-rest").innerHTML = `(+20%)`
// } else { // } else {
// document.getElementById("mod-rest").innerHTML = `(+0%)` // document.getElementById("tech-rest").innerHTML = `(+0%)`
// } // }
// } // }
if (mech.lastKillCycle + 300 > mech.cycle) { //effects active for 5 seconds after killing a mob if (mech.lastKillCycle + 300 > mech.cycle) { //effects active for 5 seconds after killing a mob
if (mod.isEnergyRecovery) mech.energy += mech.maxEnergy * 0.05 if (tech.isEnergyRecovery) mech.energy += mech.maxEnergy * 0.05
if (mod.isHealthRecovery) mech.addHealth(0.01 * mech.maxHealth) if (tech.isHealthRecovery) mech.addHealth(0.01 * mech.maxHealth)
} }
if (!(game.cycle % 420)) { //once every 7 seconds if (!(simulation.cycle % 420)) { //once every 7 seconds
fallCheck = function(who, save = false) { fallCheck = function(who, save = false) {
let i = who.length; let i = who.length;
while (i--) { while (i--) {
if (who[i].position.y > game.fallHeight) { if (who[i].position.y > simulation.fallHeight) {
if (save) { if (save) {
Matter.Body.setVelocity(who[i], { Matter.Body.setVelocity(who[i], {
x: 0, x: 0,
@@ -766,49 +818,30 @@ const game = {
//crouch playerHead.position.y - player.position.y = 9.7 //positive //crouch playerHead.position.y - player.position.y = 9.7 //positive
//standing playerHead.position.y - player.position.y = -30 //negative //standing playerHead.position.y - player.position.y = -30 //negative
// mech.undoCrouch() // mech.undoCrouch()
if (!mech.crouch && ((playerHead.position.y - player.position.y) > 0)) { // if (!mech.crouch && ((playerHead.position.y - player.position.y) > 0)) {
Matter.Body.translate(playerHead, {
x: 0,
y: 40
});
// if ((playerHead.position.y - player.position.y) > 0) {
// Matter.Body.translate(playerHead, { // Matter.Body.translate(playerHead, {
// x: 0, // x: 0,
// y: 40 // y: 40
// }); // });
// if ((playerHead.position.y - player.position.y) > 0) { // } else if (mech.crouch && ((playerHead.position.y - player.position.y) > 10)) {
// Matter.Body.translate(playerHead, {
// x: 0,
// y: 40
// });
// if ((playerHead.position.y - player.position.y) > 0) {
// Matter.Body.translate(playerHead, { // Matter.Body.translate(playerHead, {
// x: 0, // x: 0,
// y: 40 // y: 40
// }); // });
// } // }
// }
// }
} else if (mech.crouch && ((playerHead.position.y - player.position.y) > 10)) {
Matter.Body.translate(playerHead, {
x: 0,
y: 40
});
}
// else if (mech.crouch && ((playerHead.position.y - player.position.y) < 0)) {}
} }
} }
}, },
testingOutput() { testingOutput() {
ctx.fillStyle = "#000"; ctx.fillStyle = "#000";
if (!game.isConstructionMode) { if (!simulation.isConstructionMode) {
// ctx.textAlign = "right"; // ctx.textAlign = "right";
ctx.fillText("T: exit testing mode", canvas.width / 2, canvas.height - 10); ctx.fillText("T: exit testing mode", canvas.width / 2, canvas.height - 10);
// let line = 500; // let line = 500;
// const x = canvas.width - 5; // const x = canvas.width - 5;
// ctx.fillText("T: exit testing mode", x, line); // ctx.fillText("T: exit testing mode", x, line);
// line += 20; // line += 20;
// ctx.fillText("Y: give all mods", x, line); // ctx.fillText("Y: give all tech", x, line);
// line += 20; // line += 20;
// ctx.fillText("R: teleport to mouse", x, line); // ctx.fillText("R: teleport to mouse", x, line);
// line += 20; // line += 20;
@@ -823,10 +856,10 @@ const game = {
// ctx.fillText("1-7: spawn things", x, line); // ctx.fillText("1-7: spawn things", x, line);
} }
ctx.textAlign = "center"; ctx.textAlign = "center";
ctx.fillText(`(${game.mouseInGame.x.toFixed(1)}, ${game.mouseInGame.y.toFixed(1)})`, game.mouse.x, game.mouse.y - 20); ctx.fillText(`(${simulation.mouseInGame.x.toFixed(1)}, ${simulation.mouseInGame.y.toFixed(1)})`, simulation.mouse.x, simulation.mouse.y - 20);
}, },
draw: { draw: {
powerUp() { //is set by Bayesian mod powerUp() { //is set by Bayesian tech
// ctx.globalAlpha = 0.4 * Math.sin(mech.cycle * 0.15) + 0.6; // ctx.globalAlpha = 0.4 * Math.sin(mech.cycle * 0.15) + 0.6;
// for (let i = 0, len = powerUp.length; i < len; ++i) { // for (let i = 0, len = powerUp.length; i < len; ++i) {
// ctx.beginPath(); // ctx.beginPath();
@@ -899,22 +932,22 @@ const game = {
mapPath: null, //holds the path for the map to speed up drawing mapPath: null, //holds the path for the map to speed up drawing
setPaths() { setPaths() {
//runs at each new level to store the path for the map since the map doesn't change //runs at each new level to store the path for the map since the map doesn't change
game.draw.mapPath = new Path2D(); simulation.draw.mapPath = new Path2D();
for (let i = 0, len = map.length; i < len; ++i) { for (let i = 0, len = map.length; i < len; ++i) {
let vertices = map[i].vertices; let vertices = map[i].vertices;
game.draw.mapPath.moveTo(vertices[0].x, vertices[0].y); simulation.draw.mapPath.moveTo(vertices[0].x, vertices[0].y);
for (let j = 1; j < vertices.length; j += 1) { for (let j = 1; j < vertices.length; j += 1) {
game.draw.mapPath.lineTo(vertices[j].x, vertices[j].y); simulation.draw.mapPath.lineTo(vertices[j].x, vertices[j].y);
} }
game.draw.mapPath.lineTo(vertices[0].x, vertices[0].y); simulation.draw.mapPath.lineTo(vertices[0].x, vertices[0].y);
} }
}, },
mapFill: "#444", mapFill: "#444",
bodyFill: "rgba(140,140,140,0.85)", //"#999", bodyFill: "rgba(140,140,140,0.85)", //"#999",
bodyStroke: "#222", bodyStroke: "#222",
drawMapPath() { drawMapPath() {
ctx.fillStyle = game.draw.mapFill; ctx.fillStyle = simulation.draw.mapFill;
ctx.fill(game.draw.mapPath); ctx.fill(simulation.draw.mapPath);
}, },
body() { body() {
ctx.beginPath(); ctx.beginPath();
@@ -927,9 +960,9 @@ const game = {
ctx.lineTo(vertices[0].x, vertices[0].y); ctx.lineTo(vertices[0].x, vertices[0].y);
} }
ctx.lineWidth = 2; ctx.lineWidth = 2;
ctx.fillStyle = game.draw.bodyFill; ctx.fillStyle = simulation.draw.bodyFill;
ctx.fill(); ctx.fill();
ctx.strokeStyle = game.draw.bodyStroke; ctx.strokeStyle = simulation.draw.bodyStroke;
ctx.stroke(); ctx.stroke();
}, },
cons() { cons() {
@@ -1098,14 +1131,14 @@ const game = {
}, },
constructMapString: [], constructMapString: [],
constructCycle() { constructCycle() {
if (game.isConstructionMode && game.constructMouseDownPosition) { if (simulation.isConstructionMode && simulation.constructMouseDownPosition) {
function round(num, round = 25) { function round(num, round = 25) {
return Math.ceil(num / round) * round; return Math.ceil(num / round) * round;
} }
const x = round(game.constructMouseDownPosition.x) const x = round(simulation.constructMouseDownPosition.x)
const y = round(game.constructMouseDownPosition.y) const y = round(simulation.constructMouseDownPosition.y)
const dx = Math.max(25, round(game.mouseInGame.x) - x) const dx = Math.max(25, round(simulation.mouseInGame.x) - x)
const dy = Math.max(25, round(game.mouseInGame.y) - y) const dy = Math.max(25, round(simulation.mouseInGame.y) - y)
ctx.strokeStyle = "#000" ctx.strokeStyle = "#000"
ctx.lineWidth = 2; ctx.lineWidth = 2;
@@ -1113,39 +1146,39 @@ const game = {
} }
}, },
outputMapString(string) { outputMapString(string) {
if (string) game.constructMapString.push(string) //store command as a string in the next element of an array if (string) simulation.constructMapString.push(string) //store command as a string in the next element of an array
let out = "" //combine set of map strings to one string let out = "" //combine set of map strings to one string
let outHTML = "" let outHTML = ""
for (let i = 0, len = game.constructMapString.length; i < len; i++) { for (let i = 0, len = simulation.constructMapString.length; i < len; i++) {
out += game.constructMapString[i]; out += simulation.constructMapString[i];
outHTML += "<div>" + game.constructMapString[i] + "</div>" outHTML += "<div>" + simulation.constructMapString[i] + "</div>"
} }
console.log(out) console.log(out)
game.copyToClipBoard(out) simulation.copyToClipBoard(out)
document.getElementById("construct").innerHTML = outHTML document.getElementById("construct").innerHTML = outHTML
}, },
enableConstructMode() { enableConstructMode() {
game.isConstructionMode = true; simulation.isConstructionMode = true;
game.isAutoZoom = false; simulation.isAutoZoom = false;
game.zoomScale = 2600; simulation.zoomScale = 2600;
game.setZoom(); simulation.setZoom();
document.body.addEventListener("mouseup", (e) => { document.body.addEventListener("mouseup", (e) => {
if (game.testing && game.constructMouseDownPosition) { if (simulation.testing && simulation.constructMouseDownPosition) {
function round(num, round = 25) { function round(num, round = 25) {
return Math.ceil(num / round) * round; return Math.ceil(num / round) * round;
} }
//clean up positions //clean up positions
const x = round(game.constructMouseDownPosition.x) const x = round(simulation.constructMouseDownPosition.x)
const y = round(game.constructMouseDownPosition.y) const y = round(simulation.constructMouseDownPosition.y)
const dx = Math.max(25, round(game.mouseInGame.x) - x) const dx = Math.max(25, round(simulation.mouseInGame.x) - x)
const dy = Math.max(25, round(game.mouseInGame.y) - y) const dy = Math.max(25, round(simulation.mouseInGame.y) - y)
if (e.which === 2) { if (e.which === 2) {
game.outputMapString(`spawn.randomMob(${x}, ${y},0.5);`); simulation.outputMapString(`spawn.randomMob(${x}, ${y},0.5);`);
} else if (game.mouseInGame.x > game.constructMouseDownPosition.x && game.mouseInGame.y > game.constructMouseDownPosition.y) { //make sure that the width and height are positive } else if (simulation.mouseInGame.x > simulation.constructMouseDownPosition.x && simulation.mouseInGame.y > simulation.constructMouseDownPosition.y) { //make sure that the width and height are positive
if (e.which === 1) { //add map if (e.which === 1) { //add map
game.outputMapString(`spawn.mapRect(${x}, ${y}, ${dx}, ${dy});`); simulation.outputMapString(`spawn.mapRect(${x}, ${y}, ${dx}, ${dy});`);
//see map in world //see map in world
spawn.mapRect(x, y, dx, dy); spawn.mapRect(x, y, dx, dy);
@@ -1155,9 +1188,9 @@ const game = {
Matter.Body.setStatic(map[len], true); //make static Matter.Body.setStatic(map[len], true); //make static
World.add(engine.world, map[len]); //add to world World.add(engine.world, map[len]); //add to world
game.draw.setPaths() //update map graphics simulation.draw.setPaths() //update map graphics
} else if (e.which === 3) { //add body } else if (e.which === 3) { //add body
game.outputMapString(`spawn.bodyRect(${x}, ${y}, ${dx}, ${dy});`); simulation.outputMapString(`spawn.bodyRect(${x}, ${y}, ${dx}, ${dy});`);
//see map in world //see map in world
spawn.bodyRect(x, y, dx, dy); spawn.bodyRect(x, y, dx, dy);
@@ -1169,32 +1202,32 @@ const game = {
} }
} }
} }
game.constructMouseDownPosition.x = undefined simulation.constructMouseDownPosition.x = undefined
game.constructMouseDownPosition.y = undefined simulation.constructMouseDownPosition.y = undefined
}); });
game.constructMouseDownPosition.x = undefined simulation.constructMouseDownPosition.x = undefined
game.constructMouseDownPosition.y = undefined simulation.constructMouseDownPosition.y = undefined
document.body.addEventListener("mousedown", (e) => { document.body.addEventListener("mousedown", (e) => {
if (game.testing) { if (simulation.testing) {
game.constructMouseDownPosition.x = game.mouseInGame.x simulation.constructMouseDownPosition.x = simulation.mouseInGame.x
game.constructMouseDownPosition.y = game.mouseInGame.y simulation.constructMouseDownPosition.y = simulation.mouseInGame.y
} }
}); });
document.body.addEventListener("keydown", (e) => { // e.keyCode z=90 m=77 b=66 shift = 16 c = 67 document.body.addEventListener("keydown", (e) => { // e.keyCode z=90 m=77 b=66 shift = 16 c = 67
if (game.testing && e.keyCode === 90 && game.constructMapString.length) { if (simulation.testing && e.keyCode === 90 && simulation.constructMapString.length) {
if (game.constructMapString[game.constructMapString.length - 1][6] === 'm') { //remove map from current level if (simulation.constructMapString[simulation.constructMapString.length - 1][6] === 'm') { //remove map from current level
const index = map.length - 1 const index = map.length - 1
Matter.World.remove(engine.world, map[index]); Matter.World.remove(engine.world, map[index]);
map.splice(index, 1); map.splice(index, 1);
game.draw.setPaths() //update map graphics simulation.draw.setPaths() //update map graphics
} else if (game.constructMapString[game.constructMapString.length - 1][6] === 'b') { //remove body from current level } else if (simulation.constructMapString[simulation.constructMapString.length - 1][6] === 'b') { //remove body from current level
const index = body.length - 1 const index = body.length - 1
Matter.World.remove(engine.world, body[index]); Matter.World.remove(engine.world, body[index]);
body.splice(index, 1); body.splice(index, 1);
} }
game.constructMapString.pop(); simulation.constructMapString.pop();
game.outputMapString(); simulation.outputMapString();
} }
}); });
} }

View File

@@ -28,7 +28,7 @@ const spawn = {
spawn.pickList.push(spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]); spawn.pickList.push(spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]);
}, },
spawnChance(chance) { spawnChance(chance) {
return Math.random() < chance + 0.07 * game.difficulty && mob.length < -1 + 16 * Math.log10(game.difficulty + 1) return Math.random() < chance + 0.07 * simulation.difficulty && mob.length < -1 + 16 * Math.log10(simulation.difficulty + 1)
}, },
randomMob(x, y, chance = 1) { randomMob(x, y, chance = 1) {
if (spawn.spawnChance(chance) || chance === Infinity) { if (spawn.spawnChance(chance) || chance === Infinity) {
@@ -37,7 +37,7 @@ const spawn = {
} }
}, },
randomSmallMob(x, y, randomSmallMob(x, y,
num = Math.max(Math.min(Math.round(Math.random() * game.difficulty * 0.2), 4), 0), num = Math.max(Math.min(Math.round(Math.random() * simulation.difficulty * 0.2), 4), 0),
size = 16 + Math.ceil(Math.random() * 15), size = 16 + Math.ceil(Math.random() * 15),
chance = 1) { chance = 1) {
if (spawn.spawnChance(chance)) { if (spawn.spawnChance(chance)) {
@@ -48,7 +48,7 @@ const spawn = {
} }
}, },
randomBoss(x, y, chance = 1) { randomBoss(x, y, chance = 1) {
if (spawn.spawnChance(chance) && game.difficulty > 2 || chance == Infinity) { if (spawn.spawnChance(chance) && simulation.difficulty > 2 || chance == Infinity) {
//choose from the possible picklist //choose from the possible picklist
let pick = this.pickList[Math.floor(Math.random() * this.pickList.length)]; let pick = this.pickList[Math.floor(Math.random() * this.pickList.length)];
//is the pick able to be a boss? //is the pick able to be a boss?
@@ -102,7 +102,7 @@ const spawn = {
level.exit.x = 5500; level.exit.x = 5500;
level.exit.y = -330; level.exit.y = -330;
//ramp up damage //ramp up damage
for (let i = 0; i < 4; i++) level.difficultyIncrease(game.difficultyMode) for (let i = 0; i < 4; i++) level.difficultyIncrease(simulation.difficultyMode)
//pull in particles //pull in particles
@@ -121,7 +121,7 @@ const spawn = {
//draw stuff //draw stuff
for (let i = 0, len = 22; i < len; i++) { for (let i = 0, len = 22; i < len; i++) {
game.drawList.push({ //add dmg to draw queue simulation.drawList.push({ //add dmg to draw queue
x: this.position.x, x: this.position.x,
y: this.position.y, y: this.position.y,
radius: (i + 1) * 150, radius: (i + 1) * 150,
@@ -219,9 +219,9 @@ const spawn = {
}); });
} }
if (game.difficulty > 60) { if (simulation.difficulty > 60) {
spawn.randomLevelBoss(3000, -1100) spawn.randomLevelBoss(3000, -1100)
if (game.difficulty > 100) { if (simulation.difficulty > 100) {
spawn.randomLevelBoss(3000, -1300) spawn.randomLevelBoss(3000, -1300)
} }
} }
@@ -231,7 +231,7 @@ const spawn = {
me.eventHorizonCycleRate = 4 * Math.PI / me.endCycle me.eventHorizonCycleRate = 4 * Math.PI / me.endCycle
me.modeSuck = function() { me.modeSuck = function() {
//eventHorizon waves in and out //eventHorizon waves in and out
const eventHorizon = this.eventHorizon * (1 - 0.25 * Math.cos(game.cycle * this.eventHorizonCycleRate)) //0.014 const eventHorizon = this.eventHorizon * (1 - 0.25 * Math.cos(simulation.cycle * this.eventHorizonCycleRate)) //0.014
//draw darkness //draw darkness
ctx.beginPath(); ctx.beginPath();
ctx.arc(this.position.x, this.position.y, eventHorizon * 0.2, 0, 2 * Math.PI); ctx.arc(this.position.x, this.position.y, eventHorizon * 0.2, 0, 2 * Math.PI);
@@ -257,7 +257,7 @@ const spawn = {
if (Vector.magnitude(Vector.sub(this.position, player.position)) < eventHorizon) { if (Vector.magnitude(Vector.sub(this.position, player.position)) < eventHorizon) {
if (mech.energy > 0) mech.energy -= 0.01 if (mech.energy > 0) mech.energy -= 0.01
if (mech.energy < 0.15) { if (mech.energy < 0.15) {
mech.damage(0.0004 * game.dmgScale); mech.damage(0.0004 * simulation.dmgScale);
} }
const angle = Math.atan2(player.position.y - this.position.y, player.position.x - this.position.x); const angle = Math.atan2(player.position.y - this.position.y, player.position.x - this.position.x);
player.force.x -= 0.0017 * Math.cos(angle) * player.mass * (mech.onGround ? 1.7 : 1); player.force.x -= 0.0017 * Math.cos(angle) * player.mass * (mech.onGround ? 1.7 : 1);
@@ -296,7 +296,7 @@ const spawn = {
} }
if (this.cycle < 240) { //damage scales up over 2 seconds to give player time to move if (this.cycle < 240) { //damage scales up over 2 seconds to give player time to move
const scale = this.cycle / 240 const scale = this.cycle / 240
const dmg = (this.cycle < 120) ? 0 : 0.14 * game.dmgScale * scale const dmg = (this.cycle < 120) ? 0 : 0.14 * simulation.dmgScale * scale
ctx.beginPath(); ctx.beginPath();
this.laser(this.vertices[0], this.angle + Math.PI / 6, dmg); this.laser(this.vertices[0], this.angle + Math.PI / 6, dmg);
this.laser(this.vertices[1], this.angle + 3 * Math.PI / 6, dmg); this.laser(this.vertices[1], this.angle + 3 * Math.PI / 6, dmg);
@@ -329,13 +329,13 @@ const spawn = {
ctx.strokeStyle = "rgba(80,0,255,0.07)"; ctx.strokeStyle = "rgba(80,0,255,0.07)";
ctx.stroke(); // Draw it ctx.stroke(); // Draw it
} }
me.laser = function(where, angle, dmg = 0.14 * game.dmgScale) { me.laser = function(where, angle, dmg = 0.14 * simulation.dmgScale) {
const vertexCollision = function(v1, v1End, domain) { const vertexCollision = function(v1, v1End, domain) {
for (let i = 0; i < domain.length; ++i) { for (let i = 0; i < domain.length; ++i) {
let vertices = domain[i].vertices; let vertices = domain[i].vertices;
const len = vertices.length - 1; const len = vertices.length - 1;
for (let j = 0; j < len; j++) { for (let j = 0; j < len; j++) {
results = game.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]); results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
if (results.onLine1 && results.onLine2) { if (results.onLine1 && results.onLine2) {
const dx = v1.x - results.x; const dx = v1.x - results.x;
const dy = v1.y - results.y; const dy = v1.y - results.y;
@@ -350,7 +350,7 @@ const spawn = {
}; };
} }
} }
results = game.checkLineIntersection(v1, v1End, vertices[0], vertices[len]); results = simulation.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
if (results.onLine1 && results.onLine2) { if (results.onLine1 && results.onLine2) {
const dx = v1.x - results.x; const dx = v1.x - results.x;
const dy = v1.y - results.y; const dy = v1.y - results.y;
@@ -385,9 +385,9 @@ const spawn = {
vertexCollision(where, look, body); vertexCollision(where, look, body);
if (!mech.isCloak) vertexCollision(where, look, [player]); if (!mech.isCloak) vertexCollision(where, look, [player]);
if (best.who && best.who === player && mech.immuneCycle < mech.cycle) { if (best.who && best.who === player && mech.immuneCycle < mech.cycle) {
mech.immuneCycle = mech.cycle + 60 + mod.collisionImmuneCycles; //player is immune to collision damage for 30 cycles mech.immuneCycle = mech.cycle + 60 + tech.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
mech.damage(dmg); mech.damage(dmg);
game.drawList.push({ //add dmg to draw queue simulation.drawList.push({ //add dmg to draw queue
x: best.x, x: best.x,
y: best.y, y: best.y,
radius: dmg * 1500, radius: dmg * 1500,
@@ -412,7 +412,7 @@ const spawn = {
mobs.spawn(x, y, 4, radius, "#777"); mobs.spawn(x, y, 4, radius, "#777");
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.g = 0.00015; //required if using 'gravity' me.g = 0.00015; //required if using 'gravity'
me.accelMag = 0.0008 * game.accelScale; me.accelMag = 0.0008 * simulation.accelScale;
me.groupingRangeMax = 250000 + Math.random() * 100000; me.groupingRangeMax = 250000 + Math.random() * 100000;
me.groupingRangeMin = (radius * 8) * (radius * 8); me.groupingRangeMin = (radius * 8) * (radius * 8);
me.groupingStrength = 0.0005 me.groupingStrength = 0.0005
@@ -454,7 +454,7 @@ const spawn = {
mobs.spawn(x, y, 8, radius, "#9ccdc6"); mobs.spawn(x, y, 8, radius, "#9ccdc6");
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
// console.log(`mass=${me.mass}, radius = ${radius}`) // console.log(`mass=${me.mass}, radius = ${radius}`)
me.accelMag = 0.0005 * game.accelScale; me.accelMag = 0.0005 * simulation.accelScale;
me.memory = 60; me.memory = 60;
me.seeAtDistance2 = 1400000 //1200 vision range me.seeAtDistance2 = 1400000 //1200 vision range
Matter.Body.setDensity(me, 0.0005) // normal density is 0.001 // this reduces life by half and decreases knockback Matter.Body.setDensity(me, 0.0005) // normal density is 0.001 // this reduces life by half and decreases knockback
@@ -475,7 +475,7 @@ const spawn = {
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.isBoss = true; me.isBoss = true;
me.isCell = true; me.isCell = true;
me.accelMag = 0.00015 * game.accelScale; me.accelMag = 0.00015 * simulation.accelScale;
me.memory = 40; me.memory = 40;
me.isVerticesChange = true me.isVerticesChange = true
me.frictionAir = 0.012 me.frictionAir = 0.012
@@ -511,7 +511,7 @@ const spawn = {
Matter.Body.scale(this, scale, scale); Matter.Body.scale(this, scale, scale);
this.radius = Math.sqrt(this.mass * k / Math.PI) this.radius = Math.sqrt(this.mass * k / Math.PI)
} }
if (!(game.cycle % this.seePlayerFreq)) { //move away from other mobs if (!(simulation.cycle % this.seePlayerFreq)) { //move away from other mobs
const repelRange = 200 const repelRange = 200
const attractRange = 800 const attractRange = 800
for (let i = 0, len = mob.length; i < len; i++) { for (let i = 0, len = mob.length; i < len; i++) {
@@ -548,7 +548,7 @@ const spawn = {
me.isBoss = true; me.isBoss = true;
me.frictionAir = 0.01 me.frictionAir = 0.01
me.seeAtDistance2 = 1000000; me.seeAtDistance2 = 1000000;
me.accelMag = 0.0005 * game.accelScale; me.accelMag = 0.0005 * simulation.accelScale;
Matter.Body.setDensity(me, 0.0006); //normal is 0.001 Matter.Body.setDensity(me, 0.0006); //normal is 0.001
me.collisionFilter.mask = cat.bullet | cat.player me.collisionFilter.mask = cat.bullet | cat.player
me.memory = Infinity; me.memory = Infinity;
@@ -583,7 +583,7 @@ const spawn = {
} }
}; };
me.do = function() { me.do = function() {
this.stroke = `hsl(0,0%,${80+25*Math.sin(game.cycle*0.01)}%)` this.stroke = `hsl(0,0%,${80+25*Math.sin(simulation.cycle*0.01)}%)`
//steal all power ups //steal all power ups
for (let i = 0; i < Math.min(powerUp.length, this.vertices.length); i++) { for (let i = 0; i < Math.min(powerUp.length, this.vertices.length); i++) {
@@ -606,7 +606,7 @@ const spawn = {
// Matter.Body.setDensity(me, 0.0007); //extra dense //normal is 0.001 //makes effective life much lower // Matter.Body.setDensity(me, 0.0007); //extra dense //normal is 0.001 //makes effective life much lower
me.friction = 0; me.friction = 0;
me.frictionAir = 0; me.frictionAir = 0;
me.accelMag = 0.001 * Math.sqrt(game.accelScale); me.accelMag = 0.001 * Math.sqrt(simulation.accelScale);
me.g = me.accelMag * 0.6; //required if using 'gravity' me.g = me.accelMag * 0.6; //required if using 'gravity'
me.memory = 50; me.memory = 50;
spawn.shield(me, x, y); spawn.shield(me, x, y);
@@ -622,7 +622,7 @@ const spawn = {
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.isVerticesChange = true me.isVerticesChange = true
me.big = false; //required for grow me.big = false; //required for grow
me.accelMag = 0.00045 * game.accelScale; me.accelMag = 0.00045 * simulation.accelScale;
me.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.player //can't touch other mobs me.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.player //can't touch other mobs
// me.onDeath = function () { //helps collisions functions work better after vertex have been changed // me.onDeath = function () { //helps collisions functions work better after vertex have been changed
// this.vertices = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices)) // this.vertices = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices))
@@ -641,7 +641,7 @@ const spawn = {
me.frictionAir = 0.006; me.frictionAir = 0.006;
me.lookTorque = 0.0000008; //controls spin while looking for player me.lookTorque = 0.0000008; //controls spin while looking for player
me.g = 0.0002; //required if using 'gravity' me.g = 0.0002; //required if using 'gravity'
me.seePlayerFreq = Math.round((40 + 25 * Math.random()) * game.lookFreqScale); me.seePlayerFreq = Math.round((40 + 25 * Math.random()) * simulation.lookFreqScale);
const springStiffness = 0.00014; const springStiffness = 0.00014;
const springDampening = 0.0005; const springDampening = 0.0005;
@@ -695,17 +695,17 @@ const spawn = {
me.g = 0.0017; //required if using 'gravity' me.g = 0.0017; //required if using 'gravity'
me.frictionAir = 0.01; me.frictionAir = 0.01;
me.restitution = 0; me.restitution = 0;
me.delay = 120 * game.CDScale; me.delay = 120 * simulation.CDScale;
me.randomHopFrequency = 200 + Math.floor(Math.random() * 150); me.randomHopFrequency = 200 + Math.floor(Math.random() * 150);
me.randomHopCD = game.cycle + me.randomHopFrequency; me.randomHopCD = simulation.cycle + me.randomHopFrequency;
spawn.shield(me, x, y); spawn.shield(me, x, y);
me.do = function() { me.do = function() {
this.gravity(); this.gravity();
this.seePlayerCheck(); this.seePlayerCheck();
this.checkStatus(); this.checkStatus();
if (this.seePlayer.recall) { if (this.seePlayer.recall) {
if (this.cd < game.cycle && (Matter.Query.collides(this, map).length || Matter.Query.collides(this, body).length)) { if (this.cd < simulation.cycle && (Matter.Query.collides(this, map).length || Matter.Query.collides(this, body).length)) {
this.cd = game.cycle + this.delay; this.cd = simulation.cycle + this.delay;
const forceMag = (this.accelMag + this.accelMag * Math.random()) * this.mass; const forceMag = (this.accelMag + this.accelMag * Math.random()) * 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);
@@ -713,8 +713,8 @@ const spawn = {
} }
} else { } else {
//randomly hob if not aware of player //randomly hob if not aware of player
if (this.randomHopCD < game.cycle && (Matter.Query.collides(this, map).length || Matter.Query.collides(this, body).length)) { if (this.randomHopCD < simulation.cycle && (Matter.Query.collides(this, map).length || Matter.Query.collides(this, body).length)) {
this.randomHopCD = game.cycle + this.randomHopFrequency; this.randomHopCD = simulation.cycle + this.randomHopFrequency;
//slowly change randomHopFrequency after each hop //slowly change randomHopFrequency after each hop
this.randomHopFrequency = Math.max(100, this.randomHopFrequency + (0.5 - Math.random()) * 200); this.randomHopFrequency = Math.max(100, this.randomHopFrequency + (0.5 - Math.random()) * 200);
const forceMag = (this.accelMag + this.accelMag * Math.random()) * this.mass * (0.1 + Math.random() * 0.3); const forceMag = (this.accelMag + this.accelMag * Math.random()) * this.mass * (0.1 + Math.random() * 0.3);
@@ -742,9 +742,9 @@ const spawn = {
me.look = function() { me.look = function() {
this.seePlayerByLookingAt(); this.seePlayerByLookingAt();
this.checkStatus(); this.checkStatus();
if (this.seePlayer.recall && this.cd < game.cycle) { if (this.seePlayer.recall && this.cd < simulation.cycle) {
this.burstDir = Vector.normalise(Vector.sub(this.seePlayer.position, this.position)); this.burstDir = Vector.normalise(Vector.sub(this.seePlayer.position, this.position));
this.cd = game.cycle + 40; this.cd = simulation.cycle + 40;
this.do = this.spin this.do = this.spin
} }
} }
@@ -766,9 +766,9 @@ const spawn = {
ctx.lineTo(dir.x, dir.y); ctx.lineTo(dir.x, dir.y);
ctx.stroke(); ctx.stroke();
ctx.setLineDash([]); ctx.setLineDash([]);
if (this.cd < game.cycle) { if (this.cd < simulation.cycle) {
this.fill = this.rememberFill; this.fill = this.rememberFill;
this.cd = game.cycle + 180 * game.CDScale this.cd = simulation.cycle + 180 * simulation.CDScale
this.do = this.look this.do = this.look
this.force = Vector.mult(this.burstDir, this.mass * 0.25); this.force = Vector.mult(this.burstDir, this.mass * 0.25);
} }
@@ -781,7 +781,7 @@ const spawn = {
me.stroke = "transparent"; //used for drawSneaker me.stroke = "transparent"; //used for drawSneaker
me.eventHorizon = radius * 23; //required for blackhole me.eventHorizon = radius * 23; //required for blackhole
me.seeAtDistance2 = (me.eventHorizon + 400) * (me.eventHorizon + 400); //vision limit is event horizon me.seeAtDistance2 = (me.eventHorizon + 400) * (me.eventHorizon + 400); //vision limit is event horizon
me.accelMag = 0.00009 * game.accelScale; me.accelMag = 0.00009 * simulation.accelScale;
me.frictionAir = 0.025; me.frictionAir = 0.025;
me.collisionFilter.mask = cat.player | cat.bullet me.collisionFilter.mask = cat.player | cat.bullet
me.memory = Infinity; me.memory = Infinity;
@@ -795,7 +795,7 @@ const spawn = {
}); });
} }
// this.seePlayerCheckByDistance() // this.seePlayerCheckByDistance()
if (!(game.cycle % this.seePlayerFreq)) { if (!(simulation.cycle % this.seePlayerFreq)) {
if (this.distanceToPlayer2() < this.seeAtDistance2) { //&& !mech.isCloak ignore cloak for black holes if (this.distanceToPlayer2() < this.seeAtDistance2) { //&& !mech.isCloak ignore cloak for black holes
this.locatePlayer(); this.locatePlayer();
if (!this.seePlayer.yes) this.seePlayer.yes = true; if (!this.seePlayer.yes) this.seePlayer.yes = true;
@@ -806,7 +806,7 @@ const spawn = {
this.checkStatus(); this.checkStatus();
if (this.seePlayer.recall) { if (this.seePlayer.recall) {
//eventHorizon waves in and out //eventHorizon waves in and out
const eventHorizon = this.eventHorizon * (0.93 + 0.17 * Math.sin(game.cycle * 0.011)) const eventHorizon = this.eventHorizon * (0.93 + 0.17 * Math.sin(simulation.cycle * 0.011))
//accelerate towards the player //accelerate towards the player
const forceMag = this.accelMag * this.mass; const forceMag = this.accelMag * this.mass;
@@ -832,7 +832,7 @@ const spawn = {
if (Vector.magnitude(Vector.sub(this.position, player.position)) < eventHorizon) { if (Vector.magnitude(Vector.sub(this.position, player.position)) < eventHorizon) {
if (mech.energy > 0) mech.energy -= 0.004 if (mech.energy > 0) mech.energy -= 0.004
if (mech.energy < 0.1) { if (mech.energy < 0.1) {
mech.damage(0.00015 * game.dmgScale); mech.damage(0.00015 * simulation.dmgScale);
} }
const angle = Math.atan2(player.position.y - this.position.y, player.position.x - this.position.x); const angle = Math.atan2(player.position.y - this.position.y, player.position.x - this.position.x);
player.force.x -= 0.00125 * player.mass * Math.cos(angle) * (mech.onGround ? 1.8 : 1); player.force.x -= 0.00125 * player.mass * Math.cos(angle) * (mech.onGround ? 1.8 : 1);
@@ -859,7 +859,7 @@ const spawn = {
me.stroke = "transparent"; //used for drawSneaker me.stroke = "transparent"; //used for drawSneaker
me.eventHorizon = 1100; //required for black hole me.eventHorizon = 1100; //required for black hole
me.seeAtDistance2 = (me.eventHorizon + 1200) * (me.eventHorizon + 1200); //vision limit is event horizon me.seeAtDistance2 = (me.eventHorizon + 1200) * (me.eventHorizon + 1200); //vision limit is event horizon
me.accelMag = 0.00003 * game.accelScale; me.accelMag = 0.00003 * simulation.accelScale;
me.collisionFilter.mask = cat.player | cat.bullet me.collisionFilter.mask = cat.player | cat.bullet
// me.frictionAir = 0.005; // me.frictionAir = 0.005;
me.memory = 1600; me.memory = 1600;
@@ -867,7 +867,7 @@ const spawn = {
me.onDeath = function() { me.onDeath = function() {
//applying forces to player doesn't seem to work inside this method, not sure why //applying forces to player doesn't seem to work inside this method, not sure why
powerUps.spawnBossPowerUp(this.position.x, this.position.y) powerUps.spawnBossPowerUp(this.position.x, this.position.y)
if (game.difficulty > 5) { if (simulation.difficulty > 5) {
//teleport everything to center //teleport everything to center
function toMe(who, where, range) { function toMe(who, where, range) {
for (let i = 0, len = who.length; i < len; i++) { for (let i = 0, len = who.length; i < len; i++) {
@@ -891,7 +891,7 @@ const spawn = {
y: this.velocity.y * 0.95 y: this.velocity.y * 0.95
}); });
} }
if (!(game.cycle % this.seePlayerFreq)) { if (!(simulation.cycle % this.seePlayerFreq)) {
if (this.distanceToPlayer2() < this.seeAtDistance2) { //&& !mech.isCloak ignore cloak for black holes if (this.distanceToPlayer2() < this.seeAtDistance2) { //&& !mech.isCloak ignore cloak for black holes
this.locatePlayer(); this.locatePlayer();
if (!this.seePlayer.yes) this.seePlayer.yes = true; if (!this.seePlayer.yes) this.seePlayer.yes = true;
@@ -910,7 +910,7 @@ const spawn = {
this.force.y += forceMag * dy / mag; this.force.y += forceMag * dy / mag;
//eventHorizon waves in and out //eventHorizon waves in and out
const eventHorizon = this.eventHorizon * (1 + 0.2 * Math.sin(game.cycle * 0.008)) const eventHorizon = this.eventHorizon * (1 + 0.2 * Math.sin(simulation.cycle * 0.008))
// zoom camera in and out with the event horizon // zoom camera in and out with the event horizon
//draw darkness //draw darkness
@@ -938,7 +938,7 @@ const spawn = {
if (Vector.magnitude(Vector.sub(this.position, player.position)) < eventHorizon) { if (Vector.magnitude(Vector.sub(this.position, player.position)) < eventHorizon) {
if (mech.energy > 0) mech.energy -= 0.006 if (mech.energy > 0) mech.energy -= 0.006
if (mech.energy < 0.1) { if (mech.energy < 0.1) {
mech.damage(0.0002 * game.dmgScale); mech.damage(0.0002 * simulation.dmgScale);
} }
const angle = Math.atan2(player.position.y - this.position.y, player.position.x - this.position.x); const angle = Math.atan2(player.position.y - this.position.y, player.position.x - this.position.x);
player.force.x -= 0.0013 * Math.cos(angle) * player.mass * (mech.onGround ? 1.7 : 1); player.force.x -= 0.0013 * Math.cos(angle) * player.mass * (mech.onGround ? 1.7 : 1);
@@ -970,7 +970,7 @@ const spawn = {
me.frictionAir = 0.0065; me.frictionAir = 0.0065;
me.lookTorque = 0.0000008; //controls spin while looking for player me.lookTorque = 0.0000008; //controls spin while looking for player
me.g = 0.0002; //required if using 'gravity' me.g = 0.0002; //required if using 'gravity'
me.seePlayerFreq = Math.round((30 + 20 * Math.random()) * game.lookFreqScale); me.seePlayerFreq = Math.round((30 + 20 * Math.random()) * simulation.lookFreqScale);
const springStiffness = 0.00014; const springStiffness = 0.00014;
const springDampening = 0.0005; const springDampening = 0.0005;
@@ -1053,11 +1053,11 @@ const spawn = {
me.timeSkipLastCycle = 0 me.timeSkipLastCycle = 0
me.eventHorizon = 1800; //required for black hole me.eventHorizon = 1800; //required for black hole
me.seeAtDistance2 = (me.eventHorizon + 2000) * (me.eventHorizon + 2000); //vision limit is event horizon + 2000 me.seeAtDistance2 = (me.eventHorizon + 2000) * (me.eventHorizon + 2000); //vision limit is event horizon + 2000
me.accelMag = 0.0004 * game.accelScale; me.accelMag = 0.0004 * simulation.accelScale;
// me.frictionAir = 0.005; // me.frictionAir = 0.005;
// me.memory = 1600; // me.memory = 1600;
// Matter.Body.setDensity(me, 0.02); //extra dense //normal is 0.001 //makes effective life much larger // Matter.Body.setDensity(me, 0.02); //extra dense //normal is 0.001 //makes effective life much larger
Matter.Body.setDensity(me, 0.0015 + 0.0005 * Math.sqrt(game.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger Matter.Body.setDensity(me, 0.0015 + 0.0005 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
spawn.shield(me, x, y, 1); spawn.shield(me, x, y, 1);
@@ -1076,12 +1076,12 @@ const spawn = {
this.seePlayerCheck(); this.seePlayerCheck();
this.checkStatus(); this.checkStatus();
this.attraction() this.attraction()
if (!game.isTimeSkipping) { if (!simulation.isTimeSkipping) {
const compress = 1 const compress = 1
if (this.timeSkipLastCycle < game.cycle - compress && if (this.timeSkipLastCycle < simulation.cycle - compress &&
Vector.magnitude(Vector.sub(this.position, player.position)) < this.eventHorizon) { Vector.magnitude(Vector.sub(this.position, player.position)) < this.eventHorizon) {
this.timeSkipLastCycle = game.cycle this.timeSkipLastCycle = simulation.cycle
game.timeSkip(compress) simulation.timeSkip(compress)
this.fill = `rgba(0,0,0,${0.4+0.6*Math.random()})` this.fill = `rgba(0,0,0,${0.4+0.6*Math.random()})`
this.stroke = "#014" this.stroke = "#014"
@@ -1132,7 +1132,7 @@ const spawn = {
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.repulsionRange = 73000; //squared me.repulsionRange = 73000; //squared
me.laserRange = 370; me.laserRange = 370;
me.accelMag = 0.0005 * game.accelScale; me.accelMag = 0.0005 * simulation.accelScale;
me.frictionStatic = 0; me.frictionStatic = 0;
me.friction = 0; me.friction = 0;
spawn.shield(me, x, y); spawn.shield(me, x, y);
@@ -1153,7 +1153,7 @@ const spawn = {
me.restitution = 0; me.restitution = 0;
me.laserPos = me.position; //required for laserTracking me.laserPos = me.position; //required for laserTracking
me.repulsionRange = 1200000; //squared me.repulsionRange = 1200000; //squared
me.accelMag = 0.00009 * game.accelScale; me.accelMag = 0.00009 * simulation.accelScale;
me.frictionStatic = 0; me.frictionStatic = 0;
me.friction = 0; me.friction = 0;
me.onDamage = function() { me.onDamage = function() {
@@ -1216,8 +1216,8 @@ const spawn = {
me.isBoss = true; me.isBoss = true;
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
Matter.Body.rotate(me, Math.random() * Math.PI * 2); Matter.Body.rotate(me, Math.random() * Math.PI * 2);
me.accelMag = 0.0002 * Math.sqrt(game.accelScale); me.accelMag = 0.0002 * Math.sqrt(simulation.accelScale);
me.seePlayerFreq = Math.floor(30 * game.lookFreqScale); me.seePlayerFreq = Math.floor(30 * simulation.lookFreqScale);
me.memory = 420; me.memory = 420;
me.restitution = 1; me.restitution = 1;
me.frictionAir = 0.01; me.frictionAir = 0.01;
@@ -1247,7 +1247,7 @@ const spawn = {
if (this.seePlayer.recall) { if (this.seePlayer.recall) {
//set direction to turn to fire //set direction to turn to fire
if (!(game.cycle % this.seePlayerFreq)) { if (!(simulation.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
} }
@@ -1272,7 +1272,7 @@ const spawn = {
let vertices = domain[i].vertices; let vertices = domain[i].vertices;
const len = vertices.length - 1; const len = vertices.length - 1;
for (let j = 0; j < len; j++) { for (let j = 0; j < len; j++) {
results = game.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]); results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
if (results.onLine1 && results.onLine2) { if (results.onLine1 && results.onLine2) {
const dx = v1.x - results.x; const dx = v1.x - results.x;
const dy = v1.y - results.y; const dy = v1.y - results.y;
@@ -1289,7 +1289,7 @@ const spawn = {
} }
} }
} }
results = game.checkLineIntersection(v1, v1End, vertices[0], vertices[len]); results = simulation.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
if (results.onLine1 && results.onLine2) { if (results.onLine1 && results.onLine2) {
const dx = v1.x - results.x; const dx = v1.x - results.x;
const dy = v1.y - results.y; const dy = v1.y - results.y;
@@ -1327,7 +1327,7 @@ const spawn = {
// hitting player // hitting player
if (best.who === player) { if (best.who === player) {
if (mech.immuneCycle < mech.cycle) { if (mech.immuneCycle < mech.cycle) {
const dmg = 0.001 * game.dmgScale; const dmg = 0.001 * simulation.dmgScale;
mech.damage(dmg); mech.damage(dmg);
//draw damage //draw damage
ctx.fillStyle = color; ctx.fillStyle = color;
@@ -1356,7 +1356,7 @@ const spawn = {
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
Matter.Body.rotate(me, Math.random() * Math.PI * 2); Matter.Body.rotate(me, Math.random() * Math.PI * 2);
me.accelMag = 0.00007 * game.accelScale; me.accelMag = 0.00007 * simulation.accelScale;
me.onHit = function() { me.onHit = function() {
//run this function on hitting player //run this function on hitting player
this.explode(); this.explode();
@@ -1384,7 +1384,7 @@ const spawn = {
me.onDeath = function() { me.onDeath = function() {
powerUps.spawnBossPowerUp(this.position.x, this.position.y) powerUps.spawnBossPowerUp(this.position.x, this.position.y)
}; };
me.rotateVelocity = Math.min(0.0045, 0.0015 * game.accelScale * game.accelScale) * (level.levelsCleared > 8 ? 1 : -1) me.rotateVelocity = Math.min(0.0045, 0.0015 * simulation.accelScale * simulation.accelScale) * (level.levelsCleared > 8 ? 1 : -1)
me.do = function() { me.do = function() {
this.fill = '#' + Math.random().toString(16).substr(-6); //flash colors this.fill = '#' + Math.random().toString(16).substr(-6); //flash colors
this.checkStatus(); this.checkStatus();
@@ -1433,7 +1433,7 @@ const spawn = {
let vertices = domain[i].vertices; let vertices = domain[i].vertices;
const len = vertices.length - 1; const len = vertices.length - 1;
for (let j = 0; j < len; j++) { for (let j = 0; j < len; j++) {
results = game.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]); results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
if (results.onLine1 && results.onLine2) { if (results.onLine1 && results.onLine2) {
const dx = v1.x - results.x; const dx = v1.x - results.x;
const dy = v1.y - results.y; const dy = v1.y - results.y;
@@ -1448,7 +1448,7 @@ const spawn = {
}; };
} }
} }
results = game.checkLineIntersection(v1, v1End, vertices[0], vertices[len]); results = simulation.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
if (results.onLine1 && results.onLine2) { if (results.onLine1 && results.onLine2) {
const dx = v1.x - results.x; const dx = v1.x - results.x;
const dy = v1.y - results.y; const dy = v1.y - results.y;
@@ -1483,10 +1483,10 @@ const spawn = {
vertexCollision(where, look, body); vertexCollision(where, look, body);
if (!mech.isCloak) vertexCollision(where, look, [player]); if (!mech.isCloak) vertexCollision(where, look, [player]);
if (best.who && best.who === player && mech.immuneCycle < mech.cycle) { if (best.who && best.who === player && mech.immuneCycle < mech.cycle) {
mech.immuneCycle = mech.cycle + mod.collisionImmuneCycles; //player is immune to collision damage for 30 cycles mech.immuneCycle = mech.cycle + tech.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
const dmg = 0.14 * game.dmgScale; const dmg = 0.14 * simulation.dmgScale;
mech.damage(dmg); mech.damage(dmg);
game.drawList.push({ //add dmg to draw queue simulation.drawList.push({ //add dmg to draw queue
x: best.x, x: best.x,
y: best.y, y: best.y,
radius: dmg * 1500, radius: dmg * 1500,
@@ -1505,9 +1505,9 @@ const spawn = {
mobs.spawn(x, y, 6, radius, "rgb(220,50,205)"); //can't have sides above 6 or collision events don't work (probably because of a convex problem) mobs.spawn(x, y, 6, radius, "rgb(220,50,205)"); //can't have sides above 6 or collision events don't work (probably because of a convex problem)
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.isVerticesChange = true me.isVerticesChange = true
me.accelMag = 0.0006 * game.accelScale; me.accelMag = 0.0006 * simulation.accelScale;
// me.g = 0.0002; //required if using 'gravity' // me.g = 0.0002; //required if using 'gravity'
me.delay = 360 * game.CDScale; me.delay = 360 * simulation.CDScale;
me.spikeVertex = 0; me.spikeVertex = 0;
me.spikeLength = 0; me.spikeLength = 0;
me.isSpikeGrowing = false; me.isSpikeGrowing = false;
@@ -1582,20 +1582,20 @@ const spawn = {
striker(x, y, radius = 14 + Math.ceil(Math.random() * 25)) { striker(x, y, radius = 14 + Math.ceil(Math.random() * 25)) {
mobs.spawn(x, y, 5, radius, "rgb(221,102,119)"); mobs.spawn(x, y, 5, radius, "rgb(221,102,119)");
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.accelMag = 0.00034 * game.accelScale; me.accelMag = 0.00034 * simulation.accelScale;
me.g = 0.00015; //required if using 'gravity' me.g = 0.00015; //required if using 'gravity'
me.frictionStatic = 0; me.frictionStatic = 0;
me.friction = 0; me.friction = 0;
me.delay = 90 * game.CDScale; me.delay = 90 * simulation.CDScale;
me.cd = Infinity; me.cd = Infinity;
Matter.Body.rotate(me, Math.PI * 0.1); Matter.Body.rotate(me, Math.PI * 0.1);
spawn.shield(me, x, y); spawn.shield(me, x, y);
me.onDamage = function() { me.onDamage = function() {
this.cd = game.cycle + this.delay; this.cd = simulation.cycle + this.delay;
}; };
me.do = function() { me.do = function() {
this.gravity(); this.gravity();
if (!(game.cycle % this.seePlayerFreq)) { // this.seePlayerCheck(); from mobs if (!(simulation.cycle % this.seePlayerFreq)) { // this.seePlayerCheck(); from mobs
if ( if (
this.distanceToPlayer2() < this.seeAtDistance2 && this.distanceToPlayer2() < this.seeAtDistance2 &&
Matter.Query.ray(map, this.position, this.mechPosRange()).length === 0 && Matter.Query.ray(map, this.position, this.mechPosRange()).length === 0 &&
@@ -1603,7 +1603,7 @@ const spawn = {
!mech.isCloak !mech.isCloak
) { ) {
this.foundPlayer(); this.foundPlayer();
if (this.cd === Infinity) this.cd = game.cycle + this.delay * 0.7; if (this.cd === Infinity) this.cd = simulation.cycle + this.delay * 0.7;
} else if (this.seePlayer.recall) { } else if (this.seePlayer.recall) {
this.lostPlayer(); this.lostPlayer();
this.cd = Infinity this.cd = Infinity
@@ -1611,11 +1611,11 @@ const spawn = {
} }
this.checkStatus(); this.checkStatus();
this.attraction(); this.attraction();
if (this.cd < game.cycle) { if (this.cd < simulation.cycle) {
if (this.seePlayer.recall) { if (this.seePlayer.recall) {
const dist = Vector.sub(this.seePlayer.position, this.position); const dist = Vector.sub(this.seePlayer.position, this.position);
const distMag = Vector.magnitude(dist); const distMag = Vector.magnitude(dist);
this.cd = game.cycle + this.delay; this.cd = simulation.cycle + this.delay;
ctx.beginPath(); ctx.beginPath();
ctx.moveTo(this.position.x, this.position.y); ctx.moveTo(this.position.x, this.position.y);
if (distMag < 400) { if (distMag < 400) {
@@ -1639,7 +1639,7 @@ const spawn = {
let me; let me;
mobs.spawn(x, y, 5, radius, "transparent"); mobs.spawn(x, y, 5, radius, "transparent");
me = mob[mob.length - 1]; me = mob[mob.length - 1];
me.accelMag = 0.0007 * game.accelScale; me.accelMag = 0.0007 * simulation.accelScale;
me.g = 0.0002; //required if using 'gravity' me.g = 0.0002; //required if using 'gravity'
me.stroke = "transparent"; //used for drawSneaker me.stroke = "transparent"; //used for drawSneaker
me.alpha = 1; //used in drawSneaker me.alpha = 1; //used in drawSneaker
@@ -1690,7 +1690,7 @@ const spawn = {
mobs.spawn(x, y, 7, radius, "transparent"); mobs.spawn(x, y, 7, radius, "transparent");
me = mob[mob.length - 1]; me = mob[mob.length - 1];
me.seeAtDistance2 = 300000; me.seeAtDistance2 = 300000;
me.accelMag = 0.00012 * game.accelScale; me.accelMag = 0.00012 * simulation.accelScale;
if (map.length) me.searchTarget = map[Math.floor(Math.random() * (map.length - 1))].position; //required for search if (map.length) me.searchTarget = map[Math.floor(Math.random() * (map.length - 1))].position; //required for search
Matter.Body.setDensity(me, 0.00065); //normal is 0.001 //makes effective life much lower Matter.Body.setDensity(me, 0.00065); //normal is 0.001 //makes effective life much lower
me.stroke = "transparent"; //used for drawGhost me.stroke = "transparent"; //used for drawGhost
@@ -1753,7 +1753,7 @@ const spawn = {
// me.blinkLength = 150 + Math.round(Math.random() * 200); //required for blink // me.blinkLength = 150 + Math.round(Math.random() * 200); //required for blink
// me.isStatic = true; // me.isStatic = true;
// me.memory = 360; // me.memory = 360;
// me.seePlayerFreq = Math.round((40 + 30 * Math.random()) * game.lookFreqScale); // me.seePlayerFreq = Math.round((40 + 30 * Math.random()) * simulation.lookFreqScale);
// // me.isBig = false; // // me.isBig = false;
// // me.scaleMag = Math.max(5 - me.mass, 1.75); // // me.scaleMag = Math.max(5 - me.mass, 1.75);
// me.onDeath = function () { // me.onDeath = function () {
@@ -1763,23 +1763,23 @@ const spawn = {
// // } // // }
// }; // };
// me.onHit = function () { // me.onHit = function () {
// game.timeSkip(120) // simulation.timeSkip(120)
// }; // };
// me.do = function () { // me.do = function () {
// this.seePlayerCheck(); // this.seePlayerCheck();
// this.blink(); // this.blink();
// //strike by expanding // //strike by expanding
// // if (this.isBig) { // // if (this.isBig) {
// // if (this.cd - this.delay + 15 < game.cycle) { // // if (this.cd - this.delay + 15 < simulation.cycle) {
// // Matter.Body.scale(this, 1 / this.scaleMag, 1 / this.scaleMag); // // Matter.Body.scale(this, 1 / this.scaleMag, 1 / this.scaleMag);
// // this.isBig = false; // // this.isBig = false;
// // } // // }
// // } else // // } else
// if (this.seePlayer.yes && this.cd < game.cycle) { // if (this.seePlayer.yes && this.cd < simulation.cycle) {
// const dist = Vector.sub(this.seePlayer.position, this.position); // const dist = Vector.sub(this.seePlayer.position, this.position);
// const distMag2 = Vector.magnitudeSquared(dist); // const distMag2 = Vector.magnitudeSquared(dist);
// if (distMag2 < 80000) { // if (distMag2 < 80000) {
// this.cd = game.cycle + this.delay; // this.cd = simulation.cycle + this.delay;
// // Matter.Body.scale(this, this.scaleMag, this.scaleMag); // // Matter.Body.scale(this, this.scaleMag, this.scaleMag);
// // this.isBig = true; // // this.isBig = true;
@@ -1792,15 +1792,15 @@ const spawn = {
mobs.spawn(x, y, 3, radius, "transparent"); mobs.spawn(x, y, 3, radius, "transparent");
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.isBoss = true; me.isBoss = true;
Matter.Body.setDensity(me, 0.0014 + 0.0003 * Math.sqrt(game.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger Matter.Body.setDensity(me, 0.0014 + 0.0003 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.stroke = "rgba(255,0,200)"; //used for drawGhost me.stroke = "rgba(255,0,200)"; //used for drawGhost
me.seeAtDistance2 = 1500000; me.seeAtDistance2 = 1500000;
me.fireFreq = Math.floor(120 * game.CDScale); me.fireFreq = Math.floor(120 * simulation.CDScale);
me.searchTarget = map[Math.floor(Math.random() * (map.length - 1))].position; //required for search me.searchTarget = map[Math.floor(Math.random() * (map.length - 1))].position; //required for search
me.hoverElevation = 460 + (Math.random() - 0.5) * 200; //squared me.hoverElevation = 460 + (Math.random() - 0.5) * 200; //squared
me.hoverXOff = (Math.random() - 0.5) * 100; me.hoverXOff = (Math.random() - 0.5) * 100;
me.accelMag = Math.floor(10 * (Math.random() + 4.5)) * 0.00001 * game.accelScale; me.accelMag = Math.floor(10 * (Math.random() + 4.5)) * 0.00001 * simulation.accelScale;
me.g = 0.0002; //required if using 'gravity' // gravity called in hoverOverPlayer me.g = 0.0002; //required if using 'gravity' // gravity called in hoverOverPlayer
me.frictionStatic = 0; me.frictionStatic = 0;
me.friction = 0; me.friction = 0;
@@ -1834,7 +1834,7 @@ const spawn = {
me.fireFreq = 0.007 + Math.random() * 0.005; me.fireFreq = 0.007 + Math.random() * 0.005;
me.noseLength = 0; me.noseLength = 0;
me.fireAngle = 0; me.fireAngle = 0;
me.accelMag = 0.0005 * game.accelScale; me.accelMag = 0.0005 * simulation.accelScale;
me.frictionStatic = 0; me.frictionStatic = 0;
me.friction = 0; me.friction = 0;
me.frictionAir = 0.05; me.frictionAir = 0.05;
@@ -1867,14 +1867,14 @@ const spawn = {
me.fireFreq = 0.025; me.fireFreq = 0.025;
me.noseLength = 0; me.noseLength = 0;
me.fireAngle = 0; me.fireAngle = 0;
me.accelMag = 0.005 * game.accelScale; me.accelMag = 0.005 * simulation.accelScale;
me.frictionAir = 0.05; me.frictionAir = 0.05;
me.lookTorque = 0.000007 * (Math.random() > 0.5 ? -1 : 1); me.lookTorque = 0.000007 * (Math.random() > 0.5 ? -1 : 1);
me.fireDir = { me.fireDir = {
x: 0, x: 0,
y: 0 y: 0
}; };
Matter.Body.setDensity(me, 0.03 + 0.0008 * Math.sqrt(game.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger Matter.Body.setDensity(me, 0.03 + 0.0008 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.onDeath = function() { me.onDeath = function() {
powerUps.spawnBossPowerUp(this.position.x, this.position.y) powerUps.spawnBossPowerUp(this.position.x, this.position.y)
// this.vertices = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices)) //helps collisions functions work better after vertex have been changed // this.vertices = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices)) //helps collisions functions work better after vertex have been changed
@@ -1921,7 +1921,7 @@ const spawn = {
this.explode(this.mass * 120); this.explode(this.mass * 120);
}; };
me.onDeath = function() { me.onDeath = function() {
if (game.difficulty > 4) { if (simulation.difficulty > 4) {
spawn.bullet(this.position.x, this.position.y, this.radius / 3, 5); spawn.bullet(this.position.x, this.position.y, this.radius / 3, 5);
spawn.bullet(this.position.x, this.position.y, this.radius / 3, 5); spawn.bullet(this.position.x, this.position.y, this.radius / 3, 5);
spawn.bullet(this.position.x, this.position.y, this.radius / 3, 5); spawn.bullet(this.position.x, this.position.y, this.radius / 3, 5);
@@ -1983,7 +1983,7 @@ const spawn = {
me.fireFreq = 0.006 + Math.random() * 0.002; me.fireFreq = 0.006 + Math.random() * 0.002;
me.noseLength = 0; me.noseLength = 0;
me.fireAngle = 0; me.fireAngle = 0;
me.accelMag = 0.0005 * game.accelScale; me.accelMag = 0.0005 * simulation.accelScale;
me.frictionAir = 0.05; me.frictionAir = 0.05;
me.torque = 0.0001 * me.inertia; me.torque = 0.0001 * me.inertia;
me.fireDir = { me.fireDir = {
@@ -2008,7 +2008,7 @@ const spawn = {
//throw a mob/bullet at player //throw a mob/bullet at player
if (this.seePlayer.recall) { if (this.seePlayer.recall) {
//set direction to turn to fire //set direction to turn to fire
if (!(game.cycle % this.seePlayerFreq)) { if (!(simulation.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
} }
@@ -2023,7 +2023,7 @@ const spawn = {
} else if (this.noseLength > 1.5) { } else if (this.noseLength > 1.5) {
//fire //fire
spawn.sniperBullet(this.vertices[1].x, this.vertices[1].y, 5 + Math.ceil(this.radius / 15), 4); spawn.sniperBullet(this.vertices[1].x, this.vertices[1].y, 5 + Math.ceil(this.radius / 15), 4);
const v = 20 * game.accelScale; const v = 20 * simulation.accelScale;
Matter.Body.setVelocity(mob[mob.length - 1], { Matter.Body.setVelocity(mob[mob.length - 1], {
x: this.velocity.x + this.fireDir.x * v + Math.random(), x: this.velocity.x + this.fireDir.x * v + Math.random(),
y: this.velocity.y + this.fireDir.y * v + Math.random() y: this.velocity.y + this.fireDir.y * v + Math.random()
@@ -2104,8 +2104,8 @@ const spawn = {
launcher(x, y, radius = 30 + Math.ceil(Math.random() * 40)) { launcher(x, y, radius = 30 + Math.ceil(Math.random() * 40)) {
mobs.spawn(x, y, 3, radius, "rgb(150,150,255)"); mobs.spawn(x, y, 3, radius, "rgb(150,150,255)");
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.accelMag = 0.00004 * game.accelScale; me.accelMag = 0.00004 * simulation.accelScale;
me.fireFreq = Math.floor(420 + 90 * Math.random() * game.CDScale) me.fireFreq = Math.floor(420 + 90 * Math.random() * simulation.CDScale)
me.frictionStatic = 0; me.frictionStatic = 0;
me.friction = 0; me.friction = 0;
me.frictionAir = 0.02; me.frictionAir = 0.02;
@@ -2115,7 +2115,7 @@ const spawn = {
this.seePlayerCheck(); this.seePlayerCheck();
this.checkStatus(); this.checkStatus();
this.attraction(); this.attraction();
if (this.seePlayer.recall && !(game.cycle % this.fireFreq) && !mech.isBodiesAsleep) { if (this.seePlayer.recall && !(simulation.cycle % this.fireFreq) && !mech.isBodiesAsleep) {
Matter.Body.setAngularVelocity(this, 0.14) Matter.Body.setAngularVelocity(this, 0.14)
//fire a bullet from each vertex //fire a bullet from each vertex
for (let i = 0, len = this.vertices.length; i < len; i++) { for (let i = 0, len = this.vertices.length; i < len; i++) {
@@ -2134,15 +2134,15 @@ const spawn = {
mobs.spawn(x, y, 6, radius, "rgb(150,150,255)"); mobs.spawn(x, y, 6, radius, "rgb(150,150,255)");
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.isBoss = true; me.isBoss = true;
me.accelMag = 0.00008 * game.accelScale; me.accelMag = 0.00008 * simulation.accelScale;
me.fireFreq = Math.floor(360 * game.CDScale) me.fireFreq = Math.floor(360 * simulation.CDScale)
me.frictionStatic = 0; me.frictionStatic = 0;
me.friction = 0; me.friction = 0;
me.frictionAir = 0.02; me.frictionAir = 0.02;
me.memory = 420; me.memory = 420;
me.repulsionRange = 1200000; //squared me.repulsionRange = 1200000; //squared
spawn.shield(me, x, y, 1); spawn.shield(me, x, y, 1);
Matter.Body.setDensity(me, 0.004 + 0.0005 * Math.sqrt(game.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger Matter.Body.setDensity(me, 0.004 + 0.0005 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.onDeath = function() { me.onDeath = function() {
powerUps.spawnBossPowerUp(this.position.x, this.position.y) powerUps.spawnBossPowerUp(this.position.x, this.position.y)
// this.vertices = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices)) //helps collisions functions work better after vertex have been changed // this.vertices = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices)) //helps collisions functions work better after vertex have been changed
@@ -2153,7 +2153,7 @@ const spawn = {
this.checkStatus(); this.checkStatus();
this.attraction(); this.attraction();
this.repulsion(); this.repulsion();
if (this.seePlayer.recall && !(game.cycle % this.fireFreq) && !mech.isBodiesAsleep) { if (this.seePlayer.recall && !(simulation.cycle % this.fireFreq) && !mech.isBodiesAsleep) {
Matter.Body.setAngularVelocity(this, 0.11) Matter.Body.setAngularVelocity(this, 0.11)
//fire a bullet from each vertex //fire a bullet from each vertex
for (let i = 0, len = this.vertices.length; i < len; i++) { for (let i = 0, len = this.vertices.length; i < len; i++) {
@@ -2172,9 +2172,9 @@ const spawn = {
mobs.spawn(x, y, 5, radius, "rgb(245,180,255)"); mobs.spawn(x, y, 5, radius, "rgb(245,180,255)");
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.isBoss = true; me.isBoss = true;
// me.accelMag = 0.00023 * game.accelScale; // me.accelMag = 0.00023 * simulation.accelScale;
me.accelMag = 0.00008 * game.accelScale; me.accelMag = 0.00008 * simulation.accelScale;
// me.fireFreq = Math.floor(30 * game.CDScale) // me.fireFreq = Math.floor(30 * simulation.CDScale)
me.canFire = false; me.canFire = false;
me.closestVertex1 = 0; me.closestVertex1 = 0;
me.closestVertex2 = 1; me.closestVertex2 = 1;
@@ -2255,7 +2255,7 @@ const spawn = {
}; };
Matter.Body.setDensity(me, 0.000015); //normal is 0.001 Matter.Body.setDensity(me, 0.000015); //normal is 0.001
me.timeLeft = 420 * (0.8 + 0.4 * Math.random()); me.timeLeft = 420 * (0.8 + 0.4 * Math.random());
me.accelMag = 0.00017 * game.accelScale; //* (0.8 + 0.4 * Math.random()) me.accelMag = 0.00017 * simulation.accelScale; //* (0.8 + 0.4 * Math.random())
me.frictionAir = 0.01 //* (0.8 + 0.4 * Math.random()); me.frictionAir = 0.01 //* (0.8 + 0.4 * Math.random());
me.restitution = 0.5; me.restitution = 0.5;
me.leaveBody = false; me.leaveBody = false;
@@ -2302,10 +2302,10 @@ const spawn = {
}; };
Matter.Body.setDensity(me, 0.0005); //normal is 0.001 Matter.Body.setDensity(me, 0.0005); //normal is 0.001
me.g = 0.0001; //required if using 'gravity' me.g = 0.0001; //required if using 'gravity'
me.accelMag = 0.0003 * game.accelScale; me.accelMag = 0.0003 * simulation.accelScale;
me.memory = 30; me.memory = 30;
me.leaveBody = false; me.leaveBody = false;
me.seePlayerFreq = Math.round((80 + 50 * Math.random()) * game.lookFreqScale); me.seePlayerFreq = Math.round((80 + 50 * Math.random()) * simulation.lookFreqScale);
me.frictionAir = 0.002; me.frictionAir = 0.002;
me.do = function() { me.do = function() {
this.gravity(); this.gravity();
@@ -2333,10 +2333,10 @@ const spawn = {
mobs.spawn(x, y, 8, radius, "rgb(55,170,170)"); mobs.spawn(x, y, 8, radius, "rgb(55,170,170)");
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.isBoss = true; me.isBoss = true;
me.accelMag = 0.00075 * game.accelScale; me.accelMag = 0.00075 * simulation.accelScale;
me.memory = 250; me.memory = 250;
me.laserRange = 500; me.laserRange = 500;
Matter.Body.setDensity(me, 0.0015 + 0.0005 * Math.sqrt(game.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger Matter.Body.setDensity(me, 0.0015 + 0.0005 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
spawn.shield(me, x, y, 1); spawn.shield(me, x, y, 1);
me.onDeath = function() { me.onDeath = function() {
powerUps.spawnBossPowerUp(this.position.x, this.position.y) powerUps.spawnBossPowerUp(this.position.x, this.position.y)
@@ -2356,7 +2356,7 @@ const spawn = {
}; };
//snake tail //snake tail
const nodes = Math.min(8 + Math.ceil(0.5 * game.difficulty), 40) const nodes = Math.min(8 + Math.ceil(0.5 * simulation.difficulty), 40)
spawn.lineBoss(x + 105, y, "snakeBody", nodes); spawn.lineBoss(x + 105, y, "snakeBody", nodes);
//constraint boss with first 3 mobs in lineboss //constraint boss with first 3 mobs in lineboss
consBB[consBB.length] = Constraint.create({ consBB[consBB.length] = Constraint.create({
@@ -2387,7 +2387,7 @@ const spawn = {
// this.explode(); // this.explode();
// }; // };
me.collisionFilter.mask = cat.bullet | cat.player | cat.mob me.collisionFilter.mask = cat.bullet | cat.player | cat.mob
me.accelMag = 0.0004 * game.accelScale; me.accelMag = 0.0004 * simulation.accelScale;
me.leaveBody = false; me.leaveBody = false;
me.frictionAir = 0.02; me.frictionAir = 0.02;
me.isSnakeTail = true; me.isSnakeTail = true;
@@ -2418,9 +2418,9 @@ const spawn = {
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.isBoss = true; me.isBoss = true;
me.g = 0.0001; //required if using 'gravity' me.g = 0.0001; //required if using 'gravity'
me.accelMag = 0.002 * game.accelScale; me.accelMag = 0.002 * simulation.accelScale;
me.memory = 20; me.memory = 20;
Matter.Body.setDensity(me, 0.001 + 0.0005 * Math.sqrt(game.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger Matter.Body.setDensity(me, 0.001 + 0.0005 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
spawn.shield(me, x, y, 1); spawn.shield(me, x, y, 1);
me.onDeath = function() { me.onDeath = function() {
powerUps.spawnBossPowerUp(this.position.x, this.position.y) powerUps.spawnBossPowerUp(this.position.x, this.position.y)
@@ -2433,7 +2433,7 @@ const spawn = {
this.attraction(); this.attraction();
}; };
}, },
shield(target, x, y, chance = Math.min(0.02 + game.difficulty * 0.005, 0.2)) { shield(target, x, y, chance = Math.min(0.02 + simulation.difficulty * 0.005, 0.2)) {
if (this.allowShields && Math.random() < chance) { if (this.allowShields && Math.random() < chance) {
mobs.spawn(x, y, 9, target.radius + 30, "rgba(220,220,255,0.9)"); mobs.spawn(x, y, 9, target.radius + 30, "rgba(220,220,255,0.9)");
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
@@ -2526,8 +2526,8 @@ const spawn = {
x, x,
y, y,
spawn = "striker", spawn = "striker",
nodes = Math.min(2 + Math.ceil(Math.random() * (game.difficulty + 2)), 8), nodes = Math.min(2 + Math.ceil(Math.random() * (simulation.difficulty + 2)), 8),
//Math.ceil(Math.random() * 3) + Math.min(4,Math.ceil(game.difficulty/2)), //Math.ceil(Math.random() * 3) + Math.min(4,Math.ceil(simulation.difficulty/2)),
radius = Math.ceil(Math.random() * 10) + 17, // radius of each node mob radius = Math.ceil(Math.random() * 10) + 17, // radius of each node mob
sideLength = Math.ceil(Math.random() * 100) + 70, // distance between each node mob sideLength = Math.ceil(Math.random() * 100) + 70, // distance between each node mob
stiffness = Math.random() * 0.03 + 0.005 stiffness = Math.random() * 0.03 + 0.005
@@ -2560,8 +2560,8 @@ const spawn = {
x, x,
y, y,
spawn = "striker", spawn = "striker",
nodes = Math.min(3 + Math.ceil(Math.random() * game.difficulty + 2), 8), nodes = Math.min(3 + Math.ceil(Math.random() * simulation.difficulty + 2), 8),
//Math.ceil(Math.random() * 3) + Math.min(4,Math.ceil(game.difficulty/2)), //Math.ceil(Math.random() * 3) + Math.min(4,Math.ceil(simulation.difficulty/2)),
radius = Math.ceil(Math.random() * 10) + 17, radius = Math.ceil(Math.random() * 10) + 17,
l = Math.ceil(Math.random() * 80) + 30, l = Math.ceil(Math.random() * 80) + 30,
stiffness = Math.random() * 0.06 + 0.01 stiffness = Math.random() * 0.06 + 0.01

File diff suppressed because it is too large Load Diff

View File

@@ -42,6 +42,10 @@ a {
color: #08c; color: #08c;
} }
em {
opacity: 0.7;
}
#splash { #splash {
user-select: none; user-select: none;
position: absolute; position: absolute;
@@ -272,11 +276,11 @@ summary {
background-color: hsl(218, 100%, 76%); background-color: hsl(218, 100%, 76%);
} }
.build-mod-selected { .build-tech-selected {
background-color: hsl(253, 100%, 84%); background-color: hsl(253, 100%, 84%);
} }
.build-mod-selected:hover { .build-tech-selected:hover {
background-color: hsl(253, 100%, 81%); background-color: hsl(253, 100%, 81%);
} }
@@ -313,7 +317,7 @@ summary {
width: 100%; width: 100%;
height: 100%; height: 100%;
display: none; display: none;
/* background-color also set in mass-energy mod */ /* background-color also set in mass-energy tech */
background-color: #f67; background-color: #f67;
opacity: 0; opacity: 0;
transition: opacity 1s; transition: opacity 1s;
@@ -376,8 +380,9 @@ summary {
left: 15px; left: 15px;
z-index: 2; z-index: 2;
font-size: 23px; font-size: 23px;
color: #111; color: #222;
background-color: rgba(255, 255, 255, 0.4); background-color: rgba(255, 255, 255, 0.4);
line-height: 120%;
user-select: none; user-select: none;
pointer-events: none; pointer-events: none;
padding: 0px 5px 0px 5px; padding: 0px 5px 0px 5px;
@@ -394,7 +399,7 @@ summary {
color: #000; color: #000;
text-align: right; text-align: right;
opacity: 0.7; opacity: 0.7;
line-height: 140%; /* line-height: 140%; */
background-color: rgba(190, 210, 245, 0.25); background-color: rgba(190, 210, 245, 0.25);
user-select: none; user-select: none;
pointer-events: none; pointer-events: none;
@@ -403,16 +408,16 @@ summary {
/*border: 2px solid rgba(0, 0, 0, 0.4);*/ /*border: 2px solid rgba(0, 0, 0, 0.4);*/
} }
#mods { #tech {
position: absolute; position: absolute;
top: 60px; top: 60px;
right: 15px; right: 15px;
z-index: 2; z-index: 2;
font-size: 20px; font-size: 20px;
color: #000; color: #222;
text-align: right; text-align: right;
opacity: 0.35; opacity: 0.35;
line-height: 140%; line-height: 130%;
background-color: rgba(255, 255, 255, 0.4); background-color: rgba(255, 255, 255, 0.4);
user-select: none; user-select: none;
pointer-events: none; pointer-events: none;
@@ -424,28 +429,67 @@ summary {
#text-log { #text-log {
z-index: 2; z-index: 2;
position: absolute; position: absolute;
bottom: 20px; bottom: 10px;
left: 20px; left: 10px;
padding: 10px; padding: 10px;
border-radius: 10px; border-radius: 4px;
line-height: 150%; line-height: 140%;
font-size: 1.25em; font-size: 1.15em;
color: #000; color: #555;
background-color: rgba(255, 255, 255, 0.23); background-color: rgba(255, 255, 255, 0.5);
opacity: 0;
transition: opacity 0.5s; transition: opacity 0.5s;
pointer-events: none; pointer-events: none;
user-select: none; user-select: none;
} }
em { /* color for in game console output */
opacity: 0.7;
.color-text {
color: #000;
} }
.mouse-icon { .color-var {
margin-bottom: -20px; color: hsl(253, 100%, 58%);
} }
.color-symbol {
color: hsl(290, 100%, 40%);
}
.color-gun {
color: hsl(218, 100%, 58%);
}
/* colors for pause, selection and custom */
/* #text-log {
z-index: 2;
position: absolute;
bottom: 4px;
left: 6px;
line-height: 130%;
font-size: 1.2em;
color: rgb(237, 15, 148);
transition: opacity 1s;
pointer-events: none;
user-select: none;
}
.color-text {
color: rgb(0, 164, 164);
}
.color-symbol {
color: #fff;
}
.color-gun {
color: hsl(218, 100%, 70%);
} */
.color-f { .color-f {
color: #0ad; color: #0ad;
letter-spacing: 1px; letter-spacing: 1px;
@@ -565,7 +609,7 @@ em {
margin-bottom: -15px; margin-bottom: -15px;
} }
.circle-gun-mod { .circle-gun-tech {
box-shadow: 0 0 0 3px #025; box-shadow: 0 0 0 3px #025;
} }
@@ -583,7 +627,7 @@ em {
background: #0cf; background: #0cf;
} }
.mod { .tech {
/* background: rgb(116, 102, 238); */ /* background: rgb(116, 102, 238); */
/* background: hsl(253, 57%, 52%); */ /* background: hsl(253, 57%, 52%); */
background: hsl(255, 100%, 71%); background: hsl(255, 100%, 71%);
@@ -607,9 +651,7 @@ em {
background: #f7b; background: #f7b;
} }
.dice { .reroll-select {
font-size: 45px;
vertical-align: -5px;
float: right; float: right;
} }

View File

@@ -1,16 +1,17 @@
******************************************************** NEXT PATCH ******************************************************** ******************************************************** NEXT PATCH ********************************************************
added a crouch check to prevent move the head when it's already out of position updated in game console style and all messages to match real game commands
also using setPosition to move player head instead of translate new names inline with lore, mod -> tech, game -> simulation
this is probably going to cause many minor bugs, so let me know what you find
new reroll display in power up selection
tech: rocket-propelled now works with all grenade tech
******************************************************** BUGS ******************************************************** ******************************************************** BUGS ********************************************************
check for crouch after rewind check for crouch after rewind
CPT, tesseract CPT, tesseract
mod and mob are too similar
(always) make it so that when you are immune to harm you can either jump on mobs or you pass through them (always) make it so that when you are immune to harm you can either jump on mobs or you pass through them
(always) is there a way to check if the player is stuck inside the map or block (always) is there a way to check if the player is stuck inside the map or block
@@ -26,6 +27,7 @@ mod and mob are too similar
this fix was added and it is working for some cases this fix was added and it is working for some cases
maybe move the fix to once a second? maybe move the fix to once a second?
bug fix - rewrite crouch to not translate the player height, but instead switch between 2 sensors bug fix - rewrite crouch to not translate the player height, but instead switch between 2 sensors
2nd bug fix, no reports so far! might be fixed!
(intermittent, but almost every time) bug - capping the fps causes random slow downs, that can be fixed with pause (intermittent, but almost every time) bug - capping the fps causes random slow downs, that can be fixed with pause
@@ -37,8 +39,31 @@ mod and mob are too similar
******************************************************** TODO ******************************************************** ******************************************************** TODO ********************************************************
rename
health > integrity, unity
heal > also integrity, unity
level > world?
reroll > resample, reset, retry, remeasure
in game console
make all commands actually work
input.key commands don't work
rewrite to not be a console command?
add commands
death, max health, max energy, rewind
mechanic: use gun swap as an active ability for several mods
ideas?
trigger damage immunity for 3 seconds, but drain energy?
push away nearby mobs, but drain energy
produce ammo, but take 1 damage
CPT gun seems a bit weak right now. How to buff the gun? CPT gun seems a bit weak right now. How to buff the gun?
mod nail gun: slow and accurate
mod foam: fast and inaccurate
mob ability bombs/bullets that suck in player mob ability bombs/bullets that suck in player
mod where you can't stop firing, how to code? mod where you can't stop firing, how to code?
@@ -193,6 +218,8 @@ field - one block orbits you, it can protect you a bit and do collision damage
repeat map in vertical and horizontal space repeat map in vertical and horizontal space
or at least vertical space or at least vertical space
camera looks strange when you teleport player with a high velocity camera looks strange when you teleport player with a high velocity
new status effect: weakness, mobs do 75% les damage
graphic indication?
new status effect: fear - push mob away from player for a time new status effect: fear - push mob away from player for a time
@@ -387,40 +414,36 @@ AI doesn't know about:
modern pop culture modern pop culture
outside the lab outside the lab
in game console scientist console text:
output all console.log code //find starter code for this at the end of index.js 2 scientists (each one a different color text)
style at the start of each level listen to text conversation from the two colors of text strings also
make it look like a computer terminal
track multiple lines, like your vocoder program
messages about heal, ammo, mods, that just list internal computer code
example: a heal would be mech.health += 12
mono space font
square edges
black text on bottom right with no background?
or white text, or yellow
message after selecting each new (mod / gun / field)
put messages in (mod / gun / field) method
at start of run
write custom dialogue for field / guns / mods used in last game
you'd have to store an array of guns/fields/mod used last game
n-gon escape simulation ${random seed}
say something about what mobs types are queued up, and level order
**all communication should be from scientists watching the simulation; the robot shouldn't talk**
talking about the robot, watching talking about the robot, watching
trying to communicate with the robot? but how trying to communicate with the robot? but how
lines: random lines:
say something about what mobs types are queued up, and level order
I think it's planing to escape I think it's planing to escape
Why is it attacking those shapes? Why is it attacking those shapes?
Are those shapes supposed to be us? Are those shapes supposed to be us?
ending outline
add an ending to the game if no cheats
maybe the game ending should ask you to open the console and type in some commands like in the end of doki doki after final boss is cleared, player enters a level with no mobs
mirror ending (if no cheats) level maybe has some environmental damage, so player has an option to die at any time
level after final boss battle is the intro level, but flipped left right, with a fake player player can see text output between two colors of text strings (scientists)
damage the fake player to end the game audio.ambient(current time and date)<br> "text"
message about go outside player reads a conversation between the two colors of text
no ending (if cheats) first time win on east or normal they talk about:
game goes on forever how many runs the player has done
also game goes on if player attacks, the fake player they guess why
game never ends if you have used cheats they reveal the player is running simulations, and it isn't real
they ask the player to communicate
jump twice if you understand
they ask the player to enter console commands
give ammo or mods or something
They tell the play a console command to permenantly enable custom and testing mode (in local storage)
players can use this command in the future to enable custom and testing without beating the game even if local storage is wiped
they then tell the player the command to increase the difficulty and the command to restart the game.
If you win on hard or why:
they give the player and option to exit the simulation and entre the real world
simulation.exit()
This wipes all local storage, and closes the browser tab