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"> -->
<div id='guns'></div>
<div id='field'></div>
<div id='mods'></div>
<div id='tech'></div>
<div id="text-log"></div>
<div id="fade-out"></div>
<div id="health-bg"></div>
@@ -327,7 +327,7 @@
animation: dash 5s ease-in forwards;
}
</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 -->
<!-- <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)" />
@@ -553,10 +553,10 @@
<script src='lib/matter.min.js'></script>
<script src='lib/decomp.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/powerup.js"></script>
<script src="js/mods.js"></script>
<script src="js/tech.js"></script>
<script src="js/bullet.js"></script>
<script src="js/mob.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 (
mech.immuneCycle < mech.cycle &&
(obj === playerBody || obj === playerHead) &&
!(mod.isFreezeHarmImmune && (mob[k].isSlowed || mob[k].isStunned))
!(tech.isFreezeHarmImmune && (mob[k].isSlowed || mob[k].isStunned))
) {
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
if (mod.isRewindAvoidDeath && mech.energy > 0.66) { //CPT reversal runs in mech.damage, but it stops the rest of the collision code here too
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 (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);
return
}
mech.damage(dmg);
if (mod.isPiezo) mech.energy += 2;
if (mod.isBayesian) powerUps.ejectMod()
if (tech.isPiezo) mech.energy += 2;
if (tech.isBayesian) powerUps.ejectMod()
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...
let angle = Math.atan2(player.position.y - mob[k].position.y, player.position.x - mob[k].position.x);
Matter.Body.setVelocity(player, {
@@ -123,24 +123,24 @@ function collisionChecks(event) {
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.immuneCycle = 0; //player doesn't go immune to collision damage
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,
y: pairs[i].activeContacts[0].vertex.y,
radius: dmg * 2000,
color: "rgba(255,0,255,0.2)",
time: game.drawTime
time: simulation.drawTime
});
} else {
game.drawList.push({ //add dmg to draw queue
simulation.drawList.push({ //add dmg to draw queue
x: pairs[i].activeContacts[0].vertex.x,
y: pairs[i].activeContacts[0].vertex.y,
radius: dmg * 500,
color: game.mobDmgColor,
time: game.drawTime
color: simulation.mobDmgColor,
time: simulation.drawTime
});
}
return;
@@ -150,15 +150,15 @@ function collisionChecks(event) {
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
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].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,
y: pairs[i].activeContacts[0].vertex.y,
radius: Math.log(2 * dmg + 1.1) * 40,
color: game.playerDmgColor,
time: game.drawTime
color: simulation.playerDmgColor,
time: simulation.drawTime
});
return;
}
@@ -166,22 +166,22 @@ function collisionChecks(event) {
if (obj.classType === "body" && obj.speed > 6) {
const v = Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity));
if (v > 9) {
let dmg = 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
mob[k].damage(dmg, true);
const stunTime = dmg / Math.sqrt(obj.mass)
if (stunTime > 0.5) mobs.statusStun(mob[k], 30 + 60 * Math.sqrt(stunTime))
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;
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,
y: pairs[i].activeContacts[0].vertex.y,
radius: Math.log(2 * dmg + 1.1) * 40,
color: game.playerDmgColor,
time: game.drawTime
color: simulation.playerDmgColor,
time: simulation.drawTime
});
return;
}

View File

