tech: coupling - +1 coupling, coupling is a new stat that provides different buffs for each field
  releasing this early for feedback about balance and bugs

removed tech Pauli exclusion
  now the perfect diamagnatism coupling effect

snakeBoss tails are closer together
some bosses have a higher vision memory and response time

phonon gets 10% less ammo and 10% less damage
meta-analysis gives 2 research per use
energy drain rework
  in many situations drain no longer scales with regen
  this might have some bad side effects, let me know

bug fixes
  made several tech effects not an arrow function
  timeSkip graphical glitches might be improved
This commit is contained in:
landgreen
2022-08-14 19:43:01 -07:00
parent fee9526268
commit 88f891250b
10 changed files with 450 additions and 352 deletions

View File

@@ -280,10 +280,15 @@ const b = {
}, },
fireCDscale: 1, fireCDscale: 1,
setFireCD() { setFireCD() {
b.fireCDscale = tech.fireRate * tech.slowFire * tech.researchHaste * tech.aimDamage * m.fieldFireRate b.fireCDscale = tech.fireRate * tech.slowFire * tech.researchHaste * tech.aimDamage
if (m.fieldMode === 0) {
b.fireCDscale *= 0.8 ** (m.coupling)
} else if (m.fieldMode === 6) {
b.fireCDscale *= 0.75 * 0.8 ** (m.coupling)
}
if (tech.isFastTime) b.fireCDscale *= 0.5 if (tech.isFastTime) b.fireCDscale *= 0.5
if (tech.isFireRateForGuns) b.fireCDscale *= Math.pow(0.8, b.inventory.length) if (tech.isFireRateForGuns) b.fireCDscale *= Math.pow(0.82, b.inventory.length)
if (tech.isFireMoveLock) b.fireCDscale *= 0.5 if (tech.isFireMoveLock) b.fireCDscale *= 0.55
}, },
fireAttributes(dir, rotate = true) { fireAttributes(dir, rotate = true) {
if (rotate) { if (rotate) {
@@ -4876,7 +4881,7 @@ const b = {
const DIST = Vector.magnitude(sub); const DIST = Vector.magnitude(sub);
const unit = Vector.normalise(sub) const unit = Vector.normalise(sub)
if (DIST < tech.isPlasmaRange * 450 && m.energy > this.drainThreshold) { if (DIST < tech.isPlasmaRange * 450 && m.energy > this.drainThreshold) {
m.energy -= 0.00035 + m.fieldRegen //0.004; //normal plasma field is 0.00008 + m.fieldRegen = 0.00108 m.energy -= 0.00135 //0.004; //normal plasma field is 0.00008 + m.fieldRegen = 0.00108
// if (m.energy < 0) { // if (m.energy < 0) {
// m.fieldCDcycle = m.cycle + 120; // m.fieldCDcycle = m.cycle + 120;
// m.energy = 0; // m.energy = 0;
@@ -5866,7 +5871,7 @@ const b = {
ctx.lineWidth = 2 * tech.wavePacketDamage ctx.lineWidth = 2 * tech.wavePacketDamage
ctx.beginPath(); ctx.beginPath();
const end = 700 * Math.sqrt(tech.isBulletsLastLonger) / Math.sqrt(tech.waveReflections * 0.5) //should equal about 1060 const end = 700 * Math.sqrt(tech.isBulletsLastLonger) / Math.sqrt(tech.waveReflections * 0.5) //should equal about 1060
const damage = 2 * m.dmgScale * tech.wavePacketDamage * tech.waveBeamDamage * (tech.isBulletTeleport ? 1.43 : 1) //damage is lower for large radius mobs, since they feel the waves longer const damage = 1.8 * m.dmgScale * tech.wavePacketDamage * tech.waveBeamDamage * (tech.isBulletTeleport ? 1.43 : 1) //damage is lower for large radius mobs, since they feel the waves longer
for (let i = this.waves.length - 1; i > -1; i--) { for (let i = this.waves.length - 1; i > -1; i--) {
//draw wave //draw wave
@@ -5959,7 +5964,7 @@ const b = {
ctx.lineWidth = 2 * tech.wavePacketDamage ctx.lineWidth = 2 * tech.wavePacketDamage
ctx.beginPath(); ctx.beginPath();
const end = 1100 * tech.isBulletsLastLonger / Math.sqrt(tech.waveReflections * 0.5) //should equal about 1767 const end = 1100 * tech.isBulletsLastLonger / Math.sqrt(tech.waveReflections * 0.5) //should equal about 1767
const damage = 2 * m.dmgScale * tech.wavePacketDamage * tech.waveBeamDamage * (tech.isBulletTeleport ? 1.43 : 1) //damage is lower for large radius mobs, since they feel the waves longer const damage = 1.8 * m.dmgScale * tech.wavePacketDamage * tech.waveBeamDamage * (tech.isBulletTeleport ? 1.43 : 1) //damage is lower for large radius mobs, since they feel the waves longer
for (let i = this.waves.length - 1; i > -1; i--) { for (let i = this.waves.length - 1; i > -1; i--) {
const v1 = Vector.add(this.waves[i].position, Vector.mult(this.waves[i].unit1, this.waves[i].radius)) const v1 = Vector.add(this.waves[i].position, Vector.mult(this.waves[i].unit1, this.waves[i].radius))
@@ -7024,7 +7029,6 @@ const b = {
this.fire = () => { this.fire = () => {
const drain = 0.01 * (tech.isCapacitor ? 10 : 1) / b.fireCDscale const drain = 0.01 * (tech.isCapacitor ? 10 : 1) / b.fireCDscale
if (m.energy > drain) { if (m.energy > drain) {
// m.energy -= m.fieldRegen
if (this.charge < 50 * m.maxEnergy) { if (this.charge < 50 * m.maxEnergy) {
m.energy -= drain m.energy -= drain
this.charge += drain * 100 this.charge += drain * 100
@@ -7106,7 +7110,7 @@ const b = {
// b.photon({ x: m.pos.x + 23 * Math.cos(m.angle), y: m.pos.y + 23 * Math.sin(m.angle) }, m.angle) // b.photon({ x: m.pos.x + 23 * Math.cos(m.angle), y: m.pos.y + 23 * Math.sin(m.angle) }, m.angle)
// }, // },
fireLaser() { fireLaser() {
const drain = m.fieldRegen + tech.laserDrain / b.fireCDscale const drain = 0.001 + tech.laserDrain / b.fireCDscale
if (m.energy < drain) { if (m.energy < drain) {
m.fireCDcycle = m.cycle + 100; // cool down if out of energy m.fireCDcycle = m.cycle + 100; // cool down if out of energy
} else { } else {
@@ -7124,7 +7128,7 @@ const b = {
}, },
firePulse() {}, firePulse() {},
fireSplit() { fireSplit() {
const drain = m.fieldRegen + tech.laserDrain / b.fireCDscale const drain = 0.001 + tech.laserDrain / b.fireCDscale
if (m.energy < drain) { if (m.energy < drain) {
m.fireCDcycle = m.cycle + 100; // cool down if out of energy m.fireCDcycle = m.cycle + 100; // cool down if out of energy
} else { } else {
@@ -7149,7 +7153,7 @@ const b = {
} }
}, },
fireWideBeam() { fireWideBeam() {
const drain = m.fieldRegen + tech.laserDrain / b.fireCDscale const drain = 0.001 + tech.laserDrain / b.fireCDscale
if (m.energy < drain) { if (m.energy < drain) {
m.fireCDcycle = m.cycle + 100; // cool down if out of energy m.fireCDcycle = m.cycle + 100; // cool down if out of energy
} else { } else {
@@ -7214,7 +7218,7 @@ const b = {
} }
}, },
fireHistory() { fireHistory() {
drain = m.fieldRegen + tech.laserDrain / b.fireCDscale drain = 0.001 + tech.laserDrain / b.fireCDscale
if (m.energy < drain) { if (m.energy < drain) {
m.fireCDcycle = m.cycle + 100; // cool down if out of energy m.fireCDcycle = m.cycle + 100; // cool down if out of energy
} else { } else {

View File

@@ -42,7 +42,7 @@ function playerOnGroundCheck(event) {
//falling damage //falling damage
if (tech.isFallingDamage && m.immuneCycle < m.cycle && momentum > 150) { if (tech.isFallingDamage && m.immuneCycle < m.cycle && momentum > 150) {
m.damage(Math.min(Math.sqrt(momentum - 133) * 0.01, 0.25)); m.damage(Math.min(Math.sqrt(momentum - 133) * 0.01, 0.25));
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage for 30 cycles if (m.immuneCycle < m.cycle + m.collisionImmuneCycles) m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage for 30 cycles
} }
} else { } else {
m.yOffGoal = m.yOffWhen.stand; m.yOffGoal = m.yOffWhen.stand;
@@ -148,7 +148,7 @@ function collisionChecks(event) {
if (tech.isPiezo) m.energy += 20.48; if (tech.isPiezo) m.energy += 20.48;
if (tech.isStimulatedEmission) powerUps.ejectTech() if (tech.isStimulatedEmission) powerUps.ejectTech()
if (mob[k].onHit) mob[k].onHit(); if (mob[k].onHit) mob[k].onHit();
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage for 30 cycles if (m.immuneCycle < m.cycle + m.collisionImmuneCycles) m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage for 30 cycles
//extra kick between player and mob //this section would be better with forces but they don't work... //extra kick between player and mob //this section would be better with forces but they don't work...
let angle = Math.atan2(player.position.y - mob[k].position.y, player.position.x - mob[k].position.x); let angle = Math.atan2(player.position.y - mob[k].position.y, player.position.x - mob[k].position.x);
Matter.Body.setVelocity(player, { Matter.Body.setVelocity(player, {
@@ -162,7 +162,7 @@ function collisionChecks(event) {
if (tech.isAnnihilation && !mob[k].shield && !mob[k].isShielded && !mob[k].isBoss && mob[k].isDropPowerUp && m.energy > 0.34 * m.maxEnergy && mob[k].damageReduction > 0) { if (tech.isAnnihilation && !mob[k].shield && !mob[k].isShielded && !mob[k].isBoss && mob[k].isDropPowerUp && m.energy > 0.34 * m.maxEnergy && mob[k].damageReduction > 0) {
m.energy -= 0.33 * Math.max(m.maxEnergy, m.energy) //0.33 * m.energy m.energy -= 0.33 * Math.max(m.maxEnergy, m.energy) //0.33 * m.energy
if (m.immuneCycle === m.cycle + tech.collisionImmuneCycles) m.immuneCycle = 0; //player doesn't go immune to collision damage if (m.immuneCycle === m.cycle + m.collisionImmuneCycles) m.immuneCycle = 0; //player doesn't go immune to collision damage
mob[k].death(); mob[k].death();
simulation.drawList.push({ //add dmg to draw queue simulation.drawList.push({ //add dmg to draw queue
x: pairs[i].activeContacts[0].vertex.x, x: pairs[i].activeContacts[0].vertex.x,
@@ -224,7 +224,7 @@ function collisionChecks(event) {
} }
} }
let dmg = tech.blockDamage * m.dmgScale * v * obj.mass * (tech.isMobBlockFling ? 2.5 : 1) * (tech.isBlockRestitution ? 2.5 : 1); let dmg = tech.blockDamage * m.dmgScale * v * obj.mass * (tech.isMobBlockFling ? 2.5 : 1) * (tech.isBlockRestitution ? 2.5 : 1) * ((m.fieldMode === 0 || m.fieldMode === 8) ? 1 + 0.4 * m.coupling : 1);
if (mob[k].isShielded) dmg *= 0.7 if (mob[k].isShielded) dmg *= 0.7
mob[k].damage(dmg, true); mob[k].damage(dmg, true);

View File

@@ -226,6 +226,17 @@ for (let i = 0, len = tech.tech.length; i < len; i++) {
} }
const build = { const build = {
pauseGrid() { pauseGrid() {
//used for junk estimation
let junkCount = 0
let totalCount = 0
for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed() && !tech.tech[i].isBanished) {
totalCount += tech.tech[i].frequency
if (tech.tech[i].isJunk) junkCount += tech.tech[i].frequency
}
}
// ${m.coupling> 0 ? '<br>'+m.couplingDescription(): ""}
//left side //left side
let botText = "" let botText = ""
if (tech.nailBotCount) botText += `<br>nail-bots: ${tech.nailBotCount}` if (tech.nailBotCount) botText += `<br>nail-bots: ${tech.nailBotCount}`
@@ -248,13 +259,14 @@ const build = {
<br><strong><em>fire rate</em></strong>: ${((1-b.fireCDscale)*100).toFixed(b.fireCDscale < 0.1 ? 2 : 0)}% <br><strong><em>fire rate</em></strong>: ${((1-b.fireCDscale)*100).toFixed(b.fireCDscale < 0.1 ? 2 : 0)}%
<br><strong class='color-dup'>duplication</strong>: ${(tech.duplicationChance()*100).toFixed(0)}% <br><strong class='color-dup'>duplication</strong>: ${(tech.duplicationChance()*100).toFixed(0)}%
<br><strong class='color-coupling'>coupling</strong>: ${(m.coupling).toFixed(2)} <br><strong class='color-coupling'>coupling</strong>: ${(m.coupling).toFixed(2)}
${m.coupling> 0 ? '<br>'+m.couplingDescription(): ""}
${botText} ${botText}
<br> <br>
<br><strong class='color-h'>health</strong>: (${(m.health*100).toFixed(0)} / ${(m.maxHealth*100).toFixed(0)}) <br><strong class='color-h'>health</strong>: (${(m.health*100).toFixed(0)} / ${(m.maxHealth*100).toFixed(0)})
<br><strong class='color-f'>energy</strong>: (${(m.energy*100).toFixed(0)} / ${(m.maxEnergy*100).toFixed(0)}) <br><strong class='color-f'>energy</strong>: (${(m.energy*100).toFixed(0)} / ${(m.maxEnergy*100).toFixed(0)}) +(${(m.fieldRegen*6000).toFixed(0)}/s)
<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} <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}
<br><strong class='color-m'>tech</strong>: ${tech.totalCount} &nbsp; <strong class='color-r'>research</strong>: ${powerUps.research.count} <br><strong class='color-m'>tech</strong>: ${tech.totalCount} &nbsp; <strong class='color-r'>research</strong>: ${powerUps.research.count}
<br><strong class='color-j'>JUNK</strong>: ${(junkCount / totalCount * 100).toFixed(1)}%
<br> <br>
<br>seed: ${Math.initialSeed} <br>seed: ${Math.initialSeed}
<br>level: ${level.levels[level.onLevel]} (${level.difficultyText()}) &nbsp; ${m.cycle} cycles <br>level: ${level.levels[level.onLevel]} (${level.difficultyText()}) &nbsp; ${m.cycle} cycles
@@ -972,7 +984,7 @@ window.addEventListener("keydown", function(event) {
if (m.alive && localSettings.loreCount > 0) { if (m.alive && localSettings.loreCount > 0) {
if (simulation.difficultyMode > 4) { if (simulation.difficultyMode > 4) {
simulation.makeTextLog("<em>testing mode disabled for this difficulty</em>"); simulation.makeTextLog("<em>testing mode disabled for this difficulty</em>");
// break break
} }
if (simulation.testing) { if (simulation.testing) {
simulation.testing = false; simulation.testing = false;
@@ -1281,6 +1293,7 @@ if (localSettings.isAllowed && !localSettings.isEmpty) {
} }
document.getElementById("fps-select").value = localSettings.fpsCapDefault document.getElementById("fps-select").value = localSettings.fpsCapDefault
if (!localSettings.banList) localSettings.banList = ""
if (localSettings.banList.length === 0 || localSettings.banList === "undefined") { if (localSettings.banList.length === 0 || localSettings.banList === "undefined") {
localSettings.banList = "" localSettings.banList = ""
localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage

View File

@@ -16,19 +16,19 @@ const level = {
start() { start() {
if (level.levelsCleared === 0) { //this code only runs on the first level if (level.levelsCleared === 0) { //this code only runs on the first level
// simulation.enableConstructMode() //used to build maps in testing mode // simulation.enableConstructMode() //used to build maps in testing mode
// level.difficultyIncrease(5 * 4) //30 is near max on hard //60 is near max on why // level.difficultyIncrease(1 * 4) //30 is near max on hard //60 is near max on why
// simulation.isHorizontalFlipped = true // simulation.isHorizontalFlipped = true
// m.maxHealth = m.health = 100 // m.maxHealth = m.health = 100
// tech.isRerollDamage = true // tech.isRerollDamage = true
// powerUps.research.changeRerolls(100000) // powerUps.research.changeRerolls(100000)
// m.immuneCycle = Infinity //you can't take damage // m.immuneCycle = Infinity //you can't take damage
// tech.tech[297].frequency = 100 // tech.tech[297].frequency = 100
// m.setField("time dilation") //molecular assembler time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass m.setField("time dilation") //molecular assembler time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass
// b.giveGuns("nail gun") //0 nail gun 1 shotgun 2 super balls 3 matter 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 matter wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.guns[0].ammo = 1000000 // b.guns[0].ammo = 1000000
// tech.giveTech("sentry"); // tech.giveTech("coupling");
// tech.giveTech("MACHO"); // tech.giveTech("time crystals");
// tech.giveTech("elephant's toothpaste") tech.giveTech("retrocausality")
// for (let i = 0; i < 1; ++i) tech.giveTech("slow light") // for (let i = 0; i < 1; ++i) tech.giveTech("slow light")
// for (let i = 0; i < 1; ++i) tech.giveTech("free-electron laser") // for (let i = 0; i < 1; ++i) tech.giveTech("free-electron laser")
// m.damage(0.1); // m.damage(0.1);
@@ -37,7 +37,8 @@ const level = {
// for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "research"); // for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "research");
// spawn.starter(1900, -500, 200) // spawn.starter(1900, -500, 200)
// spawn.snakeSpitBoss(1900, -400) // spawn.beetleBoss(1900, -400)
// spawn.timeBoss(1900, -400)
// for (let i = 0; i < 15; ++i) spawn.starter(1900 + 300 * Math.random(), -500 + 300 * Math.random()) // for (let i = 0; i < 15; ++i) spawn.starter(1900 + 300 * Math.random(), -500 + 300 * Math.random())
// level.testing(); // level.testing();
// for (let i = 0; i < 7; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "research"); // for (let i = 0; i < 7; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "research");
@@ -1134,10 +1135,10 @@ const level = {
player.isInPortal = this.portalPair player.isInPortal = this.portalPair
//teleport //teleport
if (this.portalPair.angle % (Math.PI / 2)) { //if left, right up or down if (this.portalPair.angle % (Math.PI / 2)) { //if left, right up or down
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage for 30 cycles if (m.immuneCycle < m.cycle + m.collisionImmuneCycles) m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage for 30 cycles
Matter.Body.setPosition(player, this.portalPair.portal.position); Matter.Body.setPosition(player, this.portalPair.portal.position);
} else { //if at some odd angle } else { //if at some odd angle
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage for 30 cycles if (m.immuneCycle < m.cycle + m.collisionImmuneCycles) m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage for 30 cycles
Matter.Body.setPosition(player, this.portalPair.position); Matter.Body.setPosition(player, this.portalPair.position);
} }
//rotate velocity //rotate velocity
@@ -1325,7 +1326,7 @@ const level = {
//collision with player //collision with player
if (this.height > 0 && Matter.Query.region([player], this).length && !(m.isCloak)) { if (this.height > 0 && Matter.Query.region([player], this).length && !(m.isCloak)) {
if (m.immuneCycle < m.cycle) { if (m.immuneCycle < m.cycle) {
m.immuneCycle = m.cycle + tech.collisionImmuneCycles; m.immuneCycle = m.cycle + m.collisionImmuneCycles;
m.damage(damage) m.damage(damage)
simulation.drawList.push({ //add dmg to draw queue simulation.drawList.push({ //add dmg to draw queue
x: player.position.x, x: player.position.x,
@@ -1357,7 +1358,7 @@ const level = {
if (this.height > 0 && Matter.Query.region([player], this).length) { if (this.height > 0 && Matter.Query.region([player], this).length) {
if (m.immuneCycle < m.cycle) { if (m.immuneCycle < m.cycle) {
const DRAIN = 0.0022 * (tech.isRadioactiveResistance ? 0.25 : 1) + m.fieldRegen const DRAIN = 0.0032 * (tech.isRadioactiveResistance ? 0.25 : 1)
if (m.energy > DRAIN) { if (m.energy > DRAIN) {
m.energy -= DRAIN m.energy -= DRAIN
// m.damage(damage * (tech.isRadioactiveResistance ? 0.25 : 1) * 0.03) //still take 2% damage while you have energy // m.damage(damage * (tech.isRadioactiveResistance ? 0.25 : 1) * 0.03) //still take 2% damage while you have energy
@@ -10253,7 +10254,7 @@ const level = {
me.onDeath = function() { me.onDeath = function() {
//damage player if in range //damage player if in range
if (distance(player.position, this.position) < pulseRadius && m.immuneCycle < m.cycle) { if (distance(player.position, this.position) < pulseRadius && m.immuneCycle < m.cycle) {
m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage
m.damage(0.02 * simulation.dmgScale); m.damage(0.02 * simulation.dmgScale);
} }
simulation.drawList.push({ //add dmg to draw queue simulation.drawList.push({ //add dmg to draw queue
@@ -10616,7 +10617,7 @@ const level = {
// Trolled // Trolled
const hasCPT = tech.isRewindAvoidDeath; const hasCPT = tech.isRewindAvoidDeath;
tech.isRewindAvoidDeath = false; tech.isRewindAvoidDeath = false;
const DRAIN = 0.002 * (tech.isRadioactiveResistance ? 0.25 : 1) + m.fieldRegen; const DRAIN = 0.002 * (tech.isRadioactiveResistance ? 0.25 : 1) + 0.001;
if (m.energy > DRAIN && !tech.isEnergyHealth) { if (m.energy > DRAIN && !tech.isEnergyHealth) {
m.energy -= DRAIN; m.energy -= DRAIN;
} }
@@ -10698,7 +10699,7 @@ const level = {
if (this.isHeal) { if (this.isHeal) {
m.energy += 0.005; m.energy += 0.005;
} else { } else {
m.energy = Math.max(m.energy - 0.007 - m.fieldRegen, 0); m.energy = Math.max(m.energy - 0.006, 0);
if (m.energy <= 0.01 && m.immuneCycle < m.cycle) m.damage(0.002); if (m.energy <= 0.01 && m.immuneCycle < m.cycle) m.damage(0.002);
} }
}, },
@@ -11640,7 +11641,7 @@ const level = {
// me.onDeath = function() { // me.onDeath = function() {
// //damage player if in range // //damage player if in range
// if (distance(player.position, this.position) < pulseRadius && m.immuneCycle < m.cycle) { // if (distance(player.position, this.position) < pulseRadius && m.immuneCycle < m.cycle) {
// m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage // m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage
// m.damage(0.02 * simulation.dmgScale); // m.damage(0.02 * simulation.dmgScale);
// } // }
// simulation.drawList.push({ //add dmg to draw queue // simulation.drawList.push({ //add dmg to draw queue

View File

@@ -235,7 +235,10 @@ const mobs = {
// }) // })
// } // }
// }, // },
mobSpawnWithHealth: 1,
setMobSpawnHealth() {
mobs.mobSpawnWithHealth = 0.87 ** (tech.mobSpawnWithHealth) //+ (m.fieldMode === 0 || m.fieldMode === 7) * m.coupling
},
//********************************************************************************************** //**********************************************************************************************
//********************************************************************************************** //**********************************************************************************************
spawn(xPos, yPos, sides, radius, color) { spawn(xPos, yPos, sides, radius, color) {
@@ -256,7 +259,7 @@ const mobs = {
onHit: undefined, onHit: undefined,
alive: true, alive: true,
index: i, index: i,
health: tech.mobSpawnWithHealth, health: mobs.mobSpawnWithHealth,
showHealthBar: true, showHealthBar: true,
accelMag: 0.001 * simulation.accelScale, accelMag: 0.001 * simulation.accelScale,
cd: 0, //game cycle when cooldown will be over cd: 0, //game cycle when cooldown will be over
@@ -602,7 +605,7 @@ const mobs = {
const hitPlayer = Matter.Query.ray([player], this.position, Vector.add(this.position, Vector.mult(perp, radius * 2.05)), minorRadius) const hitPlayer = Matter.Query.ray([player], this.position, Vector.add(this.position, Vector.mult(perp, radius * 2.05)), minorRadius)
if (hitPlayer.length && m.immuneCycle < m.cycle) { if (hitPlayer.length && m.immuneCycle < m.cycle) {
m.damage(dmg * simulation.dmgScale); m.damage(dmg * simulation.dmgScale);
// m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage // m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage
} }
}, },
searchSpring() { searchSpring() {

View File

@@ -56,12 +56,20 @@ const m = {
light: 100, light: 100,
}, },
setFillColors() { setFillColors() {
this.fillColor = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light}%)` m.fillColor = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light}%)`
this.fillColorDark = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light - 25}%)` m.fillColorDark = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light - 25}%)`
let grd = ctx.createLinearGradient(-30, 0, 30, 0); let grd = ctx.createLinearGradient(-30, 0, 30, 0);
grd.addColorStop(0, m.fillColorDark); grd.addColorStop(0, m.fillColorDark);
grd.addColorStop(1, m.fillColor); grd.addColorStop(1, m.fillColor);
this.bodyGradient = grd m.bodyGradient = grd
},
setFillColorsAlpha(alpha = 0.5) {
m.fillColor = `hsla(${m.color.hue},${m.color.sat}%,${m.color.light}%,${alpha})`
m.fillColorDark = `hsla(${m.color.hue},${m.color.sat}%,${m.color.light - 25}%,${alpha})`
let grd = ctx.createLinearGradient(-30, 0, 30, 0);
grd.addColorStop(0, m.fillColorDark);
grd.addColorStop(1, m.fillColor);
m.bodyGradient = grd
}, },
height: 42, height: 42,
yOffWhen: { yOffWhen: {
@@ -498,7 +506,7 @@ const m = {
}, },
baseHealth: 1, baseHealth: 1,
setMaxHealth() { setMaxHealth() {
m.maxHealth = m.baseHealth + tech.extraMaxHealth + tech.isFallingDamage + 4 * tech.isFlipFlop * tech.isFlipFlopOn * tech.isFlipFlopHealth m.maxHealth = m.baseHealth + tech.extraMaxHealth + tech.isFallingDamage + 4 * tech.isFlipFlop * tech.isFlipFlopOn * tech.isFlipFlopHealth + (m.fieldMode === 0 || m.fieldMode === 5) * 0.5 * m.coupling
document.getElementById("health-bg").style.width = `${Math.floor(300 * m.maxHealth)}px` document.getElementById("health-bg").style.width = `${Math.floor(300 * m.maxHealth)}px`
simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-h'>maxHealth</span> <span class='color-symbol'>=</span> ${m.maxHealth.toFixed(2)}`) simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-h'>maxHealth</span> <span class='color-symbol'>=</span> ${m.maxHealth.toFixed(2)}`)
if (m.health > m.maxHealth) m.health = m.maxHealth; if (m.health > m.maxHealth) m.health = m.maxHealth;
@@ -532,6 +540,7 @@ const m = {
if (tech.isEntanglement && b.inventory[0] === b.activeGun) { if (tech.isEntanglement && b.inventory[0] === b.activeGun) {
for (let i = 0, len = b.inventory.length; i < len; i++) dmg *= 0.87 // 1 - 0.15 for (let i = 0, len = b.inventory.length; i < len; i++) dmg *= 0.87 // 1 - 0.15
} }
if (m.fieldMode === 0 || m.fieldMode === 3) dmg *= 0.75 ** m.coupling
return dmg return dmg
}, },
rewind(steps) { // m.rewind(Math.floor(Math.min(599, 137 * m.energy))) rewind(steps) { // m.rewind(Math.floor(Math.min(599, 137 * m.energy)))
@@ -599,7 +608,7 @@ const m = {
} }
} }
m.energy = Math.max(m.energy - steps / 150, 0.01) m.energy = Math.max(m.energy - steps / 150, 0.01)
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage for 30 cycles if (m.immuneCycle < m.cycle + m.collisionImmuneCycles) m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage for 30 cycles
let isDrawPlayer = true let isDrawPlayer = true
const shortPause = function() { const shortPause = function() {
@@ -647,6 +656,7 @@ const m = {
} }
} }
}, },
collisionImmuneCycles: 30,
damage(dmg) { damage(dmg) {
if (tech.isRewindAvoidDeath && m.energy > 0.6 && dmg > 0.01) { if (tech.isRewindAvoidDeath && m.energy > 0.6 && dmg > 0.01) {
const steps = Math.floor(Math.min(299, 150 * m.energy)) const steps = Math.floor(Math.min(299, 150 * m.energy))
@@ -845,7 +855,7 @@ const m = {
ctx.rotate(m.angle); ctx.rotate(m.angle);
ctx.beginPath(); ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI); ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.fillStyle = this.bodyGradient ctx.fillStyle = m.bodyGradient
ctx.fill(); ctx.fill();
ctx.arc(15, 0, 4, 0, 2 * Math.PI); ctx.arc(15, 0, 4, 0, 2 * Math.PI);
ctx.strokeStyle = "#333"; ctx.strokeStyle = "#333";
@@ -873,7 +883,7 @@ const m = {
ctx.rotate(m.angle); ctx.rotate(m.angle);
ctx.beginPath(); ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI); ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.fillStyle = this.bodyGradient ctx.fillStyle = m.bodyGradient
ctx.fill(); ctx.fill();
ctx.arc(15, 0, 4, 0, 2 * Math.PI); ctx.arc(15, 0, 4, 0, 2 * Math.PI);
ctx.strokeStyle = "#333"; ctx.strokeStyle = "#333";
@@ -902,7 +912,6 @@ const m = {
// these values are set on reset by setHoldDefaults() // these values are set on reset by setHoldDefaults()
fieldFx: 1, fieldFx: 1,
fieldJump: 1, fieldJump: 1,
fieldFireRate: 1,
blockingRecoil: 4, blockingRecoil: 4,
grabPowerUpRange2: 0, grabPowerUpRange2: 0,
isFieldActive: false, isFieldActive: false,
@@ -935,7 +944,7 @@ const m = {
fieldArc: 0, fieldArc: 0,
fieldThreshold: 0, fieldThreshold: 0,
calculateFieldThreshold() { calculateFieldThreshold() {
m.fieldThreshold = Math.cos(m.fieldArc * Math.PI) m.fieldThreshold = Math.cos((m.fieldArc) * Math.PI)
}, },
setHoldDefaults() { setHoldDefaults() {
if (tech.isFreeWormHole && m.fieldUpgrades[m.fieldMode].name !== "wormhole") { if (tech.isFreeWormHole && m.fieldUpgrades[m.fieldMode].name !== "wormhole") {
@@ -947,7 +956,6 @@ const m = {
if (removed) powerUps.directSpawn(m.pos.x, m.pos.y, "tech"); if (removed) powerUps.directSpawn(m.pos.x, m.pos.y, "tech");
} }
if (m.energy < m.maxEnergy) m.energy = m.maxEnergy; if (m.energy < m.maxEnergy) m.energy = m.maxEnergy;
// m.fieldRegen = 0.001
m.fieldMeterColor = "#0cf" m.fieldMeterColor = "#0cf"
m.eyeFillColor = m.fieldMeterColor m.eyeFillColor = m.fieldMeterColor
m.fieldShieldingScale = 1; m.fieldShieldingScale = 1;
@@ -956,7 +964,6 @@ const m = {
m.lastHit = 0 m.lastHit = 0
m.isSneakAttack = false m.isSneakAttack = false
m.duplicateChance = 0 m.duplicateChance = 0
powerUps.setDupChance();
m.grabPowerUpRange2 = 156000; m.grabPowerUpRange2 = 156000;
m.blockingRecoil = 4; m.blockingRecoil = 4;
m.fieldRange = 155; m.fieldRange = 155;
@@ -965,10 +972,9 @@ const m = {
m.isCloak = false; m.isCloak = false;
player.collisionFilter.mask = cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield player.collisionFilter.mask = cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield
m.airSpeedLimit = 125 m.airSpeedLimit = 125
m.fieldFireRate = 1
b.setFireCD();
m.fieldFx = 1 m.fieldFx = 1
m.fieldJump = 1 m.fieldJump = 1
m.setFieldRegen();
m.setMovement(); m.setMovement();
m.drop(); m.drop();
m.holdingMassScale = 0.5; m.holdingMassScale = 0.5;
@@ -976,7 +982,7 @@ const m = {
m.calculateFieldThreshold(); //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob) m.calculateFieldThreshold(); //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
m.isBodiesAsleep = true; m.isBodiesAsleep = true;
m.wakeCheck(); m.wakeCheck();
m.setMaxEnergy(); m.couplingChange()
m.hole = { m.hole = {
isOn: false, isOn: false,
isReady: false, isReady: false,
@@ -991,12 +997,12 @@ const m = {
} }
}, },
setMaxEnergy() { setMaxEnergy() {
m.maxEnergy = (tech.isMaxEnergyTech ? 0.5 : 1) + tech.bonusEnergy + tech.healMaxEnergyBonus + tech.harmonicEnergy + 2 * tech.isGroundState + 3 * tech.isRelay * tech.isFlipFlopOn * tech.isRelayEnergy + 0.6 * (m.fieldUpgrades[m.fieldMode].name === "standing wave") m.maxEnergy = (m.fieldMode === 0 || m.fieldMode === 1) * 0.4 * m.coupling + (tech.isMaxEnergyTech ? 0.5 : 1) + tech.bonusEnergy + tech.healMaxEnergyBonus + tech.harmonicEnergy + 2 * tech.isGroundState + 3 * tech.isRelay * tech.isFlipFlopOn * tech.isRelayEnergy + 0.6 * (m.fieldUpgrades[m.fieldMode].name === "standing wave")
// if (tech.isEnergyHealth) m.maxEnergy *= Math.sqrt(m.harmReduction()) // if (tech.isEnergyHealth) m.maxEnergy *= Math.sqrt(m.harmReduction())
simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-f'>maxEnergy</span> <span class='color-symbol'>=</span> ${(m.maxEnergy.toFixed(2))}`) 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", fieldMeterColor: "#0cf",
drawFieldMeter(bgColor = "rgba(0, 0, 0, 0.4)", range = 60) { drawRegenEnergy(bgColor = "rgba(0, 0, 0, 0.4)", range = 60) {
if (m.energy < m.maxEnergy) { if (m.energy < m.maxEnergy) {
m.regenEnergy(); m.regenEnergy();
ctx.fillStyle = bgColor; ctx.fillStyle = bgColor;
@@ -1014,8 +1020,8 @@ const m = {
ctx.fillRect(xOff, yOff, range * m.energy, 10); ctx.fillRect(xOff, yOff, range * m.energy, 10);
} }
}, },
drawFieldMeterCloaking: function() { drawRegenEnergyCloaking: function() {
if (m.energy < m.maxEnergy) { // replaces m.drawFieldMeter() with custom code if (m.energy < m.maxEnergy) { // replaces m.drawRegenEnergy() with custom code
m.regenEnergy(); m.regenEnergy();
const xOff = m.pos.x - m.radius * m.maxEnergy const xOff = m.pos.x - m.radius * m.maxEnergy
const yOff = m.pos.y - 50 const yOff = m.pos.y - 50
@@ -1030,7 +1036,22 @@ const m = {
ctx.stroke(); ctx.stroke();
} }
}, },
regenEnergy: function() { //used in drawFieldMeter // rewritten by some tech setFieldRegen() {
if (m.fieldMode === 6) {
m.fieldRegen = 0.003 //18 energy per second
} else if (m.fieldMode === 4) {
m.fieldRegen = 0.002 //12 energy per second
} else {
m.fieldRegen = 0.001 //6 energy per second
}
if (m.fieldMode === 0 || m.fieldMode === 4) m.fieldRegen += 0.001 * m.coupling
if (tech.isTimeCrystals) {
m.fieldRegen *= 3
} else if (tech.isGroundState) {
m.fieldRegen *= 0.5
}
},
regenEnergy: function() { //used in drawRegenEnergy // rewritten by some tech
if (m.immuneCycle < m.cycle) m.energy += m.fieldRegen; if (m.immuneCycle < m.cycle) m.energy += m.fieldRegen;
if (m.energy < 0) m.energy = 0 if (m.energy < 0) m.energy = 0
}, },
@@ -1428,7 +1449,6 @@ const m = {
} }
}, },
lookForPickUp() { //find body to pickup lookForPickUp() { //find body to pickup
if (m.energy > m.fieldRegen) m.energy -= m.fieldRegen;
const grabbing = { const grabbing = {
targetIndex: null, targetIndex: null,
targetRange: 150, targetRange: 150,
@@ -1521,27 +1541,61 @@ const m = {
couplingDescription() { couplingDescription() {
switch (m.fieldMode) { switch (m.fieldMode) {
case 0: //field emitter case 0: //field emitter
return `gain the effects of all <strong class='color-f'>fields</strong>` return `gain the effects of <strong>all</strong> other <strong class='color-f'>fields</strong>`
case 1: //standing wave case 1: //standing wave
return `<strong>+20</strong> max <strong class='color-f'>energy</strong> per <strong class='color-coupling'>coupling</strong>` return `<strong>+40</strong> max <strong class='color-f'>energy</strong> per <strong class='color-coupling'>coupling</strong>`
case 2: //perfect diamagnetism case 2: //perfect diamagnetism
return `<strong>+10°</strong> <strong>arc</strong> per <strong class='color-coupling'>coupling</strong>` return `<span style = 'font-size:89%;'><strong>invulnerable</strong> <strong>+3</strong> seconds post collision per <strong class='color-coupling'>coupling</strong></span>`
case 3: //negative mass case 3: //negative mass
return `<strong>+25%</strong> <strong class='color-defense'>defense</strong> per <strong class='color-coupling'>coupling</strong>` return `<strong>+20%</strong> <strong class='color-defense'>defense</strong> per <strong class='color-coupling'>coupling</strong>`
case 4: //assembler case 4: //assembler
return `generate <strong>4</strong> <strong class='color-f'>energy</strong> per second per <strong class='color-coupling'>coupling</strong>` return `generate <strong>6</strong> <strong class='color-f'>energy</strong> per second per <strong class='color-coupling'>coupling</strong>`
case 5: //plasma case 5: //plasma
return `<strong>+13%</strong> <strong class='color-d'>damage</strong> per <strong class='color-coupling'>coupling</strong>` return `<strong>+50</strong> max <strong class='color-h'>health</strong> per <strong class='color-coupling'>coupling</strong>`
case 6: //time dilation case 6: //time dilation
return `<strong>+20%</strong> <strong><em>fire rate</em></strong> per <strong class='color-coupling'>coupling</strong>` //<strong>movement</strong>, <strong>jumping</strong>, and return `<strong>+20%</strong> <strong><em>fire rate</em></strong> per <strong class='color-coupling'>coupling</strong>` //<strong>movement</strong>, <strong>jumping</strong>, and
case 7: //cloaking case 7: //cloaking
return `remove <strong>+10%</strong> mob <strong>durability</strong> per <strong class='color-coupling'>coupling</strong>` return `<strong>+15%</strong> <strong class='color-d'>damage</strong> per <strong class='color-coupling'>coupling</strong>`
case 8: //pilot wave case 8: //pilot wave
return `________ per <strong class='color-coupling'>coupling</strong>` return `<strong>+40%</strong> <strong class='color-block'>block</strong> collision <strong class='color-d'>damage</strong> per <strong class='color-coupling'>coupling</strong>`
case 9: //wormhole case 9: //wormhole
return `<strong>+5%</strong> <strong class='color-dup'>duplication</strong> per <strong class='color-coupling'>coupling</strong>` return `<strong>+5%</strong> <strong class='color-dup'>duplication</strong> per <strong class='color-coupling'>coupling</strong>`
} }
}, },
couplingChange() {
m.setMaxEnergy();
m.setMaxHealth();
m.setFieldRegen()
mobs.setMobSpawnHealth();
powerUps.setDupChance();
b.setFireCD();
m.collisionImmuneCycles = 30 + m.coupling * 180
// switch (m.fieldMode) {
// case 0: //field emitter
// // m.fieldFireRate = 0.8 ** (m.coupling)
// // b.setFireCD();
// break
// // case 1: //standing wave
// // break
// // case 2: //perfect diamagnetism
// // break
// // case 3: //negative mass
// // break
// // case 4: //assembler
// // break
// // case 5: //plasma
// // break
// case 6: //time dilation
// // m.fieldFireRate = 0.75 * 0.8 ** (m.coupling)
// break
// // case 7: //cloaking
// // break
// // case 8: //pilot wave
// // break
// // case 9: //wormhole
// // break
// }
},
setField(index) { setField(index) {
if (isNaN(index)) { //find index by name if (isNaN(index)) { //find index by name
let found = false let found = false
@@ -1572,6 +1626,7 @@ const m = {
m.holding(); m.holding();
m.throwBlock(); m.throwBlock();
} else if ((input.field && m.fieldCDcycle < m.cycle)) { //not hold but field button is pressed } else if ((input.field && m.fieldCDcycle < m.cycle)) { //not hold but field button is pressed
if (m.energy > m.fieldRegen) m.energy -= m.fieldRegen
m.grabPowerUp(); m.grabPowerUp();
m.lookForPickUp(); m.lookForPickUp();
if (m.energy > 0.05) { if (m.energy > 0.05) {
@@ -1583,7 +1638,7 @@ const m = {
} else { } else {
m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists) m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
} }
m.drawFieldMeter() m.drawRegenEnergy()
} }
} }
}, },
@@ -1667,6 +1722,7 @@ const m = {
m.holding(); m.holding();
m.throwBlock(); m.throwBlock();
} else if ((input.field) && m.fieldCDcycle < m.cycle) { //not hold but field button is pressed } else if ((input.field) && m.fieldCDcycle < m.cycle) { //not hold but field button is pressed
if (m.energy > m.fieldRegen) m.energy -= m.fieldRegen
m.grabPowerUp(); m.grabPowerUp();
m.lookForPickUp(); m.lookForPickUp();
} else if (m.holdingTarget && m.fieldCDcycle < m.cycle) { //holding, but field button is released } else if (m.holdingTarget && m.fieldCDcycle < m.cycle) { //holding, but field button is released
@@ -1686,7 +1742,7 @@ const m = {
} }
m.harmonicShield() m.harmonicShield()
} }
m.drawFieldMeter() m.drawRegenEnergy()
} }
} }
}, },
@@ -1835,6 +1891,7 @@ const m = {
m.holding(); m.holding();
m.throwBlock(); m.throwBlock();
} else if (input.field) { //not hold but field button is pressed } else if (input.field) { //not hold but field button is pressed
if (m.energy > m.fieldRegen) m.energy -= m.fieldRegen
m.grabPowerUp(); m.grabPowerUp();
m.lookForPickUp(); m.lookForPickUp();
m.fieldPosition = { x: m.pos.x, y: m.pos.y } m.fieldPosition = { x: m.pos.x, y: m.pos.y }
@@ -1883,8 +1940,8 @@ const m = {
m.perfectPush(true); m.perfectPush(true);
} }
} }
// m.drawFieldMeter() // m.drawRegenEnergy()
m.drawFieldMeter("rgba(0,0,0,0.2)") m.drawRegenEnergy("rgba(0,0,0,0.2)")
if (tech.isPerfectBrake) { //cap mob speed around player if (tech.isPerfectBrake) { //cap mob speed around player
const range = 200 + 140 * wave + 150 * m.energy const range = 200 + 140 * wave + 150 * m.energy
for (let i = 0; i < mob.length; i++) { for (let i = 0; i < mob.length; i++) {
@@ -1925,6 +1982,7 @@ const m = {
m.holding(); m.holding();
m.throwBlock(); m.throwBlock();
} else if (input.field && m.fieldCDcycle < m.cycle) { //push away } else if (input.field && m.fieldCDcycle < m.cycle) { //push away
if (m.energy > m.fieldRegen) m.energy -= m.fieldRegen
m.grabPowerUp(); m.grabPowerUp();
m.lookForPickUp(); m.lookForPickUp();
const DRAIN = 0.00035 const DRAIN = 0.00035
@@ -2035,8 +2093,8 @@ const m = {
// } // }
// } // }
// } // }
//draw zero-G range //draw zero-G range
if (!simulation.isTimeSkipping) {
ctx.beginPath(); ctx.beginPath();
ctx.arc(m.pos.x, m.pos.y, this.fieldDrawRadius, 0, 2 * Math.PI); ctx.arc(m.pos.x, m.pos.y, this.fieldDrawRadius, 0, 2 * Math.PI);
ctx.fillStyle = "#f5f5ff"; ctx.fillStyle = "#f5f5ff";
@@ -2044,6 +2102,7 @@ const m = {
ctx.fill(); ctx.fill();
ctx.globalCompositeOperation = "source-over"; ctx.globalCompositeOperation = "source-over";
} }
}
} else if (m.holdingTarget && m.fieldCDcycle < m.cycle) { //holding, but field button is released } else if (m.holdingTarget && m.fieldCDcycle < m.cycle) { //holding, but field button is released
m.pickUp(); m.pickUp();
this.fieldDrawRadius = 0 this.fieldDrawRadius = 0
@@ -2051,7 +2110,7 @@ const m = {
m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists) m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
this.fieldDrawRadius = 0 this.fieldDrawRadius = 0
} }
m.drawFieldMeter("rgba(0,0,0,0.2)") m.drawRegenEnergy("rgba(0,0,0,0.2)")
} }
} }
}, },
@@ -2136,6 +2195,7 @@ const m = {
m.holding(); m.holding();
m.throwBlock(); m.throwBlock();
} else if ((input.field && m.fieldCDcycle < m.cycle)) { //not hold but field button is pressed } else if ((input.field && m.fieldCDcycle < m.cycle)) { //not hold but field button is pressed
if (m.energy > m.fieldRegen) m.energy -= m.fieldRegen
m.grabPowerUp(); m.grabPowerUp();
m.lookForPickUp(); m.lookForPickUp();
if (m.energy > 0.05) { if (m.energy > 0.05) {
@@ -2147,8 +2207,7 @@ const m = {
} else { } else {
m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists) m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
} }
m.regenEnergy() m.drawRegenEnergy()
m.drawFieldMeter()
} }
} }
}, },
@@ -2177,7 +2236,7 @@ const m = {
// } else { // } else {
// m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists) // m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
// } // }
// m.drawFieldMeter("rgba(0, 0, 0, 0.2)") // m.drawRegenEnergy("rgba(0, 0, 0, 0.2)")
// if (tech.isExtruder) { // if (tech.isExtruder) {
// if (input.field) { // if (input.field) {
@@ -2434,6 +2493,7 @@ const m = {
m.holding(); m.holding();
m.throwBlock(); m.throwBlock();
} else if (input.field && m.fieldCDcycle < m.cycle) { //not hold but field button is pressed } else if (input.field && m.fieldCDcycle < m.cycle) { //not hold but field button is pressed
if (m.energy > m.fieldRegen) m.energy -= m.fieldRegen
m.grabPowerUp(); m.grabPowerUp();
m.lookForPickUp(); m.lookForPickUp();
@@ -2514,7 +2574,7 @@ const m = {
m.plasmaBall.fire() m.plasmaBall.fire()
} }
} }
m.drawFieldMeter("rgba(0, 0, 0, 0.2)") m.drawRegenEnergy("rgba(0, 0, 0, 0.2)")
m.plasmaBall.do() m.plasmaBall.do()
} }
} else if (tech.isExtruder) { } else if (tech.isExtruder) {
@@ -2525,6 +2585,7 @@ const m = {
m.holding(); m.holding();
m.throwBlock(); m.throwBlock();
} else if (input.field && m.fieldCDcycle < m.cycle) { //not hold but field button is pressed } else if (input.field && m.fieldCDcycle < m.cycle) { //not hold but field button is pressed
if (m.energy > m.fieldRegen) m.energy -= m.fieldRegen
m.grabPowerUp(); m.grabPowerUp();
m.lookForPickUp(); m.lookForPickUp();
b.extruder(); b.extruder();
@@ -2533,7 +2594,7 @@ const m = {
} else { } else {
m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists) m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
} }
m.drawFieldMeter("rgba(0, 0, 0, 0.2)") m.drawRegenEnergy("rgba(0, 0, 0, 0.2)")
if (input.field) { if (input.field) {
b.wasExtruderOn = true b.wasExtruderOn = true
} else { } else {
@@ -2565,6 +2626,7 @@ const m = {
m.holding(); m.holding();
m.throwBlock(); m.throwBlock();
} else if (input.field && m.fieldCDcycle < m.cycle) { //not hold but field button is pressed } else if (input.field && m.fieldCDcycle < m.cycle) { //not hold but field button is pressed
if (m.energy > m.fieldRegen) m.energy -= m.fieldRegen
m.grabPowerUp(); m.grabPowerUp();
m.lookForPickUp(); m.lookForPickUp();
b.plasma(); b.plasma();
@@ -2573,7 +2635,7 @@ const m = {
} else { } else {
m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists) m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
} }
m.drawFieldMeter("rgba(0, 0, 0, 0.2)") m.drawRegenEnergy("rgba(0, 0, 0, 0.2)")
} }
} }
}, },
@@ -2592,9 +2654,6 @@ const m = {
// m.fieldMeterColor = "#ff0" // m.fieldMeterColor = "#ff0"
m.fieldMeterColor = "#3fe" m.fieldMeterColor = "#3fe"
m.eyeFillColor = m.fieldMeterColor m.eyeFillColor = m.fieldMeterColor
m.fieldFireRate = 0.75
b.setFireCD();
m.fieldFx = 1.2 m.fieldFx = 1.2
m.fieldJump = 1.09 m.fieldJump = 1.09
m.setMovement(); m.setMovement();
@@ -2654,6 +2713,9 @@ const m = {
m.throwBlock(); m.throwBlock();
m.wakeCheck(); m.wakeCheck();
} else if (input.field && m.fieldCDcycle < m.cycle) { //not hold but field button is pressed } else if (input.field && m.fieldCDcycle < m.cycle) { //not hold but field button is pressed
const drain = 0.002
if (m.energy > drain) m.energy -= drain
m.grabPowerUp(); m.grabPowerUp();
if (this.rewindCount === 0) m.lookForPickUp(); if (this.rewindCount === 0) m.lookForPickUp();
@@ -2716,13 +2778,11 @@ const m = {
this.rewindCount = 0; this.rewindCount = 0;
m.wakeCheck(); m.wakeCheck();
} }
if (m.energy < m.maxEnergy) m.regenEnergy(); //extra energy regen m.drawRegenEnergy() // this calls m.regenEnergy(); also
m.drawFieldMeter() // this calls m.regenEnergy(); also
} }
} else { } else {
m.fieldFire = true; m.fieldFire = true;
m.isBodiesAsleep = false; m.isBodiesAsleep = false;
m.drain = 0.002
m.hold = function() { m.hold = function() {
if (m.isHolding) { if (m.isHolding) {
m.wakeCheck(); m.wakeCheck();
@@ -2730,17 +2790,16 @@ const m = {
m.holding(); m.holding();
m.throwBlock(); m.throwBlock();
} else if (input.field && m.fieldCDcycle < m.cycle) { } else if (input.field && m.fieldCDcycle < m.cycle) {
const drain = 0.0026
if (m.energy > drain) m.energy -= drain
m.grabPowerUp(); m.grabPowerUp();
m.lookForPickUp(); m.lookForPickUp(); //this drains energy 0.001
if (m.energy > m.drain) { if (m.energy > drain) {
m.energy -= m.drain; timeStop();
if (m.energy < m.drain) { //out of energy } else { //holding, but field button is released
m.fieldCDcycle = m.cycle + 120; m.fieldCDcycle = m.cycle + 120;
m.energy = 0; m.energy = 0;
m.wakeCheck(); m.wakeCheck();
}
timeStop();
} else { //holding, but field button is released
m.wakeCheck(); m.wakeCheck();
} }
} else if (tech.isTimeStop && player.speed < 1 && m.onGround && m.fireCDcycle < m.cycle && !input.fire) { } else if (tech.isTimeStop && player.speed < 1 && m.onGround && m.fireCDcycle < m.cycle && !input.fire) {
@@ -2765,9 +2824,7 @@ const m = {
m.wakeCheck(); m.wakeCheck();
m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists) m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
} }
if (m.energy < m.maxEnergy) m.regenEnergy(); //extra energy regen m.drawRegenEnergy()
if (m.energy < m.maxEnergy) m.regenEnergy(); //extra energy regen
m.drawFieldMeter()
} }
} }
}, },
@@ -2813,6 +2870,7 @@ const m = {
m.holding(); m.holding();
m.throwBlock(); m.throwBlock();
} else if (input.field && m.fieldCDcycle < m.cycle) { //not hold and field button is pressed } else if (input.field && m.fieldCDcycle < m.cycle) { //not hold and field button is pressed
if (m.energy > m.fieldRegen) m.energy -= m.fieldRegen
m.grabPowerUp(); m.grabPowerUp();
m.lookForPickUp(); m.lookForPickUp();
} else if (m.holdingTarget && m.fieldCDcycle < m.cycle) { //holding target exists, and field button is not pressed } else if (m.holdingTarget && m.fieldCDcycle < m.cycle) { //holding target exists, and field button is not pressed
@@ -2825,6 +2883,15 @@ const m = {
if (m.fireCDcycle + 30 < m.cycle && !input.fire) { //automatically cloak if not firing if (m.fireCDcycle + 30 < m.cycle && !input.fire) { //automatically cloak if not firing
if (!m.isCloak) { if (!m.isCloak) {
m.isCloak = true //enter cloak m.isCloak = true //enter cloak
// m.color = {
// hue: 0,
// sat: 0,
// light: 100
// }
// m.setFillColorsAlpha(0)
m.enterCloakCycle = m.cycle m.enterCloakCycle = m.cycle
if (tech.isCloakHealLastHit && m.lastHit > 0) { if (tech.isCloakHealLastHit && m.lastHit > 0) {
const heal = Math.min(0.75 * m.lastHit, m.energy) const heal = Math.min(0.75 * m.lastHit, m.energy)
@@ -2914,7 +2981,7 @@ const m = {
player.collisionFilter.mask = cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield //normal collisions player.collisionFilter.mask = cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield //normal collisions
} }
} }
this.drawFieldMeterCloaking() this.drawRegenEnergyCloaking()
//show sneak attack status //show sneak attack status
// if (m.cycle > m.lastKillCycle + 240) { // if (m.cycle > m.lastKillCycle + 240) {
// if (m.sneakAttackCharge > 0) { // if (m.sneakAttackCharge > 0) {
@@ -3258,7 +3325,7 @@ const m = {
m.fieldOn = false m.fieldOn = false
m.fieldRadius = 0 m.fieldRadius = 0
} }
m.drawFieldMeter("rgba(0,0,0,0.2)") m.drawRegenEnergy("rgba(0,0,0,0.2)")
} }
} }
}, },
@@ -3685,7 +3752,7 @@ const m = {
// } else { // } else {
// m.hole.isReady = true; // m.hole.isReady = true;
// } // }
m.drawFieldMeter() m.drawRegenEnergy()
} }
}, },
@@ -3771,7 +3838,7 @@ const m = {
// m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists) // m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
// } // }
// } // }
// m.drawFieldMeter() // m.drawRegenEnergy()
// }, // },
}, },
], ],
@@ -3955,7 +4022,7 @@ const m = {
//body //body
ctx.beginPath(); ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI); ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.fillStyle = this.bodyGradient ctx.fillStyle = m.bodyGradient
ctx.fill(); ctx.fill();
ctx.arc(15, 0, 4, 0, 2 * Math.PI); ctx.arc(15, 0, 4, 0, 2 * Math.PI);
ctx.strokeStyle = "#333"; ctx.strokeStyle = "#333";
@@ -3998,7 +4065,7 @@ const m = {
if (tech.isPiezo) m.energy += 20.48; if (tech.isPiezo) m.energy += 20.48;
if (tech.isStimulatedEmission) powerUps.ejectTech() if (tech.isStimulatedEmission) powerUps.ejectTech()
if (mob[k].onHit) mob[k].onHit(); if (mob[k].onHit) mob[k].onHit();
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage for 30 cycles if (m.immuneCycle < m.cycle + m.collisionImmuneCycles) m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage for 30 cycles
//extra kick between player and mob //this section would be better with forces but they don't work... //extra kick between player and mob //this section would be better with forces but they don't work...
let angle = Math.atan2(player.position.y - mob[k].position.y, player.position.x - mob[k].position.x); let angle = Math.atan2(player.position.y - mob[k].position.y, player.position.x - mob[k].position.x);
Matter.Body.setVelocity(player, { Matter.Body.setVelocity(player, {

View File

@@ -825,15 +825,20 @@ const powerUps = {
if (!tech.isSuperDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("tech",true)'>${tech.isCancelTech ? "?":"✕"}</div>` if (!tech.isSuperDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("tech",true)'>${tech.isCancelTech ? "?":"✕"}</div>`
text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>tech</h3>` text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>tech</h3>`
//used for junk estimation
let junkCount = 0
let totalCount = 0
let options = []; //generate all options let options = []; //generate all options
optionLengthNoDuplicates = 0 optionLengthNoDuplicates = 0
for (let i = 0; i < tech.tech.length; i++) { for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed() && !tech.tech[i].isBanished) { if (tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed() && !tech.tech[i].isBanished) {
totalCount += tech.tech[i].frequency
if (tech.tech[i].isJunk) junkCount += tech.tech[i].frequency
if (tech.tech[i].frequency > 0) optionLengthNoDuplicates++ if (tech.tech[i].frequency > 0) optionLengthNoDuplicates++
for (let j = 0, len = tech.tech[i].frequency; j < len; j++) options.push(i); for (let j = 0, len = tech.tech[i].frequency; j < len; j++) options.push(i);
} }
} }
// console.log(optionLengthNoDuplicates, options.length)
function removeOption(index) { function removeOption(index) {
for (let i = options.length; i > -1; i--) { for (let i = options.length; i > -1; i--) {
@@ -1202,7 +1207,7 @@ const powerUps = {
randomPowerUpCounter: 0, randomPowerUpCounter: 0,
spawnBossPowerUp(x, y) { //boss spawns field and gun tech upgrades spawnBossPowerUp(x, y) { //boss spawns field and gun tech upgrades
if (level.levels[level.onLevel] !== "final") { if (level.levels[level.onLevel] !== "final") {
if (m.fieldMode === 0) { if (m.fieldMode === 0 && !m.coupling) {
powerUps.spawn(x, y, "field") powerUps.spawn(x, y, "field")
} else { } else {
powerUps.randomPowerUpCounter++; powerUps.randomPowerUpCounter++;

View File

@@ -241,6 +241,7 @@ const spawn = {
tech.isHarmMACHO = false; tech.isHarmMACHO = false;
} }
me.do = function() { me.do = function() {
if (!simulation.isTimeSkipping) {
const sine = Math.sin(simulation.cycle * 0.015) const sine = Math.sin(simulation.cycle * 0.015)
this.radius = 370 * (1 + 0.1 * sine) this.radius = 370 * (1 + 0.1 * sine)
//chase player //chase player
@@ -281,6 +282,7 @@ const spawn = {
ctx.lineWidth = 1; ctx.lineWidth = 1;
ctx.stroke(); ctx.stroke();
} }
}
}, },
WIMP(x = level.exit.x + tech.wimpCount * 200 * (Math.random() - 0.5), y = level.exit.y + tech.wimpCount * 200 * (Math.random() - 0.5)) { //immortal mob that follows player //if you have the tech it spawns at start of every level at the exit WIMP(x = level.exit.x + tech.wimpCount * 200 * (Math.random() - 0.5), y = level.exit.y + tech.wimpCount * 200 * (Math.random() - 0.5)) { //immortal mob that follows player //if you have the tech it spawns at start of every level at the exit
mobs.spawn(x, y, 3, 0.1, "transparent"); mobs.spawn(x, y, 3, 0.1, "transparent");
@@ -1296,7 +1298,7 @@ const spawn = {
// Matter.Body.setDensity(me, 0.001); //normal is 0.001 // Matter.Body.setDensity(me, 0.001); //normal is 0.001
me.collisionFilter.mask = cat.bullet | cat.player | cat.body | cat.map me.collisionFilter.mask = cat.bullet | cat.player | cat.body | cat.map
me.memory = Infinity; me.memory = Infinity;
me.seePlayerFreq = 20 me.seePlayerFreq = 17
me.lockedOn = null; me.lockedOn = null;
if (vertices === 9) { if (vertices === 9) {
//on primary spawn //on primary spawn
@@ -1359,7 +1361,7 @@ const spawn = {
y: 0 y: 0
}) })
} }
this.seePlayerByHistory(); this.seePlayerByHistory(50);
this.attraction(); this.attraction();
this.checkStatus(); this.checkStatus();
}; };
@@ -2724,7 +2726,7 @@ const spawn = {
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
Matter.Body.rotate(me, Math.random() * Math.PI * 2); Matter.Body.rotate(me, Math.random() * Math.PI * 2);
me.accelMag = 0.0006 + 0.0007 * Math.sqrt(simulation.accelScale); me.accelMag = 0.0006 + 0.0007 * Math.sqrt(simulation.accelScale);
me.frictionAir = 0.05; me.frictionAir = 0.04;
// me.seePlayerFreq = 40 + Math.floor(13 * Math.random()) // me.seePlayerFreq = 40 + Math.floor(13 * Math.random())
me.memory = 240; me.memory = 240;
me.restitution = 1; me.restitution = 1;
@@ -2761,7 +2763,7 @@ const spawn = {
const angle = this.angle + Math.PI / 2; const angle = this.angle + Math.PI / 2;
c = Math.cos(angle) * this.fireDir.x + Math.sin(angle) * this.fireDir.y; c = Math.cos(angle) * this.fireDir.x + Math.sin(angle) * this.fireDir.y;
const threshold = 0.4; const threshold = 0.4;
const turn = 0.00003 * this.inertia const turn = 0.000025 * this.inertia
if (c > threshold) { if (c > threshold) {
this.torque += turn; this.torque += turn;
} else if (c < -threshold) { } else if (c < -threshold) {
@@ -2793,7 +2795,7 @@ const spawn = {
Matter.Body.rotate(me, Math.random() * Math.PI * 2); Matter.Body.rotate(me, Math.random() * Math.PI * 2);
me.accelMag = 0.00045 + 0.0005 * Math.sqrt(simulation.accelScale); me.accelMag = 0.00045 + 0.0005 * Math.sqrt(simulation.accelScale);
me.frictionAir = 0.05; me.frictionAir = 0.05;
me.seePlayerFreq = 20 me.seePlayerFreq = 13
me.memory = 420; me.memory = 420;
me.restitution = 1; me.restitution = 1;
me.frictionStatic = 0; me.frictionStatic = 0;
@@ -2902,7 +2904,7 @@ const spawn = {
} }
}; };
me.do = function() { me.do = function() {
this.seePlayerByHistory() this.seePlayerByHistory(50)
this.checkStatus(); this.checkStatus();
if (this.isInvulnerable) { if (this.isInvulnerable) {
this.invulnerableCount-- this.invulnerableCount--
@@ -3329,7 +3331,7 @@ const spawn = {
} }
me.do = function() { me.do = function() {
// this.armor(); // this.armor();
this.seePlayerByHistory() this.seePlayerByHistory(40)
if (this.nextBlinkCycle < simulation.cycle && this.seePlayer.yes) { //teleport towards the player if (this.nextBlinkCycle < simulation.cycle && this.seePlayer.yes) { //teleport towards the player
this.nextBlinkCycle = simulation.cycle + this.delay; this.nextBlinkCycle = simulation.cycle + this.delay;
const dist = Vector.sub(this.seePlayer.position, this.position); const dist = Vector.sub(this.seePlayer.position, this.position);
@@ -4424,13 +4426,13 @@ const spawn = {
} }
//time dilation //time dilation
if (!simulation.isTimeSkipping) { if (!simulation.isTimeSkipping) {
// requestAnimationFrame(() => { requestAnimationFrame(() => {
// simulation.timePlayerSkip(2)
// m.walk_cycle += m.flipLegs * m.Vx //makes the legs look like they are moving fast
// }); //wrapping in animation frame prevents errors, probably
simulation.timePlayerSkip(2) simulation.timePlayerSkip(2)
m.walk_cycle += m.flipLegs * m.Vx //makes the legs look like they are moving fast m.walk_cycle += m.flipLegs * m.Vx //makes the legs look like they are moving fast
}); //wrapping in animation frame prevents errors, probably
// simulation.timePlayerSkip(2)
// m.walk_cycle += m.flipLegs * m.Vx //makes the legs look like they are moving fast
//draw invulnerable //draw invulnerable
ctx.beginPath(); ctx.beginPath();
@@ -4516,7 +4518,7 @@ const spawn = {
powerUps.spawnBossPowerUp(this.position.x, this.position.y) powerUps.spawnBossPowerUp(this.position.x, this.position.y)
}; };
me.do = function() { me.do = function() {
this.seePlayerByHistory(); this.seePlayerByHistory(40);
this.attraction(); this.attraction();
this.checkStatus(); this.checkStatus();
this.sword() //does various things depending on what stage of the sword swing this.sword() //does various things depending on what stage of the sword swing
@@ -5659,7 +5661,7 @@ const spawn = {
// spawn.seeker(where.x, where.y); //give the bullet a rotational velocity as if they were attached to a vertex // spawn.seeker(where.x, where.y); //give the bullet a rotational velocity as if they were attached to a vertex
}; };
me.do = function() { me.do = function() {
this.seePlayerByHistory(); this.seePlayerByHistory(60);
this.attraction(); this.attraction();
this.checkStatus(); this.checkStatus();
this.eventHorizon = 900 + 200 * Math.sin(simulation.cycle * 0.005) this.eventHorizon = 900 + 200 * Math.sin(simulation.cycle * 0.005)
@@ -5673,12 +5675,14 @@ const spawn = {
// // simulation.loop(); //ending with a wipe and normal loop fixes some very minor graphical issues where things are draw in the wrong locations // // simulation.loop(); //ending with a wipe and normal loop fixes some very minor graphical issues where things are draw in the wrong locations
// }); //wrapping in animation frame prevents errors, probably // }); //wrapping in animation frame prevents errors, probably
// requestAnimationFrame(() => { //
// simulation.timePlayerSkip(1) // simulation.timePlayerSkip(1)
// m.walk_cycle += m.flipLegs * m.Vx //makes the legs look like they are moving fast // m.walk_cycle += m.flipLegs * m.Vx //makes the legs look like they are moving fast
// }); //wrapping in animation frame prevents errors, probably // }); //wrapping in animation frame prevents errors, probably
requestAnimationFrame(() => {
simulation.timePlayerSkip(1) simulation.timePlayerSkip(1)
}); //wrapping in animation frame prevents errors, probably
m.walk_cycle += m.flipLegs * m.Vx //makes the legs look like they are moving fast m.walk_cycle += m.flipLegs * m.Vx //makes the legs look like they are moving fast
ctx.beginPath(); ctx.beginPath();
@@ -5925,12 +5929,11 @@ const spawn = {
}; };
}, },
snakeSpitBoss(x, y, radius = 50) { snakeSpitBoss(x, y, radius = 50) {
const nodes = Math.min(8 + Math.ceil(0.5 * simulation.difficulty), 40)
let angle = Math.PI let angle = Math.PI
let mag = 300 const tailRadius = 300
const color1 = "rgb(235,180,255)" const color1 = "rgb(235,180,255)"
mobs.spawn(x + mag * Math.cos(angle), y + mag * Math.sin(angle), 8, radius, color1); //"rgb(55,170,170)" mobs.spawn(x + tailRadius * Math.cos(angle), y + tailRadius * Math.sin(angle), 8, radius, color1); //"rgb(55,170,170)"
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.isBoss = true; me.isBoss = true;
me.accelMag = 0.0001 + 0.0004 * Math.sqrt(simulation.accelScale) me.accelMag = 0.0001 + 0.0004 * Math.sqrt(simulation.accelScale)
@@ -5938,7 +5941,7 @@ const spawn = {
me.memory = 250; me.memory = 250;
me.laserRange = 500; 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 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.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) me.startingDamageReduction = 0.14 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0 me.damageReduction = 0
me.isInvulnerable = true me.isInvulnerable = true
@@ -5956,7 +5959,7 @@ const spawn = {
me.cycle = 0 me.cycle = 0
me.do = function() { me.do = function() {
// this.armor(); // this.armor();
this.seePlayerByHistory() this.seePlayerByHistory(40)
this.checkStatus(); this.checkStatus();
this.attraction(); this.attraction();
this.cycle++ this.cycle++
@@ -6017,24 +6020,19 @@ const spawn = {
} }
}; };
//extra space to give head room //extra space to give head room
angle -= 0.1 angle -= 0.07
mag -= 10
let previousTailID = 0 let previousTailID = 0
const nodes = Math.min(10 + Math.ceil(0.6 * simulation.difficulty), 60)
const damping = 1
const stiffness = 1
for (let i = 0; i < nodes; ++i) { for (let i = 0; i < nodes; ++i) {
angle -= 0.15 + i * 0.008 angle -= 0.1
mag -= (i < 2) ? -15 : 5 spawn.snakeBody(x + tailRadius * Math.cos(angle), y + tailRadius * Math.sin(angle), i === 0 ? 25 : 20);
spawn.snakeBody(x + mag * Math.cos(angle), y + mag * Math.sin(angle), i === 0 ? 25 : 20);
// mag -= 5
// spawn.snakeBody(x + mag * Math.cos(angle), y + mag * Math.sin(angle), 20);
if (i < 3) mob[mob.length - 1].snakeHeadID = me.id if (i < 3) mob[mob.length - 1].snakeHeadID = me.id
mob[mob.length - 1].previousTailID = previousTailID mob[mob.length - 1].previousTailID = previousTailID
previousTailID = mob[mob.length - 1].id previousTailID = mob[mob.length - 1].id
} }
const damping = 1
const stiffness = 1
this.constrain2AdjacentMobs(nodes, stiffness, false, damping); this.constrain2AdjacentMobs(nodes, stiffness, false, damping);
for (let i = mob.length - 1, len = i - nodes; i > len; i--) { //set alternating colors for (let i = mob.length - 1, len = i - nodes; i > len; i--) { //set alternating colors
if (i % 2) { if (i % 2) {
mob[i].fill = "#778" mob[i].fill = "#778"
@@ -6064,21 +6062,21 @@ const spawn = {
damping: damping damping: damping
}); });
Composite.add(engine.world, consBB[consBB.length - 1]); Composite.add(engine.world, consBB[consBB.length - 1]);
// spawn.shield(me, x, y, 1);
}, },
dragonFlyBoss(x, y, radius = 42) { //snake boss with a laser head dragonFlyBoss(x, y, radius = 42) { //snake boss with a laser head
let angle = Math.PI let angle = Math.PI
let mag = 300 const tailRadius = 300
mobs.spawn(x + mag * Math.cos(angle), y + mag * Math.sin(angle), 8, radius, "#000"); //"rgb(55,170,170)" mobs.spawn(x + tailRadius * Math.cos(angle), y + tailRadius * Math.sin(angle), 8, radius, "#000"); //"rgb(55,170,170)"
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.isBoss = true; 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 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.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) me.startingDamageReduction = 0.14 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
me.damageReduction = 0 me.damageReduction = 0
me.isInvulnerable = true me.isInvulnerable = true
me.accelMag = 0.0001 + 0.0004 * Math.sqrt(simulation.accelScale) me.accelMag = 0.00008 + 0.00045 * Math.sqrt(simulation.accelScale)
me.memory = 250; me.memory = 250;
me.seePlayerFreq = 13
me.flapRate = 0.4 me.flapRate = 0.4
me.flapArc = 0.2 //don't go past 1.57 for normal flaps me.flapArc = 0.2 //don't go past 1.57 for normal flaps
me.wingLength = 150 me.wingLength = 150
@@ -6092,7 +6090,7 @@ const spawn = {
} }
}; };
me.do = function() { me.do = function() {
this.seePlayerByHistory() this.seePlayerByHistory(40)
this.checkStatus(); this.checkStatus();
this.attraction(); this.attraction();
@@ -6118,26 +6116,24 @@ const spawn = {
this.wing(a - Math.PI / 2 + this.angleOff + this.flapArc * Math.sin(simulation.cycle * this.flapRate), this.wingLength, this.ellipticity) this.wing(a - Math.PI / 2 + this.angleOff + this.flapArc * Math.sin(simulation.cycle * this.flapRate), this.wingLength, this.ellipticity)
this.wing(a + Math.PI / 2 - this.angleOff - this.flapArc * Math.sin(simulation.cycle * this.flapRate), this.wingLength, this.ellipticity) this.wing(a + Math.PI / 2 - this.angleOff - this.flapArc * Math.sin(simulation.cycle * this.flapRate), this.wingLength, this.ellipticity)
}; };
angle -= 0.1
mag -= 10 angle -= 0.07
let previousTailID = 0 let previousTailID = 0
const nodes = Math.min(8 + Math.ceil(0.5 * simulation.difficulty), 40) const nodes = Math.min(10 + Math.ceil(0.6 * simulation.difficulty), 60)
for (let i = 0; i < nodes; ++i) { for (let i = 0; i < nodes; ++i) {
angle -= 0.15 + i * 0.008 angle -= 0.1
mag -= (i < 2) ? -15 : 5 spawn.snakeBody(x + tailRadius * Math.cos(angle), y + tailRadius * Math.sin(angle), i === 0 ? 25 : 20);
spawn.snakeBody(x + mag * Math.cos(angle), y + mag * Math.sin(angle), i === 0 ? 25 : 20); const who = mob[mob.length - 1]
if (i < 3) mob[mob.length - 1].snakeHeadID = me.id who.fill = `hsl(${160+40*Math.random()}, 100%, ${5 + 25*Math.random()*Math.random()}%)`
if (i === 0) me.snakeBody1 = mob[mob.length - 1] //track this segment, so the difference in position between this segment and the head can be used to angle the wings if (i < 3) who.snakeHeadID = me.id
mob[mob.length - 1].previousTailID = previousTailID if (i === 0) me.snakeBody1 = who //track this segment, so the difference in position between this segment and the head can be used to angle the wings
previousTailID = mob[mob.length - 1].id who.previousTailID = previousTailID
previousTailID = who.id
} }
const damping = 1 const damping = 1
const stiffness = 1 const stiffness = 1
this.constrain2AdjacentMobs(nodes, stiffness, false, damping); this.constrain2AdjacentMobs(nodes, stiffness, false, damping);
for (let i = mob.length - 1, len = i - nodes; i > len; i--) { //set alternating colors //constraint with first few mobs in tail
mob[i].fill = `hsla(${160+40*Math.random()}, 100%, ${5 + 25*Math.random()*Math.random()}%, 0.9)`
}
//constraint with first 3 mobs in line
consBB[consBB.length] = Constraint.create({ consBB[consBB.length] = Constraint.create({
bodyA: mob[mob.length - nodes], bodyA: mob[mob.length - nodes],
bodyB: mob[mob.length - 1 - nodes], bodyB: mob[mob.length - 1 - nodes],
@@ -6159,13 +6155,12 @@ const spawn = {
damping: damping damping: damping
}); });
Composite.add(engine.world, consBB[consBB.length - 1]); Composite.add(engine.world, consBB[consBB.length - 1]);
// spawn.shield(me, x, y, 1);
}, },
snakeBody(x, y, radius = 10) { snakeBody(x, y, radius = 10) {
mobs.spawn(x, y, 8, radius, "rgba(0,180,180,0.4)"); mobs.spawn(x, y, 8, radius, "rgba(0,180,180,0.4)");
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.collisionFilter.mask = cat.bullet | cat.player //| cat.mob //| cat.body me.collisionFilter.mask = cat.bullet | cat.player //| cat.mob //| cat.body
me.damageReduction = 0.015 me.damageReduction = 0.021
Matter.Body.setDensity(me, 0.0001); //normal is 0.001 Matter.Body.setDensity(me, 0.0001); //normal is 0.001
// me.accelMag = 0.0007 * simulation.accelScale; // me.accelMag = 0.0007 * simulation.accelScale;

View File

@@ -78,37 +78,20 @@ const tech = {
// if (tech.tech[i].isLore && tech.tech[i].count === 0) tech.tech.splice(i, 1) // if (tech.tech[i].isLore && tech.tech[i].count === 0) tech.tech.splice(i, 1)
// } // }
// }, // },
addJunkTechToPool(chance) { //chance is number between 0-1 addJunkTechToPool(percent) { //percent is number between 0-1
// { //count JUNK
// let count = 0
// for (let i = 0, len = tech.tech.length; i < len; i++) {
// if (tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed() && tech.tech[i].isJunk && tech.tech[i].frequency > 0) count += tech.tech[i].frequency
// }
// console.log(count)
// }
// { //count not JUNK
// let count = 0
// for (let i = 0, len = tech.tech.length; i < len; i++) {
// if (tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed() && !tech.tech[i].isJunk && tech.tech[i].frequency > 0) count++
// }
// console.log(count)
// }
// count total non junk tech
id = "github"
let count = 0
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed() && !tech.tech[i].isJunk) count += tech.tech[i].frequency
}
//make an array for possible junk tech to add //make an array for possible junk tech to add
let options = []; let options = [];
for (let i = 0; i < tech.tech.length; i++) { for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].isJunk) options.push(i); if (tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].isJunk) options.push(i);
} }
//add random array options to tech pool
if (options.length) { if (options.length) {
const num = chance * count //scale number added let countNonJunk = 0 // count total non junk tech
for (let i = 0; i < num; i++) tech.tech[options[Math.floor(Math.random() * options.length)]].frequency++ for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed() && !tech.tech[i].isJunk) countNonJunk += tech.tech[i].frequency
}
const num = percent * countNonJunk //scale number added
console.log(num)
for (let i = 0; i < num; i++) tech.tech[options[Math.floor(Math.random() * options.length)]].frequency++ //add random array options to tech pool
simulation.makeTextLog(`<span class='color-var'>tech</span>.tech.push(${num.toFixed(0)} <span class='color-text'>JUNK</span>)`) simulation.makeTextLog(`<span class='color-var'>tech</span>.tech.push(${num.toFixed(0)} <span class='color-text'>JUNK</span>)`)
return num return num
} else { } else {
@@ -162,7 +145,7 @@ const tech = {
if (tech.isMetaAnalysis && tech.tech[index].isJunk) { if (tech.isMetaAnalysis && tech.tech[index].isJunk) {
simulation.makeTextLog(`//tech: meta-analysis replaced junk tech with random tech`); simulation.makeTextLog(`//tech: meta-analysis replaced junk tech with random tech`);
tech.giveTech('random') tech.giveTech('random')
for (let i = 0; i < 3; i++) powerUps.spawn(m.pos.x + 40 * Math.random(), m.pos.y + 40 * Math.random(), "research"); for (let i = 0; i < 2; i++) powerUps.spawn(m.pos.x + 40 * Math.random(), m.pos.y + 40 * Math.random(), "research");
return return
} }
@@ -225,6 +208,7 @@ const tech = {
}, },
damageFromTech() { damageFromTech() {
let dmg = 1 //m.fieldDamage let dmg = 1 //m.fieldDamage
if (m.coupling && (m.fieldMode === 0 || m.fieldMode === 7)) dmg *= 1 + 0.15 * m.coupling
if (tech.deathSkipTime) dmg *= 1 + 0.6 * tech.deathSkipTime if (tech.deathSkipTime) dmg *= 1 + 0.6 * tech.deathSkipTime
if (tech.isNoDraftPause) dmg *= 1.34 if (tech.isNoDraftPause) dmg *= 1.34
if (tech.isCloakingDamage) dmg *= 1.35 if (tech.isCloakingDamage) dmg *= 1.35
@@ -257,7 +241,7 @@ const tech = {
return dmg * tech.slowFire * tech.aimDamage return dmg * tech.slowFire * tech.aimDamage
}, },
duplicationChance() { duplicationChance() {
return Math.max(0, (tech.isPowerUpsVanish ? 0.12 : 0) + (tech.isStimulatedEmission ? 0.15 : 0) + tech.cancelCount * 0.045 + tech.duplicateChance + 0.05 * tech.isExtraGunField + m.duplicateChance + tech.fieldDuplicate + tech.cloakDuplication + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.5 : 0) + tech.isQuantumEraserDuplication * (1 - 0.016 * (simulation.difficultyMode ** 2))) return Math.max(0, (tech.isPowerUpsVanish ? 0.12 : 0) + (tech.isStimulatedEmission ? 0.15 : 0) + tech.cancelCount * 0.045 + tech.duplicateChance + 0.05 * tech.isExtraGunField + m.duplicateChance + tech.fieldDuplicate + tech.cloakDuplication + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.5 : 0) + tech.isQuantumEraserDuplication * (1 - 0.016 * (simulation.difficultyMode ** 2)) + (m.fieldMode === 0 || m.fieldMode === 9) * 0.05 * m.coupling)
}, },
isScaleMobsWithDuplication: false, isScaleMobsWithDuplication: false,
maxDuplicationEvent() { maxDuplicationEvent() {
@@ -306,41 +290,7 @@ const tech = {
} }
} }
}, },
tech: [ tech: [{
// {
// name: "field coupling",
// descriptionFunction() {
// return `<strong>+1</strong> <strong class='color-f'>field</strong> <strong class='color-coupling'>coupling</strong> (${m.fieldUpgrades[m.fieldMode].name})<br>${ m.couplingDescription()}`
// },
// // isFieldTech: true,
// maxCount: 9,
// count: 0,
// frequency: 2,
// frequencyDefault: 2,
// allowed() {
// return (build.isExperimentSelection || powerUps.research.count > 1)
// },
// requires: "",
// // researchUsed: 0,
// // couplingToResearch: 0.1,
// effect() {
// m.coupling++
// // while (powerUps.research.count > 0) {
// // powerUps.research.changeRerolls(-1)
// // this.researchUsed++
// // m.coupling += this.couplingToResearch
// // }
// },
// remove() {
// m.coupling = 0
// // if (this.count) {
// // m.coupling -= this.researchUsed * this.couplingToResearch
// // powerUps.research.changeRerolls(this.researchUsed)
// // this.researchUsed = 0
// // }
// }
// },
{
name: "ordnance", name: "ordnance",
description: "</strong>double</strong> the <strong class='flicker'>frequency</strong> of finding <strong class='color-g'>gun</strong><strong class='color-m'>tech</strong><br>spawn a <strong class='color-g'>gun</strong>", description: "</strong>double</strong> the <strong class='flicker'>frequency</strong> of finding <strong class='color-g'>gun</strong><strong class='color-m'>tech</strong><br>spawn a <strong class='color-g'>gun</strong>",
maxCount: 1, maxCount: 1,
@@ -449,7 +399,7 @@ const tech = {
}, },
{ {
name: "active cooling", name: "active cooling",
description: "for each <strong class='color-g'>gun</strong> in your inventory<br><strong>+20%</strong> <strong><em>fire rate</em></strong>", description: "for each <strong class='color-g'>gun</strong> in your inventory<br><strong>+18%</strong> <strong><em>fire rate</em></strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -624,7 +574,7 @@ const tech = {
return !tech.isEnergyNoAmmo return !tech.isEnergyNoAmmo
}, },
requires: "not exciton", requires: "not exciton",
effect: () => { effect() {
tech.isAmmoFromHealth = true; tech.isAmmoFromHealth = true;
}, },
remove() { remove() {
@@ -695,7 +645,7 @@ const tech = {
frequencyDefault: 1, frequencyDefault: 1,
allowed() { return true }, allowed() { return true },
requires: "", requires: "",
effect: () => { effect() {
tech.restDamage += 0.36 tech.restDamage += 0.36
}, },
remove() { remove() {
@@ -704,7 +654,7 @@ const tech = {
}, },
{ {
name: "Higgs mechanism", name: "Higgs mechanism",
description: "<strong>+50%</strong> <strong><em>fire rate</em></strong><br>while <strong>firing</strong> your <strong>position</strong> is fixed", description: "<strong>+45%</strong> <strong><em>fire rate</em></strong><br>while <strong>firing</strong> your <strong>position</strong> is fixed",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -713,7 +663,7 @@ const tech = {
return !m.isShipMode && !tech.isAlwaysFire, !tech.isGrapple return !m.isShipMode && !tech.isAlwaysFire, !tech.isGrapple
}, },
requires: "not ship mode, automatic, grappling hook", requires: "not ship mode, automatic, grappling hook",
effect: () => { effect() {
tech.isFireMoveLock = true; tech.isFireMoveLock = true;
b.setFireCD(); b.setFireCD();
b.setFireMethod(); b.setFireMethod();
@@ -876,7 +826,7 @@ const tech = {
}, },
{ {
name: "heuristics", name: "heuristics",
description: "<strong>+33%</strong> <strong><em>fire rate</em></strong>", description: "<strong>+30%</strong> <strong><em>fire rate</em></strong>",
maxCount: 9, maxCount: 9,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -884,7 +834,7 @@ const tech = {
allowed() { return true }, allowed() { return true },
requires: "", requires: "",
effect() { effect() {
tech.fireRate *= 0.67 tech.fireRate *= 0.7
b.setFireCD(); b.setFireCD();
}, },
remove() { remove() {
@@ -941,7 +891,7 @@ const tech = {
return !tech.sporesOnDeath && !tech.nailsDeathMob && !tech.botSpawner && !tech.isMobBlockFling && !tech.iceIXOnDeath return !tech.sporesOnDeath && !tech.nailsDeathMob && !tech.botSpawner && !tech.isMobBlockFling && !tech.iceIXOnDeath
}, },
requires: "no other mob death tech", requires: "no other mob death tech",
effect: () => { effect() {
tech.isExplodeMob = true; tech.isExplodeMob = true;
}, },
remove() { remove() {
@@ -959,7 +909,7 @@ const tech = {
return !tech.sporesOnDeath && !tech.isExplodeMob && !tech.botSpawner && !tech.isMobBlockFling && !tech.iceIXOnDeath return !tech.sporesOnDeath && !tech.isExplodeMob && !tech.botSpawner && !tech.isMobBlockFling && !tech.iceIXOnDeath
}, },
requires: "no other mob death tech", requires: "no other mob death tech",
effect: () => { effect() {
tech.nailsDeathMob++ tech.nailsDeathMob++
}, },
remove() { remove() {
@@ -993,7 +943,7 @@ const tech = {
}, },
{ {
name: "reaction inhibitor", name: "reaction inhibitor",
description: "after mobs <strong>spawn</strong><br>remove <strong>+13%</strong> of their <strong>durability</strong>", //<strong class='color-h'>health</strong> description: "<strong>-13%</strong> maximum mob <strong>health</strong>", //<strong class='color-h'>health</strong>
maxCount: 3, maxCount: 3,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -1002,16 +952,17 @@ const tech = {
return true //tech.nailsDeathMob || tech.sporesOnDeath || tech.isExplodeMob || tech.botSpawner || tech.isMobBlockFling || tech.iceIXOnDeath return true //tech.nailsDeathMob || tech.sporesOnDeath || tech.isExplodeMob || tech.botSpawner || tech.isMobBlockFling || tech.iceIXOnDeath
}, },
requires: "", //"any mob death tech", requires: "", //"any mob death tech",
effect: () => { effect() {
tech.mobSpawnWithHealth *= 0.87 tech.mobSpawnWithHealth++
mobs.setMobSpawnHealth()
//set all mobs at full health to 0.85 //set all mobs at full health to 0.85
for (let i = 0; i < mob.length; i++) { for (let i = 0; i < mob.length; i++) {
if (mob.health > tech.mobSpawnWithHealth) mob.health = tech.mobSpawnWithHealth if (mob.health > mobs.mobSpawnWithHealth) mob.health = mobs.mobSpawnWithHealth
} }
}, },
remove() { remove() {
tech.mobSpawnWithHealth = 1; tech.mobSpawnWithHealth = 0
mobs.setMobSpawnHealth()
} }
}, },
{ {
@@ -1620,7 +1571,7 @@ const tech = {
return b.totalBots() > 1 || build.isExperimentSelection return b.totalBots() > 1 || build.isExperimentSelection
}, },
requires: "at least 2 bots", requires: "at least 2 bots",
effect: () => { effect() {
tech.isExtraBotOption = true tech.isExtraBotOption = true
for (let i = 0; i < 2; i++) b.randomBot() for (let i = 0; i < 2; i++) b.randomBot()
}, },
@@ -1645,7 +1596,7 @@ const tech = {
return tech.isExtraBotOption return tech.isExtraBotOption
}, },
requires: "robotics", requires: "robotics",
effect: () => { effect() {
for (let i = 0; i < 3; i++) b.randomBot() for (let i = 0; i < 3; i++) b.randomBot()
for (let i = 0, len = tech.tech.length; i < len; i++) { for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].isBotTech) tech.tech[i].frequency *= 3 if (tech.tech[i].isBotTech) tech.tech[i].frequency *= 3
@@ -1771,23 +1722,23 @@ const tech = {
tech.isBlockPowerUps = false tech.isBlockPowerUps = false
} }
}, },
{ // {
name: "Pauli exclusion", // name: "Pauli exclusion",
description: `after mob collisions<br>become <strong>invulnerable</strong> for <strong>+3</strong> seconds`, // description: `after mob collisions<br>become <strong>invulnerable</strong> for <strong>+3</strong> seconds`,
maxCount: 9, // maxCount: 9,
count: 0, // count: 0,
frequency: 1, // frequency: 1,
frequencyDefault: 1, // frequencyDefault: 1,
allowed() { return true }, // allowed() { return true },
requires: "", // requires: "",
effect() { // effect() {
tech.collisionImmuneCycles += 180; // m.collisionImmuneCycles += 180;
if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage // if (m.immuneCycle < m.cycle + m.collisionImmuneCycles) m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage
}, // },
remove() { // remove() {
tech.collisionImmuneCycles = 30; // m.collisionImmuneCycles = 30;
} // }
}, // },
{ {
name: "spinstatistics theorem", name: "spinstatistics theorem",
description: `every <strong>7</strong> seconds<br>become <strong>invulnerable</strong> for <strong>+1.75</strong> seconds`, description: `every <strong>7</strong> seconds<br>become <strong>invulnerable</strong> for <strong>+1.75</strong> seconds`,
@@ -1796,7 +1747,7 @@ const tech = {
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
allowed() { allowed() {
return true //tech.collisionImmuneCycles > 30 return true //m.collisionImmuneCycles > 30
}, },
requires: "", requires: "",
effect() { effect() {
@@ -2002,7 +1953,7 @@ const tech = {
return tech.isRelay return tech.isRelay
}, },
requires: "relay switch", requires: "relay switch",
effect: () => { effect() {
tech.isRelayEnergy = true tech.isRelayEnergy = true
m.setMaxEnergy() m.setMaxEnergy()
}, },
@@ -2076,7 +2027,7 @@ const tech = {
return !tech.isEnergyHealth return !tech.isEnergyHealth
}, },
requires: "not mass-energy", requires: "not mass-energy",
effect: () => { effect() {
tech.isMACHO = true; //this harm reduction comes from the particle toggling tech.isHarmMACHO tech.isMACHO = true; //this harm reduction comes from the particle toggling tech.isHarmMACHO
spawn.MACHO() spawn.MACHO()
}, },
@@ -2099,7 +2050,7 @@ const tech = {
return tech.isMACHO return tech.isMACHO
}, },
requires: "MACHO", requires: "MACHO",
effect: () => { effect() {
tech.isAxion = true tech.isAxion = true
}, },
remove() { remove() {
@@ -2233,7 +2184,7 @@ const tech = {
return !tech.isZeno && !tech.isNoHeals && !tech.isPiezo && !tech.isRewindAvoidDeath && !tech.isMutualism //&& !tech.isAmmoFromHealth && !tech.isRewindGun return !tech.isZeno && !tech.isNoHeals && !tech.isPiezo && !tech.isRewindAvoidDeath && !tech.isMutualism //&& !tech.isAmmoFromHealth && !tech.isRewindGun
}, },
requires: "not Zeno, ergodicity, piezoelectricity, CPT, antiscience, mutualism", requires: "not Zeno, ergodicity, piezoelectricity, CPT, antiscience, mutualism",
effect: () => { effect() {
m.health = 0 m.health = 0
document.getElementById("health").style.display = "none" document.getElementById("health").style.display = "none"
document.getElementById("health-bg").style.display = "none" document.getElementById("health-bg").style.display = "none"
@@ -2329,7 +2280,7 @@ const tech = {
frequencyDefault: 1, frequencyDefault: 1,
allowed() { return true }, allowed() { return true },
requires: "", requires: "",
effect: () => { effect() {
tech.isEnergyDamage = true tech.isEnergyDamage = true
}, },
remove() { remove() {
@@ -2348,14 +2299,14 @@ const tech = {
return !tech.isTimeCrystals return !tech.isTimeCrystals
}, },
requires: "not time crystals", requires: "not time crystals",
effect: () => { effect() {
m.fieldRegen = 0.0005
tech.isGroundState = true tech.isGroundState = true
m.setFieldRegen()
m.setMaxEnergy() m.setMaxEnergy()
}, },
remove() { remove() {
m.fieldRegen = 0.001;
tech.isGroundState = false tech.isGroundState = false
m.setFieldRegen()
m.setMaxEnergy() m.setMaxEnergy()
} }
}, },
@@ -2475,7 +2426,7 @@ const tech = {
effect() { effect() {
tech.isCrouchRegen = true; //only used to check for requirements tech.isCrouchRegen = true; //only used to check for requirements
m.regenEnergy = function() { m.regenEnergy = function() {
if (m.immuneCycle < m.cycle && m.crouch) m.energy += 7 * m.fieldRegen; //m.fieldRegen = 0.001 if (m.immuneCycle < m.cycle && m.crouch) m.energy += 7 * m.fieldRegen;
if (m.energy < 0) m.energy = 0 if (m.energy < 0) m.energy = 0
} }
}, },
@@ -2549,7 +2500,7 @@ const tech = {
effect() { effect() {
tech.isDamageAfterKillNoRegen = true; tech.isDamageAfterKillNoRegen = true;
m.regenEnergy = function() { m.regenEnergy = function() {
if (m.immuneCycle < m.cycle && (m.lastKillCycle + 300 < m.cycle)) m.energy += m.fieldRegen; //m.fieldRegen = 0.001 if (m.immuneCycle < m.cycle && (m.lastKillCycle + 300 < m.cycle)) m.energy += m.fieldRegen;
if (m.energy < 0) m.energy = 0 if (m.energy < 0) m.energy = 0
} }
}, },
@@ -3013,7 +2964,7 @@ const tech = {
}, },
{ {
name: "perturbation theory", name: "perturbation theory",
description: `if you have no ${powerUps.orb.research(1)} in your inventory<br><strong>+66%</strong> <strong><em>fire rate</em></strong>`, description: `if you have no ${powerUps.orb.research(1)} in your inventory<br><strong>+60%</strong> <strong><em>fire rate</em></strong>`,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -3024,7 +2975,7 @@ const tech = {
requires: "no research", requires: "no research",
effect() { effect() {
tech.isRerollHaste = true; tech.isRerollHaste = true;
tech.researchHaste = 0.33; tech.researchHaste = 0.4;
b.setFireCD(); b.setFireCD();
}, },
remove() { remove() {
@@ -3044,7 +2995,7 @@ const tech = {
return powerUps.research.count === 0 && !tech.isSuperDeterminism && !tech.isRerollHaste && !tech.isResearchReality return powerUps.research.count === 0 && !tech.isSuperDeterminism && !tech.isRerollHaste && !tech.isResearchReality
}, },
requires: "no research, not superdeterminism, Ψ(t) collapse, perturbation theory", requires: "no research, not superdeterminism, Ψ(t) collapse, perturbation theory",
effect: () => { effect() {
tech.isAnsatz = true; tech.isAnsatz = true;
}, },
remove() { remove() {
@@ -3119,7 +3070,7 @@ const tech = {
return !tech.isDeterminism && tech.duplicationChance() < 1 return !tech.isDeterminism && tech.duplicationChance() < 1
}, },
requires: "below 100% duplication chance not determinism", requires: "below 100% duplication chance not determinism",
effect: () => { effect() {
tech.isExtraGunField = true; tech.isExtraGunField = true;
}, },
remove() { remove() {
@@ -3137,7 +3088,7 @@ const tech = {
return !tech.isDeterminism return !tech.isDeterminism
}, },
requires: "not determinism", requires: "not determinism",
effect: () => { effect() {
tech.extraChoices += 2; tech.extraChoices += 2;
this.refundAmount += tech.addJunkTechToPool(0.04) this.refundAmount += tech.addJunkTechToPool(0.04)
}, },
@@ -3183,7 +3134,7 @@ const tech = {
return !tech.extraChoices && !tech.isExtraGunField && !tech.isFlipFlopChoices return !tech.extraChoices && !tech.isExtraGunField && !tech.isFlipFlopChoices
}, },
requires: "NOT EXPERIMENT MODE, not emergence, cross disciplinary, integrated circuit", requires: "NOT EXPERIMENT MODE, not emergence, cross disciplinary, integrated circuit",
effect: () => { effect() {
tech.isDeterminism = true; tech.isDeterminism = true;
//if you change the number spawned also change it in Born rule //if you change the number spawned also change it in Born rule
for (let i = 0; i < 5; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "tech"); for (let i = 0; i < 5; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "tech");
@@ -3205,7 +3156,7 @@ const tech = {
return tech.isDeterminism && !tech.isAnsatz return tech.isDeterminism && !tech.isAnsatz
}, },
requires: "NOT EXPERIMENT MODE, determinism, not ansatz", requires: "NOT EXPERIMENT MODE, determinism, not ansatz",
effect: () => { effect() {
tech.isSuperDeterminism = true; tech.isSuperDeterminism = true;
//if you change the number spawned also change it in Born rule //if you change the number spawned also change it in Born rule
for (let i = 0; i < 5; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "tech"); for (let i = 0; i < 5; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "tech");
@@ -3314,7 +3265,7 @@ const tech = {
}, },
{ {
name: "meta-analysis", name: "meta-analysis",
description: `if you choose a <strong class='color-j'>JUNK</strong> <strong class='color-m'>tech</strong> you instead get a<br>random normal <strong class='color-m'>tech</strong> and ${powerUps.orb.research(1)}`, description: `if you choose a <strong class='color-j'>JUNK</strong> <strong class='color-m'>tech</strong> you instead get a<br>random normal <strong class='color-m'>tech</strong> and ${powerUps.orb.research(2)}`,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -3496,7 +3447,7 @@ const tech = {
return tech.duplicationChance() < 1.11 return tech.duplicationChance() < 1.11
}, },
requires: "below 111% duplication chance", requires: "below 111% duplication chance",
effect: () => { effect() {
tech.isStimulatedEmission = true tech.isStimulatedEmission = true
powerUps.setDupChance(); //needed after adjusting duplication chance powerUps.setDupChance(); //needed after adjusting duplication chance
if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.15); if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.15);
@@ -3517,7 +3468,7 @@ const tech = {
return tech.duplicationChance() < 1.11 return tech.duplicationChance() < 1.11
}, },
requires: "below 111% duplication chance", requires: "below 111% duplication chance",
effect: () => { effect() {
tech.isPowerUpsVanish = true tech.isPowerUpsVanish = true
powerUps.setDupChance(); //needed after adjusting duplication chance powerUps.setDupChance(); //needed after adjusting duplication chance
if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.12); if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.12);
@@ -3596,7 +3547,7 @@ const tech = {
return (tech.totalCount > 6) return (tech.totalCount > 6)
}, },
requires: "NOT EXPERIMENT MODE, more than 6 tech", requires: "NOT EXPERIMENT MODE, more than 6 tech",
effect: () => { effect() {
//remove active bullets //to get rid of bots //remove active bullets //to get rid of bots
for (let i = 0; i < bullet.length; ++i) Matter.Composite.remove(engine.world, bullet[i]); for (let i = 0; i < bullet.length; ++i) Matter.Composite.remove(engine.world, bullet[i]);
bullet = []; bullet = [];
@@ -3664,7 +3615,7 @@ const tech = {
return (tech.totalCount > 3) && !tech.isSuperDeterminism return (tech.totalCount > 3) && !tech.isSuperDeterminism
}, },
requires: "NOT EXPERIMENT MODE, at least 4 tech, not superdeterminism", requires: "NOT EXPERIMENT MODE, at least 4 tech, not superdeterminism",
effect: () => { effect() {
const have = [] //find which tech you have const have = [] //find which tech you have
for (let i = 0; i < tech.tech.length; i++) { for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].count > 0 && !tech.tech[i].isNonRefundable) have.push(i) if (tech.tech[i].count > 0 && !tech.tech[i].isNonRefundable) have.push(i)
@@ -3696,7 +3647,7 @@ const tech = {
return (tech.totalCount > 3) && tech.duplicationChance() > 0 && !tech.isSuperDeterminism return (tech.totalCount > 3) && tech.duplicationChance() > 0 && !tech.isSuperDeterminism
}, },
requires: "NOT EXPERIMENT MODE, some duplication, at least 4 tech, not superdeterminism", requires: "NOT EXPERIMENT MODE, some duplication, at least 4 tech, not superdeterminism",
effect: () => { effect() {
const removeTotal = tech.removeTech() const removeTotal = tech.removeTech()
for (let i = 0; i < removeTotal + 1; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "tech"); for (let i = 0; i < removeTotal + 1; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "tech");
}, },
@@ -3716,7 +3667,7 @@ const tech = {
return !tech.isSuperDeterminism && tech.duplicationChance() > 0 && powerUps.research.count > 1 return !tech.isSuperDeterminism && tech.duplicationChance() > 0 && powerUps.research.count > 1
}, },
requires: "NOT EXPERIMENT MODE, some duplication, not superdeterminism", requires: "NOT EXPERIMENT MODE, some duplication, not superdeterminism",
effect: () => { effect() {
powerUps.research.changeRerolls(-2) powerUps.research.changeRerolls(-2)
simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-r'>research</span> <span class='color-symbol'>-=</span> 2`) simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-r'>research</span> <span class='color-symbol'>-=</span> 2`)
powerUps.directSpawn(m.pos.x, m.pos.y, "tech"); powerUps.directSpawn(m.pos.x, m.pos.y, "tech");
@@ -3735,7 +3686,7 @@ const tech = {
return tech.totalCount > 9 return tech.totalCount > 9
}, },
requires: "at least 10 tech", requires: "at least 10 tech",
effect: () => { effect() {
for (let i = 0, len = tech.tech.length; i < len; i++) { for (let i = 0, len = tech.tech.length; i < len; i++) {
if (tech.tech[i].count > 0) tech.tech[i].frequency *= 10 if (tech.tech[i].count > 0) tech.tech[i].frequency *= 10
} }
@@ -4575,13 +4526,14 @@ const tech = {
return tech.haveGunCheck("matter wave") && !tech.isPhaseVelocity && !tech.isBulletTeleport return tech.haveGunCheck("matter wave") && !tech.isPhaseVelocity && !tech.isBulletTeleport
}, },
requires: "matter wave, not phase velocity, uncertainty principle", requires: "matter wave, not phase velocity, uncertainty principle",
ammoScale: 11,
effect() { effect() {
tech.isLongitudinal = true; tech.isLongitudinal = true;
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "matter wave") { if (b.guns[i].name === "matter wave") {
b.guns[i].chooseFireMethod() b.guns[i].chooseFireMethod()
b.guns[i].ammoPack = b.guns[i].defaultAmmoPack / 10 b.guns[i].ammoPack = b.guns[i].defaultAmmoPack / this.ammoScale
b.guns[i].ammo = Math.ceil(b.guns[i].ammo / 10); b.guns[i].ammo = Math.ceil(b.guns[i].ammo / this.ammoScale);
simulation.updateGunHUD(); simulation.updateGunHUD();
break break
} }
@@ -4594,7 +4546,7 @@ const tech = {
tech.isLongitudinal = false; tech.isLongitudinal = false;
b.guns[i].chooseFireMethod() b.guns[i].chooseFireMethod()
b.guns[i].ammoPack = b.guns[i].defaultAmmoPack b.guns[i].ammoPack = b.guns[i].defaultAmmoPack
b.guns[i].ammo = Math.ceil(b.guns[i].ammo * 10); b.guns[i].ammo = Math.ceil(b.guns[i].ammo * this.ammoScale);
simulation.updateGunHUD(); simulation.updateGunHUD();
break break
} }
@@ -4771,7 +4723,7 @@ const tech = {
return tech.explosiveRadius === 1 && !tech.isSmallExplosion && !tech.isBlockExplode && !tech.fragments && (tech.haveGunCheck("missiles") || tech.missileBotCount || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.isPulseLaser || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && simulation.molecularMode === 1) || tech.isBoomBotUpgrade || tech.isTokamak) return tech.explosiveRadius === 1 && !tech.isSmallExplosion && !tech.isBlockExplode && !tech.fragments && (tech.haveGunCheck("missiles") || tech.missileBotCount || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.isPulseLaser || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && simulation.molecularMode === 1) || tech.isBoomBotUpgrade || tech.isTokamak)
}, },
requires: "an explosive damage source, not ammonium nitrate, nitroglycerin, chain reaction, fragmentation", requires: "an explosive damage source, not ammonium nitrate, nitroglycerin, chain reaction, fragmentation",
effect: () => { effect() {
tech.isExplodeRadio = true; //iridium-192 tech.isExplodeRadio = true; //iridium-192
}, },
remove() { remove() {
@@ -4809,7 +4761,7 @@ const tech = {
return !tech.isExplodeRadio && tech.hasExplosiveDamageCheck() return !tech.isExplodeRadio && tech.hasExplosiveDamageCheck()
}, },
requires: "an explosive damage source, not iridium-192", requires: "an explosive damage source, not iridium-192",
effect: () => { effect() {
tech.explosiveRadius += 0.24; tech.explosiveRadius += 0.24;
}, },
remove() { remove() {
@@ -4828,7 +4780,7 @@ const tech = {
return !tech.isExplodeRadio && tech.hasExplosiveDamageCheck() && !tech.isExplosionHarm return !tech.isExplodeRadio && tech.hasExplosiveDamageCheck() && !tech.isExplosionHarm
}, },
requires: "an explosive damage source, not iridium-192, acetone peroxide", requires: "an explosive damage source, not iridium-192, acetone peroxide",
effect: () => { effect() {
tech.isSmallExplosion = true; tech.isSmallExplosion = true;
}, },
remove() { remove() {
@@ -4848,7 +4800,7 @@ const tech = {
return tech.hasExplosiveDamageCheck() && !tech.isSmallExplosion return tech.hasExplosiveDamageCheck() && !tech.isSmallExplosion
}, },
requires: "an explosive damage source, not nitroglycerin", requires: "an explosive damage source, not nitroglycerin",
effect: () => { effect() {
tech.isExplosionHarm = true; tech.isExplosionHarm = true;
}, },
remove() { remove() {
@@ -4886,7 +4838,7 @@ const tech = {
return !tech.isImmuneExplosion && (build.isExperimentSelection || powerUps.research.count > 3) && (tech.haveGunCheck("missiles") || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && simulation.molecularMode === 1) || tech.missileBotCount > 0 || tech.isIncendiary || tech.isPulseLaser || tech.isTokamak || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb)) return !tech.isImmuneExplosion && (build.isExperimentSelection || powerUps.research.count > 3) && (tech.haveGunCheck("missiles") || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && simulation.molecularMode === 1) || tech.missileBotCount > 0 || tech.isIncendiary || tech.isPulseLaser || tech.isTokamak || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb))
}, },
requires: "an explosive damage source, not electric reactive armor", requires: "an explosive damage source, not electric reactive armor",
effect: () => { effect() {
tech.isSmartRadius = true; tech.isSmartRadius = true;
for (let i = 0; i < 4; i++) { for (let i = 0; i < 4; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
@@ -4910,7 +4862,7 @@ const tech = {
return !tech.isSmartRadius && !tech.isExplodeRadio && tech.hasExplosiveDamageCheck() && !tech.isEnergyHealth return !tech.isSmartRadius && !tech.isExplodeRadio && tech.hasExplosiveDamageCheck() && !tech.isEnergyHealth
}, },
requires: "an explosive damage source, not iridium-192, mass-energy", requires: "an explosive damage source, not iridium-192, mass-energy",
effect: () => { effect() {
tech.isImmuneExplosion = true; tech.isImmuneExplosion = true;
}, },
remove() { remove() {
@@ -6461,6 +6413,41 @@ const tech = {
//************************************************** field //************************************************** field
//************************************************** tech //************************************************** tech
//************************************************** //**************************************************
{
name: "coupling",
descriptionFunction() {
return `<strong>+1</strong> <strong class='color-f'>field</strong> <strong class='color-coupling'>coupling</strong> <em>(${m.fieldUpgrades[m.fieldMode].name})</em><br>${ m.couplingDescription()}`
},
// isFieldTech: true,
maxCount: 9,
count: 0,
frequency: 1,
frequencyDefault: 1,
allowed() {
return (build.isExperimentSelection || powerUps.research.count > 1)
},
requires: "",
// researchUsed: 0,
// couplingToResearch: 0.1,
effect() {
m.coupling++
m.couplingChange()
// while (powerUps.research.count > 0) {
// powerUps.research.changeRerolls(-1)
// this.researchUsed++
// m.coupling += this.couplingToResearch
// }
},
remove() {
m.coupling -= this.count
m.couplingChange()
// if (this.count) {
// m.coupling -= this.researchUsed * this.couplingToResearch
// powerUps.research.changeRerolls(this.researchUsed)
// this.researchUsed = 0
// }
}
},
{ {
name: "zero point energy", name: "zero point energy",
description: `use ${powerUps.orb.research(2)}<br><strong>+100</strong> maximum <strong class='color-f'>energy</strong>`, description: `use ${powerUps.orb.research(2)}<br><strong>+100</strong> maximum <strong class='color-f'>energy</strong>`,
@@ -6808,7 +6795,7 @@ const tech = {
return powerUps.research.count > 1 && (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || m.fieldUpgrades[m.fieldMode].name === "pilot wave") return powerUps.research.count > 1 && (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || m.fieldUpgrades[m.fieldMode].name === "pilot wave")
}, },
requires: "NOT EXPERIMENT MODE, molecular assembler", requires: "NOT EXPERIMENT MODE, molecular assembler",
effect: () => { effect() {
for (let i = 0; i < 2; i++) { for (let i = 0; i < 2; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
} }
@@ -6834,7 +6821,7 @@ const tech = {
return powerUps.research.count > 2 && (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || m.fieldUpgrades[m.fieldMode].name === "pilot wave") return powerUps.research.count > 2 && (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || m.fieldUpgrades[m.fieldMode].name === "pilot wave")
}, },
requires: "NOT EXPERIMENT MODE, molecular assembler", requires: "NOT EXPERIMENT MODE, molecular assembler",
effect: () => { effect() {
for (let i = 0; i < 3; i++) { for (let i = 0; i < 3; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
} }
@@ -6988,7 +6975,7 @@ const tech = {
return m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || m.fieldUpgrades[m.fieldMode].name === "standing wave" || m.fieldUpgrades[m.fieldMode].name === "pilot wave" return m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || m.fieldUpgrades[m.fieldMode].name === "standing wave" || m.fieldUpgrades[m.fieldMode].name === "pilot wave"
}, },
requires: "molecular assembler, pilot wave, standing wave", requires: "molecular assembler, pilot wave, standing wave",
effect: () => { effect() {
tech.isMassEnergy = true // used in m.grabPowerUp tech.isMassEnergy = true // used in m.grabPowerUp
m.energy += 2 m.energy += 2
}, },
@@ -7278,13 +7265,13 @@ const tech = {
return !tech.isGroundState && (m.fieldUpgrades[m.fieldMode].name === "time dilation" || m.fieldUpgrades[m.fieldMode].name === "pilot wave") return !tech.isGroundState && (m.fieldUpgrades[m.fieldMode].name === "time dilation" || m.fieldUpgrades[m.fieldMode].name === "pilot wave")
}, },
requires: "time dilation or pilot wave, not ground state", requires: "time dilation or pilot wave, not ground state",
effect: () => { effect() {
m.fieldRegen = 0.004
tech.isTimeCrystals = true tech.isTimeCrystals = true
m.setFieldRegen()
}, },
remove() { remove() {
m.fieldRegen = 0.001
tech.isTimeCrystals = false tech.isTimeCrystals = false
m.setFieldRegen()
} }
}, },
{ {
@@ -7492,7 +7479,7 @@ const tech = {
return m.fieldUpgrades[m.fieldMode].name === "wormhole" || m.fieldUpgrades[m.fieldMode].name === "pilot wave" || m.fieldUpgrades[m.fieldMode].name === "time dilation" return m.fieldUpgrades[m.fieldMode].name === "wormhole" || m.fieldUpgrades[m.fieldMode].name === "pilot wave" || m.fieldUpgrades[m.fieldMode].name === "time dilation"
}, },
requires: "wormhole or pilot wave", requires: "wormhole or pilot wave",
effect: () => { effect() {
tech.wimpCount++ tech.wimpCount++
spawn.WIMP() spawn.WIMP()
for (let j = 0, len = 5; j < len; j++) powerUps.spawn(level.exit.x + 100 * (Math.random() - 0.5), level.exit.y - 100 + 100 * (Math.random() - 0.5), "research", false) for (let j = 0, len = 5; j < len; j++) powerUps.spawn(level.exit.x + 100 * (Math.random() - 0.5), level.exit.y - 100 + 100 * (Math.random() - 0.5), "research", false)
@@ -8646,7 +8633,7 @@ const tech = {
return !tech.isFireMoveLock return !tech.isFireMoveLock
}, },
requires: "not Higgs mechanism", requires: "not Higgs mechanism",
effect: () => { effect() {
tech.isAlwaysFire = true; tech.isAlwaysFire = true;
b.setFireMethod(); b.setFireMethod();
}, },
@@ -9346,7 +9333,7 @@ const tech = {
ctx.beginPath(); ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI); ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.fillStyle = this.bodyGradient ctx.fillStyle = m.bodyGradient
ctx.fill(); ctx.fill();
ctx.arc(15, 0, 4, 0, 2 * Math.PI); ctx.arc(15, 0, 4, 0, 2 * Math.PI);
ctx.strokeStyle = "#333"; ctx.strokeStyle = "#333";
@@ -9389,7 +9376,7 @@ const tech = {
ctx.beginPath(); ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI); ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.fillStyle = this.bodyGradient ctx.fillStyle = m.bodyGradient
ctx.fill(); ctx.fill();
ctx.arc(15, 0, 4, 0, 2 * Math.PI); ctx.arc(15, 0, 4, 0, 2 * Math.PI);
ctx.strokeStyle = "#333"; ctx.strokeStyle = "#333";
@@ -9458,7 +9445,7 @@ const tech = {
ctx.beginPath(); ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI); ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.fillStyle = this.bodyGradient ctx.fillStyle = m.bodyGradient
ctx.fill(); ctx.fill();
ctx.stroke(); ctx.stroke();
ctx.moveTo(19, 0); ctx.moveTo(19, 0);
@@ -9566,7 +9553,7 @@ const tech = {
ctx.rotate(m.angle); ctx.rotate(m.angle);
ctx.beginPath(); ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI); ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.fillStyle = this.bodyGradient ctx.fillStyle = m.bodyGradient
ctx.fill(); ctx.fill();
ctx.strokeStyle = "#333"; ctx.strokeStyle = "#333";
ctx.lineWidth = 2; ctx.lineWidth = 2;
@@ -9586,7 +9573,7 @@ const tech = {
ctx.stroke(); ctx.stroke();
ctx.beginPath(); ctx.beginPath();
ctx.arc(18, 13, 10, 0, 2 * Math.PI); ctx.arc(18, 13, 10, 0, 2 * Math.PI);
ctx.fillStyle = this.bodyGradient; ctx.fillStyle = m.bodyGradient;
ctx.fill(); ctx.fill();
ctx.stroke(); ctx.stroke();
ctx.beginPath(); ctx.beginPath();
@@ -10266,7 +10253,6 @@ const tech = {
plasmaBotCount: null, plasmaBotCount: null,
missileBotCount: null, missileBotCount: null,
orbitBotCount: null, orbitBotCount: null,
collisionImmuneCycles: null,
blockDmg: null, blockDmg: null,
isBlockRadiation: null, isBlockRadiation: null,
isPiezo: null, isPiezo: null,

View File

@@ -1,30 +1,52 @@
******************************************************** NEXT PATCH ************************************************** ******************************************************** NEXT PATCH **************************************************
new setting: level ban list tech: coupling - +1 coupling, coupling is a new stat that provides different buffs for each field
bug fix: removed a command to preventDefault on space key, this might break something else releasing this early for feedback about balance and bugs
new boss added to level - Temple
snake tails have a lower mass and whip around a bit removed tech Pauli exclusion
auto targeting no longer works for stealth mobs now the perfect diamagnatism coupling effect
snipers, sneakers, ghosters
snipers fire more often at high difficulty, but bullets move slower at all difficulties snakeBoss tails are closer together
hoppers have move gravity, so it feels like they are hopping a bit faster some bosses have a higher vision memory and response time
phonon gets 10% less ammo and 10% less damage
meta-analysis gives 2 research per use
energy drain rework
in many situations drain no longer scales with regen
this might have some bad side effects, let me know
bug fixes
made several tech effects not an arrow function
timeSkip graphical glitches might be improved
*********************************************************** TODO ***************************************************** *********************************************************** TODO *****************************************************
tech: field coupling - +1 field coupling, coupling is a new stat that provides different buffs for each field
you can see your coupling in the pause menu coupling:
make field coupling a stat that shows in pause menu and is effected by other tech? field emitter balance?
coupling tech
names: fine-structure constant, strongly coupled, Vibronic coupling names: fine-structure constant, strongly coupled, Vibronic coupling
tech: convert all research into "coupling" tech: convert all research into "coupling"
tech: +x% field coupling, your field changes randomly every y seconds tech: +x% field coupling, your field changes randomly every y seconds
tech: coupling starts at 200%, but decays when the field is in use, coupling recharges when the field is not in use tech: coupling starts at 200%, but decays when the field is in use, coupling recharges when the field is not in use
some fields aren't used much (that's ok?) some fields aren't used much (that's ok?)
Tech: Cancelling a tech/gun/field gives x coupling
buffing your deflecting for 1 second after pressing the field button sounds cool buffing your deflecting for 1 second after pressing the field button sounds cool
2 second cooldown on the effect to prevent spamming it 2 second cooldown on the effect to prevent spamming it
buff: giving energy or doing damage makes sense buff: giving energy or doing damage makes sense
maybe this could be a rework for bremstralung maybe this could be a rework for bremstralung
rewindBoss: after hitting 1/5 damage theasholds the boss rewinds back in time to where it was a few seconds ago
track it's data like player history
worms can target player, buff their damage
can't target player in first few seconds?
draw player transparent or opaque when cloaking field is on
plasma field tech - similar to regression, but for plasma ticks
greatly increase walking speed greatly increase walking speed
not mid air control? not mid air control?
for time dilation field for time dilation field
@@ -36,6 +58,8 @@ after taking damage explode while invulnerable
quantum immortality: send you to a new tab after you die with a random load out quantum immortality: send you to a new tab after you die with a random load out
basically everything is the same as it is now, but you switch tabs basically everything is the same as it is now, but you switch tabs
Tech: Tech/guns/fields can no longer be duplicated. Duplication applies twice
tech: get sent to a new tab that closes in 3 minutes tech: get sent to a new tab that closes in 3 minutes
in the new tab you play reactor in the new tab you play reactor
if you die in reactor you die in game, if you win you get 2-3 tech in the original game? if you die in reactor you die in game, if you win you get 2-3 tech in the original game?