difficulty

difficulty rework
  difficulty adjusted through a power up on the initial level
  difficulty parameters are more precisely explained
  JUNK tech: difficulty - spawns a difficulty power up (only works before level 6)

bots no longer benefit from increased fireRate
shields have a chance spawn on almost all mobs (but not stealth mobs)
level exit door animation is 33% faster
power ups have fewer sides.  It might improve game performance, but I can't tell the difference.
1.15x base wave bullets damage (bots, particles, and phonon)
metamaterial absorber 25->30% chance to get power ups from mobs left alive
apomixis is now a JUNK tech, and it requires duplication > 99%
pilot wave field 2->3 extra choices
plasma torch slows mobs more, and don't push mobs back as much
  fixed bug where plasma torch didn't get tech degenerate matter
laserLayerBoss and layerLayer do 33% less damage
mines aren't triggered by invulnerable mobs

bug fixes
This commit is contained in:
landgreen
2024-06-02 21:43:42 -07:00
parent 507b0605d6
commit 63bfaba4a1
12 changed files with 1082 additions and 734 deletions

View File

@@ -1,7 +1,7 @@
let bullet = [];
const b = {
// dmgScale: null, //scales all damage, but not raw .dmg //set in levels.setDifficulty
// dmgScale: null, //scales all damage, but not raw .dmg
gravity: 0.0006, //most other bodies have gravity = 0.001
activeGun: null, //current gun in use by player
inventoryGun: 0,
@@ -2313,13 +2313,14 @@ const b = {
best.who.locatePlayer();
//push mobs away
const force = Vector.mult(Vector.normalise(Vector.sub(m.pos, path[1])), -0.01 * Math.min(5, best.who.mass))
Matter.Body.applyForce(best.who, path[1], force)
if (best.who.speed > 4) {
Matter.Body.setVelocity(best.who, { //friction
x: best.who.velocity.x * 0.9,
y: best.who.velocity.y * 0.9
});
if (best.who.speed > 3) {
const force = Vector.mult(Vector.normalise(Vector.sub(m.pos, path[1])), -0.005 * Math.min(5, best.who.mass))
Matter.Body.applyForce(best.who, path[1], force)
Matter.Body.setVelocity(best.who, { x: best.who.velocity.x * 0.4, y: best.who.velocity.y * 0.4 });
} else {
const force = Vector.mult(Vector.normalise(Vector.sub(m.pos, path[1])), -0.01 * Math.min(5, best.who.mass))
Matter.Body.applyForce(best.who, path[1], force)
Matter.Body.setVelocity(best.who, { x: best.who.velocity.x * 0.7, y: best.who.velocity.y * 0.7 });
}
//draw mob damage circle
simulation.drawList.push({
@@ -2702,28 +2703,13 @@ const b = {
this.lookFrequency = 55 + Math.floor(22 * Math.random())
simulation.drawList.push({ x: this.position.x, y: this.position.y, radius: 10, color: "#f00", time: 4 });
this.do = function () { //overwrite the do method for this bullet
//make mobs think the mine is where the player is
// for (let i = 0; i < mob.length; i++) {
// mob[i].seePlayer.recall = mob[i].memory + Math.round(mob[i].memory * Math.random()); //cycles before mob falls a sleep
// mob[i].seePlayer.position.x = this.position.x;
// mob[i].seePlayer.position.y = this.position.y;
// mob[i].seePlayer.yes = true;
// }
this.force.y += this.mass * 0.002; //extra gravity
if (!(simulation.cycle % this.lookFrequency)) { //find mob targets
const random = 300 * Math.random()
for (let i = 0, len = mob.length; i < len; ++i) {
if (
!mob[i].isBadTarget &&
!mob[i].isInvulnerable &&
Vector.magnitude(Vector.sub(this.position, mob[i].position)) < this.range + mob[i].radius + random &&
Matter.Query.ray(map, this.position, mob[i].position).length === 0 &&
Matter.Query.ray(body, this.position, mob[i].position).length === 0
@@ -4892,7 +4878,7 @@ const b = {
minDmgSpeed: 2,
// lookFrequency: 56 + Math.floor(17 * Math.random()) - isUpgraded * 20,
lastLookCycle: simulation.cycle + 60 * Math.random(),
delay: Math.floor((tech.isNailBotUpgrade ? 18 : 85) * b.fireCDscale),
delay: Math.floor((tech.isNailBotUpgrade ? 18 : 85)),
acceleration: (isKeep ? 0.005 : 0.001) * (1 + 0.5 * Math.random()),
range: 60 * (1 + 0.3 * Math.random()) + 3 * b.totalBots() + !isKeep * 100,
endCycle: Infinity,
@@ -4954,7 +4940,7 @@ const b = {
minDmgSpeed: 2,
lookFrequency: 26 + Math.ceil(6 * Math.random()),
cd: 0,
delay: Math.floor(60 * b.fireCDscale),
delay: Math.floor(60),
range: 70 + 3 * b.totalBots(),
endCycle: Infinity,
classType: "bullet",
@@ -5030,7 +5016,7 @@ const b = {
cd: 0,
fireCount: 0,
fireLimit: 5 + 2 * tech.isFoamBotUpgrade,
delay: Math.floor((145 + (tech.isFoamBotUpgrade ? 0 : 230)) * b.fireCDscale),// + 30 - 20 * tech.isFoamBotUpgrade,//20 + Math.floor(85 * b.fireCDscale) - 20 * tech.isFoamBotUpgrade,
delay: Math.floor((145 + (tech.isFoamBotUpgrade ? 0 : 230))),// + 30 - 20 * tech.isFoamBotUpgrade,//20 + Math.floor(85 * b.fireCDscale) - 20 * tech.isFoamBotUpgrade,
acceleration: (isKeep ? 0.005 : 0.001) * (1 + 0.5 * Math.random()),
range: 60 * (1 + 0.3 * Math.random()) + 3 * b.totalBots() + !isKeep * 100, //how far from the player the bot will move
endCycle: Infinity,
@@ -5150,7 +5136,7 @@ const b = {
cd: 0,
fireCount: 0,
fireLimit: 5 + 2 * tech.isSoundBotUpgrade,
delay: Math.floor((120 + (tech.isSoundBotUpgrade ? 0 : 70)) * b.fireCDscale),// + 30 - 20 * tech.isFoamBotUpgrade,//20 + Math.floor(85 * b.fireCDscale) - 20 * tech.isFoamBotUpgrade,
delay: Math.floor((120 + (tech.isSoundBotUpgrade ? 0 : 70))),// + 30 - 20 * tech.isFoamBotUpgrade,//20 + Math.floor(85 * b.fireCDscale) - 20 * tech.isFoamBotUpgrade,
acceleration: (isKeep ? 0.005 : 0.001) * (1 + 0.5 * Math.random()),
range: 60 * (1 + 0.3 * Math.random()) + 3 * b.totalBots() + !isKeep * 100, //how far from the player the bot will move
endCycle: Infinity,
@@ -5646,8 +5632,19 @@ const b = {
best.who.damage(dmg);
best.who.locatePlayer();
//push mobs away
const force = Vector.mult(Vector.normalise(Vector.sub(m.pos, path[1])), -0.007 * Math.min(5, best.who.mass))
Matter.Body.applyForce(best.who, path[1], force)
// const force = Vector.mult(Vector.normalise(Vector.sub(m.pos, path[1])), -0.007 * Math.min(5, best.who.mass))
// Matter.Body.applyForce(best.who, path[1], force)
//push mobs away
if (best.who.speed > 3) {
const force = Vector.mult(Vector.normalise(Vector.sub(m.pos, path[1])), -0.005 * Math.min(5, best.who.mass))
Matter.Body.applyForce(best.who, path[1], force)
Matter.Body.setVelocity(best.who, { x: best.who.velocity.x * 0.4, y: best.who.velocity.y * 0.4 });
} else {
const force = Vector.mult(Vector.normalise(Vector.sub(m.pos, path[1])), -0.01 * Math.min(5, best.who.mass))
Matter.Body.applyForce(best.who, path[1], force)
Matter.Body.setVelocity(best.who, { x: best.who.velocity.x * 0.7, y: best.who.velocity.y * 0.7 });
}
if (best.who.speed > 2.5) Matter.Body.setVelocity(best.who, { x: best.who.velocity.x * 0.75, y: best.who.velocity.y * 0.75 });
//draw mob damage circle
if (best.who.damageReduction) {
@@ -7752,10 +7749,7 @@ const b = {
}
let speed = 36
if (Matter.Query.point(map, pos).length > 0) speed = -2 //don't launch if mine will spawn inside map
b.mine(pos, {
x: speed * Math.cos(m.angle),
y: speed * Math.sin(m.angle)
}, 0)
b.mine(pos, { x: speed * Math.cos(m.angle), y: speed * Math.sin(m.angle) }, 0)
m.fireCDcycle = m.cycle + Math.floor(55 * b.fireCDscale); // cool down
}
} else {
@@ -7765,10 +7759,7 @@ const b = {
}
let speed = 23
if (Matter.Query.point(map, pos).length > 0) speed = -2 //don't launch if mine will spawn inside map
b.mine(pos, {
x: speed * Math.cos(m.angle),
y: speed * Math.sin(m.angle)
}, 0)
b.mine(pos, { x: speed * Math.cos(m.angle), y: speed * Math.sin(m.angle) }, 0)
m.fireCDcycle = m.cycle + Math.floor(35 * b.fireCDscale); // cool down
}
}
@@ -7809,11 +7800,6 @@ const b = {
ctx.arc(m.pos.x, m.pos.y, 60, this.angle - this.arcRange, this.angle + this.arcRange);
ctx.strokeStyle = '#fff' //'rgba(255,255,255,0.9)' //'hsl(189, 100%, 95%)'
ctx.stroke();
// const a = { x: radius * Math.cos(this.angle + this.arcRange), y: radius * Math.sin(this.angle + this.arcRange) }
// const b = Vector.add(m.pos, a)
// ctx.lineTo(b.x, b.y)
// ctx.fillStyle = '#fff'
// ctx.fill()
},
stuckOn() {
if (tech.isStuckOn) {
@@ -7916,6 +7902,79 @@ const b = {
}
// this.fire = this.firePhoton
},
// fireLaser() {
// // console.log('hi')
// const drain = tech.laserDrain / b.fireCDscale
// if (m.energy < drain) {
// m.fireCDcycle = m.cycle + 100; // cool down if out of energy
// } else {
// m.fireCDcycle = m.cycle
// m.energy -= drain
// const range = {
// x: 5000 * Math.cos(m.angle),
// y: 5000 * Math.sin(m.angle)
// }
// const laserSeparation = 3
// const rangeOffPlus = {
// x: laserSeparation * Math.cos(m.angle + Math.PI / 2),
// y: laserSeparation * Math.sin(m.angle + Math.PI / 2)
// }
// const rangeOffMinus = {
// x: laserSeparation * Math.cos(m.angle - Math.PI / 2),
// y: laserSeparation * Math.sin(m.angle - Math.PI / 2)
// }
// const dmg = 0.70 * tech.laserDamage / b.fireCDscale * this.lensDamage // 3.5 * 0.55 = 200% more damage
// const where = {
// x: m.pos.x + 30 * Math.cos(m.angle),
// y: m.pos.y + 30 * Math.sin(m.angle)
// }
// const eye = {
// x: m.pos.x + 15 * Math.cos(m.angle),
// y: m.pos.y + 15 * Math.sin(m.angle)
// }
// // ctx.strokeStyle = tech.laserColor;
// // ctx.lineWidth = 8
// // ctx.beginPath();
// if (Matter.Query.ray(map, eye, where).length === 0 && Matter.Query.ray(body, eye, where).length === 0) {
// b.laser(eye, {
// x: eye.x + range.x,
// y: eye.y + range.y
// }, dmg)
// }
// for (let i = 1; i < 2; i++) {
// let whereOff = Vector.add(where, {
// x: i * rangeOffPlus.x,
// y: i * rangeOffPlus.y
// })
// if (Matter.Query.ray(map, eye, whereOff).length === 0 && Matter.Query.ray(body, eye, whereOff).length === 0) {
// ctx.moveTo(eye.x, eye.y)
// ctx.lineTo(whereOff.x, whereOff.y)
// b.laser(whereOff, {
// x: whereOff.x + range.x,
// y: whereOff.y + range.y
// }, dmg)
// }
// whereOff = Vector.add(where, {
// x: i * rangeOffMinus.x,
// y: i * rangeOffMinus.y
// })
// if (Matter.Query.ray(map, eye, whereOff).length === 0 && Matter.Query.ray(body, eye, whereOff).length === 0) {
// ctx.moveTo(eye.x, eye.y)
// ctx.lineTo(whereOff.x, whereOff.y)
// b.laser(whereOff, {
// x: whereOff.x + range.x,
// y: whereOff.y + range.y
// }, dmg)
// }
// }
// // ctx.stroke();
// // if (tech.isLaserLens && b.guns[11].lensDamage !== 1) {
// // ctx.lineWidth = 20 + 3 * b.guns[11].lensDamageOn
// // ctx.globalAlpha = 0.3
// // ctx.stroke();
// // }
// }
// },
fireLaser() {
const drain = tech.laserDrain / b.fireCDscale
if (m.energy < drain) {

View File

@@ -251,11 +251,11 @@ window.addEventListener('load', () => {
}
}
if (property === "difficulty") {
simulation.difficultyMode = Number(set[property])
lore.setTechGoal()
document.getElementById("difficulty-select-experiment").value = Number(set[property])
}
// if (property === "difficulty") {
// simulation.difficultyMode = Number(set[property])
// lore.setTechGoal()
// document.getElementById("difficulty-select-experiment").value = Number(set[property])
// }
if (property === "molMode") {
simulation.molecularMode = Number(set[property])
const i = 4 //update experiment text
@@ -477,34 +477,41 @@ const build = {
<label for="hide-hud" title="hide: tech, damage taken, damage, in game console" style="font-size:1.15em;">minimal HUD</label>
<br>
<br><strong class='color-d'>damage</strong>: ${((tech.damageFromTech())).toPrecision(4)}x <span style="float: right;"><strong class='color-d'>difficulty:</strong> ${((m.dmgScale)).toPrecision(4)}x</span>
<br><strong class='color-defense'>damage taken</strong>: ${(m.defense()).toPrecision(4)}x <span style="float: right;"><strong class='color-defense'>difficulty:</strong> ${(simulation.dmgScale).toPrecision(4)}x</span>
<br><strong><em>fire rate</em></strong>: ${(1 / b.fireCDscale).toFixed(2)}x
${tech.duplicationChance() ? `<br><strong class='color-dup'>duplication</strong>: ${(tech.duplicationChance() * 100).toFixed(0)}%` : ""}
${m.coupling ? `<br><span style = 'font-size:90%;'>` + m.couplingDescription(m.coupling) + `</span> from ${(m.coupling).toFixed(0)} ${powerUps.orb.coupling(1)}` : ""}
${botText}
<br>
<br><strong class='color-h'>health</strong>: (${(m.health * 100).toFixed(0)} / ${(m.maxHealth * 100).toFixed(0)})
<span style="float: right;">mass: ${player.mass.toFixed(1)}</span>
<br><strong class='color-f'>energy</strong>: (${(m.energy * 100).toFixed(0)} / ${(m.maxEnergy * 100).toFixed(0)}) + (${(m.fieldRegen * 6000).toFixed(0)}/s)
<span style="float: right;">position: (${player.position.x.toFixed(1)}, ${player.position.y.toFixed(1)})</span>
<br><strong class='color-g'>gun</strong>: ${b.activeGun === null || b.activeGun === undefined ? "undefined" : b.guns[b.activeGun].name} &nbsp; <strong class='color-g'>ammo</strong>: ${b.activeGun === null || b.activeGun === undefined ? "0" : b.guns[b.activeGun].ammo}
<span style="float: right;">mouse: (${simulation.mouseInGame.x.toFixed(1)}, ${simulation.mouseInGame.y.toFixed(1)})</span>
<br><strong class='color-m'>tech</strong>: ${tech.totalCount} &nbsp; <strong class='color-r'>research</strong>: ${powerUps.research.count}
<span style="float: right;">velocity: (${player.velocity.x.toFixed(3)}, ${player.velocity.y.toFixed(3)})</span>
${tech.junkChance ? `<br><strong class='color-junk'>JUNK</strong>: ${(100 * tech.junkChance).toFixed(1)}% ` : ""}
<br>
<br>level: ${level.levelsCleared} ${level.levels[level.onLevel]} (${level.difficultyText()})
<br>mobs: ${spawn.pickList[0]}, ${spawn.pickList[0]}
<br>seed: ${Math.initialSeed} &nbsp; ${m.cycle} cycles
<br>mobs: ${mob.length} &nbsp; blocks: ${body.length} &nbsp; bullets: ${bullet.length} &nbsp; power ups: ${powerUp.length}
${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
</span></div>`;
<details> <summary>difficulty</summary>
<div style="display: ${simulation.difficultyMode === 1 ? "block" : "none"};"><strong>+6</strong> initial <strong>power ups</strong><br><strong>5%</strong> chance for mobs to a drop <strong class='color-m'>tech</strong></div>
<div style="display: ${simulation.difficultyMode > 1 ? "block" : "none"};"><strong>10%</strong> chance for <strong>shielded</strong> mobs<br><strong>0.5x</strong> <strong class='color-h'>heal</strong> power ups</div>
<div style="display: ${simulation.difficultyMode > 2 ? "block" : "none"};"><strong>1.5x</strong> mob movement and reactions<br><strong>0.5x</strong> <strong class='color-d'>damage</strong></div>
<div style="display: ${simulation.difficultyMode > 3 ? "block" : "none"};"><strong>+1</strong> boss per level, <strong>-1</strong> <strong class='color-m'>tech</strong> per boss<br><strong>2x</strong> <strong class='color-defense'>damage taken</strong></div>
<div style="display: ${simulation.difficultyMode > 4 ? "block" : "none"};"><strong>-3</strong> initial power ups<br><strong>0.5x</strong> <strong class='color-d'>damage</strong></div>
<div style="display: ${simulation.difficultyMode > 5 ? "block" : "none"};"><strong>10%</strong> chance for <strong>shielded</strong> mobs<br><strong>2x</strong> <strong class='color-defense'>damage taken</strong></div>
</details>
<br><strong class='color-d'>damage</strong>: ${((tech.damageFromTech())).toPrecision(4)}x <span style="float: right;"><strong class='color-d'>difficulty:</strong> ${((m.dmgScale)).toPrecision(4)}x</span>
<br><strong class='color-defense'>damage taken</strong>: ${(m.defense()).toPrecision(4)}x <span style="float: right;"><strong class='color-defense'>difficulty:</strong> ${(simulation.dmgScale).toPrecision(4)}x</span>
<br><strong><em>fire rate</em></strong>: ${(1 / b.fireCDscale).toFixed(2)}x
${tech.duplicationChance() ? `<br><strong class='color-dup'>duplication</strong>: ${(tech.duplicationChance() * 100).toFixed(0)}%` : ""}
${m.coupling ? `<br><span style = 'font-size:90%;'>` + m.couplingDescription(m.coupling) + `</span> from ${(m.coupling).toFixed(0)} ${powerUps.orb.coupling(1)}` : ""}
${botText}
<br>
<br><strong class='color-h'>health</strong>: (${(m.health * 100).toFixed(0)} / ${(m.maxHealth * 100).toFixed(0)})
<span style="float: right;">mass: ${player.mass.toFixed(1)}</span>
<br><strong class='color-f'>energy</strong>: (${(m.energy * 100).toFixed(0)} / ${(m.maxEnergy * 100).toFixed(0)}) + (${(m.fieldRegen * 6000).toFixed(0)}/s)
<span style="float: right;">position: (${player.position.x.toFixed(1)}, ${player.position.y.toFixed(1)})</span>
<br><strong class='color-g'>gun</strong>: ${b.activeGun === null || b.activeGun === undefined ? "undefined" : b.guns[b.activeGun].name} &nbsp; <strong class='color-g'>ammo</strong>: ${b.activeGun === null || b.activeGun === undefined ? "0" : b.guns[b.activeGun].ammo}
<span style="float: right;">mouse: (${simulation.mouseInGame.x.toFixed(1)}, ${simulation.mouseInGame.y.toFixed(1)})</span>
<br><strong class='color-m'>tech</strong>: ${tech.totalCount} &nbsp; <strong class='color-r'>research</strong>: ${powerUps.research.count}
<span style="float: right;">velocity: (${player.velocity.x.toFixed(3)}, ${player.velocity.y.toFixed(3)})</span>
${tech.junkChance ? `<br><strong class='color-junk'>JUNK</strong>: ${(100 * tech.junkChance).toFixed(1)}% ` : ""}
<br>
<br>mobs: ${spawn.pickList[0]}, ${spawn.pickList[0]}
<br>seed: ${Math.initialSeed} &nbsp; ${m.cycle} cycles
<br>mobs: ${mob.length} &nbsp; blocks: ${body.length} &nbsp; bullets: ${bullet.length} &nbsp; power ups: ${powerUp.length} ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}</span></div>`;
// deaths: ${mobs.mobDeaths} &nbsp;
// if (tech.isPauseSwitchField && !simulation.isChoosing) {
// const style = localSettings.isHideImages ? `style="height:auto;"` : `style="background-image: url('img/field/${m.fieldUpgrades[m.fieldMode].name}${m.fieldMode === 0 ? m.fieldUpgrades[0].imageNumber : ""}.webp');"`
// text += `<div class="pause-grid-module card-background" id ="pause-field" ${style} >
// <div class="card-text" style = "animation: fieldColorCycle 1s linear infinite alternate;">
// text += `<div class="pause-grid-module card-background" id="pause-field" ${style} >
// <div class="card-text" style="animation: fieldColorCycle 1s linear infinite alternate;">
// <div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${build.nameLink(m.fieldUpgrades[m.fieldMode].name)}</div>
// ${m.fieldUpgrades[m.fieldMode].description}</div> </div>`
if ((tech.isPauseSwitchField || simulation.testing)) { //&& !simulation.isChoosing
@@ -515,21 +522,21 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
<div class="grid-title" style="text-align: center;">↑ <div class="circle-grid field"></div> ↑</div></div>`
//button for current
const style = localSettings.isHideImages ? `style="height:auto;"` : `style="background-image: url('img/field/${m.fieldUpgrades[m.fieldMode].name}${m.fieldMode === 0 ? m.fieldUpgrades[0].imageNumber : ""}.webp');"`
text += `<div class="pause-grid-module card-background" id ="pause-field" ${style} >
<div class="card-text">
<div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${build.nameLink(m.fieldUpgrades[m.fieldMode].name)}</div>
${m.fieldUpgrades[m.fieldMode].description}</div> </div>`
text += `<div class="pause-grid-module card-background" id="pause-field" ${style} >
<div class="card-text">
<div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${build.nameLink(m.fieldUpgrades[m.fieldMode].name)}</div>
${m.fieldUpgrades[m.fieldMode].description}</div> </div>`
//button below for next
text += `<div class="pause-grid-module" id ="pause-field-next" style="animation: fieldColorCycle 3s linear infinite alternate;border-bottom: 1px solid #000;">
<div class="grid-title" style="text-align: center;">↓ <div class="circle-grid field"></div> ↓</div></div>`
text += `<div class="pause-grid-module" id="pause-field-next" style="animation: fieldColorCycle 3s linear infinite alternate;border-bottom: 1px solid #000;">
<div class="grid-title" style="text-align: center;">↓ <div class="circle-grid field"></div> ↓</div></div>`
} else {
const style = localSettings.isHideImages ? `style="height:auto;"` : `style="background-image: url('img/field/${m.fieldUpgrades[m.fieldMode].name}${m.fieldMode === 0 ? m.fieldUpgrades[0].imageNumber : ""}.webp');"`
text += `<div class="pause-grid-module card-background" id ="pause-field" ${style} >
<div class="card-text">
<div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${build.nameLink(m.fieldUpgrades[m.fieldMode].name)}</div>
${m.fieldUpgrades[m.fieldMode].description}</div> </div>`
text += `<div class="pause-grid-module card-background" id="pause-field" ${style} >
<div class="card-text">
<div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${build.nameLink(m.fieldUpgrades[m.fieldMode].name)}</div>
${m.fieldUpgrades[m.fieldMode].description}</div> </div>`
}
// for (let i = 0, len = b.inventory.length; i < len; i++) {
// text += `<div class="pause-grid-module"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${build.nameLink(b.guns[b.inventory[i]].name)} - <span style="font-size:100%;font-weight: 100;">${b.guns[b.inventory[i]].ammo}</span></div> ${b.guns[b.inventory[i]].description}</div>`
@@ -537,26 +544,26 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
for (let i = 0, len = b.inventory.length; i < len; i++) {
const style = localSettings.isHideImages ? `style="height:auto;"` : `style="background-image: url('img/gun/${b.guns[b.inventory[i]].name}.webp');"`
text += `<div class="pause-grid-module card-background" ${style} >
<div class="card-text">
<div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${build.nameLink(b.guns[b.inventory[i]].name)} - <span style="font-size:100%;font-weight: 100;">${b.guns[b.inventory[i]].ammo}</span></div>
${b.guns[b.inventory[i]].descriptionFunction()}</div> </div>`
<div class="card-text">
<div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${build.nameLink(b.guns[b.inventory[i]].name)} - <span style="font-size:100%;font-weight: 100;">${b.guns[b.inventory[i]].ammo}</span></div>
${b.guns[b.inventory[i]].descriptionFunction()}</div> </div>`
}
if (!localSettings.isHideHUD) text += `<div class="pause-grid-module pause-console" style = "background-color: rgba(255,255,255,0.3);">${document.getElementById("text-log").innerHTML}</div>` //show last in game console message
if (!localSettings.isHideHUD) text += `<div class="pause-grid-module pause-console" style="background-color: rgba(255,255,255,0.3);">${document.getElementById("text-log").innerHTML}</div>` //show last in game console message
let el = document.getElementById("pause-grid-left")
el.style.display = "grid"
el.innerHTML = text
},
generatePauseRight() {
let text = `<div class="sort">
<button onclick="build.sortTech('damage')" class='sort-button'><strong class='color-d'>damage</strong></button>
<button onclick="build.sortTech('guntech')" class='sort-button'><strong class='color-g'>gun</strong><strong class='color-m'>tech</strong></button>
<button onclick="build.sortTech('fieldtech')" class='sort-button'><strong class='color-f'>field</strong><strong class='color-m'>tech</strong></button>
<button onclick="build.sortTech('heal')" class='sort-button'><strong class='color-h'>heal</strong></button>
<button onclick="build.sortTech('damage taken')" class='sort-button'><strong style="letter-spacing: 1px;font-weight: 100;">damage taken</strong></button>
<button onclick="build.sortTech('energy')" class='sort-button'><strong class='color-f'>energy</strong></button>
<input type="search" id="sort-input" style="width: 8em;font-size: 0.6em;color:#000;" placeholder="sort by"/>
<button onclick="build.sortTech('input')" class='sort-button' style="border-radius: 0em;border: 1.5px #000 solid;font-size: 0.6em;" value="damage">sort</button>
</div>`;
<button onclick="build.sortTech('damage')" class='sort-button'><strong class='color-d'>damage</strong></button>
<button onclick="build.sortTech('guntech')" class='sort-button'><strong class='color-g'>gun</strong><strong class='color-m'>tech</strong></button>
<button onclick="build.sortTech('fieldtech')" class='sort-button'><strong class='color-f'>field</strong><strong class='color-m'>tech</strong></button>
<button onclick="build.sortTech('heal')" class='sort-button'><strong class='color-h'>heal</strong></button>
<button onclick="build.sortTech('damage taken')" class='sort-button'><strong style="letter-spacing: 1px;font-weight: 100;">damage taken</strong></button>
<button onclick="build.sortTech('energy')" class='sort-button'><strong class='color-f'>energy</strong></button>
<input type="search" id="sort-input" style="width: 8em;font-size: 0.6em;color:#000;" placeholder="sort by" />
<button onclick="build.sortTech('input')" class='sort-button' style="border-radius: 0em;border: 1.5px #000 solid;font-size: 0.6em;" value="damage">sort</button>
</div>`;
const ejectClass = (tech.isPauseEjectTech && !simulation.isChoosing) ? 'pause-eject' : ''
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].count > 0) {
@@ -728,43 +735,43 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
isExperimentRun: false,
techText(i) {
return `<div class="card-text" >
<div class="grid-title" ><div class="circle-grid tech"></div> &nbsp; ${build.nameLink(tech.tech[i].name)} ${tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : ""}</div>
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() : tech.tech[i].description}</div>`
<div class="grid-title" ><div class="circle-grid tech"></div> &nbsp; ${build.nameLink(tech.tech[i].name)} ${tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : ""}</div>
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() : tech.tech[i].description}</div>`
},
instantTechText(i) {
//
return `<div class="card-text" >
<div class="grid-title" > <div class="circle-grid-instant"></div> &nbsp; ${build.nameLink(tech.tech[i].name)} ${tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : ""}</div>
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() : tech.tech[i].description}</div>`
<div class="grid-title" > <div class="circle-grid-instant"></div> &nbsp; ${build.nameLink(tech.tech[i].name)} ${tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : ""}</div>
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() : tech.tech[i].description}</div>`
},
skinTechText(i) {
return `<div class="card-text"> <div class="grid-title">
<span style="position:relative;">
<div class="circle-grid-skin"></div>
<div class="circle-grid-skin-eye"></div>
</span> &nbsp; &nbsp; &nbsp;&nbsp; ${build.nameLink(tech.tech[i].name)} ${tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : ""}</div>
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() : tech.tech[i].description}</div>`
<span style="position:relative;">
<div class="circle-grid-skin"></div>
<div class="circle-grid-skin-eye"></div>
</span> &nbsp; &nbsp; &nbsp;&nbsp; ${build.nameLink(tech.tech[i].name)} ${tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : ""}</div>
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() : tech.tech[i].description}</div>`
},
gunTechText(i) {
return `<div class="card-text"> <div class="grid-title">
<span style="position:relative;">
<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; &nbsp; ${build.nameLink(tech.tech[i].name)} ${tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : ""}</div>
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() : tech.tech[i].description}</div>`
<span style="position:relative;">
<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; &nbsp; ${build.nameLink(tech.tech[i].name)} ${tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : ""}</div>
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() : tech.tech[i].description}</div>`
},
fieldTechText(i) {
return `<div class="card-text"><div class="grid-title">
<span style="position:relative;">
<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; &nbsp; ${build.nameLink(tech.tech[i].name)} ${tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : ""}</div>
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() : tech.tech[i].description}</div>`
<span style="position:relative;">
<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; &nbsp; ${build.nameLink(tech.tech[i].name)} ${tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : ""}</div>
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() : tech.tech[i].description}</div>`
},
junkTechText(i) {
return `<div class="card-text">
<div class="grid-title"><div class="circle-grid junk"></div> &nbsp; ${build.nameLink(tech.tech[i].name)} ${tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : ""}</div>
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() : tech.tech[i].description}</div>`
<div class="grid-title"><div class="circle-grid junk"></div> &nbsp; ${build.nameLink(tech.tech[i].name)} ${tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : ""}</div>
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() : tech.tech[i].description}</div>`
},
choosePowerUp(index, type, isAllowed = false) {
if (type === "gun") {
@@ -804,8 +811,8 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
// document.getElementById(`field-${i}`).innerHTML = `<div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${build.nameLink(m.fieldUpgrades[i].name)}</div> ${m.fieldUpgrades[i].description}`
document.getElementById(`field-${i}`).innerHTML = `<div class="card-text">
<div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${build.nameLink(m.fieldUpgrades[i].name)}</div>
${m.fieldUpgrades[i].description}</div>`
<div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${build.nameLink(m.fieldUpgrades[i].name)}</div>
${m.fieldUpgrades[i].description}</div>`
}
} else if (type === "tech") {
if (tech.tech[index].count < tech.tech[index].maxCount) {
@@ -877,72 +884,73 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
}
}
},
// <div>
// <select name="difficulty-select" id="difficulty-select-experiment">
// <option value="1">easy</option>
// <option value="2" selected>normal ⚆</option>
// <option value="4">hard ⚆</option>
// <option value="5">why ⚇</option>
// </select>
// &nbsp; &nbsp;
// <label for="hide-images-experiment" title="reload experiment with no images for fields, guns, and tech" style="font-size: 0.85em;">hide images</label>
// <input onclick="build.showImages('experiment')" type="checkbox" id="hide-images-experiment" name="hide-images-experiment" style="width:13px; height:13px;" ${localSettings.isHideImages ? "checked" : ""}>
// </div>
// <button onclick="build.sortTech('allowed', true)" class='sort-button' style="letter-spacing: 1px;font-weight: 400;">allowed</button>
// <button onclick="build.sortTech('have', true)" class='sort-button color-m' style="letter-spacing: 1px;font-weight: 800;">have</button>
populateGrid() { //background-color:var(--build-bg-color);
let text = `
<div class="experiment-start-box">
<div class="sort" style="border: 0px;">
<button onclick="build.sortTech('guntech', true)" class='sort-button'><strong class='color-g'>gun</strong><strong class='color-m'>tech</strong></button>
<button onclick="build.sortTech('fieldtech', true)" class='sort-button'><strong class='color-f'>field</strong><strong class='color-m'>tech</strong></button>
<button onclick="build.sortTech('damage', true)" class='sort-button'><strong class='color-d'>damage</strong></button>
<button onclick="build.sortTech('energy')" class='sort-button'><strong class='color-f'>energy</strong></button>
<button onclick="build.sortTech('damage taken', true)" class='sort-button'><strong style="letter-spacing: 1px;font-weight: 100;">damage taken</strong></button>
<button onclick="build.sortTech('heal')" class='sort-button'><strong class='color-h'>heal</strong></button>
<button onclick="build.sortTech('have', true)" class='sort-button color-m' style="letter-spacing: 1px;font-weight: 800;">have</button>
<button onclick="build.sortTech('allowed', true)" class='sort-button' style="letter-spacing: 1px;font-weight: 400;">allowed</button>
<input type="search" id="sort-input" style="width: 8.7em;font-size: 0.6em;color:#000;" placeholder="sort by"/>
<button onclick="build.sortTech('input', true)" class='sort-button' style="border-radius: 0em;border: 1.5px #000 solid;font-size: 0.6em;" value="damage">sort</button>
</div>
<div>
<select name="difficulty-select" id="difficulty-select-experiment">
<option value="1">easy</option>
<option value="2" selected>normal ⚆</option>
<option value="4">hard ⚆</option>
<option value="5">why ⚇</option>
</select>
&nbsp; &nbsp;
<label for="hide-images-experiment" title="reload experiment with no images for fields, guns, and tech" style="font-size: 0.85em;">hide images</label>
<input onclick="build.showImages('experiment')" type="checkbox" id="hide-images-experiment" name="hide-images-experiment" style="width:13px; height:13px;" ${localSettings.isHideImages ? "checked" : ""}>
</div>
<div>
<div style="display: grid;grid-template-columns: repeat(3, 1fr);row-gap: 10px;column-gap: 25px;grid-auto-rows: minmax(5px, auto);margin:-5px 0px 10px 25px;line-height: 100%;">
<div style="grid-column: 1;grid-row: 2 / 4;">
<svg class="SVG-button" onclick="build.startExperiment()" width="150" height="70" >
<g stroke='none' fill='#333' stroke-width="2" font-size="65px" font-family="Ariel, sans-serif">
<text x="10" y="57">start</text>
</g>
</svg>
</div>
<div style="grid-column: 2;grid-row: 2;">
<svg class="SVG-button" onclick="build.reset()" width="50" height="25">
<g stroke='none' fill='#333' stroke-width="2" font-size="17px" font-family="Ariel, sans-serif">
<text x="5" y="18">reset</text>
</g>
</svg>
</div>
<div style="grid-column: 2;grid-row: 3/4;">
<svg class="SVG-button" onclick="build.shareURL(true)" width="52" height="25">
<g stroke='none' fill='#333' stroke-width="2" font-size="17px" font-family="Ariel, sans-serif">
<text x="5" y="18">share</text>
</g>
</svg>
</div>
</div>
</div>
</div>`
<div class="experiment-start-box">
<div class="sort" style="border: 0px;">
<button onclick="build.sortTech('guntech', true)" class='sort-button'><strong class='color-g'>gun</strong><strong class='color-m'>tech</strong></button>
<button onclick="build.sortTech('fieldtech', true)" class='sort-button'><strong class='color-f'>field</strong><strong class='color-m'>tech</strong></button>
<button onclick="build.sortTech('damage', true)" class='sort-button'><strong class='color-d'>damage</strong></button>
<button onclick="build.sortTech('energy')" class='sort-button'><strong class='color-f'>energy</strong></button>
<button onclick="build.sortTech('damage taken', true)" class='sort-button'><strong style="letter-spacing: 1px;font-weight: 100;">damage taken</strong></button>
<button onclick="build.sortTech('heal')" class='sort-button'><strong class='color-h'>heal</strong></button>
<input type="search" id="sort-input" style="width: 6em;font-size: 0.6em;color:#000;" placeholder="sort by" />
<button onclick="build.sortTech('input', true)" class='sort-button' style="border-radius: 0em;border: 1.5px #000 solid;font-size: 0.6em;" value="damage">sort</button>
</div>
<div>
<div style="display: grid;grid-template-columns: repeat(3, 1fr);row-gap: 10px;column-gap: 25px;grid-auto-rows: minmax(5px, auto);margin:-5px 0px 10px 25px;line-height: 100%;">
<div style="grid-column: 1;grid-row: 2 / 4;">
<svg class="SVG-button" onclick="build.startExperiment()" width="150" height="70" >
<g stroke='none' fill='#333' stroke-width="2" font-size="65px" font-family="Ariel, sans-serif">
<text x="10" y="57">start</text>
</g>
</svg>
</div>
<div style="grid-column: 2;grid-row: 2;">
<svg class="SVG-button" onclick="build.reset()" width="50" height="25">
<g stroke='none' fill='#333' stroke-width="2" font-size="17px" font-family="Ariel, sans-serif">
<text x="5" y="18">reset</text>
</g>
</svg>
</div>
<div style="grid-column: 2;grid-row: 3/4;">
<svg class="SVG-button" onclick="build.shareURL(true)" width="52" height="25">
<g stroke='none' fill='#333' stroke-width="2" font-size="17px" font-family="Ariel, sans-serif">
<text x="5" y="18">share</text>
</g>
</svg>
</div>
</div>
</div>
</div>`
const hideStyle = `style="height:auto; border: none; background-color: transparent;"`
for (let i = 0, len = m.fieldUpgrades.length; i < len; i++) {
const style = localSettings.isHideImages ? hideStyle : `style="background-image: url('img/field/${m.fieldUpgrades[i].name}${i === 0 ? m.fieldUpgrades[0].imageNumber : ""}.webp');"`
text += `<div id="field-${i}" class="experiment-grid-module card-background ${m.fieldMode === i ? "build-field-selected" : ""}" onclick="build.choosePowerUp(${i},'field')" ${style} >
<div class="card-text">
<div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${build.nameLink(m.fieldUpgrades[i].name)}</div>
${m.fieldUpgrades[i].description}</div> </div>`
text += `<div id="field-${i}" class="experiment-grid-module card-background ${m.fieldMode === i ? " build-field-selected" : ""}" onclick="build.choosePowerUp(${i},'field')" ${style} >
<div class="card-text">
<div class="grid-title"><div class="circle-grid field"></div> &nbsp; ${build.nameLink(m.fieldUpgrades[i].name)}</div>
${m.fieldUpgrades[i].description}</div> </div>`
}
for (let i = 0, len = b.guns.length; i < len; i++) {
const style = localSettings.isHideImages ? hideStyle : `style="background-image: url('img/gun/${b.guns[i].name}.webp');"`
text += `<div id="gun-${i}" class="experiment-grid-module card-background ${b.guns[i].have ? "build-gun-selected" : ""}" onclick="build.choosePowerUp(${i},'gun')" ${style} >
<div class="card-text">
<div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${build.nameLink(b.guns[i].name)}</div>
${b.guns[i].descriptionFunction()}</div> </div>`
text += `<div id="gun-${i}" class="experiment-grid-module card-background ${b.guns[i].have ? " build-gun-selected" : ""}" onclick="build.choosePowerUp(${i},'gun')" ${style} >
<div class="card-text">
<div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${build.nameLink(b.guns[i].name)}</div>
${b.guns[i].descriptionFunction()}</div> </div>`
}
for (let i = 0, len = tech.tech.length; i < len; i++) {
if ((!tech.tech[i].isJunk || localSettings.isJunkExperiment) && !tech.tech[i].isLore) {
@@ -982,14 +990,14 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
}
document.getElementById("sort-input").addEventListener('keydown', pressEnterSort);
document.getElementById("difficulty-select-experiment").value = document.getElementById("difficulty-select").value
document.getElementById("difficulty-select-experiment").addEventListener("input", () => {
simulation.difficultyMode = Number(document.getElementById("difficulty-select-experiment").value)
lore.setTechGoal()
localSettings.difficultyMode = Number(document.getElementById("difficulty-select-experiment").value)
document.getElementById("difficulty-select").value = document.getElementById("difficulty-select-experiment").value
if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
});
// document.getElementById("difficulty-select-experiment").value = document.getElementById("difficulty-select").value
// document.getElementById("difficulty-select-experiment").addEventListener("input", () => {
// simulation.difficultyMode = Number(document.getElementById("difficulty-select-experiment").value)
// lore.setTechGoal()
// localSettings.difficultyMode = Number(document.getElementById("difficulty-select-experiment").value)
// document.getElementById("difficulty-select").value = document.getElementById("difficulty-select-experiment").value
// if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
// });
//add tooltips
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (document.getElementById(`tech-${i}`)) {
@@ -1001,7 +1009,7 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
requestAnimationFrame(() => { document.getElementById("sort-input").focus(); });
},
nameLink(text) { //converts text into a clickable wikipedia search
return `<a target="_blank" href='https://en.wikipedia.org/w/index.php?search=${encodeURIComponent(text).replace(/'/g, '%27')}&title=Special:Search' class="link">${text}</a>`
return `<a target="_blank" href='https://en.wikipedia.org/w/index.php?search=${encodeURIComponent(text).replace(/' /g, '%27')}&title=Special:Search' class="link">${text}</a>`
},
reset() {
build.isExperimentSelection = true;
@@ -1010,7 +1018,7 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
build.isExperimentSelection = true;
build.isExperimentRun = true;
simulation.paused = true;
b.inventory = []; //removes guns and ammo
b.inventory = []; //removes guns and ammo
for (let i = 0, len = b.guns.length; i < len; ++i) {
b.guns[i].count = 0;
b.guns[i].have = false;
@@ -1197,7 +1205,7 @@ const input = {
document.getElementById("key-pause").innerHTML = cleanText(input.key.pause)
document.getElementById("key-next-gun").innerHTML = cleanText(input.key.nextGun)
document.getElementById("key-previous-gun").innerHTML = cleanText(input.key.previousGun)
document.getElementById("key-testing").innerHTML = cleanText(input.key.testing) //if (localSettings.loreCount > 0)
document.getElementById("key-testing").innerHTML = cleanText(input.key.testing) //if (localSettings.loreCount > 0)
document.getElementById("splash-up").innerHTML = cleanText(input.key.up)[0]
document.getElementById("splash-down").innerHTML = cleanText(input.key.down)[0]
@@ -1437,59 +1445,59 @@ window.addEventListener("keydown", function (event) {
if (simulation.testing) tech.setCheating();
simulation.makeTextLog(
`<table class="pause-table">
<tr>
<td class='key-input-pause'>T</td>
<td class='key-used'><strong>toggle testing</strong></td>
</tr>
<tr>
<td class='key-input-pause'>R</td>
<td class='key-used'>teleport to mouse</td>
</tr>
<tr>
<td class='key-input-pause'>F</td>
<td class='key-used'>cycle field</td>
</tr>
<tr>
<td class='key-input-pause'>G</td>
<td class='key-used'>all guns</td>
</tr>
<tr>
<td class='key-input-pause'>H</td>
<td class='key-used'>+100% defense</td>
</tr>
<tr>
<td class='key-input-pause'>B</td>
<td class='key-used'>damage, research</td>
</tr>
<tr>
<td class='key-input-pause'>N</td>
<td class='key-used'>fill health, energy</td>
</tr>
<tr>
<td class='key-input-pause'>Y</td>
<td class='key-used'>random tech</td>
</tr>
<tr>
<td class='key-input-pause'>U</td>
<td class='key-used'>next level</td>
</tr>
<tr>
<td class='key-input-pause'>J</td>
<td class='key-used'>clear mobs</td>
</tr>
<tr>
<td class='key-input-pause'>I/O</td>
<td class='key-used'>zoom in / out</td>
</tr>
<tr>
<td class='key-input-pause'>1-8</td>
<td class='key-used'>spawn things</td>
</tr>
<tr>
<td class='key-input-pause'>⇧X</td>
<td class='key-used'>restart</td>
</tr>
</table>`, Infinity);
<tr>
<td class='key-input-pause'>T</td>
<td class='key-used'><strong>toggle testing</strong></td>
</tr>
<tr>
<td class='key-input-pause'>R</td>
<td class='key-used'>teleport to mouse</td>
</tr>
<tr>
<td class='key-input-pause'>F</td>
<td class='key-used'>cycle field</td>
</tr>
<tr>
<td class='key-input-pause'>G</td>
<td class='key-used'>all guns</td>
</tr>
<tr>
<td class='key-input-pause'>H</td>
<td class='key-used'>+100% defense</td>
</tr>
<tr>
<td class='key-input-pause'>B</td>
<td class='key-used'>damage, research</td>
</tr>
<tr>
<td class='key-input-pause'>N</td>
<td class='key-used'>fill health, energy</td>
</tr>
<tr>
<td class='key-input-pause'>Y</td>
<td class='key-used'>random tech</td>
</tr>
<tr>
<td class='key-input-pause'>U</td>
<td class='key-used'>next level</td>
</tr>
<tr>
<td class='key-input-pause'>J</td>
<td class='key-used'>clear mobs</td>
</tr>
<tr>
<td class='key-input-pause'>I/O</td>
<td class='key-used'>zoom in / out</td>
</tr>
<tr>
<td class='key-input-pause'>1-8</td>
<td class='key-used'>spawn things</td>
</tr>
<tr>
<td class='key-input-pause'>⇧X</td>
<td class='key-used'>restart</td>
</tr>
</table>`, Infinity);
}
}
break
@@ -1759,11 +1767,6 @@ if (localSettings.isAllowed && !localSettings.isEmpty) {
simulation.isCommunityMaps = localSettings.isCommunityMaps
document.getElementById("community-maps").checked = localSettings.isCommunityMaps
if (localSettings.difficultyMode === undefined) localSettings.difficultyMode = "2"
simulation.difficultyMode = localSettings.difficultyMode
lore.setTechGoal()
document.getElementById("difficulty-select").value = localSettings.difficultyMode
if (localSettings.fpsCapDefault === undefined) localSettings.fpsCapDefault = 'max'
if (localSettings.personalSeeds === undefined) localSettings.personalSeeds = [];
if (localSettings.fpsCapDefault === 'max') {
@@ -1791,6 +1794,14 @@ if (localSettings.isAllowed && !localSettings.isEmpty) {
if (localSettings.isHideHUD === undefined) localSettings.isHideHUD = true
document.getElementById("hide-hud").checked = localSettings.isHideHUD
if (localSettings.difficultyCompleted === undefined) {
localSettings.difficultyCompleted = [null, false, false, false, false, false, false] //null because there isn't a difficulty zero
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
}
if (localSettings.difficultyMode === undefined) localSettings.difficultyMode = "2"
simulation.difficultyMode = localSettings.difficultyMode
lore.setTechGoal()
} else {
console.log('setting default localSettings')
const isAllowed = localSettings.isAllowed //don't overwrite isAllowed value
@@ -1801,6 +1812,7 @@ if (localSettings.isAllowed && !localSettings.isEmpty) {
isJunkExperiment: false,
isCommunityMaps: false,
difficultyMode: '2',
difficultyCompleted: [null, false, false, false, false, false, false],
fpsCapDefault: 'max',
runCount: 0,
isTrainingNotAttempted: true,
@@ -1817,18 +1829,30 @@ if (localSettings.isAllowed && !localSettings.isEmpty) {
document.getElementById("community-maps").checked = localSettings.isCommunityMaps
simulation.isCommunityMaps = localSettings.isCommunityMaps
document.getElementById("hide-images").checked = localSettings.isHideImages
document.getElementById("difficulty-select").value = localSettings.difficultyMode
document.getElementById("fps-select").value = localSettings.fpsCapDefault
document.getElementById("banned").value = localSettings.banList
}
document.getElementById("control-testing").style.visibility = (localSettings.loreCount === 0) ? "hidden" : "visible"
// document.getElementById("experiment-button").style.visibility = (localSettings.loreCount === 0) ? "hidden" : "visible"
input.controlTextUpdate()
//**********************************************************************
// settings
// settings
//**********************************************************************
// difficulty-select-experiment event listener is set in build.makeGrid
// document.getElementById("difficulty-select").addEventListener("input", () => {
// simulation.difficultyMode = Number(document.getElementById("difficulty-select").value)
// lore.setTechGoal()
// localSettings.difficultyMode = simulation.difficultyMode
// localSettings.levelsClearedLastGame = 0 //after changing difficulty, reset run history
// localSettings.entanglement = undefined //after changing difficulty, reset stored tech
// if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
// });
document.getElementById("fps-select").addEventListener("input", () => {
let value = document.getElementById("fps-select").value
if (value === 'max') {
@@ -1851,17 +1875,6 @@ document.getElementById("community-maps").addEventListener("input", () => {
if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
});
// difficulty-select-experiment event listener is set in build.makeGrid
document.getElementById("difficulty-select").addEventListener("input", () => {
simulation.difficultyMode = Number(document.getElementById("difficulty-select").value)
lore.setTechGoal()
localSettings.difficultyMode = simulation.difficultyMode
localSettings.levelsClearedLastGame = 0 //after changing difficulty, reset run history
localSettings.entanglement = undefined //after changing difficulty, reset stored tech
if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
});
document.getElementById("updates").addEventListener("toggle", function () {
function loadJSON(path, success, error) { //generic function to get JSON
var xhr = new XMLHttpRequest();

View File

@@ -18,7 +18,6 @@ const level = {
// simulation.enableConstructMode() //tech.giveTech('motion sickness') //used to build maps in testing mode
// simulation.isHorizontalFlipped = true
// tech.giveTech("performance")
// level.difficultyIncrease(7 * 2) //30 is near max on hard //60 is near max on why
// m.maxHealth = m.health = 1//00000000
// m.maxEnergy = m.energy = 10000000
// tech.isRerollDamage = true
@@ -38,6 +37,9 @@ const level = {
// b.giveGuns("shotgun") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.giveGuns("wave") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.giveGuns("laser") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// tech.laserColor = "#fff"
// tech.laserColorAlpha = "rgba(255, 255, 255, 0.5)"
// b.guns[8].ammo = 100000000
// requestAnimationFrame(() => { tech.giveTech("optical amplifier") });
// for (let i = 0; i < 1; ++i) tech.giveTech("combinatorial optimization")
@@ -50,18 +52,17 @@ const level = {
// requestAnimationFrame(() => { for (let i = 0; i < 1; i++) tech.giveTech("ersatz bots") });
// for (let i = 0; i < 1; i++) tech.giveTech("tungsten carbide")
// m.lastKillCycle = m.cycle
// for (let i = 0; i < 1; ++i) tech.giveTech("anyon")
// for (let i = 0; i < 1; ++i) tech.giveTech("plasma-bot")
// for (let i = 0; i < 3; i++) powerUps.directSpawn(450, -50, "tech");
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "research");
// for (let i = 0; i < 1; i++) powerUps.directSpawn(-50, -70, "difficulty", false);
// for (let i = 0; i < 100; i++) powerUps.directSpawn(1750, -500, "coupling");
// spawn.mapRect(575, -700, 25, 425); //block mob line of site on testing
// level.towers();
// level.testing();
// for (let i = 0; i < 1; ++i) spawn.laserLayer(1400, -500)
// Matter.Body.setPosition(player, { x: -200, y: -3330 });
// for (let i = 0; i < 4; ++i) spawn.laserLayer(1300, -500 + 100 * Math.random())
// for (let i = 0; i < 1; ++i) spawn.powerUpBossBaby(1900, -500)
// spawn.sneakBoss(1900, -500)
// for (let i = 0; i < 4; ++i) spawn.ghoster(1300, -500 + 100 * Math.random())
// spawn.hopper(1900, -500)
// spawn.zombie(-3000, -500 + 300 * Math.random(), 30, 5, "white") // zombie(x, y, radius, sides, color)
// for (let i = 0; i < 5; ++i) spawn.starter(1000 + 1000 * Math.random(), -500 + 300 * Math.random())
// tech.addJunkTechToPool(2)
@@ -71,6 +72,7 @@ const level = {
level[simulation.isTraining ? "walk" : "initial"]() //normal starting level **************************************************
// for (let i = 0; i < 1; ++i) spawn.laserLayerBoss(1900, -500)
// for (let i = 0; i < 2; i++) spawn.ghoster(level.exit.x, level.exit.y) //ghosters need to spawn after the map loads
// spawn.bodyRect(2425, -120, 200, 200);
// console.log(body[body.length - 1].mass)
@@ -90,6 +92,7 @@ const level = {
// lore.techCount = 1
// level.levelsCleared = 10
// localSettings.loreCount = 2 //this sets what conversation is heard
// localSettings.levelsClearedLastGame = 10
// if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
// level.onLevel = -1 //this sets level.levels[level.onLevel] = undefined which is required to run the conversation
// level.null()
@@ -101,6 +104,8 @@ const level = {
// tech.giveTech("tinker"); //show junk tech in experiment mode
// m.storeTech()
// powerUps.spawn(m.pos.x, m.pos.y, "entanglement", false);
// for (let i = 0; i < 6; i++) localSettings.difficultyCompleted[i] = false
// localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
} else {
spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns
// spawn.pickList = ["focuser", "focuser"]
@@ -212,65 +217,65 @@ const level = {
trainingBackgroundColor: "#e1e1e1",
custom() { },
customTopLayer() { },
setDifficulty() {
simulation.difficulty = 0
m.dmgScale = 1; //damage done by player decreases each level
simulation.accelScale = 1 //mob acceleration increases each level
simulation.CDScale = 1 //mob CD time decreases each level
simulation.dmgScale = Math.max(0.1, 0.25 * simulation.difficulty) //damage done by mobs scales with total levels
simulation.healScale = 1 / (1 + simulation.difficulty * 0.043) //a higher denominator makes for lower heals // m.health += heal * simulation.healScale;
},
difficultyIncrease(num = 1) {
for (let i = 0; i < num; i++) {
simulation.difficulty++
m.dmgScale *= 0.89; //damage done by player decreases each level
if (simulation.accelScale < 6) simulation.accelScale *= 1.024 //mob acceleration increases each level
if (simulation.CDScale > 0.15) simulation.CDScale *= 0.964 //mob CD time decreases each level
updateDifficulty() {
simulation.difficulty = level.levelsCleared * simulation.difficultyMode
if (simulation.isTraining) simulation.difficulty = 1
// old
// normal mode m.dmgScale = 1, 0.81, 0.63, 0.5
// why mode m.dmgScale = 1, 0.56, 0.3, 0.17
// new
//constraint 0,1 m.dmgScale = 1, 0.8, 0.6, 0.5
//constraint 2,3 m.dmgScale = 1,
//constraint 4,5 m.dmgScale = 1, 0.5, 0.3, 0.15
// old
//normal: simulation.dmgScale = 0.1, 0.5 ,1 ,1.5 ,2 ,2.5
//hard: simulation.dmgScale = 0.1, 1 ,2 ,3 ,4 ,5
//why: simulation.dmgScale = 0.1, 1.25 ,2.5 ,3.75 ,5 ,6.25
// new
//0,1: simulation.dmgScale = 0.1, 0.5 ,1 ,1.5 ,2 ,2.5
//2,3: simulation.dmgScale = 0.1, 1 ,2 ,3 ,4 ,5
//3,4: simulation.dmgScale = 0.1, 1.25 ,2.5 ,3.75 ,5 ,6.25
let scale = 1
if (simulation.difficultyMode > 3) {
scale = 3
} else if (simulation.difficultyMode > 1) {
scale = 2
}
simulation.dmgScale = Math.max(0.1, 0.25 * simulation.difficulty) //damage done by mobs scales with total levels
m.dmgScale = Math.pow(0.82, level.levelsCleared * scale)
simulation.dmgScale = Math.max(0.1, 0.25 * level.levelsCleared * scale) //damage done by mobs scales with total levels
//
simulation.healScale = 1 / (1 + simulation.difficulty * 0.043) //a higher denominator makes for lower heals // m.health += heal * simulation.healScale;
// console.log(`CD = ${simulation.CDScale}`)
},
difficultyDecrease(num = 1) { //used in easy mode for simulation.reset()
for (let i = 0; i < num; i++) {
simulation.difficulty--
m.dmgScale /= 0.89; //damage done by player decreases each level
if (simulation.accelScale > 1) simulation.accelScale /= 1.024 //mob acceleration increases each level
if (simulation.CDScale < 1) simulation.CDScale /= 0.964 //mob CD time decreases each level
}
if (simulation.difficulty < 1) simulation.difficulty = 0;
simulation.dmgScale = Math.max(0.1, 0.25 * simulation.difficulty) //damage done by mobs scales with total levels
simulation.healScale = 1 / (1 + simulation.difficulty * 0.043)
},
difficultyText() {
if (simulation.difficultyMode === 1) {
return "easy"
} else if (simulation.difficultyMode === 2) {
return "normal"
} else if (simulation.difficultyMode === 4) {
return "hard"
} else if (simulation.difficultyMode === 5) {
return "why"
simulation.accelScale = 1.1
simulation.CDScale = 0.9
} else {
simulation.accelScale = Math.min(6, Math.pow(1.024, simulation.difficulty))
simulation.CDScale = Math.max(0.15, Math.pow(0.964, simulation.difficulty))
}
},
// difficultyIncrease(num = 1) {
// for (let i = 0; i < num; i++) {
// simulation.difficulty++
// m.dmgScale *= 0.89; //damage done by player decreases each level
// if (simulation.accelScale < 6) simulation.accelScale *= 1.024 //mob acceleration increases each level
// if (simulation.CDScale > 0.15) simulation.CDScale *= 0.964 //mob CD time decreases each level
// }
// simulation.dmgScale = Math.max(0.1, 0.25 * simulation.difficulty) //damage done by mobs scales with total levels
// simulation.healScale = 1 / (1 + simulation.difficulty * 0.043) //a higher denominator makes for lower heals // m.health += heal * simulation.healScale;
// // console.log(`CD = ${simulation.CDScale}`)
// },
levelAnnounce() {
const difficulty = simulation.isCheating ? "testing" : level.difficultyText()
const cheating = simulation.isCheating ? "(testing)" : ""
if (level.levelsCleared === 0) {
document.title = "n-gon: (" + difficulty + ")";
document.title = `n-gon: initial ${cheating}`;
} else {
document.title = `n-gon: ${level.levelsCleared} ${level.levels[level.onLevel]} (${difficulty})`
document.title = `n-gon: ${level.levelsCleared} ${level.levels[level.onLevel]} ${cheating}`
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'>m</span>.fieldMode = "<span class='color-text'>${m.fieldUpgrades[m.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'>m</span>.field.description = "<span class='color-text'>${m.fieldUpgrades[m.fieldMode].description}</span>"
// `, 1200);
},
announceMobTypes() {
simulation.makeTextLog(`spawn<span class='color-symbol'>.</span>${spawn.pickList[0]}<span class='color-symbol'>(</span>x<span class='color-symbol'>,</span>y<span class='color-symbol'>)</span>`)
@@ -281,6 +286,7 @@ const level = {
if (!level.disableExit) {
level.levelsCleared++;
level.onLevel++; //cycles map to next level
level.updateDifficulty()
if (simulation.isTraining) {
if (level.onLevel > level.levels.length - 1) { //if all training levels are completed
@@ -301,14 +307,12 @@ const level = {
simulation.splashReturn();
}, 6000);
return
} else {
level.setDifficulty()
}
} else {
if (level.onLevel > level.levels.length - 1) level.onLevel = 0;
level.difficultyIncrease(simulation.difficultyMode)
}
//reset lost tech display
for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].isLost) tech.tech[i].isLost = false;
@@ -573,9 +577,9 @@ const level = {
player.velocity.y < 0.15
) {
// level.exitCount += input.down ? 8 : 2
level.exitCount += 2
level.exitCount += 3
} else if (level.exitCount > 0) {
level.exitCount -= 2
level.exitCount -= 3
}
ctx.beginPath();
@@ -2181,7 +2185,6 @@ const level = {
document.body.style.backgroundColor = "#fff";
// color.map = "#444" //custom map color
// level.difficultyIncrease(14); //hard mode level 7
level.defaultZoom = 1500
simulation.zoomTransition(level.defaultZoom)
@@ -2268,7 +2271,6 @@ const level = {
//???
// level.difficultyIncrease(3 * 4) //30 is near max on hard //60 is near max on why
// m.addHealth(Infinity)
// spawn.starter(1900, -500, 200) //big boy
@@ -2424,51 +2426,60 @@ const level = {
spawn.mapRect(-500, -25, 25, 50); //edge shelf
spawn.mapRect(475, -25, 25, 50); //edge shelf
},
initialPowerUps() {
//wait to spawn power ups until unpaused
//power ups don't spawn in experiment mode, so they don't get removed at the start of experiment mode
const goal = simulation.cycle + 10
function cycle() {
if (simulation.cycle > goal) {
if (localSettings.loreCount === 6) {
powerUps.spawn(2095 + 20 * (Math.random() - 0.5), -2170, "field", false);
} else {
powerUps.spawnStartingPowerUps(2095 + 20 * (Math.random() - 0.5), -2200);
}
if (simulation.difficultyMode === 1) {
powerUps.spawn(2095 + 20 * (Math.random() - 0.5), -2600, "ammo", false);
powerUps.spawn(2095 + 20 * (Math.random() - 0.5), -2550, "ammo", false);
powerUps.spawn(2095 + 20 * (Math.random() - 0.5), -2400, "heal", false);
powerUps.spawn(2095 + 20 * (Math.random() - 0.5), -2350, "heal", false);
powerUps.spawn(2095 + 20 * (Math.random() - 0.5), -2350, "heal", false);
powerUps.spawn(2095 + 20 * (Math.random() - 0.5), -2100, "research", false);
powerUps.spawn(2095 + 20 * (Math.random() - 0.5), -2060, "research", false);
powerUps.spawn(2095 + 20 * (Math.random() - 0.5), -2120, "research", false);
powerUps.spawn(2095 + 20 * (Math.random() - 0.5), -2075, "research", false);
} else if (simulation.difficultyMode === 6) {
} else {
powerUps.spawn(2095 + 20 * (Math.random() - 0.5), -2300, "heal", false);
powerUps.spawn(2095 + 20 * (Math.random() - 0.5), -2100, "heal", false);
powerUps.spawn(2095 + 20 * (Math.random() - 0.5), -2060, "research", false);
}
// if (level.levelsCleared === 0) powerUps.directSpawn(-50, -70, "difficulty", false);
} else {
requestAnimationFrame(cycle);
}
}
requestAnimationFrame(cycle);
},
initial() {
if (level.levelsCleared === 0) { //if this is the 1st level of the game
if (simulation.difficultyMode > 2) spawn.setSpawnList() // hard and why difficulty don't begin with starter mobs
level.initialPowerUps()
if (level.levelsCleared === 0) powerUps.directSpawn(-60, -950, "difficulty", false);
//wait to spawn power ups until unpaused
//power ups don't spawn in experiment mode, so they don't get removed at the start of experiment mode
const goal = simulation.cycle + 10
function cycle() {
if (simulation.cycle > goal) {
if (localSettings.loreCount === 6) {
powerUps.spawn(2095 + 15 * (Math.random() - 0.5), -2170, "field", false);
} else {
powerUps.spawnStartingPowerUps(2095 + 15 * (Math.random() - 0.5), -2070 - 125);
}
if (simulation.difficultyMode < 5) { //hard, normal and easy
powerUps.spawn(2095 + 15 * (Math.random() - 0.5), -2070 - 25, "heal", false);
powerUps.spawn(2095 + 15 * (Math.random() - 0.5), -2070, "research", false);
}
if (simulation.difficultyMode < 3) { //normal and easy
powerUps.spawn(2095 + 15 * (Math.random() - 0.5), -2070 - 75, "heal", false);
}
if (simulation.difficultyMode < 2) { //easy
powerUps.spawn(2095 + 15 * (Math.random() - 0.5), -2070 - 75, "heal", false);
powerUps.spawn(2095 + 15 * (Math.random() - 0.5), -2070, "research", false);
powerUps.spawn(2095 + 15 * (Math.random() - 0.5), -2070, "research", false);
}
} else {
requestAnimationFrame(cycle);
}
if (!simulation.isCheating && !m.isShipMode && !build.isExperimentRun) {
spawn.wireFoot();
spawn.wireFootLeft();
spawn.wireKnee();
spawn.wireKneeLeft();
spawn.wireHead();
} else {
simulation.isCheating = true;
}
requestAnimationFrame(cycle);
if (localSettings.levelsClearedLastGame < 3) {
if (!simulation.isCheating && !m.isShipMode && !build.isExperimentRun) {
spawn.wireFoot();
spawn.wireFootLeft();
spawn.wireKnee();
spawn.wireKneeLeft();
spawn.wireHead();
// for (let i = 0; i < 3; i++) powerUps.spawn(2095, -1220 - 50 * i, "tech", false); //unavailable tech spawns
// spawn.mapRect(2000, -1025, 200, 25);
}
} else if (!build.isExperimentRun) {
simulation.trails()
simulation.trails(70)
//bonus power ups for clearing runs in the last game
if (!simulation.isCheating && localSettings.levelsClearedLastGame > 1) {
for (let i = 0; i < localSettings.levelsClearedLastGame / 3; i++) powerUps.spawn(2095 + 2 * Math.random(), -1270 - 50 * i, "tech", false); //spawn a tech for levels cleared in last game
@@ -2848,7 +2859,6 @@ const level = {
},
subway() {
// simulation.enableConstructMode() //tech.giveTech('motion sickness') //used to build maps in testing mode
// level.difficultyIncrease(10 * 4);
// m.maxHealth = m.health = 100
// color.map = "#333" //custom map color
document.body.style.backgroundColor = "#e3e3e3"//"#e3e3e3"//color.map//"#333"//"#000"
@@ -4226,7 +4236,6 @@ const level = {
},
towers() {
// simulation.enableConstructMode() //remove this!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// level.difficultyIncrease(10 * 4) //30 is near max on hard //60 is near max on why
// simulation.isHorizontalFlipped = true
level.announceMobTypes()
const isFlipped = (simulation.isHorizontalFlipped && Math.random() < 0.33) ? true : false
@@ -4481,7 +4490,6 @@ const level = {
factory() {
level.announceMobTypes()
// simulation.enableConstructMode() //remove this!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// level.difficultyIncrease(10 * 4) //30 is near max on hard //60 is near max on why
level.setPosToSpawn(2235, -1375); //normal spawn
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20); //bump for level entrance
@@ -7141,7 +7149,6 @@ const level = {
ctx.fill()
};
// simulation.difficulty = 4; //for testing to simulate possible mobs spawns
level.defaultZoom = 2100
simulation.zoomTransition(level.defaultZoom)
@@ -11330,9 +11337,7 @@ const level = {
anotherBoss = (x, y) => {
if (tech.isDuplicateMobs && Math.random() < tech.duplicationChance()) {
tech.isScaleMobsWithDuplication = true
spawn.randomLevelBoss(x, y, ["historyBoss"]);
tech.isScaleMobsWithDuplication = false
} else if (tech.isResearchBoss) {
if (powerUps.research.count > 2) {
powerUps.research.changeRerolls(-3)
@@ -12014,7 +12019,6 @@ const level = {
simulation.fallHeight = -15000;
powerUps.addResearchToLevel();
powerUps.spawn(3000, -230, "heal");
// level.difficultyIncrease(60)
},
temple() {
simulation.makeTextLog(`<strong>temple</strong> by <span class='color-var'>Scar1337</span>`);
@@ -12139,7 +12143,7 @@ const level = {
if (Math.random() > 0.5) powerUps.spawn(this.position.x, this.position.y, "ammo");
if (Math.random() > 0.3) powerUps.spawn(this.position.x, this.position.y, "heal", true, null, 30 * (simulation.healScale ** 0.25) * Math.sqrt(tech.largerHeals) * Math.sqrt(0.1 + Math.random() * 0.5));
};
me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1);
me.damageReduction = 0.25
me.do = function () {
// keep it slow, to stop issues from explosion knock backs
if (this.speed > 1) {
@@ -12242,7 +12246,7 @@ const level = {
if (Math.random() > 0.5) powerUps.spawn(this.position.x, this.position.y, "ammo");
if (Math.random() > 0.3) powerUps.spawn(this.position.x, this.position.y, "heal", true, null, 30 * (simulation.healScale ** 0.25) * Math.sqrt(tech.largerHeals) * Math.sqrt(0.1 + Math.random() * 0.5));
};
me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1);
me.damageReduction = 0.25
me.do = function () {
// keep it slow, to stop issues from explosion knock backs
if (this.speed > 2) {
@@ -12276,7 +12280,6 @@ const level = {
}
}
};
function secondRoomObstacle(x, y, isDark = false, size = 70) {
mobs.spawn(x, y, isDark ? 3 : 4, size, isDark ? "#0004" : "#fff4");
let me = mob[mob.length - 1];
@@ -12288,7 +12291,7 @@ const level = {
me.leaveBody = false;
me.timeLeft = 1200;
me.isObstacle = true;
me.damageReduction = isDark ? 0.5 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) : 0;
me.damageReduction = isDark ? 0.5 : 0
if (!isDark) {
me.isBadTarget = true;
me.attackCycle = 0;
@@ -12416,7 +12419,7 @@ const level = {
this.damageReduction = 0;
}
};
me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1);
me.damageReduction = 0.25
me.rings = [{
colour: "#65f",
radius: 300,
@@ -12571,7 +12574,7 @@ const level = {
if (Math.floor(cycle / spawnDelay) >= spawnCycles - 1) {
this.trapCycle = 0;
this.isInvulnerable = false;
this.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1);
this.damageReduction = 0.25
}
}
}
@@ -14273,9 +14276,7 @@ const level = {
const anotherBoss = (x, y) => {
if (tech.isDuplicateMobs && Math.random() < tech.duplicationChance()) {
tech.isScaleMobsWithDuplication = true
spawn.historyBoss(x, y)
tech.isScaleMobsWithDuplication = false
} else if (tech.isResearchBoss) {
if (powerUps.research.count > 2) {
powerUps.research.changeRerolls(-3)
@@ -14657,7 +14658,7 @@ const level = {
me.deadOrbs = []
me.energy = 1
// this boss has no orbitals, because it's not meant to ever attack on its own
me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.25
// has a shield and sustains that shield
spawn.shield(me, x, y, Infinity)
me.fireFreq = 30
@@ -15020,7 +15021,7 @@ const level = {
me.onDeath = function () {
totalCoin++;
};
me.damageReduction = 0.35 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.35
me.do = function () {
ctx.save()
ctx.translate(this.position.x, this.position.y)
@@ -27367,14 +27368,13 @@ const level = {
spawn.mapRect(-100, 0, 1000, 100);
powerUps.addResearchToLevel() //needs to run after mobs are spawned
},
ace() { //join us at discord.gg/Q8gY4WeUcm
ace() {
simulation.makeTextLog(`<strong>ace</strong> by <span class='color-var'>Richard0820</span>`);
let isDestroyed = false;
const ace = {
spawnOrbitals(who, radius, chance = Math.min(0.25 + simulation.difficulty * 0.005)) {
if (Math.random() < chance) {
// simulation.difficulty = 50
const len = Math.floor(Math.min(15, 3 + Math.sqrt(simulation.difficulty))) // simulation.difficulty = 40 on hard mode level 10
const len = Math.floor(Math.min(15, 3 + Math.sqrt(simulation.difficulty)))
const speed = (0.003 + 0.004 * Math.random() + 0.002 * Math.sqrt(simulation.difficulty)) * ((Math.random() < 0.5) ? 1 : -1)
const offSet = 6.28 * Math.random()
for (let i = 0; i < len; i++) ace.orbital(who, radius, i / len * 2 * Math.PI + offSet, speed)
@@ -27431,7 +27431,7 @@ const level = {
me.stroke = "rgb(0,0,0)";
Matter.Body.setDensity(me, 0.00001) //very low density to not mess with the original mob's motion
me.shield = true;
me.damageReduction = 0.05 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.05
me.isUnblockable = true
me.collisionFilter.category = cat.mobShield
me.collisionFilter.mask = cat.bullet;
@@ -27486,7 +27486,7 @@ const level = {
Matter.Body.setDensity(me, 0.00001) //very low density to not mess with the original mob's motion
me.frictionAir = 0;
me.shield = true;
me.damageReduction = 0.075 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.075
me.collisionFilter.category = cat.mobShield
me.collisionFilter.mask = cat.bullet;
for (let i = 0; i < nodes; ++i) {
@@ -27911,7 +27911,7 @@ const level = {
me.isBoss = true;
me.isSlashBoss = true;
me.showHealthBar = false;
me.damageReduction = 0.1 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.1
me.startingDamageReduction = me.damageReduction
me.isInvulnerable = false
me.frictionAir = 0.02
@@ -28646,8 +28646,7 @@ const level = {
const ace = {
spawnOrbitals(who, radius, chance = Math.min(0.25 + simulation.difficulty * 0.005)) {
if (Math.random() < chance) {
// simulation.difficulty = 50
const len = Math.floor(Math.min(15, 3 + Math.sqrt(simulation.difficulty))) // simulation.difficulty = 40 on hard mode level 10
const len = Math.floor(Math.min(15, 3 + Math.sqrt(simulation.difficulty)))
const speed = (0.003 + 0.004 * Math.random() + 0.002 * Math.sqrt(simulation.difficulty)) * ((Math.random() < 0.5) ? 1 : -1)
const offSet = 6.28 * Math.random()
for (let i = 0; i < len; i++) ace.orbital(who, radius, i / len * 2 * Math.PI + offSet, speed)
@@ -28704,7 +28703,7 @@ const level = {
me.stroke = "rgb(0,0,0)";
Matter.Body.setDensity(me, 0.00001) //very low density to not mess with the original mob's motion
me.shield = true;
me.damageReduction = 0.05 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.05
me.isUnblockable = true
me.collisionFilter.category = cat.mobShield
me.collisionFilter.mask = cat.bullet;
@@ -28759,7 +28758,7 @@ const level = {
Matter.Body.setDensity(me, 0.00001) //very low density to not mess with the original mob's motion
me.frictionAir = 0;
me.shield = true;
me.damageReduction = 0.075 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.075
me.collisionFilter.category = cat.mobShield
me.collisionFilter.mask = cat.bullet;
for (let i = 0; i < nodes; ++i) {
@@ -29184,7 +29183,7 @@ const level = {
me.isBoss = true;
me.isSlashBoss = true;
me.showHealthBar = false;
me.damageReduction = 0.1 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.1
me.startingDamageReduction = me.damageReduction
me.isInvulnerable = false
me.frictionAir = 0.02
@@ -31211,7 +31210,7 @@ const level = {
*/
var boss = mob[mob.length - 1];
boss.isBoss = true;
boss.damageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
boss.damageReduction = 0.2
boss.onDeath = function () {
powerUps.spawnBossPowerUp(this.position.x, this.position.y);
level.exit.x = 2560;
@@ -31553,6 +31552,7 @@ const level = {
m.energy += 0.04;
} else {
m.health += 0.001 * (dmg - mob[i].health);
if (m.health > m.maxHealth) m.health = m.maxHealth;
m.displayHealth();
}
} else {
@@ -32317,7 +32317,7 @@ const level = {
// me.torque -= me.inertia * 0.002
spawn.spawnOrbitals(me, radius + 50 + 200 * Math.random())
Matter.Body.setDensity(me, 0.03); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.25
me.isBoss = true;
// spawn.shield(me, x, y, 1); //not working, not sure why
me.onDeath = function () {
@@ -33223,7 +33223,6 @@ const level = {
spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
},
nailGun() {
level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
level.setPosToSpawn(60, -50); //normal spawn
spawn.mapRect(10, -10, 100, 20); //small platform for player
level.exit.x = 1775;
@@ -33318,7 +33317,6 @@ const level = {
spawn.mapRect(1600, -600, 425, 250);
},
shotGun() {
level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
level.setPosToSpawn(60, -50); //normal spawn
spawn.mapRect(10, -10, 100, 20); //small platform for player
level.exit.x = 1775;
@@ -33400,7 +33398,6 @@ const level = {
spawn.mapRect(1600, -600, 425, 250);
},
superBall() {
level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
level.setPosToSpawn(60, -50); //normal spawn
spawn.mapRect(10, -10, 100, 20); //small platform for player
level.exit.x = 1775;
@@ -33484,7 +33481,6 @@ const level = {
spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
},
matterWave() { //fire wave through the map to kill mosb
level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
level.setPosToSpawn(60, -50); //normal spawn
spawn.mapRect(10, -10, 100, 20); //small platform for player
level.exit.x = 1775;
@@ -33571,7 +33567,6 @@ const level = {
spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
},
missile() { //fire a missile to kill mobs and trigger button
level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
level.setPosToSpawn(60, -50); //normal spawn
spawn.mapRect(10, -10, 100, 20); //small platform for player
level.exit.x = 1775;
@@ -33660,7 +33655,6 @@ const level = {
spawn.mapRect(2025, -2800, 1075, 2450);
},
stack() { //stack blocks to get to exit
level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
level.setPosToSpawn(60, -50); //normal spawn
spawn.mapRect(10, -10, 100, 20); //small platform for player
level.exit.x = 1775;
@@ -33712,7 +33706,6 @@ const level = {
spawn.mapVertex(1300, 0, "400 0 -500 0 -300 -125 400 -125"); //base
},
mine() { //kill mobs and tack their bodies
level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
level.setPosToSpawn(300, -50); //normal spawn
spawn.mapRect(250, -10, 100, 20); //small platform for player
level.exit.x = 1775;
@@ -33796,7 +33789,6 @@ const level = {
spawn.mapVertex(1300, 0, "400 0 -600 0 -300 -125 400 -125"); //base
},
grenades() { //jump at the top of the elevator's path to go extra high
level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
level.setPosToSpawn(0, -50); //normal spawn
spawn.mapRect(-50, -10, 100, 20); //small platform for player
level.exit.x = 1900;
@@ -33916,7 +33908,6 @@ const level = {
spawn.nodeGroup(1200, -1500, "grenadier", 7);
},
harpoon() { //jump at the top of the elevator's path to go extra high
level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
level.setPosToSpawn(0, -50); //normal spawn
spawn.mapRect(-50, -10, 100, 20); //small platform for player
level.exit.x = 1900;

View File

@@ -358,7 +358,7 @@ const lore = {
setInterval(() => {
if (Math.random() < 0.5) {
spawn[spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]](1000 * (Math.random() - 0.5), -500 + 200 * (Math.random() - 0.5));
level.difficultyIncrease(simulation.difficultyMode)
// level.difficultyIncrease(simulation.difficultyMode)
} else {
spawn.randomLevelBoss(500 * (Math.random() - 0.5), -500 + 200 * (Math.random() - 0.5))
}
@@ -693,9 +693,9 @@ const lore = {
setInterval(() => {
spawn[spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]](1000 * (Math.random() - 0.5), -500 + 200 * (Math.random() - 0.5));
}, 500); //every 1/2 seconds
setInterval(() => {
level.difficultyIncrease(simulation.difficultyMode)
}, 5000); //every 5 seconds
// setInterval(() => {
// level.difficultyIncrease(simulation.difficultyMode)
// }, 5000); //every 5 seconds
},
() => {
lore.talkingColor = "#dff";

View File

@@ -418,7 +418,7 @@ const m = {
m.drop();
if (simulation.paused) build.pauseGrid() //update the build when paused
},
dmgScale: null, //scales all damage, but not raw .dmg //set in levels.setDifficulty
dmgScale: null, //scales all damage, but not raw .dmg
death() {
if (tech.isImmortal) { //if player has the immortality buff, spawn on the same level with randomized damage
//remove immortality tech
@@ -482,7 +482,7 @@ const m = {
Engine.clear(engine);
simulation.splashReturn();
//if you die after clearing fewer than 4 levels the difficulty settings automatically opens
if ((level.levelsCleared < 4 || level.levelsCleared > 12) && !simulation.isTraining && !simulation.isCheating) document.getElementById("settings-details").open = true;
if ((level.levelsCleared < 4 || level.levelsCleared > 12) && !simulation.isTraining && !simulation.isCheating) document.getElementById("constraint-details").open = true;
}, 5000);
}
},
@@ -567,7 +567,7 @@ const m = {
if (tech.isHarmReduceNoKill && m.lastKillCycle + 300 < m.cycle) dmg *= 0.3
if (tech.squirrelFx !== 1) dmg *= 0.8//Math.pow(0.78, (tech.squirrelFx - 1) / 0.4)
if (tech.isAddBlockMass && m.isHolding) dmg *= 0.1
if (tech.isSpeedHarm && player.speed > 0.1) dmg *= 1 - Math.min((tech.speedAdded + player.speed) * 0.0193, 0.8) //capped at speed of 55
if (tech.isSpeedHarm && (tech.speedAdded + player.speed) > 0.1) dmg *= 1 - Math.min((tech.speedAdded + player.speed) * 0.0193, 0.8) //capped at speed of 55
if (tech.isHarmReduce && input.field) dmg *= 0.1
if (tech.isNeutronium && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.05
if (tech.isBotArmor) dmg *= 0.95 ** b.totalBots()
@@ -716,7 +716,6 @@ const m = {
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
setTimeout(function () {
tech.maxDuplicationEvent()
simulation.wipe = function () { //set wipe to normal
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
@@ -745,7 +744,6 @@ const m = {
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
setTimeout(function () {
tech.maxDuplicationEvent()
simulation.wipe = function () { //set wipe to normal
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
@@ -2178,7 +2176,7 @@ const m = {
}
},
setMaxEnergy(isMessage = true) {
m.maxEnergy = (tech.isMaxEnergyTech ? 0.5 : 1) + tech.bonusEnergy + tech.healMaxEnergyBonus + tech.harmonicEnergy + 2.66 * tech.isGroundState + 1.5 * (m.fieldMode === 1) + (m.fieldMode === 0 || m.fieldMode === 1) * 0.05 * m.coupling + 0.77 * tech.isStandingWaveExpand
m.maxEnergy = (tech.isMaxEnergyTech ? 0.5 : 1) + tech.bonusEnergy + tech.healMaxEnergyBonus + tech.harmonicEnergy + 3 * tech.isGroundState + 1.5 * (m.fieldMode === 1) + (m.fieldMode === 0 || m.fieldMode === 1) * 0.05 * m.coupling + 0.77 * tech.isStandingWaveExpand
if (isMessage) simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-f'>maxEnergy</span> <span class='color-symbol'>=</span> ${(m.maxEnergy.toFixed(2))}`)
},
fieldMeterColor: "#0cf",
@@ -2253,10 +2251,7 @@ const m = {
//calculate a vector from body to player and make it length 1
const diff = Vector.normalise(Vector.sub(who.position, m.pos));
//make a vector for the player's direction of length 1
const dir = {
x: Math.cos(m.angle),
y: Math.sin(m.angle)
};
const dir = { x: Math.cos(m.angle), y: Math.sin(m.angle) };
//the dot product of diff and dir will return how much over lap between the vectors
if (Vector.dot(dir, diff) > m.fieldThreshold) {
return true;
@@ -2867,7 +2862,7 @@ const m = {
case 4: //assembler
return `<strong>+${(0.8 * couple).toFixed(1)}</strong> <strong class='color-f'>energy</strong> per second`
case 5: //plasma
return `<strong>${(1 + 1.5 * couple).toFixed(3)}x</strong> <strong class='color-d'>damage</strong>`
return `<strong>${(1 + 0.015 * couple).toFixed(3)}x</strong> <strong class='color-d'>damage</strong>`
case 6: //time dilation
return `<strong>+${(1 + 0.05 * couple).toFixed(2)}x</strong> longer <strong style='letter-spacing: 2px;'>stopped time</strong>` //<strong>movement</strong>, <strong>jumping</strong>, and
case 7: //cloaking
@@ -4415,7 +4410,7 @@ const m = {
//<br><strong class='color-block'>blocks</strong> can't <strong>collide</strong> with <strong>intangible</strong> mobs
//field <strong>radius</strong> decreases out of <strong>line of sight</strong>
//<strong>unlock</strong> <strong class='color-m'>tech</strong> from other <strong class='color-f'>fields</strong>
description: "use <strong class='color-f'>energy</strong> to guide <strong class='color-block'>blocks</strong><br><strong class='color-m'>tech</strong>, <strong class='color-f'>fields</strong>, and <strong class='color-g'>guns</strong> have <strong>+2</strong> <strong>choices</strong><br><strong>10</strong> <strong class='color-f'>energy</strong> per second",
description: "use <strong class='color-f'>energy</strong> to guide <strong class='color-block'>blocks</strong><br><strong class='color-m'>tech</strong>, <strong class='color-f'>fields</strong>, and <strong class='color-g'>guns</strong> have <strong>+3</strong> <strong class='color-choice'><span>ch</span><span>oi</span><span>ces</span></strong><br><strong>10</strong> <strong class='color-f'>energy</strong> per second",
effect: () => {
m.fieldMeterColor = "#333"
m.eyeFillColor = m.fieldMeterColor

View File

@@ -189,7 +189,6 @@ const powerUps = {
} else {
powerUps.do = () => powerUps.draw();
}
tech.maxDuplicationEvent() //check to see if hitting 100% duplication
} else {
powerUps.draw = powerUps.drawCircle
if (tech.isHealAttract) {
@@ -325,7 +324,6 @@ const powerUps = {
if (tech.isCancelDuplication) {
const value = 0.05
tech.duplication += value
tech.maxDuplicationEvent()
simulation.makeTextLog(`tech.duplicationChance() <span class='color-symbol'>+=</span> ${value}`)
simulation.circleFlare(value);
}
@@ -386,6 +384,129 @@ const powerUps = {
})
},
difficulty: {
name: "difficulty",
color: "#000",
size() {
return 80 / Math.pow(localSettings.difficultyMode, 1.5);
},
effect() {
const initialDifficultyMode = simulation.difficultyMode
requestAnimationFrame(() => { //add a background behind the power up menu
ctx.fillStyle = `rgba(150,150,150,0.9)`;
ctx.fillRect(0, 0, canvas.width, canvas.height);
});
powerUps.animatePowerUpGrab('rgba(0, 0, 0,0.6)')
if (!simulation.paused) {
simulation.paused = true;
simulation.isChoosing = true; //stops p from un pausing on key down
document.body.style.cursor = "auto";
document.getElementById("choose-grid").style.pointerEvents = "auto";
document.getElementById("choose-grid").style.transitionDuration = "0s";
}
//build level info
document.getElementById("choose-grid").classList.add('choose-grid-no-images');
document.getElementById("choose-grid").classList.remove('choose-grid');
document.getElementById("choose-grid").style.gridTemplateColumns = "405px" //adjust this to increase the width of the whole menu, but mostly the center column
let text = `<div>
<div class="grid-container">
<div class="left-column">
<input type="range" id="difficulty-slider" name="temp" type="range" step="1" value="1" min="1" max="6" list="values" />
<datalist id="values">
<option value="1"></option>
<option value="2"></option>
<option value="3"></option>
<option value="4"></option>
<option value="5"></option>
<option value="6"></option>
</datalist>
</div>
<div class="right-column">
<div class="row" id="constraint-1"><strong>0.82x</strong> <strong class='color-d'>damage</strong> done per level
<br><strong>1.25x</strong> <strong class='color-defense'>damage taken</strong> per level</div>
<div class="row" id="constraint-2"><strong>-5</strong> initial <strong>power ups</strong>
<br><strong>faster</strong> and <strong>more</strong> mobs per level</div>
<div class="row" id="constraint-3"><strong>0.82x</strong> <strong class='color-d'>damage</strong> done per level
<br><strong>1.25x</strong> <strong class='color-defense'>damage taken</strong> per level</div>
<div class="row" id="constraint-4"><strong>+1</strong> boss per level, <strong>-1</strong> <strong class='color-m'>tech</strong> per boss
<br><strong>-1</strong> ${powerUps.orb.research()} per level</div>
<div class="row" id="constraint-5"><strong>0.82x</strong> <strong class='color-d'>damage</strong> done per level
<br><strong>1.25x</strong> <strong class='color-defense'>damage taken</strong> per level</div>
<div class="row" id="constraint-6"><strong>3x</strong> chance for <strong>shielded</strong> mobs
<br><strong>-3</strong> initial power ups</div>
</div>
<div class="far-right-column">
<div id = "constraint-1-record">${localSettings.difficultyCompleted[1] ? "⚆" : " "}</div>
<div id = "constraint-2-record">${localSettings.difficultyCompleted[2] ? "⚆" : " "}</div>
<div id = "constraint-3-record">${localSettings.difficultyCompleted[3] ? "⚆" : " "}</div>
<div id = "constraint-4-record">${localSettings.difficultyCompleted[4] ? "⚆" : " "}</div>
<div id = "constraint-5-record">${localSettings.difficultyCompleted[5] ? "⚇" : " "}</div>
<div id = "constraint-6-record">${localSettings.difficultyCompleted[6] ? "⚇" : " "}</div>
</div>
</div>
<div class="choose-grid-module" id="choose-difficulty">
confirm difficulty parameters
</div>
</div>`
document.getElementById("choose-grid").innerHTML = text
//show level info
document.getElementById("choose-grid").style.opacity = "1"
document.getElementById("choose-grid").style.transitionDuration = "0.3s"; //how long is the fade in on
document.getElementById("choose-grid").style.visibility = "visible"
document.getElementById("choose-difficulty").addEventListener("click", () => {
level.unPause()
document.body.style.cursor = "none";
//reset hide image style
if (localSettings.isHideImages) {
document.getElementById("choose-grid").classList.add('choose-grid-no-images');
document.getElementById("choose-grid").classList.remove('choose-grid');
} else {
document.getElementById("choose-grid").classList.add('choose-grid');
document.getElementById("choose-grid").classList.remove('choose-grid-no-images');
}
if (level.levelsCleared === 0 && initialDifficultyMode !== simulation.difficultyMode) {
//remove and respawn all power ups if difficulty mode was changed
for (let i = 0; i < powerUp.length; ++i) Matter.Composite.remove(engine.world, powerUp[i]);
powerUp = [];
level.initialPowerUps()
simulation.trails(30)
}
});
let setConstraintText = function (isReset = true) {
for (let i = 1; i < 7; i++) {
const id = document.getElementById("constraint-" + i)
if (simulation.difficultyMode < i) {
id.style.opacity = "0.15"
} else {
id.style.opacity = "1"
}
}
if (isReset) {
lore.setTechGoal()
localSettings.difficultyMode = simulation.difficultyMode
localSettings.levelsClearedLastGame = 0 //after changing difficulty, reset run history
localSettings.entanglement = undefined //after changing difficulty, reset stored tech
if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
}
}
setConstraintText(false)
document.getElementById("difficulty-slider").value = simulation.difficultyMode
document.getElementById("difficulty-slider").addEventListener("input", () => {
simulation.difficultyMode = document.getElementById("difficulty-slider").value
setConstraintText()
});
for (let i = 1; i < 7; i++) {
document.getElementById("constraint-" + i).addEventListener("click", () => {
simulation.difficultyMode = i
document.getElementById("difficulty-slider").value = simulation.difficultyMode
setConstraintText()
});
}
},
},
coupling: {
name: "coupling",
color: "#0ae", //"#0cf",
@@ -541,6 +662,7 @@ const powerUps = {
overHeal *= 2 //double the over heal converted to max health
//make sure overHeal doesn't kill player
if (m.health - overHeal * m.defense() < 0) overHeal = m.health - 0.01
if (overHeal > m.maxHealth) overHeal = m.maxHealth //just in case overHeal gets too big
tech.extraMaxHealth += overHeal //increase max health
m.setMaxHealth();
m.damage(overHeal);
@@ -944,7 +1066,7 @@ const powerUps = {
}
// console.log(options.length)
if (options.length > 0 || !tech.isSuperDeterminism) {
let totalChoices = 2 + tech.extraChoices + 2 * (m.fieldMode === 8)
let totalChoices = 2 + tech.extraChoices + 3 * (m.fieldMode === 8)
if (tech.isCancelTech && tech.cancelTechCount === 1) {
totalChoices *= 3
tech.cancelTechCount++
@@ -1011,8 +1133,7 @@ const powerUps = {
for (let i = 1; i < m.fieldUpgrades.length; i++) { //skip field emitter
if (i !== m.fieldMode) options.push(i);
}
// let totalChoices = Math.min(options.length, (tech.isDeterminism ? 1 : 2 + tech.extraChoices + 2 * (m.fieldMode === 8)))
let totalChoices = 2 + tech.extraChoices + 2 * (m.fieldMode === 8)
let totalChoices = 2 + tech.extraChoices + 3 * (m.fieldMode === 8)
if (tech.isCancelTech && tech.cancelTechCount === 1) {
totalChoices *= 3
tech.cancelTechCount++
@@ -1092,8 +1213,7 @@ const powerUps = {
}
}
//set total choices
// let totalChoices = (tech.isDeterminism ? 1 : 3 + tech.extraChoices + 2 * (m.fieldMode === 8))
let totalChoices = 3 + tech.extraChoices + 2 * (m.fieldMode === 8)
let totalChoices = 3 + tech.extraChoices + 3 * (m.fieldMode === 8)
if (tech.isCancelTech && tech.cancelTechCount === 1) {
totalChoices *= 3
tech.cancelTechCount++
@@ -1327,6 +1447,7 @@ const powerUps = {
},
spawnDelay(type, count, delay = 2) {
count *= delay
// let totalSpawned = 0
let cycle = () => {
if (count > 0) {
if (m.alive) requestAnimationFrame(cycle);
@@ -1335,6 +1456,8 @@ const powerUps = {
if (!(count % delay)) {
const where = { x: m.pos.x + 50 * (Math.random() - 0.5), y: m.pos.y + 50 * (Math.random() - 0.5) }
powerUps.spawn(where.x, where.y, type);
// totalSpawned++
// if (!(totalSpawned % 10)) delay++
}
}
}
@@ -1400,11 +1523,10 @@ const powerUps = {
powerUps.randomPowerUpCounter++;
powerUpChance(Math.max(level.levelsCleared, 10) * 0.1)
}
if (!(simulation.difficulty > spawn.secondaryBossThreshold)) {
if (!(simulation.difficultyMode > 2 && level.levelsCleared > 1)) {
powerUps.randomPowerUpCounter += 0.6;
powerUpChance(Math.max(level.levelsCleared, 6) * 0.1)
}
function powerUpChance(chanceToFail) {
if (Math.random() * chanceToFail < powerUps.randomPowerUpCounter) {
powerUps.randomPowerUpCounter = 0;
@@ -1446,8 +1568,8 @@ const powerUps = {
powerUps.spawn(x, y, "ammo", false);
}
},
addResearchToLevel() { //add a random power up to a location that has a mob, mostly used to give each level one randomly placed research
if (mob.length && Math.random() < 0.45 - 0.3 * (simulation.difficultyMode > 4)) { //lower chance on why difficulty
addResearchToLevel() { //add a random power up to a location that has a mob, mostly used to give each level a research
if (simulation.difficultyMode < 4 && mob.length) { //don't spawn on higher difficulty settings
const index = Math.floor(Math.random() * mob.length)
powerUps.spawn(mob[index].position.x, mob[index].position.y, "research");
}
@@ -1535,7 +1657,7 @@ const powerUps = {
tech.tech[index].frequency = 0 //banish tech
powerUps.ejectTech(index)
if (m.immuneCycle < m.cycle) m.damage(tech.pauseEjectTech * 0.01)
tech.pauseEjectTech *= 1.2
tech.pauseEjectTech *= 1.3
document.getElementById(`${index}-pause-tech`).style.textDecoration = "line-through"
document.getElementById(`${index}-pause-tech`).style.animation = ""
document.getElementById(`${index}-pause-tech`).onclick = null
@@ -1614,7 +1736,7 @@ const powerUps = {
properties.isDuplicated = true
} else {
properties.inertia = Infinity //prevents rotation for circles only
polygonSides = 0
polygonSides = 12
}
powerUp[index] = Matter.Bodies.polygon(x, y, polygonSides, size, properties);
if (mode) powerUp[index].mode = mode

View File

@@ -192,10 +192,11 @@ const simulation = {
levelsCleared: 0,
difficultyMode: 2, //normal difficulty is 2
difficulty: 0,
dmgScale: null, //set in levels.setDifficulty
constraint: 0,
dmgScale: null,
healScale: 1,
accelScale: null, //set in levels.setDifficulty
CDScale: null, //set in levels.setDifficulty
accelScale: null,
CDScale: null,
molecularMode: Math.floor(4 * Math.random()), //0 spores, 1 missile, 2 ice IX, 3 drones //randomize molecular assembler field type
// dropFPS(cap = 40, time = 15) {
// simulation.fpsCap = cap
@@ -625,8 +626,8 @@ const simulation = {
restoreCamera() {
ctx.restore();
},
trails() {
const swapPeriod = 150
trails(swapPeriod = 150) {
// const swapPeriod = 150
const len = 30
for (let i = 0; i < len; i++) {
setTimeout(function () {
@@ -846,10 +847,7 @@ const simulation = {
level.onLevel = 0;
level.levelsCleared = 0;
//resetting difficulty
// simulation.difficulty = 0;
level.setDifficulty()
simulation.difficultyMode = Number(document.getElementById("difficulty-select").value)
level.updateDifficulty()
simulation.clearNow = true;
document.getElementById("text-log").style.display = "none"
@@ -1143,15 +1141,6 @@ const simulation = {
simulation.updateGunHUD();
}
// for (i = 0, len = b.guns.length; i < len; i++) { //find which gun is mine
// if (b.guns[i].name === "mine") {
// b.guns[i].ammo += count
// if (tech.ammoCap) b.guns[i].ammo = Math.min(tech.ammoCap, b.guns[i].ammo)
// simulation.updateGunHUD();
// break;
// }
// }
if (tech.isMutualism && !tech.isEnergyHealth) {
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].isMutualismActive) {
@@ -1304,7 +1293,7 @@ const simulation = {
for (let i = 0, len = mob.length; i < len; i++) {
if (mob[i].isDropPowerUp && mob[i].alive) count++
}
count *= 0.25 //to fake the 25% chance, this makes it not random, and more predictable
count *= 0.3 //to fake the 25% chance, this makes it not random, and more predictable
let cycle = () => { //run after waiting a cycle for the map to be cleared
const types = ["heal", "ammo", "heal", "ammo", "research", "coupling", "boost", "tech", "gun", "field"]
for (let i = 0; i < count; i++) powerUps.spawnDelay(types[Math.floor(Math.random() * types.length)], 1)

View File

@@ -48,7 +48,8 @@ const spawn = {
// spawn.pickList.push(spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]);
},
spawnChance(chance) {
return Math.random() < chance + 0.07 * simulation.difficulty && mob.length < -1 + 16 * Math.log10(simulation.difficulty + 1)
const difficultyChance = simulation.difficultyMode === 1 ? 1 : simulation.difficulty
return (Math.random() < chance + 0.07 * difficultyChance) && (mob.length < -1 + 16 * Math.log10(simulation.difficulty + 1))
},
randomMob(x, y, chance = 1) {
if (spawn.spawnChance(chance) || chance === Infinity) {
@@ -112,24 +113,8 @@ const spawn = {
}
}
},
secondaryBossThreshold: 22,
secondaryBossChance(x, y) {
// if (tech.isDuplicateMobs && Math.random() < tech.duplicationChance()) {
// tech.isScaleMobsWithDuplication = true
// spawn.randomLevelBoss(x, y);
// tech.isScaleMobsWithDuplication = false
// return true
// } else if (tech.isResearchBoss) {
// if (powerUps.research.count > 2) {
// powerUps.research.changeRerolls(-3)
// simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-r'>research</span> <span class='color-symbol'>-=</span> 3<br>${powerUps.research.count}`)
// } else {
// tech.addJunkTechToPool(0.49)
// }
// spawn.randomLevelBoss(x, y);
// return true
// }
if (simulation.difficulty > spawn.secondaryBossThreshold) { //starts on hard mode level 6, level 12 on easy, level 4 on why?
if (simulation.difficultyMode > 2 && level.levelsCleared > 1) {
spawn.randomLevelBoss(x, y);
} else {
return false
@@ -178,7 +163,7 @@ const spawn = {
// }
// }
if (tech.isMoveMACHO && m.crouch) {
if (tech.isMoveMACHO && m.crouch && input.down) {
Matter.Body.setVelocity(this, Vector.add(Vector.mult(this.velocity, 0.97), Vector.mult(player.velocity, 0.03)))
Matter.Body.setPosition(this, Vector.add(Vector.mult(this.position, 0.95), Vector.mult(player.position, 0.05)))
}
@@ -934,6 +919,12 @@ const spawn = {
me.onDeath = function () {
if (!this.hasRunDeathScript) {
this.hasRunDeathScript = true
//record win on this difficulty level to show up in the difficulty settings as a
if (!simulation.isCheating) {
localSettings.difficultyCompleted[simulation.difficultyMode] = true
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
}
//make a block body to replace this one
//this body is too big to leave behind in the normal way mobs.replace()
const len = body.length;
@@ -1029,8 +1020,6 @@ const spawn = {
}
requestAnimationFrame(loop);
}
// for (let i = 0; i < 3; i++)
level.difficultyIncrease(simulation.difficultyMode) //ramp up damage
//remove power Ups, to avoid spamming console
function removeAll(array) {
for (let i = 0; i < array.length; ++i) Matter.Composite.remove(engine.world, array[i]);
@@ -1274,7 +1263,7 @@ const spawn = {
const me = mob[mob.length - 1];
me.isBoss = true;
Matter.Body.setDensity(me, 0.002); //normal density even though its a boss
me.damageReduction = 0.04 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1); //extra reduction for a boss, because normal density
me.damageReduction = 0.04
me.frictionAir = 0.01;
me.accelMag = 0.0002;
me.onDeath = function () {
@@ -1440,7 +1429,7 @@ const spawn = {
me.cellMassMax = 70
me.collisionFilter.mask = cat.player | cat.bullet //| cat.body | cat.map
Matter.Body.setDensity(me, 0.0001 + 0.00002 * simulation.difficulty) // normal density is 0.001
me.damageReduction = 0.17 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1); //me.damageReductionGoal
me.damageReduction = 0.17
const k = 642 //k=r^2/m
me.split = function () {
@@ -1525,7 +1514,7 @@ const spawn = {
me.onHit = function () { //run this function on hitting player
this.explode();
};
me.damageReduction = 0.14 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1);
me.damageReduction = 0.14
me.doAwake = function () {
this.alwaysSeePlayer();
this.checkStatus();
@@ -1640,7 +1629,7 @@ const spawn = {
powerUps.spawnRandomPowerUp(this.position.x, this.position.y) // manual power up spawn to avoid spawning too many tech with "symbiosis"
}
}
me.damageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.2
//required setup for invulnerable
// me.isInvulnerable = false
me.invulnerabilityCountDown = 0
@@ -1702,7 +1691,7 @@ const spawn = {
} else if (!m.isCloak) {
me.foundPlayer();
}
me.damageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.2
me.isInvulnerable = true
me.startingDamageReduction = me.damageReduction
me.damageReduction = 0
@@ -1780,7 +1769,7 @@ const spawn = {
me.foundPlayer();
}
me.damageReduction = 0.22 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.22
me.isInvulnerable = true
me.startingDamageReduction = me.damageReduction
me.damageReduction = 0
@@ -2157,7 +2146,7 @@ const spawn = {
mobs.spawn(x, y, 5, radius, "rgb(0,200,180)");
let me = mob[mob.length - 1];
me.isBoss = true;
me.damageReduction = 0.09 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.09
me.accelMag = 0.05; //jump height
me.g = 0.003; //required if using this.gravity
me.frictionAir = 0.01;
@@ -2207,7 +2196,7 @@ const spawn = {
// powerUps.spawnBossPowerUp(this.position.x, this.position.y)
// };
// me.lastSpeed = me.speed
// me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
// me.damageReduction = 0.25
// me.do = function() {
// // this.armor();
// this.gravity();
@@ -2279,10 +2268,7 @@ const spawn = {
me.fill = "#28b";
me.rememberFill = me.fill;
me.cd = 0;
me.burstDir = {
x: 0,
y: 0
};
me.burstDir = { x: 0, y: 0 };
me.frictionAir = 0.022;
me.lookTorque = 0.0000014;
me.restitution = 0;
@@ -2386,6 +2372,7 @@ const spawn = {
ctx.fill();
}
}
if (simulation.difficultyMode === 6) spawn.shield(me, x, y);
},
// timeBoss(x, y, radius = 25) {
// mobs.spawn(x, y, 12, radius, "#000");
@@ -2403,7 +2390,7 @@ const spawn = {
// me.onDeath = function() {
// powerUps.spawnBossPowerUp(this.position.x, this.position.y)
// };
// me.damageReduction = 0.23 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
// me.damageReduction = 0.23
// me.do = function() {
// //keep it slow, to stop issues from explosion knock backs
// if (!(simulation.cycle % this.seePlayerFreq)) {
@@ -2483,7 +2470,7 @@ const spawn = {
// toMe(bullet, this.position, this.eventHorizon))
}
};
me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.25
me.do = function () {
//keep it slow, to stop issues from explosion knock backs
if (this.speed > 1) {
@@ -2586,7 +2573,7 @@ const spawn = {
let me = mob[mob.length - 1];
Matter.Body.setDensity(me, 0.003); //extra dense //normal is 0.001 //makes effective life much larger and damage on collision
me.isBoss = true;
me.damageReduction = 0.13 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) //normal is 1, most bosses have 0.25
me.damageReduction = 0.13 //normal is 1, most bosses have 0.25
targets.push(me.id) //add to shield protection
me.friction = 0;
@@ -2675,7 +2662,7 @@ const spawn = {
let me = mob[mob.length - 1];
me.babyList = [] //list of mobs that are apart of this boss
Matter.Body.setDensity(me, 0.0015); //extra dense //normal is 0.001 //makes effective life much larger and damage on collision
me.damageReduction = 0.13 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) //normal is 1, most bosses have 0.25
me.damageReduction = 0.13 //normal is 1, most bosses have 0.25
me.isBoss = true;
me.friction = 0;
@@ -2991,7 +2978,7 @@ const spawn = {
me.laserRange = 350;
me.seeAtDistance2 = 2000000;
me.isBoss = true;
me.damageReduction = 0.35 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) // me.damageReductionGoal
me.damageReduction = 0.35 // me.damageReductionGoal
me.showHealthBar = false; //drawn in this.awake
me.delayLimit = 60 + Math.floor(30 * Math.random());
@@ -3162,7 +3149,7 @@ const spawn = {
mobs.spawn(x, y, 7, radius, '#16576b');
let me = mob[mob.length - 1];
Matter.Body.setDensity(me, 0.002); //extra dense //normal is 0.001 //makes effective life much larger
// me.damageReduction = 0.04 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
// me.damageReduction = 0.04
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);
@@ -3265,7 +3252,7 @@ const spawn = {
mobs.spawn(x, y, 7, radius, color);
let me = mob[mob.length - 1];
Matter.Body.setDensity(me, 0.0025); //extra dense //normal is 0.001 //makes effective life much larger
// me.damageReduction = 0.04 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
// me.damageReduction = 0.04
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);
@@ -3416,7 +3403,7 @@ const spawn = {
let me = mob[mob.length - 1];
me.isBoss = true;
Matter.Body.setDensity(me, 0.005); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.07 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.07
me.startingDamageReduction = me.damageReduction
me.isInvulnerable = false
me.nextHealthThreshold = 0.75
@@ -3607,7 +3594,7 @@ const spawn = {
let me = mob[mob.length - 1];
me.isBoss = true;
Matter.Body.setDensity(me, 0.004); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.1 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.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);
@@ -3699,7 +3686,7 @@ const spawn = {
mobs.spawn(x, y, 3, radius, "rgb(0,235,255)");
let me = mob[mob.length - 1];
me.isBoss = true;
me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.25
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);
@@ -3805,7 +3792,7 @@ const spawn = {
Matter.Body.rotate(me, Math.PI * 0.1);
Matter.Body.setDensity(me, 0.002); //extra dense //normal is 0.001 //makes effective life much larger
me.isBoss = true;
me.damageReduction = 0.034 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.034
me.frictionStatic = 0;
me.friction = 0;
@@ -3903,7 +3890,7 @@ const spawn = {
me.do = function () {
if (player.speed > 5) this.do = this.fire //don't attack until player moves
}
me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.25
me.fire = function () {
// this.armor();
this.checkStatus();
@@ -4004,6 +3991,7 @@ const spawn = {
me.pulseRadius = Math.min(400, 170 + simulation.difficulty * 3)
me.fireDelay = Math.max(75, 140 - simulation.difficulty * 0.5)
me.isFiring = false
spawn.shield(me, x, y);
me.onHit = function () { };
me.canSeeTarget = function () {
const angle = this.angle + Math.PI / 2;
@@ -4124,7 +4112,7 @@ const spawn = {
}
Matter.Body.rotate(me, Math.random() * Math.PI * 2);
me.accelMag = 0.0002 * simulation.accelScale;
// me.frictionAir = 1
spawn.shield(me, x, y);
me.lasers = [] //keeps track of static laser beams
me.laserLimit = simulation.difficultyMode < 3 ? 1 : 2
@@ -4180,7 +4168,7 @@ const spawn = {
if (this.lasers[i].fade > 0.99) {
if (best.who && (best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) { // hitting player
m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage after getting hit
const dmg = 0.05 * simulation.dmgScale;
const dmg = 0.03 * simulation.dmgScale;
m.damage(dmg);
simulation.drawList.push({ //add dmg to draw queue
x: best.x,
@@ -4270,14 +4258,12 @@ const spawn = {
}
Matter.Body.rotate(me, Math.random() * Math.PI * 2);
me.accelMag = 0.0001 * simulation.accelScale;
me.isBoss = true;
me.onDeath = function () {
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
};
Matter.Body.setDensity(me, 0.03); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.25
me.startingDamageReduction = me.damageReduction
me.isInvulnerable = false
me.nextHealthThreshold = 0.75
@@ -4286,17 +4272,13 @@ const spawn = {
if (this.health < this.nextHealthThreshold) {
this.health = this.nextHealthThreshold - 0.01
this.nextHealthThreshold = Math.floor(this.health * 4) / 4 //0.75,0.5,0.25
this.invulnerableCount = 120
this.invulnerableCount = 90
this.isInvulnerable = true
this.damageReduction = 0
// if (this.health > 0.74) this.laserLimit += 2 //increase total lasers once player gets into combat
// this.addLaser()
this.laserDelay = 130
}
};
me.lasers = [] //keeps track of static laser beams
// me.laserLimit = 1 + 2 * (simulation.difficultyMode < 3 ? 1 : 2)
me.laserLimit = 2 + (simulation.difficultyMode < 3 ? 1 : 2)
me.fireDelay = Math.max(75, 140 - simulation.difficulty * 0.5)
me.cycle = 0
@@ -4349,7 +4331,7 @@ const spawn = {
if (this.lasers[i].fade > 0.99) {
if (best.who && (best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) { // hitting player
m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage after getting hit
const dmg = 0.05 * simulation.dmgScale;
const dmg = 0.03 * simulation.dmgScale;
m.damage(dmg);
simulation.drawList.push({ //add dmg to draw queue
x: best.x,
@@ -4412,7 +4394,6 @@ const spawn = {
this.force.y += force.y;
} else { //drift
const force = Vector.mult(Vector.normalise(Vector.sub(this.driftGoal, this.position)), 0.00001 * this.mass)
// const force = Vector.mult(this.driftGoal, 0.0001 * this.mass)
this.force.x += force.x;
this.force.y += force.y;
}
@@ -4452,6 +4433,7 @@ const spawn = {
Matter.Body.rotate(me, Math.random() * Math.PI * 2);
me.accelMag = 0.0001 * simulation.accelScale;
me.laserInterval = 100
spawn.shield(me, x, y);
me.onHit = function () {
//run this function on hitting player
this.explode();
@@ -4529,7 +4511,7 @@ const spawn = {
// me.torque -= me.inertia * 0.002
spawn.spawnOrbitals(me, radius + 50 + 200 * Math.random())
Matter.Body.setDensity(me, 0.03); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.25
me.isBoss = true;
// spawn.shield(me, x, y, 1); //not working, not sure why
me.onDeath = function () {
@@ -4743,7 +4725,7 @@ const spawn = {
// spawn.shield(me, x, y, 1);
Matter.Body.setDensity(me, 0.005); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.12 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.12
me.isBoss = true;
me.onDamage = function () { };
me.onDeath = function () {
@@ -4839,7 +4821,7 @@ const spawn = {
me.restitution = 1
// spawn.spawnOrbitals(me, radius + 50 + 125 * Math.random(), 1)
Matter.Body.setDensity(me, 0.002 + 0.0001 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.09 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.09
me.startingDamageReduction = me.damageReduction
me.isInvulnerable = false
me.nextHealthThreshold = 0.75
@@ -4935,7 +4917,7 @@ const spawn = {
me.isBoss = true;
me.isReactorBoss = true;
Matter.Body.setDensity(me, 0.001); //normal is 0.001
me.damageReduction = 0.04 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.04
me.startingDamageReduction = me.damageReduction
me.isInvulnerable = false
me.nextHealthThreshold = 0.75
@@ -5092,7 +5074,7 @@ const spawn = {
me.isBoss = true;
me.isReactorBoss = true;
Matter.Body.setDensity(me, 0.003); //normal is 0.001
me.damageReduction = 0.1 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.1
me.startingDamageReduction = me.damageReduction
me.inertia = Infinity;
me.isInvulnerable = false
@@ -5185,7 +5167,7 @@ const spawn = {
// me.skipRate = 1 + Math.floor(simulation.difficulty*0.02)
// spawn.shield(me, x, y, 1);
Matter.Body.setDensity(me, 0.001); //normal is 0.001
me.damageReduction = 0.05 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.05
me.startingDamageReduction = me.damageReduction
me.isInvulnerable = false
me.onDamage = function () {
@@ -5292,7 +5274,7 @@ const spawn = {
let me = mob[mob.length - 1];
Matter.Body.rotate(me, 2 * Math.PI * Math.random());
me.isBoss = true;
me.damageReduction = 0.1 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.1
me.startingDamageReduction = me.damageReduction
me.isInvulnerable = false
me.frictionAir = 0.02
@@ -5740,7 +5722,7 @@ const spawn = {
let me = mob[mob.length - 1];
Matter.Body.setDensity(me, 0.001); //extra dense //normal is 0.001 //makes effective life much larger
me.isBoss = true;
me.damageReduction = 0.15 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.15
me.accelMag = 0.0017 * Math.sqrt(simulation.accelScale);
me.frictionAir = 0.01;
@@ -5789,12 +5771,12 @@ const spawn = {
this.isCloaked = true;
this.isBadTarget = true;
this.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob //can't touch player
this.damageReduction = 0.04 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
this.damageReduction = 0.04
}
}
me.deCloak = function () {
if (this.isCloaked) {
this.damageReduction = 0.4 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
this.damageReduction = 0.4
this.isCloaked = false;
this.isBadTarget = false;
this.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob; //can touch player
@@ -5802,7 +5784,7 @@ const spawn = {
}
me.do = function () {
if (this.damageReduction === 0) {
this.damageReduction = 0.04 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
this.damageReduction = 0.04
let i = this.status.length //clear bad status effects
while (i--) {
if (this.status[i].type === "stun" || this.status[i].type === "dot") this.status.splice(i, 1);
@@ -5852,6 +5834,8 @@ const spawn = {
me.showHealthBar = false;
me.memory = 240;
me.isVanished = false;
// spawn.shield(me, x, y); //makes it too hard to stealth
me.onDamage = function () {
if (!this.isVanished && this.health < 0.1 && !this.isStunned && !this.isSlowed) { //if health is below 10% teleport to a random spot on player history, heal, and cloak
this.health = 1;
@@ -5931,6 +5915,7 @@ const spawn = {
me.memory = 900;
me.delay = 60
me.cd = 0;
spawn.shield(me, x, y, 1); // bad for stealth
me.onHit = function () {
if (this.cd < simulation.cycle) {
this.cd = simulation.cycle + this.delay;
@@ -6063,7 +6048,7 @@ const spawn = {
me.collisionFilter.mask = cat.player | cat.bullet //| cat.body
spawn.shield(me, x, y, 1);
const len = Math.floor(Math.min(15, 3 + Math.sqrt(simulation.difficulty))) // simulation.difficulty = 40 on hard mode level 10
const len = Math.floor(Math.min(15, 3 + Math.sqrt(simulation.difficulty)))
const speed = (0.007 + 0.003 * Math.random() + 0.004 * Math.sqrt(simulation.difficulty))
let radiusOrbitals = radius + 125 + 350 * Math.random()
for (let i = 0; i < len; i++) spawn.orbital(me, radiusOrbitals, i / len * 2 * Math.PI, speed)
@@ -6073,7 +6058,7 @@ const spawn = {
me.onDeath = function () {
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
};
me.damageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.2
me.do = function () {
// this.armor();
this.seePlayerCheckByDistance();
@@ -6106,7 +6091,7 @@ const spawn = {
me.onDeath = function () { //helps collisions functions work better after vertex have been changed
// this.vertices = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices))
}
// spawn.shield(me, x, y);
spawn.shield(me, x, y);
me.do = function () {
this.seePlayerByLookingAt();
this.checkStatus();
@@ -6131,7 +6116,7 @@ const spawn = {
me.isBoss = true;
Matter.Body.setDensity(me, 0.01 + 0.0004 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.2
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
me.isVerticesChange = true
@@ -6293,14 +6278,11 @@ const spawn = {
me.accelMag = 0.0005 * simulation.accelScale;
me.frictionAir = 0.05;
me.torque = 0.0001 * me.inertia;
me.fireDir = {
x: 0,
y: 0
};
me.fireDir = { x: 0, y: 0 };
me.onDeath = function () { //helps collisions functions work better after vertex have been changed
// this.vertices = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices))
}
// spawn.shield(me, x, y);
spawn.shield(me, x, y);
me.do = function () {
// this.seePlayerByLookingAt();
this.seePlayerCheck();
@@ -6492,7 +6474,7 @@ const spawn = {
let me = mob[mob.length - 1];
me.isBoss = true;
Matter.Body.setDensity(me, 0.0022 + 0.0002 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.2
me.accelMag = 0.0001 * simulation.accelScale;
me.fireFreq = Math.floor(330 * simulation.CDScale)
@@ -6535,7 +6517,7 @@ const spawn = {
// let me = mob[mob.length - 1];
// me.isBoss = true;
// Matter.Body.setDensity(me, 0.0022 + 0.0002 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
// me.damageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
// me.damageReduction = 0.2
// me.fireFreq = Math.floor(60 * simulation.CDScale)
// me.seePlayerFreq = 15
@@ -6636,7 +6618,7 @@ const spawn = {
// let me = mob[mob.length - 1];
// me.isBoss = true;
// Matter.Body.setDensity(me, 0.0022 + 0.0002 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
// me.damageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
// me.damageReduction = 0.2
// me.accelMag = 0.0001 * simulation.accelScale;
// me.fireFreq = Math.floor(180 * simulation.CDScale)
@@ -6732,7 +6714,7 @@ const spawn = {
});
}
};
me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.25
me.do = function () {
// this.armor();
if (this.grenadeLimiter > 1) this.grenadeLimiter--
@@ -6757,16 +6739,13 @@ const spawn = {
me.accelMag = 0.0006 * simulation.accelScale;
me.frictionAir = 0.05;
me.torque = 0.0001 * me.inertia * (Math.random() > 0.5 ? -1 : 1)
me.fireDir = {
x: 0,
y: 0
};
me.fireDir = { x: 0, y: 0 };
me.onDeath = function () { //helps collisions functions work better after vertex have been changed
spawn.grenade(this.position.x, this.position.y, 200 * simulation.CDScale);
// mob[mob.length - 1].collisionFilter.category = 0
mob[mob.length - 1].collisionFilter.mask = cat.player | cat.map;
}
// spawn.shield(me, x, y);
spawn.shield(me, x, y);
me.do = function () {
this.seePlayerCheck();
this.checkStatus();
@@ -6897,7 +6876,7 @@ const spawn = {
me.onDamage = function () {
this.cycle = 0
};
me.damageReduction = 0.35 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.35
me.do = function () {
Matter.Body.rotate(this, 0.003) //gently spin around
this.checkStatus();
@@ -6919,8 +6898,8 @@ const spawn = {
ctx.moveTo(this.position.x, this.position.y)
ctx.lineTo(mob[i].position.x, mob[i].position.y)
spawn.shield(mob[i], mob[i].position.x, mob[i].position.y, 1, true);
// me.damageReduction = 0.075 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
mob[mob.length - 1].damageReduction = 0.5 * 0.075 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) //shields are extra strong
// me.damageReduction = 0.075
mob[mob.length - 1].damageReduction = 0.5 * 0.075 //shields are extra strong
}
}
if (!this.isShielded && this.alive) spawn.shield(this, this.position.x, this.position.y, 1, true);
@@ -6943,7 +6922,7 @@ const spawn = {
spawn.spawnOrbitals(me, radius + 50 + 100 * Math.random())
Matter.Body.setDensity(me, 0.0025); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.07 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.07
me.startingDamageReduction = me.damageReduction
me.isInvulnerable = false
me.onDeath = function () {
@@ -7033,7 +7012,7 @@ const spawn = {
// this.vertices = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices)) //helps collisions functions work better after vertex have been changed
};
me.onDamage = function () { };
me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.25
me.do = function () {
// this.armor();
this.seePlayerCheck();
@@ -7167,49 +7146,6 @@ const spawn = {
// this.attraction();
};
},
// exploder(x, y, radius = 40 + Math.ceil(Math.random() * 50)) {
// mobs.spawn(x, y, 4, radius, "rgb(255,0,0)");
// let me = mob[mob.length - 1];
// me.onHit = function() { //run this function on hitting player
// this.explode();
// };
// me.g = 0.0003; //required if using this.gravity
// me.seePlayerFreq = 50 + Math.floor(Math.random() * 20)
// me.do = function() {
// this.gravity();
// if (!(simulation.cycle % this.seePlayerFreq)) {
// if (
// this.distanceToPlayer2() < this.seeAtDistance2 &&
// Matter.Query.ray(map, this.position, this.playerPosRandomY()).length === 0 &&
// Matter.Query.ray(body, this.position, this.playerPosRandomY()).length === 0 &&
// !m.isCloak
// ) {
// this.foundPlayer();
// } else if (this.seePlayer.recall) {
// for (let i = 0; i < 20; i++) {
// let history = m.history[(m.cycle - 30 * i) % 600]
// if (Matter.Query.ray(map, this.position, history.position).length === 0) {
// this.seePlayer.recall = this.memory + Math.round(this.memory * Math.random()); //seconds before mob falls a sleep
// this.seePlayer.position.x = history.position.x;
// this.seePlayer.position.y = history.position.y;
// ctx.beginPath();
// ctx.moveTo(this.position.x, this.position.y);
// ctx.lineTo(history.position.x, history.position.y);
// ctx.lineWidth = 5;
// ctx.strokeStyle = "#000";
// ctx.stroke();
// break
// }
// }
// this.lostPlayer();
// }
// }
// this.checkStatus();
// this.attraction();
// };
// },
exploder(x, y, radius = 40 + Math.ceil(Math.random() * 50)) {
mobs.spawn(x, y, 4, radius, "rgb(255,0,0)");
let me = mob[mob.length - 1];
@@ -7218,6 +7154,7 @@ const spawn = {
this.explode();
};
me.g = 0.0004; //required if using this.gravity
spawn.shield(me, x, y);
me.do = function () {
this.gravity();
this.seePlayerCheck();
@@ -7238,7 +7175,7 @@ const spawn = {
me.memory = 250;
me.laserRange = 500;
Matter.Body.setDensity(me, 0.0022 + 0.00022 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.startingDamageReduction = 0.14 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.startingDamageReduction = 0.14
me.damageReduction = 0
me.isInvulnerable = true
@@ -7367,7 +7304,7 @@ const spawn = {
let me = mob[mob.length - 1];
me.isBoss = true;
Matter.Body.setDensity(me, 0.00165 + 0.00011 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.startingDamageReduction = 0.1 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.startingDamageReduction = 0.1
me.damageReduction = 0
me.isInvulnerable = true
@@ -7497,7 +7434,7 @@ const spawn = {
let me = mob[mob.length - 1];
me.isBoss = true;
Matter.Body.setDensity(me, 0.0005 + 0.0002 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.25
me.startingDamageReduction = me.damageReduction
me.isInvulnerable = false
me.nextHealthThreshold = 0.75
@@ -7589,14 +7526,15 @@ const spawn = {
}
};
},
shield(target, x, y, chance = Math.min(0.02 + simulation.difficulty * 0.005, 0.2) + tech.duplicationChance()) {
//chance = Math.min(0.02 + simulation.difficulty * 0.005, 0.2) + tech.duplicationChance()
shield(target, x, y, chance = (simulation.difficultyMode === 6 ? 3 : 1) * 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];
me.stroke = "rgb(220,220,255)";
Matter.Body.setDensity(me, 0.00001) //very low density to not mess with the original mob's motion
me.shield = true;
me.damageReduction = 0.05 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.05
me.isUnblockable = true
me.collisionFilter.category = cat.mobShield
me.collisionFilter.mask = cat.bullet;
@@ -7652,7 +7590,7 @@ const spawn = {
Matter.Body.setDensity(me, 0.00001) //very low density to not mess with the original mob's motion
me.frictionAir = 0;
me.shield = true;
me.damageReduction = 0.075 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.075
me.collisionFilter.category = cat.mobShield
me.collisionFilter.mask = cat.bullet;
for (let i = 0; i < nodes; ++i) {
@@ -7689,8 +7627,7 @@ const spawn = {
},
spawnOrbitals(who, radius, chance = Math.min(0.25 + simulation.difficulty * 0.005)) {
if (Math.random() < chance) {
// simulation.difficulty = 50
const len = Math.floor(Math.min(15, 3 + Math.sqrt(simulation.difficulty))) // simulation.difficulty = 40 on hard mode level 10
const len = Math.floor(Math.min(15, 3 + Math.sqrt(simulation.difficulty)))
const speed = (0.003 + 0.004 * Math.random() + 0.002 * Math.sqrt(simulation.difficulty)) * ((Math.random() < 0.5) ? 1 : -1)
const offSet = 6.28 * Math.random()
for (let i = 0; i < len; i++) spawn.orbital(who, radius, i / len * 2 * Math.PI + offSet, speed)
@@ -7747,7 +7684,7 @@ const spawn = {
let me = mob[mob.length - 1];
me.isBoss = true;
Matter.Body.setDensity(me, 0.0017 + 0.0002 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.1 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0.1
me.stroke = "transparent"; //used for drawGhost
me.seeAtDistance2 = 2000000;
@@ -7956,13 +7893,18 @@ const spawn = {
this.force.x += -0.003;
player.force.x += 0.06;
// player.force.y -= 0.15;
//remove difficulty power up if the wire breaks to prevent getting power ups and then making the difficulty harder
for (let i = 0; i < powerUp.length; ++i) {
if (powerUp[i].name === "difficulty") {
Matter.Composite.remove(engine.world, powerUp[i]);
powerUp.splice(i, 1);
}
}
}
//player is extra heavy from wires
Matter.Body.setVelocity(player, {
x: player.velocity.x,
y: player.velocity.y + 0.3
})
Matter.Body.setVelocity(player, { x: player.velocity.x, y: player.velocity.y + 0.3 })
//player friction from the wires
if (m.pos.x > 700 && player.velocity.x > -2) {
@@ -7974,10 +7916,7 @@ const spawn = {
})
}
//move to player
Matter.Body.setPosition(this, {
x: m.pos.x + (42 * Math.cos(m.angle + Math.PI)),
y: m.pos.y + (42 * Math.sin(m.angle + Math.PI))
})
Matter.Body.setPosition(this, { x: m.pos.x + (42 * Math.cos(m.angle + Math.PI)), y: m.pos.y + (42 * Math.sin(m.angle + Math.PI)) })
}
//draw wire
ctx.beginPath();

View File

@@ -248,22 +248,6 @@ const tech = {
duplicationChance() {
return Math.min(1, Math.max(0, (tech.isPowerUpsVanish ? 0.13 : 0) + (tech.isStimulatedEmission ? 0.2 : 0) + tech.duplication + tech.duplicateChance + 0.05 * tech.isExtraGunField + m.duplicateChance + tech.fieldDuplicate + 0.08 * tech.isDuplicateMobs + 0.03 * tech.isMassProduction + 0.04 * tech.isHealAttract + tech.cloakDuplication + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.6 : 0) + 0.06 * tech.isDupEnergy))
},
isScaleMobsWithDuplication: false,
maxDuplicationEvent() {
if (tech.is100Duplicate && tech.duplicationChance() > 0.99) {
tech.is100Duplicate = false
const range = 1300
tech.isScaleMobsWithDuplication = true
for (let i = 0, len = 9; i < len; i++) {
const angle = 2 * Math.PI * i / len
spawn.randomLevelBoss(m.pos.x + range * Math.cos(angle), m.pos.y + range * Math.sin(angle), spawn.nonCollideBossList);
}
spawn.historyBoss(0, 0)
spawn.pulsarBoss(level.exit.x, level.exit.y, 70, true)
spawn.blockBoss(level.enter.x, level.enter.y)
tech.isScaleMobsWithDuplication = false
}
},
setTechFrequency(name, frequency) {
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].name === name) tech.tech[i].frequency = frequency
@@ -2485,7 +2469,7 @@ const tech = {
},
{
name: "entropic gravity",
description: "<strong>crouching</strong> pulls the <strong class='color-MACHO'>MACHO</strong> towards you<br> <strong>1.5x</strong> to all <strong class='color-MACHO'>MACHO</strong> effects",
description: "<strong>crouching</strong> pulls the <strong class='color-MACHO'>MACHO</strong> towards you<br> <strong>1.5x</strong> for all <strong class='color-MACHO'>MACHO</strong> effects",
maxCount: 1,
count: 0,
frequency: 2,
@@ -2651,7 +2635,7 @@ const tech = {
}
},
{
name: "Abelian group",
name: "abelian group",
description: `<strong>4x</strong> <strong class='color-d'>damage</strong> while <strong class="color-invulnerable">invulnerable</strong>`,
maxCount: 1,
count: 0,
@@ -2709,7 +2693,7 @@ const tech = {
},
{
name: "ground state",
description: "<strong>+266</strong> maximum <strong class='color-f'>energy</strong><br><strong>0.66x</strong> passive <strong class='color-f'>energy</strong> generation",
description: "<strong>+300</strong> maximum <strong class='color-f'>energy</strong><br><strong>0.66x</strong> passive <strong class='color-f'>energy</strong> generation",
maxCount: 1,
count: 0,
frequency: 1,
@@ -4269,26 +4253,6 @@ const tech = {
if (this.count) powerUps.setPowerUpMode(); //needed after adjusting duplication chance
}
},
{
name: "apomixis",
description: `when you reach <strong>100%</strong> <strong class='color-dup'>duplication</strong><br>spawn <strong>11 bosses</strong> with <strong>2x</strong> <strong>durability</strong>`,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
// isInstant: true,
allowed() {
return tech.duplicationChance() > 0.5
},
requires: "duplication chance above 50%",
effect() {
tech.is100Duplicate = true;
tech.maxDuplicationEvent()
},
remove() {
tech.is100Duplicate = false;
}
},
{
name: "stimulated emission",
description: "<strong>+20%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong>,<br><strong>collisions</strong> <span class='color-remove'>eject</span> a random <strong class='color-m'>tech</strong>",
@@ -4482,7 +4446,7 @@ const tech = {
{
name: "paradigm shift",
descriptionFunction() {
return `when <strong>paused</strong> clicking a <strong class='color-m'>tech</strong> <span class='color-remove'>ejects</span> it<br><strong>${tech.pauseEjectTech.toFixed(1)}</strong> ${tech.isEnergyHealth ? "<strong class='color-f'>energy</strong>" : "<strong class='color-h'>health</strong>"} cost <em>(1.2x cost each use)</em>`
return `when <strong>paused</strong> clicking a <strong class='color-m'>tech</strong> <span class='color-remove'>ejects</span> it<br><strong>${tech.pauseEjectTech.toFixed(1)}</strong> ${tech.isEnergyHealth ? "<strong class='color-f'>energy</strong>" : "<strong class='color-h'>health</strong>"} cost <em>(1.3x cost each use)</em>`
},
maxCount: 1,
count: 0,
@@ -5149,7 +5113,7 @@ const tech = {
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isIceCrystals || tech.isSporeFreeze || (m.fieldMode === 4 && simulation.molecularMode === 2) || tech.isIceShot || tech.isNeedleIce || (m.coupling && (m.fieldMode === 3 || m.fieldMode === 0))
return tech.isIceCrystals || tech.isSporeFreeze || (m.fieldMode === 4 && simulation.molecularMode === 2) || tech.isIceShot || tech.isNeedleIce || (m.coupling && (m.fieldMode === 2 || m.fieldMode === 0))
},
requires: "a freeze effect",
effect() {
@@ -5446,11 +5410,11 @@ const tech = {
requires: "wave",
effect() {
tech.waveBeamSpeed *= 0.75;
tech.waveBeamDamage += 0.27 * 0.4 //this sets base wave damage
tech.waveBeamDamage += 0.3 * 0.4 //this sets base wave damage
},
remove() {
tech.waveBeamSpeed = 11;
tech.waveBeamDamage = 0.27 //this sets base wave damage
tech.waveBeamDamage = 0.3 //this sets base wave damage
}
},
{
@@ -8071,7 +8035,7 @@ const tech = {
frequency: 2,
frequencyDefault: 2,
allowed() {
return (m.fieldMode === 10 || m.fieldMode === 4 || m.fieldMode === 8)
return (m.fieldMode === 10 || m.fieldMode === 5 || m.fieldMode === 8) //1 standing wave 2 perfect diamagnetism 3 negative mass 4 molecular assembler 5 plasma torch 6 time dilation 7 metamaterial cloaking 8 pilot wave 9 wormhole 10 grappling hook
},
requires: "plasma torch, grappling hook, pilot wave",
effect() {
@@ -8353,7 +8317,7 @@ const tech = {
{
name: "metamaterial absorber", //quantum eraser
descriptionFunction() {
return `for each mob left <strong>alive</strong> after you exit a <strong>level</strong><br>there is a <strong>25%</strong> chance to spawn a random <strong>power up</strong>`
return `for each mob left <strong>alive</strong> after you exit a <strong>level</strong><br>there is a <strong>30%</strong> chance to spawn a random <strong>power up</strong>`
},
isFieldTech: true,
maxCount: 1,
@@ -9135,7 +9099,7 @@ const tech = {
// },
{
name: "return",
description: "return to the start of the game<br>reduce combat <strong>difficulty</strong> by <strong>2 levels</strong>",
description: "return to the start of the game",
maxCount: 1,
count: 0,
frequency: 0,
@@ -9144,7 +9108,6 @@ const tech = {
allowed: () => true,
requires: "",
effect() {
level.difficultyDecrease(simulation.difficultyMode * 2)
level.onLevel = 0
simulation.clearNow = true //end current level
},
@@ -10657,7 +10620,7 @@ const tech = {
remove() { }
},
{
name: "stubs",
name: "wall jump",
description: "no knees or toes are drawn on the player<br>you can wall climb though",
maxCount: 1,
count: 0,
@@ -10670,11 +10633,12 @@ const tech = {
requires: "",
effect() {
m.skin.stubs()
Matter.Body.scale(player.parts[3], 2, 2);
jumpSensor.vertices[0].x += -22
jumpSensor.vertices[3].x += -22
jumpSensor.vertices[1].x += 22
jumpSensor.vertices[2].x += 22
},
remove() {
// if (this.count) m.resetSkin();
}
remove() { }
},
{
name: "Sleipnir",
@@ -10767,25 +10731,6 @@ const tech = {
if (this.count) m.resetSkin();
}
},
{
name: "wall jump",
description: "jump on walls",
maxCount: 1,
count: 0,
frequency: 0,
isJunk: true,
allowed() {
return !m.isShipMode
},
requires: "",
effect() {
jumpSensor.vertices[0].x += -22
jumpSensor.vertices[3].x += -22
jumpSensor.vertices[1].x += 22
jumpSensor.vertices[2].x += 22
},
remove() { }
},
{
name: "posture",
description: "stand a bit taller",
@@ -10869,7 +10814,7 @@ const tech = {
// },
{
name: "ship",
description: "fly around with no legs<br>reduce combat <strong>difficulty</strong> by <strong>1 level</strong>",
description: "fly around with no legs",
maxCount: 1,
count: 0,
frequency: 0,
@@ -10882,7 +10827,6 @@ const tech = {
effect() {
m.isAltSkin = true
m.shipMode()
level.difficultyDecrease(simulation.difficultyMode)
//unlock relativistic rotation
for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].name === "relativistic rotation") tech.tech[i].frequency = 10
@@ -10983,23 +10927,6 @@ const tech = {
},
remove() { }
},
{
name: "growth hacking",
description: "increase combat <strong>difficulty</strong> by <strong>1 level</strong>",
maxCount: 1,
count: 0,
frequency: 0,
isInstant: true,
isJunk: true,
allowed() {
return true
},
requires: "",
effect() {
level.difficultyIncrease(simulation.difficultyMode)
},
remove() { }
},
{
name: "stun",
description: "<strong>stun</strong> all mobs for up to <strong>8</strong> seconds",
@@ -11045,6 +10972,23 @@ const tech = {
},
remove() { }
},
{
name: "difficulty",
description: "spawn a power up that lets you<br>adjust the simulation <strong>difficulty</strong> parameters",
maxCount: 1,
count: 0,
frequency: 0,
isInstant: true,
isJunk: true,
allowed() {
return level.levelsCleared < 6
},
requires: "before level 6",
effect() {
powerUps.spawn(m.pos.x, m.pos.y, "difficulty");
},
remove() { }
},
{
name: "re-research",
description: `<strong>eject</strong> all your ${powerUps.orb.research(1)}`,
@@ -11083,6 +11027,31 @@ const tech = {
},
remove() { }
},
{
name: "apomixis",
description: `spawn <strong>11 bosses</strong>`,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
isInstant: true,
isJunk: true,
allowed() {
return tech.duplicationChance() > 0.99
},
requires: "duplication chance above 99%",
effect() {
const range = 1300
for (let i = 0, len = 9; i < len; i++) {
const angle = 2 * Math.PI * i / len
spawn.randomLevelBoss(m.pos.x + range * Math.cos(angle), m.pos.y + range * Math.sin(angle), spawn.nonCollideBossList);
}
spawn.historyBoss(0, 0)
spawn.pulsarBoss(level.exit.x, level.exit.y, 70, true)
spawn.blockBoss(level.enter.x, level.enter.y)
},
remove() { }
},
{
name: "mobs!",
descriptionFunction() {
@@ -11762,7 +11731,6 @@ const tech = {
pauseEjectTech: null,
isShieldPierce: null,
isDuplicateMobs: null,
is100Duplicate: null,
isDynamoBotUpgrade: null,
isBlockPowerUps: null,
isDamageAfterKillNoRegen: null,