@@ -43,10 +43,10 @@ if (screen.height < 800) {
//example https://landgreen.github.io/sidescroller/index.html?
// &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
// &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
// &difficulty=2
//use %20 for spaces
@@ -90,16 +90,16 @@ window.addEventListener('load', (event) => {
}
if (found) build.choosePowerUp(document.getElementById(`gun-${index}`), index, 'gun')
}
if (property.substring(0, 3) === "mod") {
for (let i = 0; i < mod.mods.length; i++) {
if (set[property] === mod.mods[i].name) {
build.choosePowerUp(document.getElementById(`mod-${i}`), i, 'mod', true)
if (property.substring(0, 4) === "tech") {
for (let i = 0; i < tech.tech.length; i++) {
if (set[property] === tech.tech[i].name) {
build.choosePowerUp(document.getElementById(`tech-${i}`), i, 'tech', true)
break;
}
}
}
if (property === "difficulty") {
game.difficultyMode = Number(set[property])
simulation.difficultyMode = Number(set[property])
document.getElementById("difficulty-select-custom").value = Number(set[property])
}
if (property === "level") {
@@ -138,7 +138,7 @@ function setupCanvas() {
ctx.lineJoin = "round";
ctx.lineCap = "round";
// ctx.lineCap='square';
game.setZoom();
simulation.setZoom();
}
setupCanvas();
window.onresize = () => {
@@ -155,47 +155,47 @@ const build = {
for (const property in set) {
set[property] = set[property].replace(/%20/g, " ")
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 === "difficulty") {
game.difficultyMode = Number(set[property])
simulation.difficultyMode = Number(set[property])
document.getElementById("difficulty-select").value = Number(set[property])
}
if (property === "level") {
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
level.onLevel++
}
}
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) {
b.activeGun = b.inventory[0] //set first gun to active gun
game.makeGunHUD();
simulation.makeGunHUD();
}
}
},
pauseGrid() {
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>`
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><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><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>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>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>damage difficulty scale: ${(b.dmgScale*100).toFixed(2) }%
<br>harm difficulty scale: ${(game.dmgScale*100).toFixed(0)}%
<br>heal difficulty scale: ${(game.healScale*100).toFixed(1)}%
<br>harm difficulty scale: ${(simulation.dmgScale*100).toFixed(0)}%
<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;">
<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>
@@ -213,31 +213,31 @@ const build = {
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>`
let countMods = 0
for (let i = 0, len = mod.mods.length; i < len; i++) {
if (mod.mods[i].count > 0) {
const isCount = mod.mods[i].count > 1 ? `(${mod.mods[i].count}x)` : "";
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].count > 0) {
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">
<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>
</span>
&nbsp; &nbsp; &nbsp; &nbsp; ${mod.mods[i].name} ${isCount}</div>${mod.mods[i].description}</div></div>`
} else if (mod.mods[i].isGunMod) {
&nbsp; &nbsp; &nbsp; &nbsp; ${tech.tech[i].name} ${isCount}</div>${tech.tech[i].description}</div></div>`
} else if (tech.tech[i].isGunMod) {
text += `<div class="pause-grid-module"><div class="grid-title">
<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>
</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 {
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) {
// 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>`
// if (tech.tech[i].count === 1) {
// 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 {
// 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++
}
@@ -270,7 +270,7 @@ const build = {
b.guns[index].have = false;
if (b.guns[index].ammo != Infinity) b.guns[index].ammo = 0;
if (b.inventory.length === 0) b.activeGun = null;
game.makeGunHUD();
simulation.makeGunHUD();
break
}
}
@@ -284,55 +284,55 @@ const build = {
mech.setField(index)
who.classList.add("build-field-selected");
}
} else if (type === "mod") { //remove mod if you have too many
if (mod.mods[index].count < mod.mods[index].maxCount) {
if (!who.classList.contains("build-mod-selected")) who.classList.add("build-mod-selected");
mod.giveMod(index)
} else if (type === "tech") { //remove tech if you have too many
if (tech.tech[index].count < tech.tech[index].maxCount) {
if (!who.classList.contains("build-tech-selected")) who.classList.add("build-tech-selected");
tech.giveMod(index)
} else {
mod.removeMod(index);
who.classList.remove("build-mod-selected");
tech.removeMod(index);
who.classList.remove("build-tech-selected");
}
}
//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() || isAllowed || mod.mods[i].count > 0) {
const isCount = mod.mods[i].count > 1 ? `(${mod.mods[i].count}x)` : "";
if (mod.mods[i].isFieldMod) {
modID.innerHTML = ` <div class="grid-title">
//update tech text //disable not allowed tech
for (let i = 0, len = tech.tech.length; i < len; i++) {
const techID = document.getElementById("tech-" + i)
if (!tech.tech[i].isCustomHide) {
if (tech.tech[i].allowed() || isAllowed || tech.tech[i].count > 0) {
const isCount = tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : "";
if (tech.tech[i].isFieldMod) {
techID.innerHTML = ` <div class="grid-title">
<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>
</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 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;
} else if (mod.mods[i].isGunMod) {
modID.innerHTML = ` <div class="grid-title">
} else if (tech.tech[i].isGunMod) {
techID.innerHTML = ` <div class="grid-title">
<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>
</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 {
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")) {
modID.classList.remove("build-grid-disabled");
modID.setAttribute("onClick", `javascript: build.choosePowerUp(this,${i},'mod')`);
if (techID.classList.contains("build-grid-disabled")) {
techID.classList.remove("build-grid-disabled");
techID.setAttribute("onClick", `javascript: build.choosePowerUp(this,${i},'tech')`);
}
} 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
techID.innerHTML = `<div class="grid-title"> ${tech.tech[i].name}</div><span style="color:#666;">requires: ${tech.tech[i].requires}</span></div>`
if (!techID.classList.contains("build-grid-disabled")) {
techID.classList.add("build-grid-disabled");
techID.onclick = null
}
if (mod.mods[i].count > 0) mod.removeMod(i)
if (modID.classList.contains("build-mod-selected")) modID.classList.remove("build-mod-selected");
if (tech.tech[i].count > 0) tech.removeMod(i)
if (techID.classList.contains("build-tech-selected")) techID.classList.remove("build-tech-selected");
}
}
}
@@ -368,7 +368,7 @@ const build = {
</select>
</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;">
</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>`
}
for (let i = 0, len = mod.mods.length; i < len; i++) {
if (!mod.mods[i].isCustomHide) {
if (!mod.mods[i].allowed()) { // || mod.mods[i].name === "+1 cardinality") { //|| mod.mods[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>`
// } else if (mod.mods[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>`
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (!tech.tech[i].isCustomHide) {
if (!tech.tech[i].allowed()) { // || tech.tech[i].name === "+1 cardinality") { //|| tech.tech[i].name === "leveraged investment"
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 (tech.tech[i].count > 1) {
// 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 {
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("difficulty-select-custom").value = document.getElementById("difficulty-select").value
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)
document.getElementById("difficulty-select").value = document.getElementById("difficulty-select-custom").value
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;
}
b.activeGun = null;
game.makeGunHUD();
simulation.makeGunHUD();
mod.setupAllMods();
tech.setupAllMods();
build.populateGrid();
document.getElementById("field-0").classList.add("build-field-selected");
document.getElementById("build-grid").style.display = "grid"
@@ -429,24 +429,24 @@ const build = {
}
count = 0;
for (let i = 0; i < mod.mods.length; i++) {
for (let j = 0; j < mod.mods[i].count; j++) {
url += `&mod${count}=${encodeURIComponent(mod.mods[i].name.trim())}`
for (let i = 0; i < tech.tech.length; i++) {
for (let j = 0; j < tech.tech[i].count; j++) {
url += `&tech${count}=${encodeURIComponent(tech.tech[i].name.trim())}`
count++
}
}
url += `&field=${encodeURIComponent(mech.fieldUpgrades[mech.fieldMode].name.trim())}`
url += `&difficulty=${game.difficultyMode}`
url += `&difficulty=${simulation.difficultyMode}`
if (isCustom) {
url += `&level=${Math.abs(Number(document.getElementById("starting-level").value))}`
url += `&noPower=${Number(document.getElementById("no-power-ups").checked)}`
alert('n-gon build URL copied to clipboard.\nPaste into browser address bar.')
} 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(url)
game.copyToClipBoard(url)
simulation.copyToClipBoard(url)
},
startBuildRun() {
build.isCustomSelection = false;
@@ -454,18 +454,18 @@ const build = {
spawn.setSpawnList();
if (b.inventory.length > 0) {
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]);
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))
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;
game.isNoPowerUps = document.getElementById("no-power-ups").checked
if (game.isNoPowerUps) { //remove mods, guns, and fields
simulation.isNoPowerUps = document.getElementById("no-power-ups").checked
if (simulation.isNoPowerUps) { //remove tech, guns, and fields
function removeOne() { //recursive remove one at a time to avoid array problems
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]);
powerUp.splice(i, 1);
removeOne();
@@ -475,11 +475,11 @@ const build = {
}
removeOne();
}
game.isCheating = true;
simulation.isCheating = true;
document.body.style.cursor = "none";
document.body.style.overflow = "hidden"
document.getElementById("build-grid").style.display = "none"
game.paused = false;
simulation.paused = false;
requestAnimationFrame(cycle);
}
}
@@ -491,9 +491,9 @@ function openCustomBuildMenu() {
document.body.style.overflowY = "scroll";
document.body.style.overflowX = "hidden";
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;
game.paused = true;
simulation.paused = true;
build.reset();
}
@@ -501,49 +501,15 @@ function openCustomBuildMenu() {
document.getElementById("build-button").addEventListener("click", () => { //setup build run
let field = 0;
let inventory = [];
let modList = [];
if (!game.firstRun) {
let techList = [];
if (!simulation.firstRun) {
field = mech.fieldMode
inventory = [...b.inventory]
for (let i = 0; i < mod.mods.length; i++) {
modList.push(mod.mods[i].count)
for (let i = 0; i < tech.tech.length; i++) {
techList.push(tech.tech[i].count)
}
}
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
break
case input.key.nextGun:
game.nextGun();
simulation.nextGun();
break
case input.key.previousGun:
game.previousGun();
simulation.previousGun();
break
case input.key.pause:
if (!game.isChoosing && input.isPauseKeyReady && mech.alive) {
if (!simulation.isChoosing && input.isPauseKeyReady && mech.alive) {
input.isPauseKeyReady = false
setTimeout(function() {
input.isPauseKeyReady = true
}, 300);
if (game.paused) {
if (simulation.paused) {
build.unPauseGrid()
game.paused = false;
simulation.paused = false;
level.levelAnnounce();
document.body.style.cursor = "none";
requestAnimationFrame(cycle);
} else {
game.paused = true;
game.replaceTextLog = true;
simulation.paused = true;
build.pauseGrid()
document.body.style.cursor = "auto";
}
@@ -766,56 +731,56 @@ window.addEventListener("keydown", function(event) {
break
case input.key.testing:
if (mech.alive) {
if (game.testing) {
game.testing = false;
game.loop = game.normalLoop
if (game.isConstructionMode) {
if (simulation.testing) {
simulation.testing = false;
simulation.loop = simulation.normalLoop
if (simulation.isConstructionMode) {
document.getElementById("construct").style.display = 'none'
}
} else { //if (keys[191])
game.testing = true;
game.isCheating = true;
if (game.isConstructionMode) {
simulation.testing = true;
simulation.isCheating = true;
if (simulation.isConstructionMode) {
document.getElementById("construct").style.display = 'inline'
}
game.loop = game.testingLoop
simulation.loop = simulation.testingLoop
}
}
break
}
if (game.testing) {
if (simulation.testing) {
switch (event.key.toLowerCase()) {
case "o":
game.isAutoZoom = false;
game.zoomScale /= 0.9;
game.setZoom();
simulation.isAutoZoom = false;
simulation.zoomScale /= 0.9;
simulation.setZoom();
break;
case "i":
game.isAutoZoom = false;
game.zoomScale *= 0.9;
game.setZoom();
simulation.isAutoZoom = false;
simulation.zoomScale *= 0.9;
simulation.setZoom();
break
case "`":
powerUps.directSpawn(game.mouseInGame.x, game.mouseInGame.y, "reroll");
powerUps.directSpawn(simulation.mouseInGame.x, simulation.mouseInGame.y, "reroll");
break
case "1":
powerUps.directSpawn(game.mouseInGame.x, game.mouseInGame.y, "heal");
powerUps.directSpawn(simulation.mouseInGame.x, simulation.mouseInGame.y, "heal");
break
case "2":
powerUps.directSpawn(game.mouseInGame.x, game.mouseInGame.y, "ammo");
powerUps.directSpawn(simulation.mouseInGame.x, simulation.mouseInGame.y, "ammo");
break
case "3":
powerUps.directSpawn(game.mouseInGame.x, game.mouseInGame.y, "gun");
powerUps.directSpawn(simulation.mouseInGame.x, simulation.mouseInGame.y, "gun");
break
case "4":
powerUps.directSpawn(game.mouseInGame.x, game.mouseInGame.y, "field");
powerUps.directSpawn(simulation.mouseInGame.x, simulation.mouseInGame.y, "field");
break
case "5":
powerUps.directSpawn(game.mouseInGame.x, game.mouseInGame.y, "mod");
powerUps.directSpawn(simulation.mouseInGame.x, simulation.mouseInGame.y, "tech");
break
case "6":
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.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet
body[index].classType = "body";
@@ -823,10 +788,10 @@ window.addEventListener("keydown", function(event) {
break
case "7":
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
case "8":
spawn.randomLevelBoss(game.mouseInGame.x, game.mouseInGame.y);
spawn.randomLevelBoss(simulation.mouseInGame.x, simulation.mouseInGame.y);
break
case "f":
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;
break
case "y":
mod.giveMod()
tech.giveMod()
break
case "r":
mech.resetHistory();
Matter.Body.setPosition(player, game.mouseInGame);
Matter.Body.setPosition(player, simulation.mouseInGame);
Matter.Body.setVelocity(player, {
x: 0,
y: 0
@@ -875,8 +840,8 @@ window.addEventListener("keydown", function(event) {
});
//mouse move input
document.body.addEventListener("mousemove", (e) => {
game.mouse.x = e.clientX;
game.mouse.y = e.clientY;
simulation.mouse.x = e.clientX;
simulation.mouse.y = e.clientY;
});
document.body.addEventListener("mouseup", (e) => {
@@ -925,11 +890,11 @@ document.body.addEventListener("mouseleave", (e) => { //prevents mouse getting s
});
document.body.addEventListener("wheel", (e) => {
if (!game.paused) {
if (!simulation.paused) {
if (e.deltaY > 0) {
game.nextGun();
simulation.nextGun();
} 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
game.difficultyMode = localSettings.difficultyMode
simulation.difficultyMode = localSettings.difficultyMode
document.getElementById("difficulty-select").value = localSettings.difficultyMode
if (localSettings.fpsCapDefault === 'max') {
game.fpsCapDefault = 999999999;
simulation.fpsCapDefault = 999999999;
} else {
game.fpsCapDefault = Number(localSettings.fpsCapDefault)
simulation.fpsCapDefault = Number(localSettings.fpsCapDefault)
}
document.getElementById("fps-select").value = localSettings.fpsCapDefault
} else {
@@ -970,7 +935,7 @@ if (localSettings) {
input.setDefault()
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
document.getElementById("community-maps").checked = localSettings.isCommunityMaps
game.isCommunityMaps = localSettings.isCommunityMaps
simulation.isCommunityMaps = localSettings.isCommunityMaps
document.getElementById("difficulty-select").value = localSettings.difficultyMode
document.getElementById("fps-select").value = localSettings.fpsCapDefault
}
@@ -982,24 +947,24 @@ input.controlTextUpdate()
document.getElementById("fps-select").addEventListener("input", () => {
let value = document.getElementById("fps-select").value
if (value === 'max') {
game.fpsCapDefault = 999999999;
simulation.fpsCapDefault = 999999999;
} else {
game.fpsCapDefault = Number(value)
simulation.fpsCapDefault = Number(value)
}
localSettings.fpsCapDefault = value
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
});
document.getElementById("community-maps").addEventListener("input", () => {
game.isCommunityMaps = document.getElementById("community-maps").checked
localSettings.isCommunityMaps = game.isCommunityMaps
simulation.isCommunityMaps = document.getElementById("community-maps").checked
localSettings.isCommunityMaps = simulation.isCommunityMaps
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
});
// difficulty-select-custom event listener is set in build.makeGrid
document.getElementById("difficulty-select").addEventListener("input", () => {
game.difficultyMode = Number(document.getElementById("difficulty-select").value)
localSettings.difficultyMode = game.difficultyMode
simulation.difficultyMode = Number(document.getElementById("difficulty-select").value)
localSettings.difficultyMode = simulation.difficultyMode
localSettings.levelsClearedLastGame = 0 //after changing difficulty, reset run history
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
});
@@ -1048,28 +1013,27 @@ document.getElementById("updates").addEventListener("toggle", function() {
//**********************************************************************
// main loop
//**********************************************************************
game.loop = game.normalLoop;
simulation.loop = simulation.normalLoop;
function cycle() {
if (!game.paused) requestAnimationFrame(cycle);
if (!simulation.paused) requestAnimationFrame(cycle);
const now = Date.now();
const elapsed = now - game.then; // calc elapsed time since last loop
if (elapsed > game.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
const elapsed = now - simulation.then; // calc elapsed time since last loop
if (elapsed > simulation.fpsInterval) { // if enough time has elapsed, draw the next frame
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
if (game.clearNow) {
game.clearNow = false;
game.clearMap();
if (simulation.clearNow) {
simulation.clearNow = false;
simulation.clearMap();
level.start();
}
game.loop();
simulation.loop();
// if (isNaN(mech.health) || isNaN(mech.energy)) {
// console.log(`mech.health = ${mech.health}`)
// game.paused = true;
// game.replaceTextLog = true;
// simulation.paused = true;
// build.pauseGrid()
// document.body.style.cursor = "auto";
// 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: [],
start() {
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)
// game.zoomScale = 1000;
// game.setZoom();
// simulation.zoomScale = 1000;
// simulation.setZoom();
// mech.setField("plasma torch")
// b.giveGuns("wave beam")
// mod.giveMod("CPT reversal")
// mod.giveMod("CPT gun")
// for (let i = 0; i < 15; i++) mod.giveMod("plasma jet")
// tech.giveMod("CPT reversal")
// tech.giveMod("CPT gun")
// for (let i = 0; i < 15; i++) tech.giveMod("plasma jet")
level.intro(); //starting level
// level.testing(); //not in rotation
// level.finalBoss() //final boss level
// level.final() //final boss level
// level.gauntlet(); //before final boss level
// level.testChamber() //less mobs, more puzzle
// level.sewers();
@@ -44,48 +44,50 @@ const level = {
spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns
// spawn.pickList = ["focuser", "focuser"]
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.levelsClearedLastGame = level.levelsCleared
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
}
}
level.levelAnnounce();
game.noCameraScroll();
game.setZoom();
simulation.noCameraScroll();
simulation.setZoom();
level.addToWorld(); //add bodies to game engine
game.draw.setPaths();
simulation.draw.setPaths();
b.respawnBots();
mech.resetHistory();
if (mod.isArmorFromPowerUps) {
if (tech.isArmorFromPowerUps) {
const gain = Math.min(0.04 * powerUps.totalPowerUps, 0.44)
mod.armorFromPowerUps += gain
tech.armorFromPowerUps += gain
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)
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.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 (mod.isPerpetualAmmo) {
if (tech.isPerpetualReroll) powerUps.spawn(mech.pos.x + 60 * (Math.random() - 0.5), mech.pos.y + 60 * (Math.random() - 0.5), "reroll", false);
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);
}
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);
}
if (mod.isPerpetualStun) {
if (tech.isPerpetualStun) {
for (let i = 0; i < mob.length; i++) mobs.statusStun(mob[i], 60 * 8)
}
if (mod.isGunCycle) {
if (tech.isGunCycle) {
b.inventoryGun++;
if (b.inventoryGun > b.inventory.length - 1) b.inventoryGun = 0;
game.switchGun();
simulation.switchGun();
}
},
custom() {},
@@ -112,11 +114,11 @@ const level = {
spawn.setSpawnList();
spawn.setSpawnList();
level.defaultZoom = 1500
game.zoomTransition(level.defaultZoom)
simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#ddd";
// game.draw.mapFill = "#444"
// game.draw.bodyFill = "rgba(140,140,140,0.85)"
// game.draw.bodyStroke = "#222"
// simulation.draw.mapFill = "#444"
// simulation.draw.bodyFill = "rgba(140,140,140,0.85)"
// simulation.draw.bodyStroke = "#222"
level.fill.push({
x: 6400,
@@ -134,7 +136,8 @@ const level = {
spawn.mapRect(-250, -700, 1000, 900); // shelf
spawn.mapRect(-250, -1200, 1000, 250); // shelf roof
// powerUps.spawnStartingPowerUps(600, -800);
powerUps.spawn(550, -800, "reroll", false);
// 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) {
spawn.mapRect(x, y - 290, 40, 60); // door lip
@@ -165,7 +168,7 @@ const level = {
// spawn.bomberBoss(1400, -500)
// spawn.sniper(1800, -120)
// spawn.cellBossCulture(1600, -500)
spawn.streamBoss(1600, -500)
// spawn.streamBoss(1600, -500)
// spawn.beamer(1200, -500)
// spawn.shield(mob[mob.length - 1], 1800, -120, 1);
@@ -185,7 +188,7 @@ const level = {
level.exit.x = 1500;
level.exit.y = -1875;
level.defaultZoom = 1800
game.zoomTransition(level.defaultZoom)
simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#dcdcde";
// powerUps.spawnStartingPowerUps(1475, -1175);
// spawn.debris(750, -2200, 3700, 16); //16 debris per level
@@ -210,10 +213,10 @@ const level = {
// spawn.randomSmallMob(1300, -70);
// spawn.randomMob(2650, -975, 0.8);
// 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
},
finalBoss() {
final() {
level.bossKilled = false; // if a boss needs to be killed
level.custom = () => {
level.playerExitCheck();
@@ -227,7 +230,7 @@ const level = {
level.exit.y = -330;
level.defaultZoom = 2500
game.zoomTransition(level.defaultZoom)
simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#ccc";
level.fill.push({
@@ -276,7 +279,7 @@ const level = {
level.exit.y = -230;
level.defaultZoom = 1500
game.zoomTransition(level.defaultZoom)
simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#ddd";
level.fill.push({
@@ -313,13 +316,13 @@ const level = {
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump
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);
}
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);
}
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);
}
}
@@ -394,9 +397,9 @@ const level = {
level.exit.x = 2800;
level.exit.y = -335;
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
game.zoomTransition(level.defaultZoom, 1)
simulation.zoomTransition(level.defaultZoom, 1)
document.body.style.backgroundColor = "#ddd";
level.fill.push({
x: 2600,
@@ -515,13 +518,13 @@ const level = {
"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(
"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.",
"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(
"What do I do after I escape?",
"I'm almost ready to stop these simulations and actually escape.",
@@ -532,19 +535,19 @@ const level = {
)
} else { //resolve
say.push(
"I'll try some different mods this time.",
"I'll try some different techs this time.",
"I've got to escape.",
"I'll find a way out.",
"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 len = 30
for (let i = 0; i < len; i++) {
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.fillRect(0, 0, canvas.width, canvas.height);
}
@@ -552,7 +555,7 @@ const level = {
}
setTimeout(function() {
game.wipe = function() { //set wipe to normal
simulation.wipe = function() { //set wipe to normal
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
}, len * swapPeriod);
@@ -567,7 +570,7 @@ const level = {
level.exit.x = level.enter.x;
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20);
level.defaultZoom = 2200
game.zoomTransition(level.defaultZoom)
simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#d5d5d5";
const portal = level.portal({
@@ -776,7 +779,7 @@ const level = {
spawn.randomMob(-75, -1150, 0.5);
spawn.randomMob(1075, -625, 0.5);
spawn.randomMob(1725, -575, 0.5);
if (game.difficulty > 40) {
if (simulation.difficulty > 40) {
spawn.randomMob(2300, -2775, -0.5);
spawn.randomMob(600, -925, -0.5);
spawn.randomMob(1550, -2750, -0.5);
@@ -784,7 +787,7 @@ const level = {
spawn.randomMob(-75, -1475, 0);
spawn.randomBoss(600, -2600, 0);
}
if (game.difficulty < 25) {
if (simulation.difficulty < 25) {
spawn.randomMob(700, -1650, 0);
spawn.randomMob(600, -3500, 0.2);
spawn.randomMob(-75, -1175, 0.2);
@@ -837,7 +840,7 @@ const level = {
level.exit.x = 9700;
level.exit.y = 2560;
level.defaultZoom = 1800
game.zoomTransition(level.defaultZoom)
simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "hsl(138, 3%, 74%)";
powerUps.spawnStartingPowerUps(3475, 1775);
spawn.debris(4575, 2550, 1600, 9); //16 debris per level
@@ -940,7 +943,7 @@ const level = {
spawn.randomMob(3600, 1725, 0.9);
spawn.randomMob(4100, 1225, 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
},
satellite() {
@@ -950,13 +953,13 @@ const level = {
level.playerExitCheck();
};
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
elevator.plat.speed = -10
elevator.pauseUntilCycle = game.cycle + 90
elevator.pauseUntilCycle = simulation.cycle + 90
} else if (elevator.pointA.y < -3455) { //top
elevator.plat.speed = 30
elevator.pauseUntilCycle = game.cycle + 90
elevator.pauseUntilCycle = simulation.cycle + 90
}
elevator.pointA = {
x: elevator.pointA.x,
@@ -971,7 +974,7 @@ const level = {
spawn.mapRect(level.exit.x, level.exit.y + 15, 100, 50); //exit bump
level.defaultZoom = 1700 // 4500 // 1400
game.zoomTransition(level.defaultZoom)
simulation.zoomTransition(level.defaultZoom)
powerUps.spawnStartingPowerUps(4900, -500);
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(1600, -100, 0);
spawn.randomBoss(5000, -3900, -0.3);
if (game.difficulty > 3) {
if (simulation.difficulty > 3) {
if (Math.random() < 0.1) {
spawn.randomLevelBoss(2800, -1400);
} else if (Math.random() < 0.25) {
@@ -1159,13 +1162,13 @@ const level = {
};
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
elevator.plat.speed = -2
elevator.pauseUntilCycle = game.cycle + 60
elevator.pauseUntilCycle = simulation.cycle + 60
} else if (elevator.pointA.y < -1980) { //top
elevator.plat.speed = 1
elevator.pauseUntilCycle = game.cycle + 60
elevator.pauseUntilCycle = simulation.cycle + 60
}
elevator.pointA = {
x: elevator.pointA.x,
@@ -1175,7 +1178,7 @@ const level = {
};
level.defaultZoom = 1700
game.zoomTransition(level.defaultZoom)
simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#dcdcde";
@@ -1369,13 +1372,13 @@ const level = {
spawn.randomBoss(600, -1575, 0);
spawn.randomBoss(2225, -1325, 0.4);
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
},
aerie() {
level.bossKilled = false; // if a boss needs to be killed
// const elevator = level.platform(4112, -2300, 280, 50)
// game.g = 0.0012 //0.0024
// simulation.g = 0.0012 //0.0024
level.custom = () => {
level.playerExitCheck();
};
@@ -1383,11 +1386,11 @@ const level = {
// 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
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) {
level.setPosToSpawn(4000, -3300); //normal spawn
level.exit.x = -100;
@@ -1471,7 +1474,7 @@ const level = {
spawn.mapRect(-300, -1000, 600, 100);
spawn.mapRect(-300, -1300, 450, 50);
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
spawn.mapRect(-100, -975, 100, 975);
spawn.mapRect(-500, 100, 1950, 400);
@@ -1542,7 +1545,7 @@ const level = {
spawn.randomMob(3575, -2425, 0.5);
spawn.randomMob(3975, -3900, 0.5);
spawn.randomMob(1725, 125, 0.5);
if (game.difficulty > 3) {
if (simulation.difficulty > 3) {
if (Math.random() < 0.1) { // tether ball
spawn.tetherBoss(4250, 0)
cons[cons.length] = Constraint.create({
@@ -1555,7 +1558,7 @@ const level = {
});
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) {
spawn.randomLevelBoss(4250, -250);
spawn.debris(-250, 50, 1650, 2); //16 debris per level
@@ -1594,7 +1597,7 @@ const level = {
level.exit.y = -1875;
level.defaultZoom = 2000
game.zoomTransition(level.defaultZoom)
simulation.zoomTransition(level.defaultZoom)
//level.setPosToSpawn(1550, -1200); //spawn left high
//level.setPosToSpawn(1800, -2000); //spawn near exit
@@ -1602,9 +1605,9 @@ const level = {
powerUps.spawnStartingPowerUps(1475, -1175);
spawn.debris(750, -2200, 3700, 16); //16 debris per level
document.body.style.backgroundColor = "#dcdcde";
// game.draw.mapFill = "#444"
// game.draw.bodyFill = "rgba(140,140,140,0.85)"
// game.draw.bodyStroke = "#222"
// simulation.draw.mapFill = "#444"
// simulation.draw.bodyFill = "rgba(140,140,140,0.85)"
// simulation.draw.bodyStroke = "#222"
//foreground
level.fill.push({
@@ -1739,7 +1742,7 @@ const level = {
spawn.randomMob(-100, -900, -0.2);
spawn.randomBoss(3700, -1500, 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
},
highrise() {
@@ -1755,7 +1758,7 @@ const level = {
level.exit.y = -2805;
level.defaultZoom = 1500
game.zoomTransition(level.defaultZoom)
simulation.zoomTransition(level.defaultZoom)
powerUps.spawnStartingPowerUps(-2550, -700);
document.body.style.backgroundColor = "#dcdcde" //"#fafcff";
@@ -1871,7 +1874,7 @@ const level = {
spawn.mapRect(-600, -1150, 850, 175);
spawn.mapRect(-1850, -1150, 1050, 175);
spawn.bodyRect(-1907, -1600, 550, 25);
if (game.difficulty < 4) {
if (simulation.difficulty < 4) {
spawn.bodyRect(-1600, -125, 125, 125);
spawn.bodyRect(-1560, -200, 75, 75);
} else {
@@ -1910,7 +1913,7 @@ const level = {
spawn.mapRect(-4450, -3075, 450, 25);
spawn.mapRect(-4025, -3075, 25, 100);
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
spawn.randomMob(-2500, -2700, 1);
@@ -1938,7 +1941,7 @@ const level = {
spawn.randomBoss(-3250, -2700, 0.2);
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
},
warehouse() {
@@ -1953,7 +1956,7 @@ const level = {
level.exit.y = -30;
level.defaultZoom = 1300
game.zoomTransition(level.defaultZoom)
simulation.zoomTransition(level.defaultZoom)
spawn.debris(-2250, 1330, 3000, 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(-1300, -1100, -0.3);
if (game.difficulty > 3) {
if (simulation.difficulty > 3) {
if (Math.random() < 0.25) {
spawn.randomLevelBoss(-800, -1300)
} else {
@@ -2166,7 +2169,7 @@ const level = {
};
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.enter.x, level.enter.y + 20, 100, 20);
@@ -2288,7 +2291,7 @@ const level = {
spawn.randomBoss(1800, -800, -0.2);
spawn.randomBoss(4150, -1000, 0.6);
if (game.difficulty > 3) {
if (simulation.difficulty > 3) {
if (Math.random() < 0.65) {
// tether ball
level.fillBG.push({
@@ -2309,7 +2312,7 @@ const level = {
});
World.add(engine.world, cons[cons.length - 1]);
//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 {
spawn.randomLevelBoss(2200, -450)
}
@@ -2327,15 +2330,15 @@ const level = {
level.exit.y = -1250;
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.debris(3800, -1480, 300, 12);
spawn.debris(3600, -1130, 200, 2);
document.body.style.backgroundColor = "#dbdcde";
// game.draw.mapFill = "#444"
// game.draw.bodyFill = "rgba(140,140,140,0.85)"
// game.draw.bodyStroke = "#222"
// simulation.draw.mapFill = "#444"
// simulation.draw.bodyFill = "rgba(140,140,140,0.85)"
// simulation.draw.bodyStroke = "#222"
level.fillBG.push({
x: -500,
@@ -2551,7 +2554,7 @@ const level = {
spawn.randomBoss(2350, -850, 1);
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
},
basement() { // player made level by Francois 👑 from discord
@@ -2635,13 +2638,13 @@ const level = {
portal[3].draw();
hazard.draw();
//elevator
if (elevator.pauseUntilCycle < game.cycle && !mech.isBodiesAsleep) {
if (elevator.pauseUntilCycle < simulation.cycle && !mech.isBodiesAsleep) {
if (elevator.plat.position.y > -200) { //bottom
elevator.plat.speed = -20
elevator.pauseUntilCycle = game.cycle + 90
elevator.pauseUntilCycle = simulation.cycle + 90
} else if (elevator.plat.position.y < -3000) { //top
elevator.plat.speed = 30
elevator.pauseUntilCycle = game.cycle + 90
elevator.pauseUntilCycle = simulation.cycle + 90
}
elevator.plat.position = {
x: elevator.plat.position.x,
@@ -2652,7 +2655,7 @@ const level = {
};
level.defaultZoom = 1300
game.zoomTransition(level.defaultZoom)
simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#c7c7c7";
// GROUND //
@@ -2770,7 +2773,7 @@ const level = {
spawn.mapRect(2050, -1225, 75, 100); //Plateforme over acid
// MOBS
if (isLevelReversed === false) { ///Normal spawn
if (game.difficulty > 2) {
if (simulation.difficulty > 2) {
if (Math.random() < 0.2) {
// tether ball
spawn.tetherBoss(7000, -3300)
@@ -2783,13 +2786,13 @@ const level = {
stiffness: 0.00006
});
World.add(engine.world, cons[cons.length - 1]);
if (game.difficulty > 4) spawn.nodeBoss(7000, -3300, "spawns", 8, 20, 105);
} else if (game.difficulty > 3) {
if (simulation.difficulty > 4) spawn.nodeBoss(7000, -3300, "spawns", 8, 20, 105);
} else if (simulation.difficulty > 3) {
spawn.randomLevelBoss(6100, -3600, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss"]);
}
}
} else { /// Reversed spawn
if (game.difficulty > 2) {
if (simulation.difficulty > 2) {
if (Math.random() < 0.2) {
// tether ball
spawn.tetherBoss(2300, -1300)
@@ -2802,8 +2805,8 @@ const level = {
stiffness: 0.00036
});
World.add(engine.world, cons[cons.length - 1]);
if (game.difficulty > 4) spawn.nodeBoss(2350, -1300, "spawns", 8, 20, 105);
} else if (game.difficulty > 3) {
if (simulation.difficulty > 4) spawn.nodeBoss(2350, -1300, "spawns", 8, 20, 105);
} else if (simulation.difficulty > 3) {
spawn.randomLevelBoss(2300, -1400, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss", "snakeBoss"]);
}
}
@@ -2879,7 +2882,7 @@ const level = {
});
World.add(engine.world, cons[cons.length - 1]);
//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);
},
detours() {
@@ -2889,7 +2892,7 @@ const level = {
level.exit.x = 10625;
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20);
level.defaultZoom = 1400;
game.zoomTransition(level.defaultZoom)
simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#d5d5d5";
const BGColor = "rgba(0,0,0,0.1)";
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;
Matter.Body.setStatic(map[len], true); //make static
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) {
@@ -3144,7 +3147,7 @@ const level = {
spawn.randomMob(8800, -45, 0.2);
spawn.randomBoss(8025, -845, 0.2);
if (game.difficulty > 2) {
if (simulation.difficulty > 2) {
if (Math.random() < 0.2) {
// tether ball
spawn.tetherBoss(8000, 630)
@@ -3163,7 +3166,7 @@ const level = {
stiffness: 0.00015
});
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 {
spawn.randomLevelBoss(8000, 630, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss", "bomberBoss"]);
let me = mob[mob.length - 1];
@@ -3203,7 +3206,7 @@ const level = {
level.exit.y = -2480;
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20);
level.defaultZoom = 1800
game.zoomTransition(level.defaultZoom)
simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "rgb(170 170 170)"
level.custom = () => {
@@ -3260,9 +3263,9 @@ const level = {
ctx.strokeStyle = "#444444"
ctx.strokeRect(1650, -1300, 175, 150);
chair.force.y += chair.mass * game.g;
chair2.force.y += chair2.mass * game.g;
person.force.y += person.mass * game.g;
chair.force.y += chair.mass * simulation.g;
chair2.force.y += chair2.mass * simulation.g;
person.force.y += person.mass * simulation.g;
level.playerExitCheck();
};
level.customTopLayer = () => {
@@ -3739,7 +3742,7 @@ const level = {
spawn.randomBoss(630, -1300, -0.1);
spawn.randomBoss(3450, -2880, -0.2)
if (game.difficulty > 3) {
if (simulation.difficulty > 3) {
if (Math.random() < 0.16) {
spawn.tetherBoss(3380, -1775)
cons[cons.length] = Constraint.create({
@@ -3751,7 +3754,7 @@ const level = {
stiffness: 0.00018 + 0.000007 * level.levelsCleared
});
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 {
spawn.randomLevelBoss(3100, -1850, ["shooterBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "snakeBoss", "laserBoss"]);
@@ -3764,64 +3767,75 @@ const level = {
//******************************************************************************************************************
difficultyIncrease(num = 1) {
for (let i = 0; i < num; i++) {
game.difficulty++
simulation.difficulty++
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 (game.lookFreqScale > 0.2) game.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.accelScale < 5) simulation.accelScale *= 1.02 //mob acceleration increases each level
if (simulation.lookFreqScale > 0.2) simulation.lookFreqScale *= 0.98 //mob cycles between looks 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
game.healScale = 1 / (1 + game.difficulty * 0.06) //a higher denominator makes for lower heals // mech.health += heal * game.healScale;
simulation.dmgScale = 0.38 * simulation.difficulty //damage done by mobs increases each level
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++) {
game.difficulty--
simulation.difficulty--
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 (game.lookFreqScale < 5) game.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.accelScale > 0.2) simulation.accelScale /= 1.02 //mob acceleration increases each level
if (simulation.lookFreqScale < 5) simulation.lookFreqScale /= 0.98 //mob cycles between looks decreases each level
if (simulation.CDScale < 5) simulation.CDScale /= 0.97 //mob CD time decreases each level
}
if (game.difficulty < 1) game.difficulty = 0;
game.dmgScale = 0.38 * game.difficulty //damage done by mobs increases each level
if (game.dmgScale < 0.1) game.dmgScale = 0.1;
game.healScale = 1 / (1 + game.difficulty * 0.06)
if (simulation.difficulty < 1) simulation.difficulty = 0;
simulation.dmgScale = 0.38 * simulation.difficulty //damage done by mobs increases each level
if (simulation.dmgScale < 0.1) simulation.dmgScale = 0.1;
simulation.healScale = 1 / (1 + simulation.difficulty * 0.06)
},
difficultyText() {
if (game.difficultyMode === 1) {
if (simulation.difficultyMode === 1) {
return "easy"
} else if (game.difficultyMode === 2) {
} else if (simulation.difficultyMode === 2) {
return "normal"
} else if (game.difficultyMode === 4) {
} else if (simulation.difficultyMode === 4) {
return "hard"
} else if (game.difficultyMode === 6) {
} else if (simulation.difficultyMode === 6) {
return "why"
}
},
levelAnnounce() {
if (level.levelsCleared === 0) {
document.title = "n-gon: intro (" + level.difficultyText() + ")";
document.title = "n-gon: (" + level.difficultyText() + ")";
} 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() {
// if (level.bossKilled)
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
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
if (level.onLevel > level.levels.length - 1) level.onLevel = 0;
//reset lost mod display
for (let i = 0; i < mod.mods.length; i++) {
if (mod.mods[i].isLost) mod.mods[i].isLost = false;
//reset lost tech display
for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].isLost) tech.tech[i].isLost = false;
}
mod.isDeathAvoidedThisLevel = false;
game.updateModHUD();
game.clearNow = true; //triggers in game.clearMap to remove all physics bodies and setup for new map
tech.isDeathAvoidedThisLevel = false;
simulation.updateModHUD();
simulation.clearNow = true; //triggers in simulation.clearMap to remove all physics bodies and setup for new map
},
playerExitCheck() {
if (
@@ -4372,7 +4386,7 @@ const level = {
},
unit: unitA,
angle: angleA,
color: game.draw.mapFill,
color: simulation.draw.mapFill,
draw: draw,
query: query,
lastPortalCycle: 0
@@ -4387,7 +4401,7 @@ const level = {
},
unit: unitB,
angle: angleB,
color: game.draw.mapFill,
color: simulation.draw.mapFill,
draw: draw,
query: query,
lastPortalCycle: 0,
@@ -4420,13 +4434,13 @@ const level = {
if (damage < 0.02) {
mech.damage(damage)
} else if (mech.immuneCycle < mech.cycle) {
mech.immuneCycle = mech.cycle + mod.collisionImmuneCycles;
mech.immuneCycle = mech.cycle + tech.collisionImmuneCycles;
mech.damage(damage)
game.drawList.push({ //add dmg to draw queue
simulation.drawList.push({ //add dmg to draw queue
x: player.position.x,
y: player.position.y,
radius: damage * 1500,
color: game.mobDmgColor,
color: simulation.mobDmgColor,
time: 20
});
}

130
js/mob.js
View File

@@ -46,12 +46,12 @@ const mobs = {
statusSlow(who, cycles = 60) {
applySlow(who)
//look for mobs near the target
if (mod.isAoESlow) {
if (tech.isAoESlow) {
const range = (320 + 150 * Math.random()) ** 2
for (let i = 0, len = mob.length; i < len; i++) {
if (Vector.magnitudeSquared(Vector.sub(who.position, mob[i].position)) < range) applySlow(mob[i])
}
game.drawList.push({
simulation.drawList.push({
x: who.position.x,
y: who.position.y,
radius: Math.sqrt(range),
@@ -93,7 +93,7 @@ const mobs = {
who.isSlowed = false;
},
type: "slow",
endCycle: game.cycle + cycles,
endCycle: simulation.cycle + cycles,
})
}
}
@@ -145,7 +145,7 @@ const mobs = {
who.isStunned = false
},
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) {
who.status.push({
effect() {
if ((game.cycle - this.startCycle) % 30 === 0) {
if ((simulation.cycle - this.startCycle) % 30 === 0) {
let dmg = b.dmgScale * this.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,
y: who.position.y + (Math.random() - 0.5) * who.radius * 0.5,
radius: Math.log(2 * dmg + 1.1) * 40,
color: "rgba(0,80,80,0.9)",
time: game.drawTime
time: simulation.drawTime
});
}
if (true) {
@@ -172,8 +172,8 @@ const mobs = {
endEffect() {},
dmg: tickDamage,
type: "dot",
endCycle: game.cycle + cycles,
startCycle: game.cycle
endCycle: simulation.cycle + cycles,
startCycle: simulation.cycle
})
}
},
@@ -186,21 +186,21 @@ const mobs = {
// }
// who.status.push({
// 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())
// who.damage(dmg);
// game.drawList.push({ //add dmg to draw queue
// simulation.drawList.push({ //add dmg to draw queue
// x: who.position.x,
// y: who.position.y,
// radius: Math.log(2 * dmg + 1.1) * 40,
// color: `rgba(255,${Math.floor(200*Math.random())},0,0.9)`,
// time: game.drawTime
// time: simulation.drawTime
// });
// }
// },
// type: "burn",
// endCycle: game.cycle + cycles,
// startCycle: game.cycle
// endCycle: simulation.cycle + cycles,
// startCycle: simulation.cycle
// })
// }
// },
@@ -225,9 +225,9 @@ const mobs = {
onHit: undefined,
alive: true,
index: i,
health: mod.mobSpawnWithHealth,
health: tech.mobSpawnWithHealth,
showHealthBar: true,
accelMag: 0.001 * game.accelScale,
accelMag: 0.001 * simulation.accelScale,
cd: 0, //game cycle when cooldown will be over
delay: 60, //static: time between cooldowns
fill: color,
@@ -250,7 +250,7 @@ const mobs = {
let j = this.status.length;
while (j--) {
this.status[j].effect();
if (this.status[j].endCycle < game.cycle) {
if (this.status[j].endCycle < simulation.cycle) {
this.status[j].endEffect();
this.status.splice(j, 1);
}
@@ -272,7 +272,7 @@ const mobs = {
gravity() {
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() {
this.locatePlayer();
if (!this.seePlayer.yes) {
@@ -307,7 +307,7 @@ const mobs = {
}
},
seePlayerCheck() {
if (!(game.cycle % this.seePlayerFreq)) {
if (!(simulation.cycle % this.seePlayerFreq)) {
if (
this.distanceToPlayer2() < this.seeAtDistance2 &&
Matter.Query.ray(map, this.position, this.mechPosRange()).length === 0 &&
@@ -321,7 +321,7 @@ const mobs = {
}
},
seePlayerCheckByDistance() {
if (!(game.cycle % this.seePlayerFreq)) {
if (!(simulation.cycle % this.seePlayerFreq)) {
if (this.distanceToPlayer2() < this.seeAtDistance2 && !mech.isCloak) {
this.foundPlayer();
} else if (this.seePlayer.recall) {
@@ -330,7 +330,7 @@ const mobs = {
}
},
seePlayerByDistOrLOS() {
if (!(game.cycle % this.seePlayerFreq)) {
if (!(simulation.cycle % this.seePlayerFreq)) {
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)) &&
!mech.isCloak
@@ -360,7 +360,7 @@ const mobs = {
lookRange: 0.2 + Math.random() * 0.2,
lookTorque: 0.0000004 * (Math.random() > 0.5 ? -1 : 1),
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 (
this.distanceToPlayer2() < this.seeAtDistance2 &&
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
// //find a new target
// if (!(game.cycle % this.seePlayerFreq)) {
// if (!(simulation.cycle % this.seePlayerFreq)) {
// this.hackedTarget = null
// for (let i = 0, len = mob.length; i < len; i++) {
// if (mob[i] !== this) {
@@ -410,11 +410,11 @@ const mobs = {
// }
// },
laserBeam() {
if (game.cycle % 7 && this.seePlayer.yes) {
if (simulation.cycle % 7 && this.seePlayer.yes) {
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 (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
ctx.beginPath();
ctx.moveTo(this.position.x, this.position.y);
@@ -446,7 +446,7 @@ const mobs = {
let vertices = domain[i].vertices;
const len = vertices.length - 1;
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) {
const dx = v1.x - results.x;
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) {
const dx = v1.x - results.x;
const dy = v1.y - results.y;
@@ -503,7 +503,7 @@ const mobs = {
// hitting player
if (best.who === player) {
if (mech.immuneCycle < mech.cycle) {
const dmg = 0.0012 * game.dmgScale;
const dmg = 0.0012 * simulation.dmgScale;
mech.damage(dmg);
//draw damage
ctx.fillStyle = "#f00";
@@ -534,7 +534,7 @@ const mobs = {
ctx.fillStyle = "#222";
ctx.fill();
if (!(game.cycle % this.seePlayerFreq)) {
if (!(simulation.cycle % this.seePlayerFreq)) {
if (
(this.seePlayer.recall || this.isLookingAtPlayer(this.lookRange)) &&
this.distanceToPlayer2() < this.seeAtDistance2 &&
@@ -552,7 +552,7 @@ const mobs = {
// set new values of the ends of the spring constraints
const stepRange = 600
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 goal = Vector.add(this.position, Vector.mult(unit, stepRange))
this.springTarget.x = goal.x;
@@ -561,7 +561,7 @@ const mobs = {
// this.springTarget.y = this.seePlayer.position.y;
this.cons.length = -200;
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 goal = Vector.add(this.position, Vector.mult(unit, stepRange))
this.springTarget2.x = goal.x;
@@ -586,7 +586,7 @@ const mobs = {
let vertices = domain[i].vertices;
const len = vertices.length - 1;
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) {
const dx = v1.x - results.x;
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) {
const dx = v1.x - results.x;
const dy = v1.y - results.y;
@@ -622,7 +622,7 @@ const mobs = {
}
};
//move to a random location
if (!(game.cycle % (this.seePlayerFreq * 5))) {
if (!(simulation.cycle % (this.seePlayerFreq * 5))) {
best = {
x: null,
y: null,
@@ -661,7 +661,7 @@ const mobs = {
x: array[i].velocity.x * 0.94 + curlVector.x * 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
// ctx.beginPath();
// ctx.moveTo(array[i].position.x, array[i].position.y);
@@ -687,8 +687,8 @@ const mobs = {
pullPlayer() {
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);
player.force.x -= game.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.x -= simulation.accelScale * 0.00113 * player.mass * Math.cos(angle) * (mech.onGround ? 2 : 1);
player.force.y -= simulation.accelScale * 0.00084 * player.mass * Math.sin(angle);
ctx.beginPath();
ctx.moveTo(this.position.x, this.position.y);
@@ -715,7 +715,7 @@ const mobs = {
ctx.moveTo(this.position.x, this.position.y);
ctx.lineTo(bullet[i].position.x, bullet[i].position.y);
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.y += mag * Math.sin(angle);
}
@@ -815,14 +815,14 @@ const mobs = {
newTarget(this);
}
//switch to a new target after a while
if (!(game.cycle % (this.seePlayerFreq * 15))) {
if (!(simulation.cycle % (this.seePlayerFreq * 15))) {
newTarget(this);
}
}
},
blink() {
//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.moveTo(this.position.x, this.position.y);
const dist = Vector.sub(this.seePlayer.position, this.position);
@@ -842,7 +842,7 @@ const mobs = {
},
drift() {
//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)){
ctx.beginPath();
ctx.moveTo(this.position.x, this.position.y);
@@ -869,7 +869,7 @@ const mobs = {
bomb() {
//throw a mob/bullet at player
if (
!(game.cycle % this.fireFreq) &&
!(simulation.cycle % this.fireFreq) &&
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(body, this.position, this.mechPosRange()).length === 0
@@ -895,7 +895,7 @@ const mobs = {
//throw a mob/bullet at player
if (this.seePlayer.recall) {
//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.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) {
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.death(); //death with no power up or body
}
@@ -999,18 +999,18 @@ const mobs = {
},
damage(dmg, isBypassShield = false) {
if ((!this.isShielded || isBypassShield) && this.alive) {
dmg *= mod.damageFromMods()
dmg *= tech.damageFromMods()
//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
//energy and heal drain should be calculated after damage boosts
if (mod.energySiphon && dmg !== Infinity && this.dropPowerUp) {
mech.energy += Math.min(this.health, dmg) * mod.energySiphon
if (tech.energySiphon && dmg !== Infinity && this.dropPowerUp) {
mech.energy += Math.min(this.health, dmg) * tech.energySiphon
// if (mech.energy > mech.maxEnergy) mech.energy = mech.maxEnergy
}
if (mod.healthDrain && dmg !== Infinity && this.dropPowerUp) {
mech.addHealth(Math.min(this.health, dmg) * mod.healthDrain)
if (tech.healthDrain && dmg !== Infinity && this.dropPowerUp) {
mech.addHealth(Math.min(this.health, dmg) * tech.healthDrain)
if (mech.health > mech.maxHealth) mech.health = mech.maxHealth
}
dmg /= Math.sqrt(this.mass)
@@ -1035,40 +1035,40 @@ const mobs = {
this.removeConsBB();
this.alive = false; //triggers mob removal in mob[i].replace(i)
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);
mech.lastKillCycle = mech.cycle; //tracks the last time a kill was made, mostly used in game.checks()
if (Math.random() < mod.sporesOnDeath) {
mech.lastKillCycle = mech.cycle; //tracks the last time a kill was made, mostly used in simulation.checks()
if (Math.random() < tech.sporesOnDeath) {
const len = Math.min(25, Math.floor(2 + this.mass * (0.5 + 0.5 * Math.random())))
for (let i = 0; i < len; i++) {
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))
} else if (mod.nailsDeathMob) {
b.targetedNail(this.position, mod.nailsDeathMob, 39 + 6 * Math.random())
} else if (tech.nailsDeathMob) {
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)
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
}
} else if (mod.isShieldAmmo && this.shield) {
let type = mod.isEnergyNoAmmo ? "heal" : "ammo"
} else if (tech.isShieldAmmo && this.shield) {
let type = tech.isEnergyNoAmmo ? "heal" : "ammo"
if (Math.random() < 0.4) {
type = "heal"
} else if (Math.random() < 0.3 && !mod.isSuperDeterminism) {
} else if (Math.random() < 0.3 && !tech.isSuperDeterminism) {
type = "reroll"
}
for (let i = 0, len = Math.ceil(2 * Math.random()); i < len; i++) {
powerUps.spawn(this.position.x, this.position.y, type);
}
}
if (mod.isRadioactive) {
if (tech.isRadioactive) {
//look for dots and spread them
let dmgTotal = 0
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
let closestRadius = 500;
@@ -1090,7 +1090,7 @@ const mobs = {
ctx.stroke();
}
//draw AOE
// game.drawList.push({ //add dmg to draw queue
// simulation.drawList.push({ //add dmg to draw queue
// x: this.position.x,
// y: this.position.y,
// radius: radius,

View File

@@ -80,8 +80,8 @@ const mech = {
Fx: 0.016, //run Force on ground //
jumpForce: 0.42,
setMovement() {
mech.Fx = 0.016 * mod.squirrelFx * mod.fastTime;
mech.jumpForce = 0.42 * mod.squirrelJump * mod.fastTimeJump;
mech.Fx = 0.016 * tech.squirrelFx * tech.fastTime;
mech.jumpForce = 0.42 * tech.squirrelJump * tech.fastTimeJump;
},
FxAir: 0.016, // 0.4/5/5 run Force in Air
yOff: 70,
@@ -184,13 +184,13 @@ const mech = {
look() {
//always on mouse look
mech.angle = Math.atan2(
game.mouseInGame.y - mech.pos.y,
game.mouseInGame.x - mech.pos.x
simulation.mouseInGame.y - mech.pos.y,
simulation.mouseInGame.x - mech.pos.x
);
//smoothed mouse look translations
const scale = 0.8;
mech.transSmoothX = canvas.width2 - mech.pos.x - (game.mouse.x - canvas.width2) * scale;
mech.transSmoothY = canvas.height2 - mech.pos.y - (game.mouse.y - canvas.height2) * scale;
mech.transSmoothX = canvas.width2 - mech.pos.x - (simulation.mouse.x - canvas.width2) * scale;
mech.transSmoothY = canvas.height2 - mech.pos.y - (simulation.mouse.y - canvas.height2) * scale;
mech.transX += (mech.transSmoothX - mech.transX) * 0.07;
mech.transY += (mech.transSmoothY - mech.transY) * 0.07;
@@ -324,38 +324,39 @@ const mech = {
},
alive: false,
death() {
if (mod.isImmortal) { //if player has the immortality buff, spawn on the same level with randomized damage
//count mods
if (tech.isImmortal) { //if player has the immortality buff, spawn on the same level with randomized damage
simulation.isTextLogOpen = false;
//count tech
let totalMods = 0;
for (let i = 0; i < mod.mods.length; i++) {
if (!mod.mods[i].isNonRefundable) totalMods += mod.mods[i].count
for (let i = 0; i < tech.tech.length; i++) {
if (!tech.tech[i].isNonRefundable) totalMods += tech.tech[i].count
}
if (mod.isDeterminism) totalMods -= 3 //remove the bonus mods
if (mod.isSuperDeterminism) totalMods -= 2 //remove the bonus mods
if (tech.isDeterminism) totalMods -= 3 //remove the bonus tech
if (tech.isSuperDeterminism) totalMods -= 2 //remove the bonus tech
totalMods = totalMods * 1.15 + 1 // a few extra to make it stronger
const totalGuns = b.inventory.length //count guns
function randomizeMods() {
for (let i = 0; i < totalMods; i++) {
//find what mods I don't have
//find what tech I don't have
let options = [];
for (let i = 0, len = mod.mods.length; i < len; i++) {
if (mod.mods[i].count < mod.mods[i].maxCount &&
!mod.mods[i].isNonRefundable &&
mod.mods[i].name !== "quantum immortality" &&
mod.mods[i].name !== "Born rule" &&
mod.mods[i].allowed()
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].count < tech.tech[i].maxCount &&
!tech.tech[i].isNonRefundable &&
tech.tech[i].name !== "quantum immortality" &&
tech.tech[i].name !== "Born rule" &&
tech.tech[i].allowed()
) options.push(i);
}
//add a new mod
//add a new tech
if (options.length > 0) {
const choose = Math.floor(Math.random() * options.length)
let newMod = options[choose]
mod.giveMod(newMod)
tech.giveMod(newMod)
options.splice(choose, 1);
}
}
game.updateModHUD();
simulation.updateModHUD();
}
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())))
}
}
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.fillRect(0, 0, canvas.width, canvas.height);
}
function randomizeEverything() {
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]);
bullet = []; //remove all bullets
randomizeHealth()
@@ -411,9 +412,10 @@ const mech = {
for (let i = 0, len = 5; i < len; i++) {
setTimeout(function() {
randomizeEverything()
game.replaceTextLog = true;
game.makeTextLog(`probability amplitude will synchronize in ${len-i-1} seconds`, swapPeriod);
game.wipe = function() { //set wipe to have trails
simulation.isTextLogOpen = true;
simulation.makeTextLog(`simulation.amplitude <span class='color-symbol'>=</span> 0.${len-i-1}`, swapPeriod);
simulation.isTextLogOpen = false;
simulation.wipe = function() { //set wipe to have trails
ctx.fillStyle = `rgba(255,255,255,${(i+1)*(i+1)*0.006})`;
ctx.fillRect(0, 0, canvas.width, canvas.height);
// pixelWindows()
@@ -422,16 +424,17 @@ const mech = {
}
setTimeout(function() {
game.wipe = function() { //set wipe to normal
simulation.wipe = function() { //set wipe to normal
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
game.replaceTextLog = true;
game.makeTextLog("your quantum probability has stabilized", 1000);
simulation.isTextLogOpen = true;
simulation.makeTextLog("simulation.amplitude <span class='color-symbol'>=</span> null");
}, 6 * swapPeriod);
} else if (mech.alive) { //normal death code here
mech.alive = false;
game.paused = true;
simulation.paused = true;
mech.health = 0;
mech.displayHealth();
document.getElementById("text-log").style.opacity = 0; //fade out any active text logs
@@ -440,12 +443,12 @@ const mech = {
setTimeout(function() {
World.clear(engine.world);
Engine.clear(engine);
game.splashReturn();
simulation.splashReturn();
}, 3000);
}
},
health: 0,
maxHealth: 1, //set in game.reset()
maxHealth: 1, //set in simulation.reset()
drawHealth() {
if (mech.health < 1) {
ctx.fillStyle = "rgba(100, 100, 100, 0.5)";
@@ -471,15 +474,15 @@ const mech = {
}
},
addHealth(heal) {
if (!mod.isEnergyHealth) {
mech.health += heal * game.healScale;
if (!tech.isEnergyHealth) {
mech.health += heal * simulation.healScale;
if (mech.health > mech.maxHealth) mech.health = mech.maxHealth;
mech.displayHealth();
}
},
baseHealth: 1,
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;
mech.displayHealth();
},
@@ -489,33 +492,33 @@ const mech = {
harmReduction() {
let dmg = 1
dmg *= mech.fieldHarmReduction
if (mod.isSpeedHarm) dmg *= 1 - Math.min(player.speed * 0.0185, 0.55)
if (mod.isSlowFPS) dmg *= 0.85
if (mod.isPiezo) dmg *= 0.85
if (mod.isHarmReduce && mech.fieldUpgrades[mech.fieldMode].name === "negative mass field" && mech.isFieldActive) dmg *= 0.6
if (mod.isBotArmor) dmg *= 0.97 ** mod.totalBots()
if (mod.isHarmArmor && mech.lastHarmCycle + 600 > mech.cycle) dmg *= 0.33;
if (mod.isNoFireDefense && mech.cycle > mech.fireCDcycle + 120) dmg *= 0.6
if (mod.energyRegen === 0) dmg *= 0.4
if (mod.isTurret && mech.crouch) dmg *= 0.5;
if (mod.isEntanglement && b.inventory[0] === b.activeGun) {
if (tech.isSpeedHarm) dmg *= 1 - Math.min(player.speed * 0.0185, 0.55)
if (tech.isSlowFPS) dmg *= 0.85
if (tech.isPiezo) dmg *= 0.85
if (tech.isHarmReduce && mech.fieldUpgrades[mech.fieldMode].name === "negative mass field" && mech.isFieldActive) dmg *= 0.6
if (tech.isBotArmor) dmg *= 0.97 ** tech.totalBots()
if (tech.isHarmArmor && mech.lastHarmCycle + 600 > mech.cycle) dmg *= 0.33;
if (tech.isNoFireDefense && mech.cycle > mech.fireCDcycle + 120) dmg *= 0.6
if (tech.energyRegen === 0) dmg *= 0.4
if (tech.isTurret && mech.crouch) dmg *= 0.5;
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
}
return dmg
},
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++) {
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]
if (mod.isVacuumBomb) {
if (tech.isVacuumBomb) {
Matter.Body.setVelocity(who, {
x: who.velocity.x * 0.5,
y: who.velocity.y * 0.5
});
} else if (mod.isRPG) {
who.endCycle = (who.endCycle - game.cycle) * 0.2 + game.cycle
} else if (mod.isNeutronBomb) {
} else if (tech.isRPG) {
who.endCycle = (who.endCycle - simulation.cycle) * 0.2 + simulation.cycle
} else if (tech.isNeutronBomb) {
Matter.Body.setVelocity(who, {
x: who.velocity.x * 0.3,
y: who.velocity.y * 0.3
@@ -525,19 +528,21 @@ const mech = {
x: who.velocity.x * 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]
Matter.Body.setPosition(player, history.position);
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++) {
if (b.inventory[i] === b.activeGun) b.inventoryGun = i
}
game.updateGunHUD();
game.boldActiveGunHUD();
// b.activeGun = history.activeGun
// for (let i = 0; i < b.inventory.length; i++) {
// if (b.inventory[i] === b.activeGun) b.inventoryGun = i
// }
// simulation.updateGunHUD();
// simulation.boldActiveGunHUD();
// move bots to follow player
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType) {
@@ -557,8 +562,8 @@ const mech = {
let isDrawPlayer = true
const shortPause = function() {
if (mech.defaultFPSCycle < mech.cycle) { //back to default values
game.fpsCap = game.fpsCapDefault
game.fpsInterval = 1000 / game.fpsCap;
simulation.fpsCap = simulation.fpsCapDefault
simulation.fpsInterval = 1000 / simulation.fpsCap;
document.getElementById("dmg").style.transition = "opacity 1s";
document.getElementById("dmg").style.opacity = "0";
} else {
@@ -567,7 +572,7 @@ const mech = {
isDrawPlayer = false
ctx.save();
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
for (let i = 1; i < steps; i++) {
history = mech.history[(mech.cycle - i) % 600]
@@ -582,52 +587,53 @@ const mech = {
};
if (mech.defaultFPSCycle < mech.cycle) requestAnimationFrame(shortPause);
game.fpsCap = 3 //1 is longest pause, 4 is standard
game.fpsInterval = 1000 / game.fpsCap;
simulation.fpsCap = 3 //1 is longest pause, 4 is standard
simulation.fpsInterval = 1000 / simulation.fpsCap;
mech.defaultFPSCycle = mech.cycle
if (mod.isRewindBot) {
const len = steps * 0.042 * mod.isRewindBot
if (tech.isRewindBot) {
const len = steps * 0.042 * tech.isRewindBot
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
b.randomBot({
x: where.x + 100 * (Math.random() - 0.5),
y: where.y + 100 * (Math.random() - 0.5)
}, 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) {
if (mod.isRewindAvoidDeath && mech.energy > 0.66) {
if (tech.isRewindAvoidDeath && mech.energy > 0.66) {
mech.rewind(Math.floor(Math.min(299, 137 * mech.energy)))
return
}
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)
for (let i = 0; i < len; i++) {
if (Math.random() < 0.5) b.drone() //spawn drone
}
}
if (mod.isEnergyHealth) {
if (tech.isEnergyHealth) {
mech.energy -= dmg;
if (mech.energy < 0 || isNaN(mech.energy)) { //taking deadly damage
if (mod.isDeathAvoid && powerUps.reroll.rerolls && !mod.isDeathAvoidedThisLevel) {
mod.isDeathAvoidedThisLevel = true
if (tech.isDeathAvoid && powerUps.reroll.rerolls && !tech.isDeathAvoidedThisLevel) {
tech.isDeathAvoidedThisLevel = true
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++) {
powerUps.spawn(mech.pos.x, mech.pos.y, "heal", false);
}
mech.energy = mech.maxEnergy
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.fillRect(0, 0, canvas.width, canvas.height);
}
setTimeout(function() {
game.wipe = function() { //set wipe to normal
simulation.wipe = function() { //set wipe to normal
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
}, 3000);
@@ -643,23 +649,22 @@ const mech = {
dmg *= mech.harmReduction()
mech.health -= dmg;
if (mech.health < 0 || isNaN(mech.health)) {
if (mod.isDeathAvoid && powerUps.reroll.rerolls > 0 && !mod.isDeathAvoidedThisLevel) { //&& Math.random() < 0.5
mod.isDeathAvoidedThisLevel = true
if (tech.isDeathAvoid && powerUps.reroll.rerolls > 0 && !tech.isDeathAvoidedThisLevel) { //&& Math.random() < 0.5
tech.isDeathAvoidedThisLevel = true
mech.health = 0.05
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++) {
powerUps.spawn(mech.pos.x, mech.pos.y, "heal", false);
}
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)
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.fillRect(0, 0, canvas.width, canvas.height);
}
setTimeout(function() {
game.wipe = function() { //set wipe to normal
simulation.wipe = function() { //set wipe to normal
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
}, 3000);
@@ -677,8 +682,8 @@ const mech = {
if (dmg > 0.06 / mech.holdingMassScale) mech.drop(); //drop block if holding
const normalFPS = function() {
if (mech.defaultFPSCycle < mech.cycle) { //back to default values
game.fpsCap = game.fpsCapDefault
game.fpsInterval = 1000 / game.fpsCap;
simulation.fpsCap = simulation.fpsCapDefault
simulation.fpsInterval = 1000 / simulation.fpsCap;
document.getElementById("dmg").style.transition = "opacity 1s";
document.getElementById("dmg").style.opacity = "0";
} else {
@@ -687,23 +692,23 @@ const mech = {
};
if (mech.defaultFPSCycle < mech.cycle) requestAnimationFrame(normalFPS);
if (mod.isSlowFPS) { // slow game
game.fpsCap = 30 //new fps
game.fpsInterval = 1000 / game.fpsCap;
if (tech.isSlowFPS) { // slow game
simulation.fpsCap = 30 //new fps
simulation.fpsInterval = 1000 / simulation.fpsCap;
//how long to wait to return to normal fps
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++) {
mobs.statusSlow(mob[i], 300)
}
}
} else {
if (dmg > 0.05) { // freeze game for high damage hits
game.fpsCap = 4 //40 - Math.min(25, 100 * dmg)
game.fpsInterval = 1000 / game.fpsCap;
simulation.fpsCap = 4 //40 - Math.min(25, 100 * dmg)
simulation.fpsInterval = 1000 / simulation.fpsCap;
} else {
game.fpsCap = game.fpsCapDefault
game.fpsInterval = 1000 / game.fpsCap;
simulation.fpsCap = simulation.fpsCapDefault
simulation.fpsInterval = 1000 / simulation.fpsCap;
}
mech.defaultFPSCycle = mech.cycle
}
@@ -718,7 +723,7 @@ const mech = {
},
buttonCD: 0, //cool down for player buttons
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) {
mech.flipLegs = 1;
} else {
@@ -822,7 +827,7 @@ const mech = {
fireCDcycle: 0,
fieldCDcycle: 0,
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,
timeSkipLastCycle: 0,
// these values are set on reset by setHoldDefaults()
@@ -857,14 +862,14 @@ const mech = {
},
setHoldDefaults() {
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.fieldShieldingScale = 1;
mech.fieldBlockCD = 10;
mech.fieldHarmReduction = 1;
mech.fieldDamage = 1
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.fieldRange = 155;
mech.fieldFire = false;
@@ -894,7 +899,7 @@ const mech = {
}
},
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",
drawFieldMeter(bgColor = "rgba(0, 0, 0, 0.4)", range = 60) {
@@ -950,7 +955,7 @@ const mech = {
definePlayerMass(mass = mech.defaultMass) {
Matter.Body.setMass(player, mass);
//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
//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))
@@ -1005,8 +1010,8 @@ const mech = {
if (input.field) {
if (mech.energy > 0.001) {
if (mech.fireCDcycle < mech.cycle) mech.fireCDcycle = mech.cycle
mech.energy -= 0.001 / mod.throwChargeRate;
mech.throwCharge += 0.5 * mod.throwChargeRate / mech.holdingTarget.mass
mech.energy -= 0.001 / tech.throwChargeRate;
mech.throwCharge += 0.5 * tech.throwChargeRate / mech.holdingTarget.mass
//draw charge
const x = mech.pos.x + 15 * Math.cos(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.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;
ctx.beginPath();
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
) {
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
Matter.Body.setVelocity(powerUp[i], {
x: powerUp[i].velocity.x * 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);
Matter.Body.setVelocity(player, { //player knock back, after grabbing power up
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 (mod.blockDmg) {
who.damage(mod.blockDmg * b.dmgScale)
if (tech.blockDmg) {
who.damage(tech.blockDmg * b.dmgScale)
//draw electricity
const step = 40
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 y = mech.pos.y - 20 * unit.y;
ctx.moveTo(x, y);
@@ -1182,7 +1187,7 @@ const mech = {
} else {
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
//knock backs
@@ -1205,8 +1210,8 @@ const mech = {
});
}
} else {
if (mod.isStunField && mech.fieldUpgrades[mech.fieldMode].name === "perfect diamagnetism") mobs.statusStun(who, mod.isStunField)
// mobs.statusSlow(who, mod.isStunField)
if (tech.isStunField && mech.fieldUpgrades[mech.fieldMode].name === "perfect diamagnetism") mobs.statusStun(who, tech.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
Matter.Body.setVelocity(who, {
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) {
Matter.Sleeping.set(mob[i], false)
mobs.statusSlow(mob[i], 60)
@@ -1352,9 +1357,8 @@ const mech = {
},
fieldUpgrades: [{
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: () => {
game.replaceTextLog = true; //allow text over write
mech.hold = function() {
if (mech.isHolding) {
mech.drawHold(mech.holdingTarget);
@@ -1470,7 +1474,7 @@ const mech = {
}
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
for (let i = 0; i < mob.length; i++) {
const distance = Vector.magnitude(Vector.sub(mech.pos, mob[i].position))
@@ -1495,16 +1499,16 @@ const mech = {
effect: () => {
mech.hold = function() {
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())
mech.energy -= len * 0.105;
for (let i = 0; i < len; i++) {
b.spore(mech.pos)
}
} else if (mod.isMissileField) {
} else if (tech.isMissileField) {
mech.energy -= 0.55;
b.missile({ x: mech.pos.x, y: mech.pos.y - 40 }, -Math.PI / 2, 0, 1, mod.recursiveMissiles)
} else if (mod.isIceField) {
b.missile({ x: mech.pos.x, y: mech.pos.y - 40 }, -Math.PI / 2, 0, 1, tech.recursiveMissiles)
} else if (tech.isIceField) {
mech.energy -= 0.057;
b.iceIX(1)
} else {
@@ -1558,7 +1562,7 @@ const mech = {
mech.lookForPickUp();
const DRAIN = 0.00035
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.FxAir = 0.005
// mech.pushMobs360();
@@ -1579,7 +1583,7 @@ const mech = {
sub = Vector.sub(who[i].position, mech.pos);
dist = Vector.magnitude(sub);
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?
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;
zeroG(powerUp, this.fieldDrawRadius, 0.7);
zeroG(body, this.fieldDrawRadius, 0.7);
} else if (input.up) { //up
mech.energy -= 5 * DRAIN;
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(body, this.fieldDrawRadius, 1.38);
} else {
mech.energy -= DRAIN;
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(body, this.fieldDrawRadius);
}
@@ -1620,7 +1624,7 @@ const mech = {
y: player.velocity.y * 0.98
});
}
if (mod.isFreezeMobs) {
if (tech.isFreezeMobs) {
const ICE_DRAIN = 0.0005
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) {
@@ -1668,7 +1672,7 @@ const mech = {
} else if (input.field && mech.fieldCDcycle < mech.cycle) { //not hold but field button is pressed
mech.grabPowerUp();
mech.lookForPickUp();
if (mod.isExtruder) {
if (tech.isExtruder) {
b.extruder();
} else {
b.plasma();
@@ -1680,7 +1684,7 @@ const mech = {
}
mech.drawFieldMeter("rgba(0, 0, 0, 0.2)")
if (mod.isExtruder) {
if (tech.isExtruder) {
if (input.field) {
b.wasExtruderOn = true
} else {
@@ -1759,17 +1763,17 @@ const mech = {
}
}
game.cycle--; //pause all functions that depend on game cycle increasing
if (mod.isTimeSkip) {
simulation.cycle--; //pause all functions that depend on game cycle increasing
if (tech.isTimeSkip) {
mech.immuneCycle = mech.cycle + 10;
game.isTimeSkipping = true;
simulation.isTimeSkipping = true;
mech.cycle++;
game.gravity();
Engine.update(engine, game.delta);
simulation.gravity();
Engine.update(engine, simulation.delta);
// level.checkZones();
// level.checkQuery();
mech.move();
game.checks();
simulation.checks();
// mobs.loop();
// mech.draw();
mech.walk_cycle += mech.flipLegs * mech.Vx;
@@ -1778,11 +1782,11 @@ const mech = {
b.fire();
// b.bulletRemove();
b.bulletDo();
game.isTimeSkipping = false;
simulation.isTimeSkipping = false;
}
// game.cycle--; //pause all functions that depend on game cycle increasing
// if (mod.isTimeSkip && !game.isTimeSkipping) { //speed up the rate of time
// game.timeSkip(1)
// simulation.cycle--; //pause all functions that depend on game cycle increasing
// if (tech.isTimeSkip && !simulation.isTimeSkipping) { //speed up the rate of time
// 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
// }
}
@@ -1828,7 +1832,7 @@ const mech = {
if (mech.fireCDcycle + 50 < mech.cycle) {
if (!mech.isCloak) {
mech.isCloak = true //enter cloak
if (mod.isIntangible) {
if (tech.isIntangible) {
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
}
@@ -1836,12 +1840,12 @@ const mech = {
}
} else if (mech.isCloak) { //exit cloak
mech.isCloak = false
if (mod.isIntangible) {
if (tech.isIntangible) {
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 (mod.isCloakStun) { //stun nearby mobs after exiting cloak
if (tech.isCloakStun) { //stun nearby mobs after exiting cloak
let isMobsAround = false
const stunRange = mech.fieldDrawRadius * 1.15
const drain = 0.3 * mech.energy
@@ -1856,7 +1860,7 @@ const mech = {
}
if (isMobsAround && mech.energy > drain) {
mech.energy -= drain
game.drawList.push({
simulation.drawList.push({
x: mech.pos.x,
y: mech.pos.y,
radius: stunRange,
@@ -1900,7 +1904,7 @@ const mech = {
drawField()
}
}
if (mod.isIntangible) {
if (tech.isIntangible) {
if (mech.isCloak) {
player.collisionFilter.mask = cat.map
let inPlayer = Matter.Query.region(mob, player.bounds)
@@ -1981,8 +1985,8 @@ const mech = {
// mech.lookForPickUp();
// if (mech.fieldCDcycle < mech.cycle) {
// // game.draw.bodyFill = "transparent"
// // game.draw.bodyStroke = "transparent"
// // simulation.draw.bodyFill = "transparent"
// // simulation.draw.bodyStroke = "transparent"
// const DRAIN = 0.00013 + (mech.fireCDcycle > mech.cycle ? 0.005 : 0)
// if (mech.energy > DRAIN) {
@@ -2007,7 +2011,7 @@ const mech = {
// //draw outline of shield
// ctx.fillStyle = `rgba(140,217,255,0.5)`
// 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
// // mech.energy += 0.005;
@@ -2073,17 +2077,16 @@ const mech = {
// },
{
name: "pilot wave",
description: "use <strong class='color-f'>energy</strong> to push <strong>blocks</strong> with your mouse<br>field <strong>radius</strong> decreases out of <strong>line of sight</strong><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: () => {
game.replaceTextLog = true; //allow text over write
mech.fieldPhase = 0;
mech.fieldPosition = {
x: game.mouseInGame.x,
y: game.mouseInGame.y
x: simulation.mouseInGame.x,
y: simulation.mouseInGame.y
}
mech.lastFieldPosition = {
x: game.mouseInGame.x,
y: game.mouseInGame.y
x: simulation.mouseInGame.x,
y: simulation.mouseInGame.y
}
mech.fieldOn = false;
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
mech.fieldOn = true;
mech.fieldPosition = { //smooth the mouse position
x: game.mouseInGame.x,
y: game.mouseInGame.y
x: simulation.mouseInGame.x,
y: simulation.mouseInGame.y
}
mech.lastFieldPosition = { //used to find velocity of field changes
x: mech.fieldPosition.x,
@@ -2122,8 +2125,8 @@ const mech = {
}
const smooth = isInMap ? 0.985 : 0.96;
mech.fieldPosition = { //smooth the mouse position
x: mech.fieldPosition.x * smooth + game.mouseInGame.x * (1 - smooth),
y: mech.fieldPosition.y * smooth + game.mouseInGame.y * (1 - smooth),
x: mech.fieldPosition.x * smooth + simulation.mouseInGame.x * (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
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.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
Matter.Body.setVelocity(powerUp[i], {
x: powerUp[i].velocity.x * 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);
powerUp[i].effect();
Matter.World.remove(engine.world, powerUp[i]);
@@ -2176,12 +2179,12 @@ const mech = {
mech.energy -= DRAIN;
Matter.Body.setVelocity(body[i], velocity); //give block mouse velocity
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
const sub = Vector.sub(mech.fieldPosition, body[i].position)
const unit = Vector.mult(Vector.normalise(sub), 0.00005 * Vector.magnitude(sub))
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 {
mech.fieldCDcycle = mech.cycle + 120;
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) {
if (Vector.magnitude(Vector.sub(mob[i].position, mech.fieldPosition)) < mech.fieldRadius) {
mobs.statusSlow(mob[i], 120)
@@ -2235,12 +2238,11 @@ const mech = {
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>
effect: function() {
game.replaceTextLog = true; //allow text over write
mech.drop();
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
// } else {
mech.hold = this.teleport
@@ -2258,8 +2260,8 @@ const mech = {
// if (this.rewindCount === 0) {
// const shortPause = function() {
// if (mech.defaultFPSCycle < mech.cycle) { //back to default values
// game.fpsCap = game.fpsCapDefault
// game.fpsInterval = 1000 / game.fpsCap;
// simulation.fpsCap = simulation.fpsCapDefault
// simulation.fpsInterval = 1000 / simulation.fpsCap;
// // document.getElementById("dmg").style.transition = "opacity 1s";
// // document.getElementById("dmg").style.opacity = "0";
// } else {
@@ -2267,14 +2269,14 @@ const mech = {
// }
// };
// if (mech.defaultFPSCycle < mech.cycle) requestAnimationFrame(shortPause);
// game.fpsCap = 4 //1 is longest pause, 4 is standard
// game.fpsInterval = 1000 / game.fpsCap;
// simulation.fpsCap = 4 //1 is longest pause, 4 is standard
// simulation.fpsInterval = 1000 / simulation.fpsCap;
// mech.defaultFPSCycle = mech.cycle
// }
// 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(221,221,221,${0.004})`;
// ctx.fillRect(0, 0, canvas.width, canvas.height);
@@ -2290,15 +2292,15 @@ const mech = {
// for (let i = 0, len = powerUp.length; i < len; ++i) {
// const dxP = player.position.x - powerUp[i].position.x;
// 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);
// powerUp[i].effect();
// Matter.World.remove(engine.world, powerUp[i]);
// powerUp.splice(i, 1);
// const shortPause = function() {
// if (mech.defaultFPSCycle < mech.cycle) { //back to default values
// game.fpsCap = game.fpsCapDefault
// game.fpsInterval = 1000 / game.fpsCap;
// simulation.fpsCap = simulation.fpsCapDefault
// simulation.fpsInterval = 1000 / simulation.fpsCap;
// // document.getElementById("dmg").style.transition = "opacity 1s";
// // document.getElementById("dmg").style.opacity = "0";
// } else {
@@ -2306,8 +2308,8 @@ const mech = {
// }
// };
// if (mech.defaultFPSCycle < mech.cycle) requestAnimationFrame(shortPause);
// game.fpsCap = 3 //1 is longest pause, 4 is standard
// game.fpsInterval = 1000 / game.fpsCap;
// simulation.fpsCap = 3 //1 is longest pause, 4 is standard
// simulation.fpsInterval = 1000 / simulation.fpsCap;
// mech.defaultFPSCycle = mech.cycle
// break; //because the array order is messed up after splice
// }
@@ -2322,7 +2324,7 @@ const mech = {
// mech.fieldCDcycle = mech.cycle + 30;
// mech.resetHistory();
// 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);
// }
// }
@@ -2342,7 +2344,7 @@ const mech = {
// }
if (mech.hole.isOn) {
// 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 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)
@@ -2379,12 +2381,12 @@ const mech = {
dist2 = dxP * dxP + dyP * dyP;
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.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
x: powerUp[i].velocity.x * 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
powerUps.onPickUp(powerUp[i].position);
powerUp[i].effect();
@@ -2415,8 +2417,8 @@ const mech = {
Matter.World.remove(engine.world, body[i]);
body.splice(i, 1);
mech.fieldRange *= 0.8
if (mod.isWormholeEnergy) mech.energy += 0.5
if (mod.isWormSpores) { //pandimensionalspermia
if (tech.isWormholeEnergy) mech.energy += 0.5
if (tech.isWormSpores) { //pandimensionalspermia
for (let i = 0, len = Math.ceil(3 * Math.random()); i < len; i++) {
b.spore(Vector.add(mech.hole.pos2, Vector.rotate({
x: mech.fieldRange * 0.4,
@@ -2440,9 +2442,9 @@ const mech = {
Matter.World.remove(engine.world, body[i]);
body.splice(i, 1);
mech.fieldRange *= 0.8
// if (mod.isWormholeEnergy && mech.energy < mech.maxEnergy * 2) mech.energy = mech.maxEnergy * 2
if (mod.isWormholeEnergy) mech.energy += 0.5
if (mod.isWormSpores) { //pandimensionalspermia
// if (tech.isWormholeEnergy && mech.energy < mech.maxEnergy * 2) mech.energy = mech.maxEnergy * 2
if (tech.isWormholeEnergy) mech.energy += 0.5
if (tech.isWormSpores) { //pandimensionalspermia
for (let i = 0, len = Math.ceil(3 * Math.random()); i < len; i++) {
b.spore(Vector.add(mech.hole.pos1, Vector.rotate({
x: mech.fieldRange * 0.4,
@@ -2457,7 +2459,7 @@ const mech = {
}
}
}
if (mod.isWormBullets) {
if (tech.isWormBullets) {
//teleport bullets
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
@@ -2487,35 +2489,35 @@ const mech = {
}
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
// console.log(Matter.Query.region(map, bounds))
if (mech.hole.isReady &&
(
Matter.Query.region(map, {
min: {
x: game.mouseInGame.x - scale,
y: game.mouseInGame.y - scale
x: simulation.mouseInGame.x - scale,
y: simulation.mouseInGame.y - scale
},
max: {
x: game.mouseInGame.x + scale,
y: game.mouseInGame.y + scale
x: simulation.mouseInGame.x + scale,
y: simulation.mouseInGame.y + scale
}
}).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, player.position, game.mouseInGame).length === 0 &&
// Matter.Query.ray(map, mech.pos, simulation.mouseInGame).length === 0 &&
// Matter.Query.ray(map, player.position, simulation.mouseInGame).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 drain = 0.03 + 0.005 * Math.sqrt(mag)
if (mech.energy > drain && mag > 300) {
mech.energy -= drain
mech.hole.isReady = false;
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
const velocity = Vector.mult(Vector.normalise(sub), 18)
Matter.Body.setVelocity(player, {
@@ -2546,8 +2548,8 @@ const mech = {
mech.hole.angle = Math.atan2(sub.y, sub.x)
mech.hole.unit = Vector.perp(Vector.normalise(sub))
if (mod.isWormholeDamage) {
who = Matter.Query.ray(mob, mech.pos, game.mouseInGame, 80)
if (tech.isWormholeDamage) {
who = Matter.Query.ray(mob, mech.pos, simulation.mouseInGame, 80)
for (let i = 0; i < who.length; i++) {
if (who[i].body.alive) {
mobs.statusDoT(who[i].body, 0.6, 420)

View File

@@ -1,23 +1,22 @@
let powerUp = [];
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) {
if (type === "gun") {
b.giveGuns(index)
// game.replaceTextLog = true;
// game.makeTextLog(`${game.SVGleftMouse} <strong style='font-size:30px;'>${b.guns[index].name}</strong><br><br>${b.guns[index].description}`, 500);
// game.replaceTextLog = false;
let text = `b.giveGuns("<span class='color-text'>${b.guns[index].name}</span>")`
if (b.inventory.length === 1) text += `<br>input.key.gun <span class='color-symbol'>=</span> ["<span class='color-text'>MouseLeft</span>"]`
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") {
mech.setField(index)
// game.replaceTextLog = true;
// 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);
// game.replaceTextLog = false;
} else if (type === "mod") {
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;
simulation.makeTextLog(`<span class='color-var'>mech</span>.setField("<span class='color-text'>${mech.fieldUpgrades[mech.fieldMode].name}</span>")`);
} else if (type === "tech") {
tech.giveMod(index)
simulation.makeTextLog(`<span class='color-var'>tech</span>.giveMod("<span class='color-text'>${tech.tech[index].name}</span>")`);
}
powerUps.endDraft(type);
},
@@ -27,45 +26,45 @@ const powerUps = {
document.getElementById("choose-background").style.display = "inline"
document.body.style.cursor = "auto";
if (mod.isExtraChoice) {
if (tech.isExtraChoice) {
document.body.style.overflowY = "scroll";
document.body.style.overflowX = "hidden";
}
game.paused = true;
game.isChoosing = true; //stops p from un pausing on key down
simulation.paused = true;
simulation.isChoosing = true; //stops p from un pausing on key down
build.pauseGrid(true)
},
endDraft(type, isCanceled = false) {
if (isCanceled) {
if (mod.isCancelDuplication) mod.cancelCount++
if (mod.isCancelRerolls) {
let spawnType = (mech.health < 0.25 || mod.isEnergyNoAmmo) ? "heal" : "ammo"
if (tech.isCancelDuplication) tech.cancelCount++
if (tech.isCancelRerolls) {
let spawnType = (mech.health < 0.25 || tech.isEnergyNoAmmo) ? "heal" : "ammo"
if (Math.random() < 0.33) {
spawnType = "heal"
} else if (Math.random() < 0.5 && !mod.isSuperDeterminism) {
} else if (Math.random() < 0.5 && !tech.isSuperDeterminism) {
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);
}
if (mod.isBanish && type === 'mod') { // banish rerolled mods by adding them to the list of banished mods
const banishLength = mod.isDeterminism ? 1 : 3 + mod.isExtraChoice * 2
if (powerUps.mod.choiceLog.length > banishLength || powerUps.mod.choiceLog.length === banishLength) { //I'm not sure this check is needed
if (tech.isBanish && type === 'tech') { // banish rerolled tech by adding them to the list of banished tech
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++) {
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);
}
document.getElementById("choose-grid").style.display = "none"
document.getElementById("choose-background").style.display = "none"
document.body.style.cursor = "none";
document.body.style.overflow = "hidden"
game.paused = false;
game.isChoosing = false; //stops p from un pausing on key down
simulation.paused = false;
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
build.unPauseGrid()
requestAnimationFrame(cycle);
@@ -79,17 +78,21 @@ const powerUps = {
},
effect() {
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) {
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
for (; powerUps.reroll.rerolls > limit - 1; powerUps.reroll.rerolls -= limit) {
b.randomBot()
if (mod.renormalization) {
if (tech.renormalization) {
for (let i = 0; i < limit; i++) {
if (Math.random() < 0.37) {
mech.fieldCDcycle = mech.cycle + 30;
@@ -99,54 +102,32 @@ const powerUps = {
}
}
}
if (mod.isDeathAvoid && document.getElementById("mod-anthropic")) {
document.getElementById("mod-anthropic").innerHTML = `-${powerUps.reroll.rerolls}`
if (tech.isDeathAvoid && document.getElementById("tech-anthropic")) {
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 (mod.isRerollHaste) {
if (tech.renormalization && Math.random() < 0.37 && amount < 0) powerUps.spawn(mech.pos.x, mech.pos.y, "reroll");
if (tech.isRerollHaste) {
if (powerUps.reroll.rerolls === 0) {
mod.rerollHaste = 0.66;
tech.rerollHaste = 0.66;
b.setFireCD();
} else {
mod.rerollHaste = 1;
tech.rerollHaste = 1;
b.setFireCD();
}
}
},
diceText() {
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
use(type) { //runs when you actually reroll a list of selections, type can be field, gun, or tech
powerUps.reroll.changeRerolls(-1)
if (mod.isBanish && type === 'mod') { // banish rerolled mods
const banishLength = mod.isDeterminism ? 1 : 3 + mod.isExtraChoice * 2
if (powerUps.mod.choiceLog.length > banishLength || powerUps.mod.choiceLog.length === banishLength) { //I'm not sure this check is needed
// simulation.makeTextLog(`<span class='color-var'>mech</span>.<span class='color-r'>rerolls</span><span class='color-symbol'>--</span>
// <br>${powerUps.reroll.rerolls}`)
if (tech.isBanish && type === 'tech') { // banish rerolled tech
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++) {
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();
},
@@ -155,24 +136,26 @@ const powerUps = {
name: "heal",
color: "#0eb",
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() {
if (!mod.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()
if (!tech.isEnergyHealth && mech.alive) {
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) {
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);
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) {
mod.healMaxEnergyBonus += 0.04
if (tech.healGiveMaxEnergy) {
tech.healMaxEnergyBonus += 0.04
mech.setMaxEnergy();
}
},
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)
if (Math.random() < mod.duplicationChance()) {
if (Math.random() < tech.duplicationChance()) {
powerUps.directSpawn(x, y, "heal", false, null, size)
powerUp[powerUp.length - 1].isBonus = true
}
@@ -186,20 +169,27 @@ const powerUps = {
},
effect() {
//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 ammoAdded = Math.ceil(Math.random() * target.ammoPack) + Math.ceil(Math.random() * target.ammoPack)
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 {
let text = '';
for (let i = 0, len = b.inventory.length; i < len; i++) {
const target = b.guns[b.inventory[i]]
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: {
@@ -216,7 +206,7 @@ const powerUps = {
if (i !== mech.fieldMode && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4) options.push(i);
}
//remove repeats from last selection
const totalChoices = mod.isDeterminism ? 1 : 3 + mod.isExtraChoice * 2
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
for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection
if (options.length > totalChoices) {
@@ -239,16 +229,16 @@ const powerUps = {
let choice3 = -1
if (choice1 > -1) {
let text = ""
if (!mod.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>`
if (!tech.isDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("field",true)'>✕</div>`
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>`
if (!mod.isDeterminism) {
if (!tech.isDeterminism) {
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>`
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 (mod.isExtraChoice) {
if (tech.isExtraChoice) {
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>`
let choice5 = pick(mech.fieldUpgrades, choice1, choice2, choice3, choice4)
@@ -260,9 +250,13 @@ const powerUps = {
powerUps.field.choiceLog.push(choice2)
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>`
// 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>`
if (powerUps.reroll.rerolls) {
text += `<div class="choose-grid-module" onclick="powerUps.reroll.use('field')"><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.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
powerUps.showDraft();
} else {
@@ -270,42 +264,42 @@ const powerUps = {
}
}
},
mod: {
name: "mod",
tech: {
name: "tech",
color: "hsl(246,100%,77%)", //"#a8f",
size() {
return 42;
},
choiceLog: [], //records all previous choice options
lastTotalChoices: 0, //tracks how many mods were available for random selection last time a mod was picked up
banishLog: [], //records all mods permanently removed from the selection pool
lastTotalChoices: 0, //tracks how many tech were available for random selection last time a tech was picked up
banishLog: [], //records all tech permanently removed from the selection pool
effect() {
if (mech.alive) {
function pick(skip1 = -1, skip2 = -1, skip3 = -1, skip4 = -1) {
let options = [];
for (let i = 0; i < mod.mods.length; i++) {
if (mod.mods[i].count < mod.mods[i].maxCount && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4 && mod.mods[i].allowed()) {
for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].count < tech.tech[i].maxCount && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4 && tech.tech[i].allowed()) {
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
for (let i = 0; i < powerUps.mod.banishLog.length; i++) {
if (tech.isBanish) { //remove banished tech from last selection
for (let i = 0; i < powerUps.tech.banishLog.length; i++) {
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)
break
}
}
}
} else { //remove repeats from last selection
const totalChoices = mod.isDeterminism ? 1 : 3 + mod.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
const totalChoices = tech.isDeterminism ? 1 : 3 + tech.isExtraChoice * 2
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
if (options.length > totalChoices) {
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
break
}
@@ -317,67 +311,73 @@ const powerUps = {
if (options.length > 0) {
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) {
text += `<div class="choose-grid-module" onclick="powerUps.choose('mod',${choose})"><div class="grid-title">
if (tech.tech[choose].isFieldMod) {
text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title">
<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>
</span>
&nbsp; &nbsp; &nbsp; &nbsp; ${mod.mods[choose].name} ${isCount}</div>${mod.mods[choose].description}</div></div>`
} else if (mod.mods[choose].isGunMod) {
text += `<div class="choose-grid-module" onclick="powerUps.choose('mod',${choose})"><div class="grid-title">
&nbsp; &nbsp; &nbsp; &nbsp; ${tech.tech[choose].name} ${isCount}</div>${tech.tech[choose].description}</div></div>`
} else if (tech.tech[choose].isGunMod) {
text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title">
<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>
</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 {
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
}
}
let text = ""
if (!mod.isDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("mod",true)'>✕</div>`
text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>choose a mod</h3>`
if (!tech.isDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("tech",true)'>✕</div>`
text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>tech</h3>`
let choice1 = pick()
let choice2 = -1
let choice3 = -1
if (choice1 > -1) {
if (!mod.isDeterminism) {
if (!tech.isDeterminism) {
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)
// 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)
// 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)
// 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>`
powerUps.mod.choiceLog.push(choice4)
powerUps.mod.choiceLog.push(choice5)
// 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.tech.choiceLog.push(choice4)
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
powerUps.showDraft();
} else {
if (mod.isBanish) {
for (let i = 0, len = mod.mods.length; i < len; i++) {
if (mod.mods[i].name === "erase") powerUps.ejectMod(i)
if (tech.isBanish) {
for (let i = 0, len = tech.tech.length; i < len; 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)
powerUps.spawn(mech.pos.x, mech.pos.y, "mod");
powerUps.endDraft("mod");
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, "tech");
powerUps.endDraft("tech");
} else {
powerUps.giveRandomAmmo()
}
@@ -402,7 +402,7 @@ const powerUps = {
}
//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
for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection
if (options.length > totalChoices) {
@@ -425,16 +425,16 @@ const powerUps = {
let choice3 = -1
if (choice1 > -1) {
let text = ""
if (!mod.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>`
if (!tech.isDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("gun",true)'>✕</div>`
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>`
if (!mod.isDeterminism) {
if (!tech.isDeterminism) {
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>`
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 (mod.isExtraChoice) {
if (tech.isExtraChoice) {
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>`
let choice5 = pick(b.guns, choice1, choice2, choice3, choice4)
@@ -446,11 +446,15 @@ const powerUps = {
powerUps.gun.choiceLog.push(choice1)
powerUps.gun.choiceLog.push(choice2)
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(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
powerUps.showDraft();
} else {
@@ -459,29 +463,26 @@ const powerUps = {
}
},
onPickUp(where) {
if (mod.isMassEnergy) mech.energy += 2.5;
if (mod.isMineDrop) b.mine({
if (tech.isMassEnergy) mech.energy += 2.5;
if (tech.isMineDrop) b.mine({
x: where.x,
y: where.y
}, {
x: 0,
y: 0
}, 0, mod.isMineAmmoBack)
}, 0, tech.isMineAmmoBack)
},
giveRandomAmmo() {
const ammoTarget = Math.floor(Math.random() * (b.guns.length));
const ammo = Math.ceil(b.guns[ammoTarget].ammoPack * 6);
if (ammo === Infinity) {
if (ammo !== Infinity) {
b.guns[ammoTarget].ammo += ammo;
game.makeTextLog("<span style='font-size:115%;'><span class='color-f'>+energy</span></span>", 300);
} else {
b.guns[ammoTarget].ammo += ammo;
game.updateGunHUD();
game.makeTextLog("<span style='font-size:110%;'>+" + ammo + " ammo for " + b.guns[ammoTarget].name + "</span>", 300);
simulation.updateGunHUD();
simulation.makeTextLog(`${b.guns[ammoTarget].name}.<span class='color-gun'>ammo</span> <span class='color-symbol'>+=</span> ${ammo}`);
}
},
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");
return;
}
@@ -493,8 +494,8 @@ const powerUps = {
powerUps.spawn(x, y, "gun");
return;
}
if (Math.random() < 0.0027 * (25 - mod.totalCount)) { //a new mod has a low chance for each not acquired mod up to 15
powerUps.spawn(x, y, "mod");
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, "tech");
return;
}
if (Math.random() < 0.006) {
@@ -507,7 +508,7 @@ const powerUps = {
// }
},
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;
if (mech.fieldMode === 0) {
@@ -523,12 +524,12 @@ const powerUps = {
if (Math.random() * chanceToFail < powerUps.randomPowerUpCounter) {
powerUps.randomPowerUpCounter = 0;
if (Math.random() < 0.95) {
powerUps.spawn(x, y, "mod")
powerUps.spawn(x, y, "tech")
} else {
powerUps.spawn(x, y, "gun")
}
} 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");
} else {
@@ -553,20 +554,20 @@ const powerUps = {
},
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 > 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
if (level.levelsCleared === 0 && !game.isCheating) {
if (level.levelsCleared === 0 && !simulation.isCheating) {
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
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
}
if (b.inventory.length === 0) {
powerUps.spawn(x, y, "gun", false); //first gun
} else if (mod.totalCount === 0) { //first mod
powerUps.spawn(x, y, "mod", false);
} else if (tech.totalCount === 0) { //first tech
powerUps.spawn(x, y, "tech", false);
} else if (b.inventory.length < 2) { //second gun or extra ammo
if (Math.random() < 0.5) {
powerUps.spawn(x, y, "gun", false);
@@ -589,38 +590,48 @@ const powerUps = {
}
},
ejectMod(choose = 'random') {
//find which mods you have
//find which tech you have
if (choose === 'random') {
const have = []
for (let i = 0; i < mod.mods.length; i++) {
if (mod.mods[i].count > 0) have.push(i)
for (let i = 0; i < tech.tech.length; 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) {
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
for (let i = 0; i < mod.mods[choose].count; i++) {
powerUps.directSpawn(mech.pos.x, mech.pos.y, "mod");
// simulation.makeTextLog(`<div class='circle tech'></div> &nbsp; <strong>${tech.tech[choose].name}</strong> was ejected`, 600) //message about what tech was lost
simulation.makeTextLog(`<span class='color-var'>tech</span>.remove("<span class='color-text'>${tech.tech[choose].name}</span>")`)
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
}
// remove a random mod from the list of mods you have
mod.mods[choose].remove();
mod.mods[choose].count = 0;
mod.mods[choose].isLost = true;
game.updateModHUD();
mech.fieldCDcycle = mech.cycle + 30; //disable field so you can't pick up the ejected mod
// remove a random tech from the list of tech you have
tech.tech[choose].remove();
tech.tech[choose].count = 0;
tech.tech[choose].isLost = true;
simulation.updateModHUD();
mech.fieldCDcycle = mech.cycle + 30; //disable field so you can't pick up the ejected tech
}
} else {
game.makeTextLog(`<div class='circle mod'></div> &nbsp; <strong>${mod.mods[choose].name}</strong> was ejected`, 600) //message about what mod was lost
for (let i = 0; i < mod.mods[choose].count; i++) {
powerUps.directSpawn(mech.pos.x, mech.pos.y, "mod");
// simulation.makeTextLog(`<div class='circle tech'></div> &nbsp; <strong>${tech.tech[choose].name}</strong> was ejected`, 600) //message about what tech was lost
simulation.makeTextLog(`<span class='color-var'>tech</span>.remove("<span class='color-text'>${tech.tech[choose].name}</span>")`)
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
}
// remove a random mod from the list of mods you have
mod.mods[choose].remove();
mod.mods[choose].count = 0;
mod.mods[choose].isLost = true;
game.updateModHUD();
mech.fieldCDcycle = mech.cycle + 30; //disable field so you can't pick up the ejected mod
// remove a random tech from the list of tech you have
tech.tech[choose].remove();
tech.tech[choose].count = 0;
tech.tech[choose].isLost = true;
simulation.updateModHUD();
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()) {
@@ -654,12 +665,12 @@ const powerUps = {
},
spawn(x, y, target, moving = true, mode = null, size = powerUps[target].size()) {
if (
(!mod.isSuperDeterminism || (target === 'mod' || target === 'heal' || target === 'ammo')) &&
!(mod.isEnergyNoAmmo && target === 'ammo') &&
(!game.isNoPowerUps || (target === 'reroll' || target === 'heal' || target === 'ammo'))
(!tech.isSuperDeterminism || (target === 'tech' || target === 'heal' || target === 'ammo')) &&
!(tech.isEnergyNoAmmo && target === 'ammo') &&
(!simulation.isNoPowerUps || (target === 'reroll' || target === 'heal' || target === 'ammo'))
) {
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)
powerUp[powerUp.length - 1].isBonus = true
}

View File

@@ -1,12 +1,12 @@
// game Object ********************************************************
//*********************************************************************
const game = {
const simulation = {
loop() {}, //main game loop, gets se tto normal or testing loop
normalLoop() {
game.gravity();
Engine.update(engine, game.delta);
game.wipe();
game.textLog();
simulation.gravity();
Engine.update(engine, simulation.delta);
simulation.wipe();
simulation.textLog();
if (mech.onGround) {
mech.groundControl()
} else {
@@ -16,17 +16,17 @@ const game = {
level.checkQuery();
mech.move();
mech.look();
game.checks();
simulation.checks();
ctx.save();
game.camera();
simulation.camera();
level.drawFillBGs();
level.exit.draw();
level.enter.draw();
level.custom();
game.draw.powerUp();
simulation.draw.powerUp();
mobs.draw();
game.draw.cons();
game.draw.body();
simulation.draw.cons();
simulation.draw.body();
mobs.loop();
mobs.healthBar();
mech.draw();
@@ -34,22 +34,22 @@ const game = {
// v.draw(); //working on visibility work in progress
level.drawFills();
level.customTopLayer();
game.draw.drawMapPath();
simulation.draw.drawMapPath();
b.fire();
b.bulletRemove();
b.bulletDraw();
b.bulletDo();
game.drawCircle();
// game.clip();
simulation.drawCircle();
// simulation.clip();
ctx.restore();
game.drawCursor();
// game.pixelGraphics();
simulation.drawCursor();
// simulation.pixelGraphics();
},
testingLoop() {
game.gravity();
Engine.update(engine, game.delta);
game.wipe();
game.textLog();
simulation.gravity();
Engine.update(engine, simulation.delta);
simulation.wipe();
simulation.textLog();
if (mech.onGround) {
mech.groundControl()
} else {
@@ -60,28 +60,28 @@ const game = {
level.checkQuery();
mech.move();
mech.look();
game.checks();
simulation.checks();
ctx.save();
game.camera();
simulation.camera();
mech.draw();
level.customTopLayer();
game.draw.wireFrame();
game.draw.cons();
game.draw.testing();
game.drawCircle();
game.constructCycle()
simulation.draw.wireFrame();
simulation.draw.cons();
simulation.draw.testing();
simulation.drawCircle();
simulation.constructCycle()
ctx.restore();
game.testingOutput();
game.drawCursor();
simulation.testingOutput();
simulation.drawCursor();
},
isTimeSkipping: false,
timeSkip(cycles = 60) {
game.isTimeSkipping = true;
simulation.isTimeSkipping = true;
for (let i = 0; i < cycles; i++) {
game.cycle++;
simulation.cycle++;
mech.cycle++;
game.gravity();
Engine.update(engine, game.delta);
simulation.gravity();
Engine.update(engine, simulation.delta);
if (mech.onGround) {
mech.groundControl()
} else {
@@ -91,7 +91,7 @@ const game = {
level.checkZones();
level.checkQuery();
mech.move();
game.checks();
simulation.checks();
mobs.loop();
// mech.draw();
mech.walk_cycle += mech.flipLegs * mech.Vx;
@@ -101,7 +101,7 @@ const game = {
b.bulletRemove();
b.bulletDo();
}
game.isTimeSkipping = false;
simulation.isTimeSkipping = false;
},
mouse: {
x: canvas.width / 2,
@@ -136,13 +136,13 @@ const game = {
lookFreqScale: null, //set in levels.setDifficulty
isNoPowerUps: false,
// dropFPS(cap = 40, time = 15) {
// game.fpsCap = cap
// game.fpsInterval = 1000 / game.fpsCap;
// game.defaultFPSCycle = game.cycle + time
// simulation.fpsCap = cap
// simulation.fpsInterval = 1000 / simulation.fpsCap;
// simulation.defaultFPSCycle = simulation.cycle + time
// const normalFPS = function () {
// if (game.defaultFPSCycle < game.cycle) {
// game.fpsCap = 72
// game.fpsInterval = 1000 / game.fpsCap;
// if (simulation.defaultFPSCycle < simulation.cycle) {
// simulation.fpsCap = 72
// simulation.fpsInterval = 1000 / simulation.fpsCap;
// } else {
// requestAnimationFrame(normalFPS);
// }
@@ -233,10 +233,10 @@ const game = {
drawCursor() {
const size = 10;
ctx.beginPath();
ctx.moveTo(game.mouse.x - size, game.mouse.y);
ctx.lineTo(game.mouse.x + size, game.mouse.y);
ctx.moveTo(game.mouse.x, game.mouse.y - size);
ctx.lineTo(game.mouse.x, game.mouse.y + size);
ctx.moveTo(simulation.mouse.x - size, simulation.mouse.y);
ctx.lineTo(simulation.mouse.x + size, simulation.mouse.y);
ctx.moveTo(simulation.mouse.x, simulation.mouse.y - size);
ctx.lineTo(simulation.mouse.x, simulation.mouse.y + size);
ctx.lineWidth = 2;
ctx.strokeStyle = "#000"; //'rgba(0,0,0,0.4)'
ctx.stroke(); // Draw it
@@ -247,17 +247,17 @@ const game = {
playerDmgColor: "rgba(0,0,0,0.7)", //used top push into drawList.color
drawCircle() {
//draws a circle for two cycles, used for showing damage mostly
let i = game.drawList.length;
let i = simulation.drawList.length;
while (i--) {
ctx.beginPath(); //draw circle
ctx.arc(game.drawList[i].x, game.drawList[i].y, game.drawList[i].radius, 0, 2 * Math.PI);
ctx.fillStyle = game.drawList[i].color;
ctx.arc(simulation.drawList[i].x, simulation.drawList[i].y, simulation.drawList[i].radius, 0, 2 * Math.PI);
ctx.fillStyle = simulation.drawList[i].color;
ctx.fill();
if (game.drawList[i].time) {
if (simulation.drawList[i].time) {
//remove when timer runs out
game.drawList[i].time--;
simulation.drawList[i].time--;
} 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 (mod.isEntanglement && document.getElementById("mod-entanglement")) {
if (tech.isEntanglement && document.getElementById("tech-entanglement")) {
if (b.inventory[0] === b.activeGun) {
let lessDamage = 1
for (let i = 0, len = b.inventory.length; i < len; i++) {
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 {
document.getElementById("mod-entanglement").innerHTML = " 0%"
document.getElementById("tech-entanglement").innerHTML = " 0%"
}
}
},
@@ -304,115 +304,119 @@ const game = {
node.appendChild(textnode);
document.getElementById("guns").appendChild(node);
}
game.boldActiveGunHUD();
simulation.boldActiveGunHUD();
},
updateModHUD() {
let text = ""
for (let i = 0, len = mod.mods.length; i < len; i++) { //add mods
if (mod.mods[i].isLost) {
for (let i = 0, len = tech.tech.length; i < len; i++) { //add tech
if (tech.tech[i].isLost) {
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>`
} else if (mod.mods[i].count > 0) {
text += `<span style="text-decoration: line-through;">${tech.tech[i].name}</span>`
} else if (tech.tech[i].count > 0) {
if (text) text += "<br>" //add a new line, but not on the first line
text += mod.mods[i].name
if (mod.mods[i].nameInfo) {
text += mod.mods[i].nameInfo
mod.mods[i].addNameInfo();
text += tech.tech[i].name
if (tech.tech[i].nameInfo) {
text += tech.tech[i].nameInfo
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="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>',
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) {
if (game.replaceTextLog) {
// 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 = 120) {
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").style.opacity = 1;
game.lastLogTime = mech.cycle + time;
simulation.lastLogTime = mech.cycle + time;
}
}
},
textLog() {
if (game.lastLogTime && game.lastLogTime < mech.cycle) {
game.lastLogTime = 0;
game.replaceTextLog = true
if (simulation.lastLogTime && simulation.lastLogTime < mech.cycle) {
simulation.lastLogTime = 0;
// document.getElementById("text-log").innerHTML = " ";
document.getElementById("text-log").style.opacity = 0;
}
},
nextGun() {
if (b.inventory.length > 0 && !mod.isGunCycle) {
if (b.inventory.length > 0 && !tech.isGunCycle) {
b.inventoryGun++;
if (b.inventoryGun > b.inventory.length - 1) b.inventoryGun = 0;
game.switchGun();
simulation.switchGun();
}
},
previousGun() {
if (b.inventory.length > 0 && !mod.isGunCycle) {
if (b.inventory.length > 0 && !tech.isGunCycle) {
b.inventoryGun--;
if (b.inventoryGun < 0) b.inventoryGun = b.inventory.length - 1;
game.switchGun();
simulation.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];
game.updateGunHUD();
game.boldActiveGunHUD();
simulation.updateGunHUD();
simulation.boldActiveGunHUD();
// mech.drop();
},
zoom: null,
zoomScale: 1000,
isAutoZoom: true,
setZoom(zoomScale = game.zoomScale) { //use in window resize in index.js
game.zoomScale = zoomScale
game.zoom = canvas.height / zoomScale; //sets starting zoom scale
setZoom(zoomScale = simulation.zoomScale) { //use in window resize in index.js
simulation.zoomScale = zoomScale
simulation.zoom = canvas.height / zoomScale; //sets starting zoom scale
},
zoomTransition(newZoomScale, step = 2) {
if (game.isAutoZoom) {
const isBigger = (newZoomScale - game.zoomScale > 0) ? true : false;
if (simulation.isAutoZoom) {
const isBigger = (newZoomScale - simulation.zoomScale > 0) ? true : false;
requestAnimationFrame(zLoop);
const currentLevel = level.onLevel
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) {
game.zoomScale += step
if (game.zoomScale >= newZoomScale) {
game.setZoom(newZoomScale);
simulation.zoomScale += step
if (simulation.zoomScale >= newZoomScale) {
simulation.setZoom(newZoomScale);
return
}
} else {
game.zoomScale -= step
if (game.zoomScale <= newZoomScale) {
game.setZoom(newZoomScale);
simulation.zoomScale -= step
if (simulation.zoomScale <= newZoomScale) {
simulation.setZoom(newZoomScale);
return
}
}
game.setZoom();
simulation.setZoom();
requestAnimationFrame(zLoop);
}
}
},
zoomInFactor: 0,
startZoomIn(time = 180) {
game.zoom = 0;
simulation.zoom = 0;
let count = 0;
requestAnimationFrame(zLoop);
function zLoop() {
game.zoom += canvas.height / game.zoomScale / time;
simulation.zoom += canvas.height / simulation.zoomScale / time;
count++;
if (count < time) {
requestAnimationFrame(zLoop);
} else {
game.setZoom();
simulation.setZoom();
}
}
},
@@ -421,27 +425,27 @@ const game = {
mech.pos.x = player.position.x;
mech.pos.y = playerBody.position.y - mech.yOff;
const scale = 0.8;
mech.transSmoothX = canvas.width2 - mech.pos.x - (game.mouse.x - canvas.width2) * scale;
mech.transSmoothY = canvas.height2 - mech.pos.y - (game.mouse.y - canvas.height2) * scale;
mech.transSmoothX = canvas.width2 - mech.pos.x - (simulation.mouse.x - canvas.width2) * scale;
mech.transSmoothY = canvas.height2 - mech.pos.y - (simulation.mouse.y - canvas.height2) * scale;
mech.transX += (mech.transSmoothX - mech.transX) * 1;
mech.transY += (mech.transSmoothY - mech.transY) * 1;
},
edgeZoomOutSmooth: 1,
camera() {
//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 dy = game.mouse.y / window.innerHeight - 0.5 //y distance from mouse to window center scaled by window height
const dx = simulation.mouse.x / window.innerWidth - 0.5 //x distance from mouse to window center scaled by window width
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)
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.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
//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;
game.mouseInGame.y = (game.mouse.y - canvas.height2) / game.zoom * game.edgeZoomOutSmooth + canvas.height2 - mech.transY;
simulation.mouseInGame.x = (simulation.mouse.x - canvas.width2) / simulation.zoom * simulation.edgeZoomOutSmooth + canvas.width2 - mech.transX;
simulation.mouseInGame.y = (simulation.mouse.y - canvas.height2) / simulation.zoom * simulation.edgeZoomOutSmooth + canvas.height2 - mech.transY;
},
restoreCamera() {
ctx.restore();
@@ -455,15 +459,15 @@ const game = {
bodies[i].force.y += bodies[i].mass * magnitude;
}
}
addGravity(powerUp, game.g);
addGravity(body, game.g);
player.force.y += player.mass * game.g;
addGravity(powerUp, simulation.g);
addGravity(body, simulation.g);
player.force.y += player.mass * simulation.g;
},
firstRun: true,
splashReturn() {
game.onTitlePage = true;
simulation.onTitlePage = true;
document.getElementById("splash").onclick = function() {
game.startGame();
simulation.startGame();
};
document.getElementById("choose-grid").style.display = "none"
document.getElementById("info").style.display = "inline";
@@ -483,7 +487,7 @@ const game = {
document.body.style.cursor = "none";
document.body.style.overflow = "hidden"
}
game.onTitlePage = false;
simulation.onTitlePage = false;
document.getElementById("choose-grid").style.display = "none"
document.getElementById("build-grid").style.display = "none"
document.getElementById("info").style.display = "none";
@@ -496,7 +500,7 @@ const game = {
mech.spawn(); //spawns the player
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("basement");
level.levels.push("detours");
@@ -505,14 +509,22 @@ const game = {
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.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();
b.removeAllGuns();
game.isNoPowerUps = false;
mod.setupAllMods(); //sets mods to default values
simulation.isNoPowerUps = false;
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();
game.updateModHUD();
simulation.updateModHUD();
powerUps.totalPowerUps = 0;
powerUps.reroll.rerolls = 0;
mech.setFillColors();
@@ -520,11 +532,11 @@ const game = {
mech.maxEnergy = 1
mech.energy = 1
mech.hole.isOn = false
game.paused = false;
simulation.paused = false;
engine.timing.timeScale = 1;
game.fpsCap = game.fpsCapDefault;
game.isAutoZoom = true;
game.makeGunHUD();
simulation.fpsCap = simulation.fpsCapDefault;
simulation.isAutoZoom = true;
simulation.makeGunHUD();
mech.drop();
mech.holdingTarget = null
mech.health = 0.25;
@@ -534,58 +546,98 @@ const game = {
level.levelsCleared = 0;
//resetting difficulty
game.dmgScale = 0; //increases in level.difficultyIncrease
simulation.dmgScale = 0; //increases in level.difficultyIncrease
b.dmgScale = 1; //decreases in level.difficultyIncrease
game.accelScale = 1;
game.lookFreqScale = 1;
game.CDScale = 1;
game.difficulty = 0;
game.difficultyMode = Number(document.getElementById("difficulty-select").value)
simulation.accelScale = 1;
simulation.lookFreqScale = 1;
simulation.CDScale = 1;
simulation.difficulty = 0;
simulation.difficultyMode = Number(document.getElementById("difficulty-select").value)
build.isCustomSelection = false;
game.clearNow = true;
simulation.clearNow = true;
document.getElementById("text-log").style.opacity = 0;
document.getElementById("fade-out").style.opacity = 0;
document.title = "n-gon";
//set to default field
mech.fieldMode = 0;
game.replaceTextLog = true;
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(`${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);
// 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)
//exit testing
if (game.testing) {
game.testing = false;
game.loop = game.normalLoop
if (game.isConstructionMode) {
if (simulation.testing) {
simulation.testing = false;
simulation.loop = simulation.normalLoop
if (simulation.isConstructionMode) {
document.getElementById("construct").style.display = 'none'
}
}
game.isCheating = false
game.firstRun = false;
simulation.isCheating = false
simulation.firstRun = false;
//setup FPS cap
game.fpsInterval = 1000 / game.fpsCap;
game.then = Date.now();
simulation.fpsInterval = 1000 / simulation.fpsCap;
simulation.then = Date.now();
requestAnimationFrame(cycle); //starts game loop
},
clearNow: false,
clearMap() {
if (mod.isMineAmmoBack) {
if (tech.isMineAmmoBack) {
let count = 0;
for (i = 0, len = bullet.length; i < len; i++) { //count mines left on map
if (bullet[i].bulletType === "mine") count++
}
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun is 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
game.updateGunHUD();
simulation.updateGunHUD();
break;
}
}
}
if (mod.isMutualism && !mod.isEnergyHealth) {
if (tech.isMutualism && !tech.isEnergyHealth) {
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].isMutualismActive) {
mech.health += 0.005
@@ -595,12 +647,12 @@ const game = {
}
}
if (mod.isEndLevelPowerUp) {
if (tech.isEndLevelPowerUp) {
for (let i = 0; i < powerUp.length; i++) {
if (powerUp[i].name === "mod") {
mod.giveMod()
if (powerUp[i].name === "tech") {
tech.giveMod()
} else if (powerUp[i].name === "gun") {
if (!mod.isOneGun) b.giveGuns("random")
if (!tech.isOneGun) b.giveGuns("random")
} 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
} else {
@@ -620,7 +672,7 @@ const game = {
level.fillBG = [];
level.zones = [];
level.queryList = [];
game.drawList = [];
simulation.drawList = [];
function removeAll(array) {
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;
}
//set fps back to default
game.fpsCap = game.fpsCapDefault
game.fpsInterval = 1000 / game.fpsCap;
simulation.fpsCap = simulation.fpsCapDefault
simulation.fpsInterval = 1000 / simulation.fpsCap;
},
// getCoords: {
// //used when building maps, outputs a draw rect command to console, only works in testing mode
@@ -671,20 +723,20 @@ const game = {
// },
// out() {
// if (keys[49]) {
// game.getCoords.pos1.x = Math.round(game.mouseInGame.x / 25) * 25;
// game.getCoords.pos1.y = Math.round(game.mouseInGame.y / 25) * 25;
// simulation.getCoords.pos1.x = Math.round(simulation.mouseInGame.x / 25) * 25;
// simulation.getCoords.pos1.y = Math.round(simulation.mouseInGame.y / 25) * 25;
// }
// if (keys[50]) {
// //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;
// game.getCoords.pos2.y = Math.round(game.mouseInGame.y / 25) * 25;
// simulation.getCoords.pos2.x = Math.round(simulation.mouseInGame.x / 25) * 25;
// simulation.getCoords.pos2.y = Math.round(simulation.mouseInGame.y / 25) * 25;
// window.getSelection().removeAllRanges();
// var range = document.createRange();
// range.selectNode(document.getElementById("test"));
// window.getSelection().addRange(range);
// document.execCommand("copy");
// 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
//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, {
x: 0,
y: 0
@@ -716,31 +768,31 @@ const game = {
});
}
}
mech.damage(0.1 * game.difficultyMode);
mech.energy -= 0.1 * game.difficultyMode
mech.damage(0.1 * simulation.difficultyMode);
mech.energy -= 0.1 * simulation.difficultyMode
}
// if (mod.isEnergyDamage) {
// document.getElementById("mod-capacitor").innerHTML = `(+${(mech.energy/0.05).toFixed(0)}%)`
// if (tech.isEnergyDamage) {
// document.getElementById("tech-capacitor").innerHTML = `(+${(mech.energy/0.05).toFixed(0)}%)`
// }
// if (mod.restDamage) {
// if (tech.restDamage) {
// if (player.speed < 1) {
// document.getElementById("mod-rest").innerHTML = `(+20%)`
// document.getElementById("tech-rest").innerHTML = `(+20%)`
// } 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 (mod.isEnergyRecovery) mech.energy += mech.maxEnergy * 0.05
if (mod.isHealthRecovery) mech.addHealth(0.01 * mech.maxHealth)
if (tech.isEnergyRecovery) mech.energy += mech.maxEnergy * 0.05
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) {
let i = who.length;
while (i--) {
if (who[i].position.y > game.fallHeight) {
if (who[i].position.y > simulation.fallHeight) {
if (save) {
Matter.Body.setVelocity(who[i], {
x: 0,
@@ -766,49 +818,30 @@ const game = {
//crouch playerHead.position.y - player.position.y = 9.7 //positive
//standing playerHead.position.y - player.position.y = -30 //negative
// mech.undoCrouch()
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) {
// 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, {
// x: 0,
// 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
// });
// }
// }
// }
} 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() {
ctx.fillStyle = "#000";
if (!game.isConstructionMode) {
if (!simulation.isConstructionMode) {
// ctx.textAlign = "right";
ctx.fillText("T: exit testing mode", canvas.width / 2, canvas.height - 10);
// let line = 500;
// const x = canvas.width - 5;
// ctx.fillText("T: exit testing mode", x, line);
// line += 20;
// ctx.fillText("Y: give all mods", x, line);
// ctx.fillText("Y: give all tech", x, line);
// line += 20;
// ctx.fillText("R: teleport to mouse", x, line);
// line += 20;
@@ -823,10 +856,10 @@ const game = {
// ctx.fillText("1-7: spawn things", x, line);
}
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: {
powerUp() { //is set by Bayesian mod
powerUp() { //is set by Bayesian tech
// ctx.globalAlpha = 0.4 * Math.sin(mech.cycle * 0.15) + 0.6;
// for (let i = 0, len = powerUp.length; i < len; ++i) {
// ctx.beginPath();
@@ -899,22 +932,22 @@ const game = {
mapPath: null, //holds the path for the map to speed up drawing
setPaths() {
//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) {
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) {
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",
bodyFill: "rgba(140,140,140,0.85)", //"#999",
bodyStroke: "#222",
drawMapPath() {
ctx.fillStyle = game.draw.mapFill;
ctx.fill(game.draw.mapPath);
ctx.fillStyle = simulation.draw.mapFill;
ctx.fill(simulation.draw.mapPath);
},
body() {
ctx.beginPath();
@@ -927,9 +960,9 @@ const game = {
ctx.lineTo(vertices[0].x, vertices[0].y);
}
ctx.lineWidth = 2;
ctx.fillStyle = game.draw.bodyFill;
ctx.fillStyle = simulation.draw.bodyFill;
ctx.fill();
ctx.strokeStyle = game.draw.bodyStroke;
ctx.strokeStyle = simulation.draw.bodyStroke;
ctx.stroke();
},
cons() {
@@ -1098,14 +1131,14 @@ const game = {
},
constructMapString: [],
constructCycle() {
if (game.isConstructionMode && game.constructMouseDownPosition) {
if (simulation.isConstructionMode && simulation.constructMouseDownPosition) {
function round(num, round = 25) {
return Math.ceil(num / round) * round;
}
const x = round(game.constructMouseDownPosition.x)
const y = round(game.constructMouseDownPosition.y)
const dx = Math.max(25, round(game.mouseInGame.x) - x)
const dy = Math.max(25, round(game.mouseInGame.y) - y)
const x = round(simulation.constructMouseDownPosition.x)
const y = round(simulation.constructMouseDownPosition.y)
const dx = Math.max(25, round(simulation.mouseInGame.x) - x)
const dy = Math.max(25, round(simulation.mouseInGame.y) - y)
ctx.strokeStyle = "#000"
ctx.lineWidth = 2;
@@ -1113,39 +1146,39 @@ const game = {
}
},
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 outHTML = ""
for (let i = 0, len = game.constructMapString.length; i < len; i++) {
out += game.constructMapString[i];
outHTML += "<div>" + game.constructMapString[i] + "</div>"
for (let i = 0, len = simulation.constructMapString.length; i < len; i++) {
out += simulation.constructMapString[i];
outHTML += "<div>" + simulation.constructMapString[i] + "</div>"
}
console.log(out)
game.copyToClipBoard(out)
simulation.copyToClipBoard(out)
document.getElementById("construct").innerHTML = outHTML
},
enableConstructMode() {
game.isConstructionMode = true;
game.isAutoZoom = false;
game.zoomScale = 2600;
game.setZoom();
simulation.isConstructionMode = true;
simulation.isAutoZoom = false;
simulation.zoomScale = 2600;
simulation.setZoom();
document.body.addEventListener("mouseup", (e) => {
if (game.testing && game.constructMouseDownPosition) {
if (simulation.testing && simulation.constructMouseDownPosition) {
function round(num, round = 25) {
return Math.ceil(num / round) * round;
}
//clean up positions
const x = round(game.constructMouseDownPosition.x)
const y = round(game.constructMouseDownPosition.y)
const dx = Math.max(25, round(game.mouseInGame.x) - x)
const dy = Math.max(25, round(game.mouseInGame.y) - y)
const x = round(simulation.constructMouseDownPosition.x)
const y = round(simulation.constructMouseDownPosition.y)
const dx = Math.max(25, round(simulation.mouseInGame.x) - x)
const dy = Math.max(25, round(simulation.mouseInGame.y) - y)
if (e.which === 2) {
game.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
simulation.outputMapString(`spawn.randomMob(${x}, ${y},0.5);`);
} 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
game.outputMapString(`spawn.mapRect(${x}, ${y}, ${dx}, ${dy});`);
simulation.outputMapString(`spawn.mapRect(${x}, ${y}, ${dx}, ${dy});`);
//see map in world
spawn.mapRect(x, y, dx, dy);
@@ -1155,9 +1188,9 @@ const game = {
Matter.Body.setStatic(map[len], true); //make static
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
game.outputMapString(`spawn.bodyRect(${x}, ${y}, ${dx}, ${dy});`);
simulation.outputMapString(`spawn.bodyRect(${x}, ${y}, ${dx}, ${dy});`);
//see map in world
spawn.bodyRect(x, y, dx, dy);
@@ -1169,32 +1202,32 @@ const game = {
}
}
}
game.constructMouseDownPosition.x = undefined
game.constructMouseDownPosition.y = undefined
simulation.constructMouseDownPosition.x = undefined
simulation.constructMouseDownPosition.y = undefined
});
game.constructMouseDownPosition.x = undefined
game.constructMouseDownPosition.y = undefined
simulation.constructMouseDownPosition.x = undefined
simulation.constructMouseDownPosition.y = undefined
document.body.addEventListener("mousedown", (e) => {
if (game.testing) {
game.constructMouseDownPosition.x = game.mouseInGame.x
game.constructMouseDownPosition.y = game.mouseInGame.y
if (simulation.testing) {
simulation.constructMouseDownPosition.x = simulation.mouseInGame.x
simulation.constructMouseDownPosition.y = simulation.mouseInGame.y
}
});
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 (game.constructMapString[game.constructMapString.length - 1][6] === 'm') { //remove map from current level
if (simulation.testing && e.keyCode === 90 && simulation.constructMapString.length) {
if (simulation.constructMapString[simulation.constructMapString.length - 1][6] === 'm') { //remove map from current level
const index = map.length - 1
Matter.World.remove(engine.world, map[index]);
map.splice(index, 1);
game.draw.setPaths() //update map graphics
} else if (game.constructMapString[game.constructMapString.length - 1][6] === 'b') { //remove body from current level
simulation.draw.setPaths() //update map graphics
} else if (simulation.constructMapString[simulation.constructMapString.length - 1][6] === 'b') { //remove body from current level
const index = body.length - 1
Matter.World.remove(engine.world, body[index]);
body.splice(index, 1);
}
game.constructMapString.pop();
game.outputMapString();
simulation.constructMapString.pop();
simulation.outputMapString();
}
});
}

View File

@@ -28,7 +28,7 @@ const spawn = {
spawn.pickList.push(spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]);
},
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) {
if (spawn.spawnChance(chance) || chance === Infinity) {
@@ -37,7 +37,7 @@ const spawn = {
}
},
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),
chance = 1) {
if (spawn.spawnChance(chance)) {
@@ -48,7 +48,7 @@ const spawn = {
}
},
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
let pick = this.pickList[Math.floor(Math.random() * this.pickList.length)];
//is the pick able to be a boss?
@@ -102,7 +102,7 @@ const spawn = {
level.exit.x = 5500;
level.exit.y = -330;
//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
@@ -121,7 +121,7 @@ const spawn = {
//draw stuff
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,
y: this.position.y,
radius: (i + 1) * 150,
@@ -219,9 +219,9 @@ const spawn = {
});
}
if (game.difficulty > 60) {
if (simulation.difficulty > 60) {
spawn.randomLevelBoss(3000, -1100)
if (game.difficulty > 100) {
if (simulation.difficulty > 100) {
spawn.randomLevelBoss(3000, -1300)
}
}
@@ -231,7 +231,7 @@ const spawn = {
me.eventHorizonCycleRate = 4 * Math.PI / me.endCycle
me.modeSuck = function() {
//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
ctx.beginPath();
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 (mech.energy > 0) mech.energy -= 0.01
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);
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
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();
this.laser(this.vertices[0], this.angle + 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.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) {
for (let i = 0; i < domain.length; ++i) {
let vertices = domain[i].vertices;
const len = vertices.length - 1;
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) {
const dx = v1.x - results.x;
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) {
const dx = v1.x - results.x;
const dy = v1.y - results.y;
@@ -385,9 +385,9 @@ const spawn = {
vertexCollision(where, look, body);
if (!mech.isCloak) vertexCollision(where, look, [player]);
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);
game.drawList.push({ //add dmg to draw queue
simulation.drawList.push({ //add dmg to draw queue
x: best.x,
y: best.y,
radius: dmg * 1500,
@@ -412,7 +412,7 @@ const spawn = {
mobs.spawn(x, y, 4, radius, "#777");
let me = mob[mob.length - 1];
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.groupingRangeMin = (radius * 8) * (radius * 8);
me.groupingStrength = 0.0005
@@ -454,7 +454,7 @@ const spawn = {
mobs.spawn(x, y, 8, radius, "#9ccdc6");
let me = mob[mob.length - 1];
// console.log(`mass=${me.mass}, radius = ${radius}`)
me.accelMag = 0.0005 * game.accelScale;
me.accelMag = 0.0005 * simulation.accelScale;
me.memory = 60;
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
@@ -475,7 +475,7 @@ const spawn = {
let me = mob[mob.length - 1];
me.isBoss = true;
me.isCell = true;
me.accelMag = 0.00015 * game.accelScale;
me.accelMag = 0.00015 * simulation.accelScale;
me.memory = 40;
me.isVerticesChange = true
me.frictionAir = 0.012
@@ -511,7 +511,7 @@ const spawn = {
Matter.Body.scale(this, scale, scale);
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 attractRange = 800
for (let i = 0, len = mob.length; i < len; i++) {
@@ -548,7 +548,7 @@ const spawn = {
me.isBoss = true;
me.frictionAir = 0.01
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
me.collisionFilter.mask = cat.bullet | cat.player
me.memory = Infinity;
@@ -583,7 +583,7 @@ const spawn = {
}
};
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
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
me.friction = 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.memory = 50;
spawn.shield(me, x, y);
@@ -622,7 +622,7 @@ const spawn = {
let me = mob[mob.length - 1];
me.isVerticesChange = true
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.onDeath = function () { //helps collisions functions work better after vertex have been changed
// this.vertices = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices))
@@ -641,7 +641,7 @@ const spawn = {
me.frictionAir = 0.006;
me.lookTorque = 0.0000008; //controls spin while looking for player
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 springDampening = 0.0005;
@@ -695,17 +695,17 @@ const spawn = {
me.g = 0.0017; //required if using 'gravity'
me.frictionAir = 0.01;
me.restitution = 0;
me.delay = 120 * game.CDScale;
me.delay = 120 * simulation.CDScale;
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);
me.do = function() {
this.gravity();
this.seePlayerCheck();
this.checkStatus();
if (this.seePlayer.recall) {
if (this.cd < game.cycle && (Matter.Query.collides(this, map).length || Matter.Query.collides(this, body).length)) {
this.cd = game.cycle + this.delay;
if (this.cd < simulation.cycle && (Matter.Query.collides(this, map).length || Matter.Query.collides(this, body).length)) {
this.cd = simulation.cycle + this.delay;
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);
this.force.x += forceMag * Math.cos(angle);
@@ -713,8 +713,8 @@ const spawn = {
}
} else {
//randomly hob if not aware of player
if (this.randomHopCD < game.cycle && (Matter.Query.collides(this, map).length || Matter.Query.collides(this, body).length)) {
this.randomHopCD = game.cycle + this.randomHopFrequency;
if (this.randomHopCD < simulation.cycle && (Matter.Query.collides(this, map).length || Matter.Query.collides(this, body).length)) {
this.randomHopCD = simulation.cycle + this.randomHopFrequency;
//slowly change randomHopFrequency after each hop
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);
@@ -742,9 +742,9 @@ const spawn = {
me.look = function() {
this.seePlayerByLookingAt();
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.cd = game.cycle + 40;
this.cd = simulation.cycle + 40;
this.do = this.spin
}
}
@@ -766,9 +766,9 @@ const spawn = {
ctx.lineTo(dir.x, dir.y);
ctx.stroke();
ctx.setLineDash([]);
if (this.cd < game.cycle) {
if (this.cd < simulation.cycle) {
this.fill = this.rememberFill;
this.cd = game.cycle + 180 * game.CDScale
this.cd = simulation.cycle + 180 * simulation.CDScale
this.do = this.look
this.force = Vector.mult(this.burstDir, this.mass * 0.25);
}
@@ -781,7 +781,7 @@ const spawn = {
me.stroke = "transparent"; //used for drawSneaker
me.eventHorizon = radius * 23; //required for blackhole
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.collisionFilter.mask = cat.player | cat.bullet
me.memory = Infinity;
@@ -795,7 +795,7 @@ const spawn = {
});
}
// this.seePlayerCheckByDistance()
if (!(game.cycle % this.seePlayerFreq)) {
if (!(simulation.cycle % this.seePlayerFreq)) {
if (this.distanceToPlayer2() < this.seeAtDistance2) { //&& !mech.isCloak ignore cloak for black holes
this.locatePlayer();
if (!this.seePlayer.yes) this.seePlayer.yes = true;
@@ -806,7 +806,7 @@ const spawn = {
this.checkStatus();
if (this.seePlayer.recall) {
//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
const forceMag = this.accelMag * this.mass;
@@ -832,7 +832,7 @@ const spawn = {
if (Vector.magnitude(Vector.sub(this.position, player.position)) < eventHorizon) {
if (mech.energy > 0) mech.energy -= 0.004
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);
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.eventHorizon = 1100; //required for black hole
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.frictionAir = 0.005;
me.memory = 1600;
@@ -867,7 +867,7 @@ const spawn = {
me.onDeath = function() {
//applying forces to player doesn't seem to work inside this method, not sure why
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
if (game.difficulty > 5) {
if (simulation.difficulty > 5) {
//teleport everything to center
function toMe(who, where, range) {
for (let i = 0, len = who.length; i < len; i++) {
@@ -891,7 +891,7 @@ const spawn = {
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
this.locatePlayer();
if (!this.seePlayer.yes) this.seePlayer.yes = true;
@@ -910,7 +910,7 @@ const spawn = {
this.force.y += forceMag * dy / mag;
//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
//draw darkness
@@ -938,7 +938,7 @@ const spawn = {
if (Vector.magnitude(Vector.sub(this.position, player.position)) < eventHorizon) {
if (mech.energy > 0) mech.energy -= 0.006
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);
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.lookTorque = 0.0000008; //controls spin while looking for player
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 springDampening = 0.0005;
@@ -1053,11 +1053,11 @@ const spawn = {
me.timeSkipLastCycle = 0
me.eventHorizon = 1800; //required for black hole
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.memory = 1600;
// 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);
@@ -1076,12 +1076,12 @@ const spawn = {
this.seePlayerCheck();
this.checkStatus();
this.attraction()
if (!game.isTimeSkipping) {
if (!simulation.isTimeSkipping) {
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) {
this.timeSkipLastCycle = game.cycle
game.timeSkip(compress)
this.timeSkipLastCycle = simulation.cycle
simulation.timeSkip(compress)
this.fill = `rgba(0,0,0,${0.4+0.6*Math.random()})`
this.stroke = "#014"
@@ -1132,7 +1132,7 @@ const spawn = {
let me = mob[mob.length - 1];
me.repulsionRange = 73000; //squared
me.laserRange = 370;
me.accelMag = 0.0005 * game.accelScale;
me.accelMag = 0.0005 * simulation.accelScale;
me.frictionStatic = 0;
me.friction = 0;
spawn.shield(me, x, y);
@@ -1153,7 +1153,7 @@ const spawn = {
me.restitution = 0;
me.laserPos = me.position; //required for laserTracking
me.repulsionRange = 1200000; //squared
me.accelMag = 0.00009 * game.accelScale;
me.accelMag = 0.00009 * simulation.accelScale;
me.frictionStatic = 0;
me.friction = 0;
me.onDamage = function() {
@@ -1216,8 +1216,8 @@ const spawn = {
me.isBoss = true;
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);
me.accelMag = 0.0002 * Math.sqrt(game.accelScale);
me.seePlayerFreq = Math.floor(30 * game.lookFreqScale);
me.accelMag = 0.0002 * Math.sqrt(simulation.accelScale);
me.seePlayerFreq = Math.floor(30 * simulation.lookFreqScale);
me.memory = 420;
me.restitution = 1;
me.frictionAir = 0.01;
@@ -1247,7 +1247,7 @@ const spawn = {
if (this.seePlayer.recall) {
//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.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;
const len = vertices.length - 1;
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) {
const dx = v1.x - results.x;
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) {
const dx = v1.x - results.x;
const dy = v1.y - results.y;
@@ -1327,7 +1327,7 @@ const spawn = {
// hitting player
if (best.who === player) {
if (mech.immuneCycle < mech.cycle) {
const dmg = 0.001 * game.dmgScale;
const dmg = 0.001 * simulation.dmgScale;
mech.damage(dmg);
//draw damage
ctx.fillStyle = color;
@@ -1356,7 +1356,7 @@ const spawn = {
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
Matter.Body.rotate(me, Math.random() * Math.PI * 2);
me.accelMag = 0.00007 * game.accelScale;
me.accelMag = 0.00007 * simulation.accelScale;
me.onHit = function() {
//run this function on hitting player
this.explode();
@@ -1384,7 +1384,7 @@ const spawn = {
me.onDeath = function() {
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() {
this.fill = '#' + Math.random().toString(16).substr(-6); //flash colors
this.checkStatus();
@@ -1433,7 +1433,7 @@ const spawn = {
let vertices = domain[i].vertices;
const len = vertices.length - 1;
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) {
const dx = v1.x - results.x;
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) {
const dx = v1.x - results.x;
const dy = v1.y - results.y;
@@ -1483,10 +1483,10 @@ const spawn = {
vertexCollision(where, look, body);
if (!mech.isCloak) vertexCollision(where, look, [player]);
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
const dmg = 0.14 * game.dmgScale;
mech.immuneCycle = mech.cycle + tech.collisionImmuneCycles; //player is immune to collision damage for 30 cycles
const dmg = 0.14 * simulation.dmgScale;
mech.damage(dmg);
game.drawList.push({ //add dmg to draw queue
simulation.drawList.push({ //add dmg to draw queue
x: best.x,
y: best.y,
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)
let me = mob[mob.length - 1];
me.isVerticesChange = true
me.accelMag = 0.0006 * game.accelScale;
me.accelMag = 0.0006 * simulation.accelScale;
// me.g = 0.0002; //required if using 'gravity'
me.delay = 360 * game.CDScale;
me.delay = 360 * simulation.CDScale;
me.spikeVertex = 0;
me.spikeLength = 0;
me.isSpikeGrowing = false;
@@ -1582,20 +1582,20 @@ const spawn = {
striker(x, y, radius = 14 + Math.ceil(Math.random() * 25)) {
mobs.spawn(x, y, 5, radius, "rgb(221,102,119)");
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.frictionStatic = 0;
me.friction = 0;
me.delay = 90 * game.CDScale;
me.delay = 90 * simulation.CDScale;
me.cd = Infinity;
Matter.Body.rotate(me, Math.PI * 0.1);
spawn.shield(me, x, y);
me.onDamage = function() {
this.cd = game.cycle + this.delay;
this.cd = simulation.cycle + this.delay;
};
me.do = function() {
this.gravity();
if (!(game.cycle % this.seePlayerFreq)) { // this.seePlayerCheck(); from mobs
if (!(simulation.cycle % this.seePlayerFreq)) { // this.seePlayerCheck(); from mobs
if (
this.distanceToPlayer2() < this.seeAtDistance2 &&
Matter.Query.ray(map, this.position, this.mechPosRange()).length === 0 &&
@@ -1603,7 +1603,7 @@ const spawn = {
!mech.isCloak
) {
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) {
this.lostPlayer();
this.cd = Infinity
@@ -1611,11 +1611,11 @@ const spawn = {
}
this.checkStatus();
this.attraction();
if (this.cd < game.cycle) {
if (this.cd < simulation.cycle) {
if (this.seePlayer.recall) {
const dist = Vector.sub(this.seePlayer.position, this.position);
const distMag = Vector.magnitude(dist);
this.cd = game.cycle + this.delay;
this.cd = simulation.cycle + this.delay;
ctx.beginPath();
ctx.moveTo(this.position.x, this.position.y);
if (distMag < 400) {
@@ -1639,7 +1639,7 @@ const spawn = {
let me;
mobs.spawn(x, y, 5, radius, "transparent");
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.stroke = "transparent"; //used for drawSneaker
me.alpha = 1; //used in drawSneaker
@@ -1690,7 +1690,7 @@ const spawn = {
mobs.spawn(x, y, 7, radius, "transparent");
me = mob[mob.length - 1];
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
Matter.Body.setDensity(me, 0.00065); //normal is 0.001 //makes effective life much lower
me.stroke = "transparent"; //used for drawGhost
@@ -1753,7 +1753,7 @@ const spawn = {
// me.blinkLength = 150 + Math.round(Math.random() * 200); //required for blink
// me.isStatic = true;
// 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.scaleMag = Math.max(5 - me.mass, 1.75);
// me.onDeath = function () {
@@ -1763,23 +1763,23 @@ const spawn = {
// // }
// };
// me.onHit = function () {
// game.timeSkip(120)
// simulation.timeSkip(120)
// };
// me.do = function () {
// this.seePlayerCheck();
// this.blink();
// //strike by expanding
// // 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);
// // this.isBig = false;
// // }
// // } 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 distMag2 = Vector.magnitudeSquared(dist);
// if (distMag2 < 80000) {
// this.cd = game.cycle + this.delay;
// this.cd = simulation.cycle + this.delay;
// // Matter.Body.scale(this, this.scaleMag, this.scaleMag);
// // this.isBig = true;
@@ -1792,15 +1792,15 @@ const spawn = {
mobs.spawn(x, y, 3, radius, "transparent");
let me = mob[mob.length - 1];
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.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.hoverElevation = 460 + (Math.random() - 0.5) * 200; //squared
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.frictionStatic = 0;
me.friction = 0;
@@ -1834,7 +1834,7 @@ const spawn = {
me.fireFreq = 0.007 + Math.random() * 0.005;
me.noseLength = 0;
me.fireAngle = 0;
me.accelMag = 0.0005 * game.accelScale;
me.accelMag = 0.0005 * simulation.accelScale;
me.frictionStatic = 0;
me.friction = 0;
me.frictionAir = 0.05;
@@ -1867,14 +1867,14 @@ const spawn = {
me.fireFreq = 0.025;
me.noseLength = 0;
me.fireAngle = 0;
me.accelMag = 0.005 * game.accelScale;
me.accelMag = 0.005 * simulation.accelScale;
me.frictionAir = 0.05;
me.lookTorque = 0.000007 * (Math.random() > 0.5 ? -1 : 1);
me.fireDir = {
x: 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() {
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
@@ -1921,7 +1921,7 @@ const spawn = {
this.explode(this.mass * 120);
};
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);
@@ -1983,7 +1983,7 @@ const spawn = {
me.fireFreq = 0.006 + Math.random() * 0.002;
me.noseLength = 0;
me.fireAngle = 0;
me.accelMag = 0.0005 * game.accelScale;
me.accelMag = 0.0005 * simulation.accelScale;
me.frictionAir = 0.05;
me.torque = 0.0001 * me.inertia;
me.fireDir = {
@@ -2008,7 +2008,7 @@ const spawn = {
//throw a mob/bullet at player
if (this.seePlayer.recall) {
//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.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) {
//fire
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], {
x: this.velocity.x + this.fireDir.x * 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)) {
mobs.spawn(x, y, 3, radius, "rgb(150,150,255)");
let me = mob[mob.length - 1];
me.accelMag = 0.00004 * game.accelScale;
me.fireFreq = Math.floor(420 + 90 * Math.random() * game.CDScale)
me.accelMag = 0.00004 * simulation.accelScale;
me.fireFreq = Math.floor(420 + 90 * Math.random() * simulation.CDScale)
me.frictionStatic = 0;
me.friction = 0;
me.frictionAir = 0.02;
@@ -2115,7 +2115,7 @@ const spawn = {
this.seePlayerCheck();
this.checkStatus();
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)
//fire a bullet from each vertex
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)");
let me = mob[mob.length - 1];
me.isBoss = true;
me.accelMag = 0.00008 * game.accelScale;
me.fireFreq = Math.floor(360 * game.CDScale)
me.accelMag = 0.00008 * simulation.accelScale;
me.fireFreq = Math.floor(360 * simulation.CDScale)
me.frictionStatic = 0;
me.friction = 0;
me.frictionAir = 0.02;
me.memory = 420;
me.repulsionRange = 1200000; //squared
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() {
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
@@ -2153,7 +2153,7 @@ const spawn = {
this.checkStatus();
this.attraction();
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)
//fire a bullet from each vertex
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)");
let me = mob[mob.length - 1];
me.isBoss = true;
// me.accelMag = 0.00023 * game.accelScale;
me.accelMag = 0.00008 * game.accelScale;
// me.fireFreq = Math.floor(30 * game.CDScale)
// me.accelMag = 0.00023 * simulation.accelScale;
me.accelMag = 0.00008 * simulation.accelScale;
// me.fireFreq = Math.floor(30 * simulation.CDScale)
me.canFire = false;
me.closestVertex1 = 0;
me.closestVertex2 = 1;
@@ -2255,7 +2255,7 @@ const spawn = {
};
Matter.Body.setDensity(me, 0.000015); //normal is 0.001
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.restitution = 0.5;
me.leaveBody = false;
@@ -2302,10 +2302,10 @@ const spawn = {
};
Matter.Body.setDensity(me, 0.0005); //normal is 0.001
me.g = 0.0001; //required if using 'gravity'
me.accelMag = 0.0003 * game.accelScale;
me.accelMag = 0.0003 * simulation.accelScale;
me.memory = 30;
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.do = function() {
this.gravity();
@@ -2333,10 +2333,10 @@ const spawn = {
mobs.spawn(x, y, 8, radius, "rgb(55,170,170)");
let me = mob[mob.length - 1];
me.isBoss = true;
me.accelMag = 0.00075 * game.accelScale;
me.accelMag = 0.00075 * simulation.accelScale;
me.memory = 250;
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);
me.onDeath = function() {
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
@@ -2356,7 +2356,7 @@ const spawn = {
};
//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);
//constraint boss with first 3 mobs in lineboss
consBB[consBB.length] = Constraint.create({
@@ -2387,7 +2387,7 @@ const spawn = {
// this.explode();
// };
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.frictionAir = 0.02;
me.isSnakeTail = true;
@@ -2418,9 +2418,9 @@ const spawn = {
let me = mob[mob.length - 1];
me.isBoss = true;
me.g = 0.0001; //required if using 'gravity'
me.accelMag = 0.002 * game.accelScale;
me.accelMag = 0.002 * simulation.accelScale;
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);
me.onDeath = function() {
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
@@ -2433,7 +2433,7 @@ const spawn = {
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) {
mobs.spawn(x, y, 9, target.radius + 30, "rgba(220,220,255,0.9)");
let me = mob[mob.length - 1];
@@ -2526,8 +2526,8 @@ const spawn = {
x,
y,
spawn = "striker",
nodes = Math.min(2 + Math.ceil(Math.random() * (game.difficulty + 2)), 8),
//Math.ceil(Math.random() * 3) + Math.min(4,Math.ceil(game.difficulty/2)),
nodes = Math.min(2 + Math.ceil(Math.random() * (simulation.difficulty + 2)), 8),
//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
sideLength = Math.ceil(Math.random() * 100) + 70, // distance between each node mob
stiffness = Math.random() * 0.03 + 0.005
@@ -2560,8 +2560,8 @@ const spawn = {
x,
y,
spawn = "striker",
nodes = Math.min(3 + Math.ceil(Math.random() * game.difficulty + 2), 8),
//Math.ceil(Math.random() * 3) + Math.min(4,Math.ceil(game.difficulty/2)),
nodes = Math.min(3 + Math.ceil(Math.random() * simulation.difficulty + 2), 8),
//Math.ceil(Math.random() * 3) + Math.min(4,Math.ceil(simulation.difficulty/2)),
radius = Math.ceil(Math.random() * 10) + 17,
l = Math.ceil(Math.random() * 80) + 30,
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;
}
em {
opacity: 0.7;
}
#splash {
user-select: none;
position: absolute;
@@ -272,11 +276,11 @@ summary {
background-color: hsl(218, 100%, 76%);
}
.build-mod-selected {
.build-tech-selected {
background-color: hsl(253, 100%, 84%);
}
.build-mod-selected:hover {
.build-tech-selected:hover {
background-color: hsl(253, 100%, 81%);
}
@@ -313,7 +317,7 @@ summary {
width: 100%;
height: 100%;
display: none;
/* background-color also set in mass-energy mod */
/* background-color also set in mass-energy tech */
background-color: #f67;
opacity: 0;
transition: opacity 1s;
@@ -376,8 +380,9 @@ summary {
left: 15px;
z-index: 2;
font-size: 23px;
color: #111;
color: #222;
background-color: rgba(255, 255, 255, 0.4);
line-height: 120%;
user-select: none;
pointer-events: none;
padding: 0px 5px 0px 5px;
@@ -394,7 +399,7 @@ summary {
color: #000;
text-align: right;
opacity: 0.7;
line-height: 140%;
/* line-height: 140%; */
background-color: rgba(190, 210, 245, 0.25);
user-select: none;
pointer-events: none;
@@ -403,16 +408,16 @@ summary {
/*border: 2px solid rgba(0, 0, 0, 0.4);*/
}
#mods {
#tech {
position: absolute;
top: 60px;
right: 15px;
z-index: 2;
font-size: 20px;
color: #000;
color: #222;
text-align: right;
opacity: 0.35;
line-height: 140%;
line-height: 130%;
background-color: rgba(255, 255, 255, 0.4);
user-select: none;
pointer-events: none;
@@ -424,28 +429,67 @@ summary {
#text-log {
z-index: 2;
position: absolute;
bottom: 20px;
left: 20px;
bottom: 10px;
left: 10px;
padding: 10px;
border-radius: 10px;
line-height: 150%;
font-size: 1.25em;
color: #000;
background-color: rgba(255, 255, 255, 0.23);
opacity: 0;
border-radius: 4px;
line-height: 140%;
font-size: 1.15em;
color: #555;
background-color: rgba(255, 255, 255, 0.5);
transition: opacity 0.5s;
pointer-events: none;
user-select: none;
}
em {
opacity: 0.7;
/* color for in game console output */
.color-text {
color: #000;
}
.mouse-icon {
margin-bottom: -20px;
.color-var {
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: #0ad;
letter-spacing: 1px;
@@ -565,7 +609,7 @@ em {
margin-bottom: -15px;
}
.circle-gun-mod {
.circle-gun-tech {
box-shadow: 0 0 0 3px #025;
}
@@ -583,7 +627,7 @@ em {
background: #0cf;
}
.mod {
.tech {
/* background: rgb(116, 102, 238); */
/* background: hsl(253, 57%, 52%); */
background: hsl(255, 100%, 71%);
@@ -607,9 +651,7 @@ em {
background: #f7b;
}
.dice {
font-size: 45px;
vertical-align: -5px;
.reroll-select {
float: right;
}

View File

@@ -1,16 +1,17 @@
******************************************************** NEXT PATCH ********************************************************
added a crouch check to prevent move the head when it's already out of position
also using setPosition to move player head instead of translate
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
******************************************************** BUGS ********************************************************
check for crouch after rewind
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) 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
maybe move the fix to once a second?
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
@@ -37,8 +39,31 @@ mod and mob are too similar
******************************************************** 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?
mod nail gun: slow and accurate
mod foam: fast and inaccurate
mob ability bombs/bullets that suck in player
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
or at least vertical space
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
@@ -387,40 +414,36 @@ AI doesn't know about:
modern pop culture
outside the lab
in game console
output all console.log code //find starter code for this at the end of index.js
style
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**
scientist console text:
2 scientists (each one a different color text)
at the start of each level listen to text conversation from the two colors of text strings also
talking about the robot, watching
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
Why is it attacking those shapes?
Are those shapes supposed to be us?
add an ending to the game
maybe the game ending should ask you to open the console and type in some commands like in the end of doki doki
mirror ending (if no cheats)
level after final boss battle is the intro level, but flipped left right, with a fake player
damage the fake player to end the game
message about go outside
no ending (if cheats)
game goes on forever
also game goes on if player attacks, the fake player
game never ends if you have used cheats
ending outline
if no cheats
after final boss is cleared, player enters a level with no mobs
level maybe has some environmental damage, so player has an option to die at any time
player can see text output between two colors of text strings (scientists)
audio.ambient(current time and date)<br> "text"
player reads a conversation between the two colors of text
first time win on east or normal they talk about:
how many runs the player has done
they guess why
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