renamed MACHO -> dark matter
tech: MACHO - dark matter is active when you are outside not inside it's range, 1.5 to dark matter effects
tech: dark energy - inside dark matter regen 10 energy
tech: stability - 0.3x damage taken if health equals maxHealth
tech: instability - 2x damage if damage taken is 1x
tech: control theory - 1.5x damage if health equals maxHealth
tech: inertial confinement - while charging tokamak you can fly, but energy drains
tech: stellarator - after firing a block with tokamak, spawn up to 5 heals

boss health nerf: almost every boss has ~0.8x less health
  secondary bosses also spawn 2 ammo
aerostat 0.85->0.9 damage on the ground
Pauli exclusion 6->8 seconds of invulnerable after getting hit
Gibbs free energy 2->0 research cost, 1.01->1.05 damage scales with energy below 100->maxEnergy
cache 15->17x ammo

several bug fixes
This commit is contained in:
landgreen
2024-06-28 19:44:07 -07:00
parent 5e12cea685
commit f43a5e3231
16 changed files with 555 additions and 241 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 63 KiB

BIN
img/control theory.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

BIN
img/dark energy.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

BIN
img/dark matter.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

BIN
img/instability.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

BIN
img/stability.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

BIN
img/stellarator.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

View File

@@ -26,7 +26,7 @@ const level = {
// tech.tech[297].frequency = 100 // tech.tech[297].frequency = 100
// tech.addJunkTechToPool(0.5) // tech.addJunkTechToPool(0.5)
// m.couplingChange(10) // m.couplingChange(10)
// m.setField("time dilation") //1 standing wave 2 perfect diamagnetism 3 negative mass 4 molecular assembler 5 plasma torch 6 time dilation 7 metamaterial cloaking 8 pilot wave 9 wormhole 10 grappling hook // m.setField("negative mass") //1 standing wave 2 perfect diamagnetism 3 negative mass 4 molecular assembler 5 plasma torch 6 time dilation 7 metamaterial cloaking 8 pilot wave 9 wormhole 10 grappling hook
// m.energy = 0 // m.energy = 0
// powerUps.research.count = 3 // powerUps.research.count = 3
// tech.isHookWire = true // tech.isHookWire = true
@@ -43,9 +43,9 @@ const level = {
// b.guns[8].ammo = 100000000 // b.guns[8].ammo = 100000000
// requestAnimationFrame(() => { tech.giveTech("optical amplifier") }); // requestAnimationFrame(() => { tech.giveTech("optical amplifier") });
// tech.giveTech("1st ionization energy") // tech.giveTech("1st ionization energy")
// for (let i = 0; i < 1; ++i) tech.giveTech("negative feedback") // for (let i = 0; i < 1; ++i) tech.giveTech("tokamak")
// for (let i = 0; i < 2; ++i) tech.giveTech("delayed-choice") // for (let i = 0; i < 1; ++i) tech.giveTech("inertial confinement")
// for (let i = 0; i < 1; ++i) tech.giveTech("pulse") // for (let i = 0; i < 1; ++i) tech.giveTech("stellarator")
// for (let i = 0; i < 1; ++i) tech.giveTech("mass-energy equivalence") // for (let i = 0; i < 1; ++i) tech.giveTech("mass-energy equivalence")
// requestAnimationFrame(() => { for (let i = 0; i < 10; i++) b.orbitBot(m.pos, false) }); // requestAnimationFrame(() => { for (let i = 0; i < 10; i++) b.orbitBot(m.pos, false) });
// requestAnimationFrame(() => { for (let i = 0; i < 1; i++) tech.giveTech("1st ionization energy") }); // requestAnimationFrame(() => { for (let i = 0; i < 1; i++) tech.giveTech("1st ionization energy") });
@@ -54,11 +54,11 @@ const level = {
// for (let i = 0; i < 1; ++i) tech.giveTech("compression engine") // for (let i = 0; i < 1; ++i) tech.giveTech("compression engine")
// for (let i = 0; i < 3; i++) powerUps.directSpawn(450, -50, "tech"); // for (let i = 0; i < 3; i++) powerUps.directSpawn(450, -50, "tech");
// for (let i = 0; i < 1; i++) powerUps.directSpawn(-50, -70, "difficulty", false); // for (let i = 0; i < 1; i++) powerUps.directSpawn(-50, -70, "difficulty", false);
// for (let i = 0; i < 100; i++) powerUps.directSpawn(1750, -500, "coupling");
// spawn.mapRect(575, -700, 25, 425); //block mob line of site on testing // spawn.mapRect(575, -700, 25, 425); //block mob line of site on testing
// level.arena(); level.testing();
// for (let i = 0; i < 1; ++i) spawn.snakeSpitBoss(1400, -500) // for (let i = 0; i < 1; ++i) spawn.snakeBoss(1400, -500)
// for (let i = 0; i < 2; i++) powerUps.directSpawn(800, -100, "coupling");
// Matter.Body.setPosition(player, { x: -200, y: -3330 }); // Matter.Body.setPosition(player, { x: -200, y: -3330 });
// for (let i = 0; i < 4; ++i) spawn.sucker(1300, -500 + 100 * Math.random()) // for (let i = 0; i < 4; ++i) spawn.sucker(1300, -500 + 100 * Math.random())
// spawn.hopper(1900, -500) // spawn.hopper(1900, -500)
@@ -68,11 +68,10 @@ const level = {
// spawn.tetherBoss(1900, -500, { x: 1900, y: -500 }) // spawn.tetherBoss(1900, -500, { x: 1900, y: -500 })
// for (let i = 0; i < 40; ++i) tech.giveTech() // for (let i = 0; i < 40; ++i) tech.giveTech()
level[simulation.isTraining ? "walk" : "initial"]() //normal starting level ************************************************** // level[simulation.isTraining ? "walk" : "initial"]() //normal starting level **************************************************
// for (let i = 0; i < 1; ++i) spawn.laserLayerBoss(1900, -500) // for (let i = 0; i < 1; ++i) spawn.laserLayerBoss(1900, -500)
// for (let i = 0; i < 2; i++) spawn.ghoster(level.exit.x, level.exit.y) //ghosters need to spawn after the map loads // for (let i = 0; i < 2; i++) spawn.ghoster(level.exit.x, level.exit.y) //ghosters need to spawn after the map loads
// spawn.bodyRect(2425, -120, 200, 200);
// console.log(body[body.length - 1].mass) // console.log(body[body.length - 1].mass)
// simulation.isAutoZoom = false; //look in close // simulation.isAutoZoom = false; //look in close
// simulation.zoomScale *= 0.5; // simulation.zoomScale *= 0.5;
@@ -134,7 +133,7 @@ const level = {
} }
} }
} }
if (tech.isMACHO) spawn.MACHO() if (tech.isDarkMatter) spawn.darkMatter()
for (let i = 0; i < tech.wimpCount; i++) { for (let i = 0; i < tech.wimpCount; i++) {
spawn.WIMP() spawn.WIMP()
mob[mob.length - 1].isDecoupling = true //so you can find it to remove mob[mob.length - 1].isDecoupling = true //so you can find it to remove
@@ -151,6 +150,7 @@ const level = {
newLevelOrPhase() { //runs on each new level but also on final boss phases newLevelOrPhase() { //runs on each new level but also on final boss phases
//used for generalist and pigeonhole principle //used for generalist and pigeonhole principle
tech.cancelTechCount = 0 tech.cancelTechCount = 0
tech.tokamakHealCount = 0
tech.buffedGun++ tech.buffedGun++
if (tech.buffedGun > b.inventory.length - 1) tech.buffedGun = 0; if (tech.buffedGun > b.inventory.length - 1) tech.buffedGun = 0;
if (tech.isGunCycle && b.activeGun !== null && b.inventory.length) { if (tech.isGunCycle && b.activeGun !== null && b.inventory.length) {
@@ -12651,7 +12651,7 @@ const level = {
Promise.resolve().then(() => { Promise.resolve().then(() => {
// Clear all WIMPS and their research // Clear all WIMPS and their research
for (let i = 0; i < mob.length; i++) { for (let i = 0; i < mob.length; i++) {
if (mob[i] && !mob[i].isMACHO) { if (mob[i] && !mob[i].isDarkMatter) {
mob[i].isWIMP = true; mob[i].isWIMP = true;
} }
} }
@@ -13302,7 +13302,7 @@ const level = {
if (simulation.cycle % 4 === 0) { if (simulation.cycle % 4 === 0) {
let newMobPositions = []; let newMobPositions = [];
for (const i of mob) { for (const i of mob) {
if (!(i.isMACHO || i.isWIMP || i.isObstacle)) newMobPositions.push({ if (!(i.isDarkMatter || i.isWIMP || i.isObstacle)) newMobPositions.push({
x: i.position.x, x: i.position.x,
y: i.position.y y: i.position.y
}); });
@@ -13572,7 +13572,7 @@ const level = {
level.setPosToSpawn(x, y); level.setPosToSpawn(x, y);
trapPlayer(x, y); trapPlayer(x, y);
for (let i = 0; i < mob.length; i++) { for (let i = 0; i < mob.length; i++) {
if (mob[i].isMACHO) { if (mob[i].isDarkMatter) {
setPos(mob[i], { setPos(mob[i], {
x, x,
y y

View File

@@ -547,10 +547,11 @@ const m = {
lastCalculatedDefense: 0, //used to decided if defense bar needs to be redrawn (in simulation.checks) lastCalculatedDefense: 0, //used to decided if defense bar needs to be redrawn (in simulation.checks)
defense() { defense() {
let dmg = 1 let dmg = 1
if (tech.isMaxHealthDefense && m.health === m.maxHealth) dmg *= 0.3
if (tech.isDiaphragm) dmg *= 0.55 + 0.35 * Math.sin(m.cycle * 0.0075); if (tech.isDiaphragm) dmg *= 0.55 + 0.35 * Math.sin(m.cycle * 0.0075);
if (tech.isZeno) dmg *= 0.15 if (tech.isZeno) dmg *= 0.15
if (tech.isFieldHarmReduction) dmg *= 0.6 if (tech.isFieldHarmReduction) dmg *= 0.6
if (tech.isHarmMACHO) dmg *= tech.isMoveMACHO ? 0.3 : 0.4 if (tech.isHarmDarkMatter) dmg *= (tech.isMoveDarkMatter || tech.isNotDarkMatter) ? 0.25 : 0.4
if (tech.isImmortal) dmg *= 0.7 if (tech.isImmortal) dmg *= 0.7
if (m.fieldMode === 0 || m.fieldMode === 3) dmg *= 0.973 ** m.coupling if (m.fieldMode === 0 || m.fieldMode === 3) dmg *= 0.973 ** m.coupling
if (tech.isHarmReduceNoKill && m.lastKillCycle + 300 < m.cycle) dmg *= 0.3 if (tech.isHarmReduceNoKill && m.lastKillCycle + 300 < m.cycle) dmg *= 0.3
@@ -2364,6 +2365,30 @@ const m = {
ctx.lineTo(m.holdingTarget.vertices[i + 1].x, m.holdingTarget.vertices[i + 1].y); ctx.lineTo(m.holdingTarget.vertices[i + 1].x, m.holdingTarget.vertices[i + 1].y);
ctx.fill(); ctx.fill();
} }
if (tech.isTokamakFly && m.throwCharge > 4 && m.energy > 0.01) {
player.force.y -= 0.5 * player.mass * simulation.g; //add some reduced gravity
// const mass = (player.mass + 10) / 3 * simulation.g //this makes it so you fly slower with larger blocks
let isDrain = false
const thrust = player.mass * simulation.g * Math.pow(5 / player.mass, 0.1)
if (input.down) {
isDrain = true
player.force.y += 0.9 * thrust;
} else if (input.up) {
isDrain = true
player.force.y -= 0.9 * thrust
}
if (!m.onGround) {
if (input.left) {
isDrain = true
player.force.x -= 0.4 * thrust
} else if (input.right) {
isDrain = true
player.force.x += 0.4 * thrust
}
if (isDrain) m.energy -= 0.0017;
}
}
} else { } else {
//draw charge //draw charge
const x = m.pos.x + 15 * Math.cos(m.angle); const x = m.pos.x + 15 * Math.cos(m.angle);
@@ -2425,6 +2450,12 @@ const m = {
} }
} }
b.pulse(60 * Math.pow(m.holdingTarget.mass, 0.25), m.angle) b.pulse(60 * Math.pow(m.holdingTarget.mass, 0.25), m.angle)
if (tech.isTokamakHeal && tech.tokamakHealCount < 5) {
tech.tokamakHealCount++
let massScale = Math.min(65 * Math.sqrt(m.maxHealth), 14 * Math.pow(m.holdingTarget.mass, 0.4))
if (powerUps.healGiveMaxEnergy) massScale = powerUps["heal"].size()
powerUps.spawn(m.pos.x, m.pos.y, "heal", true, null, massScale * (simulation.healScale ** 0.25) * Math.sqrt(tech.largerHeals * (tech.isHalfHeals ? 0.5 : 1))) // spawn(x, y, target, moving = true, mode = null, size = powerUps[target].size()) {
}
} else { //normal throw } else { //normal throw
//bullet-like collisions //bullet-like collisions
m.holdingTarget.collisionFilter.category = cat.bullet m.holdingTarget.collisionFilter.category = cat.bullet
@@ -2962,7 +2993,7 @@ const m = {
drainCD: 0, drainCD: 0,
effect: () => { effect: () => {
m.fieldBlockCD = 0; m.fieldBlockCD = 0;
m.blockingRecoil = 1.5 //4 is normal m.blockingRecoil = 1 //4 is normal
m.fieldRange = 185 m.fieldRange = 185
m.fieldShieldingScale = 1.6 * Math.pow(0.5, (tech.harmonics - 2)) m.fieldShieldingScale = 1.6 * Math.pow(0.5, (tech.harmonics - 2))
// m.fieldHarmReduction = 0.66; //33% reduction // m.fieldHarmReduction = 0.66; //33% reduction

View File

@@ -668,7 +668,7 @@ const powerUps = {
}); });
} else if (overHeal > 0.13) { //if leftover heals spawn a new spammer heal power up } else if (overHeal > 0.13) { //if leftover heals spawn a new spammer heal power up
requestAnimationFrame(() => { requestAnimationFrame(() => {
powerUps.directSpawn(this.position.x, this.position.y, "heal", true, null, overHeal * 40 * (simulation.healScale ** 0.25))// directSpawn(x, y, target, moving = true, mode = null, size = powerUps[target].size()) { powerUps.directSpawn(this.position.x, this.position.y, "heal", true, null, Math.min(1, overHeal) * 40 * (simulation.healScale ** 0.25))// directSpawn(x, y, target, moving = true, mode = null, size = powerUps[target].size()) {
}); });
} }
if (tech.isHealBrake) { if (tech.isHealBrake) {

View File

@@ -116,13 +116,15 @@ const spawn = {
secondaryBossChance(x, y) { secondaryBossChance(x, y) {
if (simulation.difficultyMode > 2 && level.levelsCleared > 2) { if (simulation.difficultyMode > 2 && level.levelsCleared > 2) {
spawn.randomLevelBoss(x, y); spawn.randomLevelBoss(x, y);
powerUps.directSpawn(x - 30, y, "ammo");
powerUps.directSpawn(x + 30, y, "ammo");
} else { } else {
return false return false
} }
}, },
//mob templates ********************************************************************************************* //mob templates *********************************************************************************************
//*********************************************************************************************************** //***********************************************************************************************************
MACHO(x = m.pos.x, y = m.pos.y) { //immortal mob that follows player //if you have the tech it spawns at start of every level at the player darkMatter(x = m.pos.x, y = m.pos.y) { //immortal mob that follows player //if you have the tech it spawns at start of every level at the player
mobs.spawn(x, y, 3, 0.1, "transparent"); mobs.spawn(x, y, 3, 0.1, "transparent");
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.stroke = "transparent" me.stroke = "transparent"
@@ -135,13 +137,14 @@ const spawn = {
me.collisionFilter.category = 0; me.collisionFilter.category = 0;
me.collisionFilter.mask = 0; //cat.player //| cat.body me.collisionFilter.mask = 0; //cat.player //| cat.body
me.chaseSpeed = 3.3 me.chaseSpeed = 3.3
me.isMACHO = true; me.isDarkMatter = true;
me.frictionAir = 0.006 me.frictionAir = 0.006
me.onDeath = function () { me.onDeath = function () {
tech.isHarmMACHO = false; tech.isHarmDarkMatter = false;
} }
me.do = function () { me.do = function () {
if (!simulation.isTimeSkipping) { if (!simulation.isTimeSkipping) {
const scale = (tech.isMoveDarkMatter || tech.isNotDarkMatter) ? 1.6 : 1
const sine = Math.sin(simulation.cycle * 0.015) const sine = Math.sin(simulation.cycle * 0.015)
this.radius = 111 * tech.isDarkStar + 370 * (1 + 0.1 * sine) this.radius = 111 * tech.isDarkStar + 370 * (1 + 0.1 * sine)
//chase player //chase player
@@ -163,7 +166,7 @@ const spawn = {
// } // }
// } // }
if (tech.isMoveMACHO && m.crouch && input.down) { if (tech.isMoveDarkMatter && m.crouch && input.down) {
Matter.Body.setVelocity(this, Vector.add(Vector.mult(this.velocity, 0.97), Vector.mult(player.velocity, 0.03))) Matter.Body.setVelocity(this, Vector.add(Vector.mult(this.velocity, 0.97), Vector.mult(player.velocity, 0.03)))
Matter.Body.setPosition(this, Vector.add(Vector.mult(this.position, 0.95), Vector.mult(player.position, 0.05))) Matter.Body.setPosition(this, Vector.add(Vector.mult(this.position, 0.95), Vector.mult(player.position, 0.05)))
} }
@@ -171,18 +174,34 @@ const spawn = {
this.force.x += force.x this.force.x += force.x
this.force.y += force.y this.force.y += force.y
if (tech.isNotDarkMatter) {
if (mag < this.radius) { //buff to player when inside radius if (mag < this.radius) { //buff to player when inside radius
tech.isHarmMACHO = true; tech.isHarmDarkMatter = false;
//draw halo } else {
ctx.strokeStyle = "rgba(80,120,200,0.2)" //"rgba(255,255,0,0.2)" //ctx.strokeStyle = `rgba(0,0,255,${0.5+0.5*Math.random()})` tech.isHarmDarkMatter = true;
ctx.beginPath(); //draw halo
ctx.arc(m.pos.x, m.pos.y, 36, 0, 2 * Math.PI); ctx.strokeStyle = "rgba(80,120,200,0.2)" //"rgba(255,255,0,0.2)" //ctx.strokeStyle = `rgba(0,0,255,${0.5+0.5*Math.random()})`
ctx.lineWidth = 10; ctx.beginPath();
ctx.stroke(); ctx.arc(m.pos.x, m.pos.y, 36, 0, 2 * Math.PI);
ctx.lineWidth = 10;
ctx.stroke();
if (tech.isDarkEnergy) m.energy += 0.0017 * scale
}
} else { } else {
tech.isHarmMACHO = false; if (mag < this.radius) { //buff to player when inside radius
tech.isHarmDarkMatter = true;
//draw halo
ctx.strokeStyle = "rgba(80,120,200,0.2)" //"rgba(255,255,0,0.2)" //ctx.strokeStyle = `rgba(0,0,255,${0.5+0.5*Math.random()})`
ctx.beginPath();
ctx.arc(m.pos.x, m.pos.y, 36, 0, 2 * Math.PI);
ctx.lineWidth = 10;
ctx.stroke();
if (tech.isDarkEnergy) m.energy += 0.0017 * scale
} else {
tech.isHarmDarkMatter = false;
}
} }
//draw outline //draw outline
ctx.beginPath(); ctx.beginPath();
ctx.arc(this.position.x, this.position.y, this.radius + 15, 0, 2 * Math.PI); ctx.arc(this.position.x, this.position.y, this.radius + 15, 0, 2 * Math.PI);
@@ -196,7 +215,7 @@ const spawn = {
for (let i = 0, len = mob.length; i < len; ++i) { for (let i = 0, len = mob.length; i < len; ++i) {
if (mob[i].alive && !mob[i].isShielded) { if (mob[i].alive && !mob[i].isShielded) {
if (Vector.magnitude(Vector.sub(this.position, mob[i].position)) - mob[i].radius < this.radius) { if (Vector.magnitude(Vector.sub(this.position, mob[i].position)) - mob[i].radius < this.radius) {
const dmg = 0.025 * m.dmgScale * (tech.isMoveMACHO ? 1.5 : 1) const dmg = 0.03 * m.dmgScale * scale
mob[i].damage(dmg); mob[i].damage(dmg);
simulation.drawList.push({ //add dmg to draw queue simulation.drawList.push({ //add dmg to draw queue
x: mob[i].position.x, x: mob[i].position.x,
@@ -1428,7 +1447,7 @@ const spawn = {
me.seeAtDistance2 = 1400000; me.seeAtDistance2 = 1400000;
me.cellMassMax = 70 me.cellMassMax = 70
me.collisionFilter.mask = cat.player | cat.bullet | cat.body// | cat.map me.collisionFilter.mask = cat.player | cat.bullet | cat.body// | cat.map
Matter.Body.setDensity(me, 0.00012 + 0.00001 * simulation.difficulty) // normal density is 0.001 Matter.Body.setDensity(me, 0.00012 + 0.000008 * simulation.difficulty) // normal density is 0.001
me.damageReduction = 0.17 me.damageReduction = 0.17
const k = 642 //k=r^2/m const k = 642 //k=r^2/m
@@ -1691,7 +1710,7 @@ const spawn = {
} else if (!m.isCloak) { } else if (!m.isCloak) {
me.foundPlayer(); me.foundPlayer();
} }
me.damageReduction = 0.2 me.damageReduction = 0.21
me.isInvulnerable = true me.isInvulnerable = true
me.startingDamageReduction = me.damageReduction me.startingDamageReduction = me.damageReduction
me.damageReduction = 0 me.damageReduction = 0
@@ -1769,7 +1788,7 @@ const spawn = {
me.foundPlayer(); me.foundPlayer();
} }
me.damageReduction = 0.22 me.damageReduction = 0.23
me.isInvulnerable = true me.isInvulnerable = true
me.startingDamageReduction = me.damageReduction me.startingDamageReduction = me.damageReduction
me.damageReduction = 0 me.damageReduction = 0
@@ -2146,7 +2165,7 @@ const spawn = {
mobs.spawn(x, y, 5, radius, "rgb(0,200,180)"); mobs.spawn(x, y, 5, radius, "rgb(0,200,180)");
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.isBoss = true; me.isBoss = true;
me.damageReduction = 0.09 me.damageReduction = 0.12
me.accelMag = 0.05; //jump height me.accelMag = 0.05; //jump height
me.g = 0.003; //required if using this.gravity me.g = 0.003; //required if using this.gravity
me.frictionAir = 0.01; me.frictionAir = 0.01;
@@ -2470,7 +2489,7 @@ const spawn = {
// toMe(bullet, this.position, this.eventHorizon)) // toMe(bullet, this.position, this.eventHorizon))
} }
}; };
me.damageReduction = 0.25 me.damageReduction = 0.27
me.do = function () { me.do = function () {
//keep it slow, to stop issues from explosion knock backs //keep it slow, to stop issues from explosion knock backs
if (this.speed > 1) { if (this.speed > 1) {
@@ -2662,7 +2681,7 @@ const spawn = {
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.babyList = [] //list of mobs that are apart of this boss me.babyList = [] //list of mobs that are apart of this boss
Matter.Body.setDensity(me, 0.0015); //extra dense //normal is 0.001 //makes effective life much larger and damage on collision Matter.Body.setDensity(me, 0.0015); //extra dense //normal is 0.001 //makes effective life much larger and damage on collision
me.damageReduction = 0.13 //normal is 1, most bosses have 0.25 me.damageReduction = 0.14 //normal is 1, most bosses have 0.25
me.isBoss = true; me.isBoss = true;
me.friction = 0; me.friction = 0;
@@ -2978,7 +2997,7 @@ const spawn = {
me.laserRange = 350; me.laserRange = 350;
me.seeAtDistance2 = 2000000; me.seeAtDistance2 = 2000000;
me.isBoss = true; me.isBoss = true;
me.damageReduction = 0.35 // me.damageReductionGoal me.damageReduction = 0.38 // me.damageReductionGoal
me.showHealthBar = false; //drawn in this.awake me.showHealthBar = false; //drawn in this.awake
me.delayLimit = 60 + Math.floor(30 * Math.random()); me.delayLimit = 60 + Math.floor(30 * Math.random());
@@ -3403,7 +3422,7 @@ const spawn = {
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.isBoss = true; me.isBoss = true;
Matter.Body.setDensity(me, 0.005); //extra dense //normal is 0.001 //makes effective life much larger Matter.Body.setDensity(me, 0.005); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.07 me.damageReduction = 0.08
me.startingDamageReduction = me.damageReduction me.startingDamageReduction = me.damageReduction
me.isInvulnerable = false me.isInvulnerable = false
me.nextHealthThreshold = 0.75 me.nextHealthThreshold = 0.75
@@ -3594,7 +3613,7 @@ const spawn = {
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.isBoss = true; me.isBoss = true;
Matter.Body.setDensity(me, 0.004); //extra dense //normal is 0.001 //makes effective life much larger Matter.Body.setDensity(me, 0.004); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.1 me.damageReduction = 0.12
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);
@@ -3686,7 +3705,7 @@ const spawn = {
mobs.spawn(x, y, 3, radius, "rgb(0,235,255)"); mobs.spawn(x, y, 3, radius, "rgb(0,235,255)");
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.isBoss = true; me.isBoss = true;
me.damageReduction = 0.25 me.damageReduction = 0.27
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);
@@ -3792,7 +3811,7 @@ const spawn = {
Matter.Body.rotate(me, Math.PI * 0.1); Matter.Body.rotate(me, Math.PI * 0.1);
Matter.Body.setDensity(me, 0.002); //extra dense //normal is 0.001 //makes effective life much larger Matter.Body.setDensity(me, 0.002); //extra dense //normal is 0.001 //makes effective life much larger
me.isBoss = true; me.isBoss = true;
me.damageReduction = 0.034 me.damageReduction = 0.038
me.frictionStatic = 0; me.frictionStatic = 0;
me.friction = 0; me.friction = 0;
@@ -3850,6 +3869,156 @@ const spawn = {
this.checkStatus(); this.checkStatus();
}; };
}, },
snakeBoss(x, y) {
mobs.spawn(x, y, 0, 30, `rgba(255,0,200)`); //"rgb(221,102,119)"
let me = mob[mob.length - 1];
me.stroke = "transparent"; //used for drawGhost
// Matter.Body.setStatic(me, true); //make static, breaks game on player collision
Matter.Body.setDensity(me, 0.002); //extra dense //normal is 0.001 //makes effective life much larger
me.isBoss = true;
me.damageReduction = 0.02
me.startingDamageReduction = me.damageReduction
me.isInvulnerable = false
me.nextHealthThreshold = 0.75
me.invulnerableCount = 0
me.history = []
for (let i = 0; i < 15; i++) {
me.history.push({ x: me.position.x + i, y: me.position.y })
}
me.frictionStatic = 0;
me.friction = 0;
me.memory = 240
me.seePlayerFreq = 55
me.delay = 6 + 4 * simulation.CDScale;
me.nextBlinkCycle = me.delay;
me.radius = 30
me.JumpDistance = me.radius * 2
// spawn.shield(me, x, y, 1);
me.collisionFilter.mask = cat.bullet | cat.map //| cat.body //cat.player |
me.onDamage = function () {
if (this.health < this.nextHealthThreshold) {
this.health = this.nextHealthThreshold - 0.01
this.nextHealthThreshold = Math.floor(this.health * 4) / 4 //0.75,0.5,0.25
this.invulnerableCount = 90
this.isInvulnerable = true
this.damageReduction = 0
this.laserDelay = 130
const where = this.history[0]
for (let i = 0; i < 10; i++) {
this.history.unshift(where)
}
}
};
me.onDeath = function () {
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
}
me.do = function () {
const color = `rgba(255,0,200,${0.3 + 0.07 * Math.random()})`
//check for player in between each segment
for (let i = 0; i < this.history.length - 1; i++) {
if (Matter.Query.ray([player], this.history[i], this.history[i + 1], 10).length > 0) {
m.damage(0.004 * simulation.dmgScale);
simulation.drawList.push({ //add dmg to draw queue
x: m.pos.x,
y: m.pos.y,
radius: 30,
color: color,
time: 10
});
break
}
}
if (this.nextBlinkCycle < simulation.cycle) { //teleport towards the player
this.nextBlinkCycle = simulation.cycle + this.delay;
//custom see player by history code
let move = (target = this.seePlayer.position) => {
const dist = Vector.sub(target, this.position);
Matter.Body.translate(this, Vector.mult(Vector.normalise(dist), this.JumpDistance));
Matter.Body.setVelocity(this, { x: 0, y: 0 });
Matter.Body.setAngle(this, 0);
Matter.Body.setAngularVelocity(this, 0)
//track previous locations for the tail
this.history.push({ x: this.position.x, y: this.position.y }) //add newest to end
this.history.shift() //remove first (oldest)
}
//look for close powers up in line of sight
let close = {
dist2: Infinity,
targetPos: null
}
for (let i = 0; i < powerUp.length; i++) {
if (Matter.Query.ray(map, this.position, powerUp[i].position).length === 0) {
const dist = Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position))
if (dist < close.dist2) {
close = {
dist2: dist,
// targetPos: { x: powerUp[i].position.x, y: powerUp[i].position.y }
target: powerUp[i]
}
}
}
}
if (close.dist2 < 5000 * 5000) {
//chase power ups
move(close.target.position)
//check if close to power up and eat it
if (close.dist2 < 200 * 200) {
//eat power up
}
} else if (Matter.Query.ray(map, this.position, this.playerPosRandomY()).length === 0 && !m.isCloak) {
this.seePlayer.yes = true;
this.locatePlayer();
if (!this.seePlayer.yes) this.seePlayer.yes = true;
move()
} else if (this.seePlayer.recall) {
this.lostPlayer();
if (!m.isCloak) {
for (let i = 0; i < 50; i++) { //if lost player lock onto a player location in history
let history = m.history[(m.cycle - 10 * i) % 600]
if (Matter.Query.ray(map, this.position, history.position).length === 0) {
this.seePlayer.recall = this.memory + Math.round(this.memory * Math.random()); //cycles before mob falls a sleep
this.seePlayer.position.x = history.position.x;
this.seePlayer.position.y = history.position.y;
this.seePlayer.yes = true;
move()
break
}
}
}
}
}
this.checkStatus();
if (this.isInvulnerable) {
this.invulnerableCount--
if (this.invulnerableCount < 0) {
this.isInvulnerable = false
this.damageReduction = this.startingDamageReduction
}
//draw invulnerable
ctx.beginPath();
let vertices = this.vertices;
ctx.moveTo(vertices[0].x, vertices[0].y);
for (let j = 1; j < vertices.length; j++) ctx.lineTo(vertices[j].x, vertices[j].y);
ctx.lineTo(vertices[0].x, vertices[0].y);
ctx.lineWidth = 13 + 5 * Math.random();
ctx.strokeStyle = `rgba(255,255,255,${0.5 + 0.2 * Math.random()})`;
ctx.stroke();
}
//draw history
ctx.beginPath();
for (let i = 0, len = this.history.length; i < len; i++) {
ctx.lineTo(this.history[i].x, this.history[i].y)
}
ctx.lineWidth = this.radius * 2;
ctx.strokeStyle = color //"rgba(0,235,255,0.5)";
ctx.stroke();
};
},
pulsarBoss(x, y, radius = 90, isNonCollide = false) { pulsarBoss(x, y, radius = 90, isNonCollide = false) {
mobs.spawn(x, y, 3, radius, "#a0f"); mobs.spawn(x, y, 3, radius, "#a0f");
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
@@ -3890,7 +4059,7 @@ const spawn = {
me.do = function () { me.do = function () {
if (player.speed > 5) this.do = this.fire //don't attack until player moves if (player.speed > 5) this.do = this.fire //don't attack until player moves
} }
me.damageReduction = 0.25 me.damageReduction = 0.29
me.fire = function () { me.fire = function () {
// this.armor(); // this.armor();
this.checkStatus(); this.checkStatus();
@@ -4263,7 +4432,7 @@ const spawn = {
powerUps.spawnBossPowerUp(this.position.x, this.position.y) powerUps.spawnBossPowerUp(this.position.x, this.position.y)
}; };
Matter.Body.setDensity(me, 0.03); //extra dense //normal is 0.001 //makes effective life much larger Matter.Body.setDensity(me, 0.03); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.33 me.damageReduction = 0.36
me.startingDamageReduction = me.damageReduction me.startingDamageReduction = me.damageReduction
me.isInvulnerable = false me.isInvulnerable = false
me.nextHealthThreshold = 0.75 me.nextHealthThreshold = 0.75
@@ -4725,7 +4894,7 @@ const spawn = {
// spawn.shield(me, x, y, 1); // spawn.shield(me, x, y, 1);
Matter.Body.setDensity(me, 0.005); //extra dense //normal is 0.001 //makes effective life much larger Matter.Body.setDensity(me, 0.005); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.12 me.damageReduction = 0.13
me.isBoss = true; me.isBoss = true;
me.onDamage = function () { }; me.onDamage = function () { };
me.onDeath = function () { me.onDeath = function () {
@@ -4820,8 +4989,8 @@ const spawn = {
me.frictionAir = 0; me.frictionAir = 0;
me.restitution = 1 me.restitution = 1
// spawn.spawnOrbitals(me, radius + 50 + 125 * Math.random(), 1) // spawn.spawnOrbitals(me, radius + 50 + 125 * Math.random(), 1)
Matter.Body.setDensity(me, 0.002 + 0.0001 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger Matter.Body.setDensity(me, 0.002 + 0.00005 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.09 me.damageReduction = 0.11
me.startingDamageReduction = me.damageReduction me.startingDamageReduction = me.damageReduction
me.isInvulnerable = false me.isInvulnerable = false
me.nextHealthThreshold = 0.75 me.nextHealthThreshold = 0.75
@@ -5274,7 +5443,7 @@ const spawn = {
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
Matter.Body.rotate(me, 2 * Math.PI * Math.random()); Matter.Body.rotate(me, 2 * Math.PI * Math.random());
me.isBoss = true; me.isBoss = true;
me.damageReduction = 0.1 me.damageReduction = 0.11
me.startingDamageReduction = me.damageReduction me.startingDamageReduction = me.damageReduction
me.isInvulnerable = false me.isInvulnerable = false
me.frictionAir = 0.02 me.frictionAir = 0.02
@@ -5722,7 +5891,7 @@ const spawn = {
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
Matter.Body.setDensity(me, 0.001); //extra dense //normal is 0.001 //makes effective life much larger Matter.Body.setDensity(me, 0.001); //extra dense //normal is 0.001 //makes effective life much larger
me.isBoss = true; me.isBoss = true;
me.damageReduction = 0.15 me.damageReduction = 0.17
me.accelMag = 0.0017 * Math.sqrt(simulation.accelScale); me.accelMag = 0.0017 * Math.sqrt(simulation.accelScale);
me.frictionAir = 0.01; me.frictionAir = 0.01;
@@ -6030,7 +6199,7 @@ const spawn = {
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.isBoss = true; me.isBoss = true;
Matter.Body.setDensity(me, 0.0025 + 0.00013 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger Matter.Body.setDensity(me, 0.0025 + 0.00009 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.stroke = "transparent"; //used for drawGhost me.stroke = "transparent"; //used for drawGhost
me.seeAtDistance2 = 1500000; me.seeAtDistance2 = 1500000;
@@ -6057,7 +6226,7 @@ const spawn = {
me.onDeath = function () { me.onDeath = function () {
powerUps.spawnBossPowerUp(this.position.x, this.position.y) powerUps.spawnBossPowerUp(this.position.x, this.position.y)
}; };
me.damageReduction = 0.2 me.damageReduction = 0.22
me.do = function () { me.do = function () {
// this.armor(); // this.armor();
this.seePlayerCheckByDistance(); this.seePlayerCheckByDistance();
@@ -6114,8 +6283,8 @@ const spawn = {
}, 2000); //add in a delay in case the level gets flipped left right }, 2000); //add in a delay in case the level gets flipped left right
me.isBoss = true; me.isBoss = true;
Matter.Body.setDensity(me, 0.01 + 0.0004 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger Matter.Body.setDensity(me, 0.01 + 0.0003 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.2 me.damageReduction = 0.22
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
me.isVerticesChange = true me.isVerticesChange = true
@@ -6472,8 +6641,8 @@ const spawn = {
mobs.spawn(x, y, 6, radius, "rgb(150,150,255)"); mobs.spawn(x, y, 6, radius, "rgb(150,150,255)");
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.isBoss = true; me.isBoss = true;
Matter.Body.setDensity(me, 0.0022 + 0.0002 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger Matter.Body.setDensity(me, 0.0022 + 0.00015 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.2 me.damageReduction = 0.22
me.accelMag = 0.0001 * simulation.accelScale; me.accelMag = 0.0001 * simulation.accelScale;
me.fireFreq = Math.floor(330 * simulation.CDScale) me.fireFreq = Math.floor(330 * simulation.CDScale)
@@ -6684,7 +6853,7 @@ const spawn = {
spawn.spawnOrbitals(me, radius + 50, 1); spawn.spawnOrbitals(me, radius + 50, 1);
spawn.spawnOrbitals(me, radius + 125, 1); spawn.spawnOrbitals(me, radius + 125, 1);
spawn.spawnOrbitals(me, radius + 200, 1); spawn.spawnOrbitals(me, radius + 200, 1);
Matter.Body.setDensity(me, 0.004 + 0.0002 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger Matter.Body.setDensity(me, 0.004 + 0.00015 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.onDeath = function () { //helps collisions functions work better after vertex have been changed me.onDeath = function () { //helps collisions functions work better after vertex have been changed
setTimeout(() => { //fix mob in place, but allow rotation setTimeout(() => { //fix mob in place, but allow rotation
for (let i = 0, len = 6; i < len; i++) { for (let i = 0, len = 6; i < len; i++) {
@@ -6713,7 +6882,7 @@ const spawn = {
}); });
} }
}; };
me.damageReduction = 0.25 me.damageReduction = 0.27
me.do = function () { me.do = function () {
// this.armor(); // this.armor();
if (this.grenadeLimiter > 1) this.grenadeLimiter-- if (this.grenadeLimiter > 1) this.grenadeLimiter--
@@ -6875,7 +7044,7 @@ const spawn = {
me.onDamage = function () { me.onDamage = function () {
this.cycle = 0 this.cycle = 0
}; };
me.damageReduction = 0.35 me.damageReduction = 0.39
me.do = function () { me.do = function () {
Matter.Body.rotate(this, 0.003) //gently spin around Matter.Body.rotate(this, 0.003) //gently spin around
this.checkStatus(); this.checkStatus();
@@ -7011,7 +7180,7 @@ const spawn = {
// this.vertices = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices)) //helps collisions functions work better after vertex have been changed // this.vertices = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices)) //helps collisions functions work better after vertex have been changed
}; };
me.onDamage = function () { }; me.onDamage = function () { };
me.damageReduction = 0.25 me.damageReduction = 0.28
me.do = function () { me.do = function () {
// this.armor(); // this.armor();
this.seePlayerCheck(); this.seePlayerCheck();
@@ -7393,7 +7562,7 @@ const spawn = {
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.body //| cat.mob me.collisionFilter.mask = cat.bullet | cat.player | cat.body //| cat.mob
me.damageReduction = 0.028 me.damageReduction = 0.031
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;
@@ -7432,8 +7601,8 @@ const spawn = {
mobs.spawn(x, y, 8, radius, "rgb(0,60,80)"); mobs.spawn(x, y, 8, radius, "rgb(0,60,80)");
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.isBoss = true; me.isBoss = true;
Matter.Body.setDensity(me, 0.0005 + 0.0002 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger Matter.Body.setDensity(me, 0.0006 + 0.0001 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.25 me.damageReduction = 0.27
me.startingDamageReduction = me.damageReduction me.startingDamageReduction = me.damageReduction
me.isInvulnerable = false me.isInvulnerable = false
me.nextHealthThreshold = 0.75 me.nextHealthThreshold = 0.75
@@ -7682,8 +7851,8 @@ const spawn = {
mobs.spawn(x, y, nodes, radius, "rgb(255,0,150)"); mobs.spawn(x, y, nodes, radius, "rgb(255,0,150)");
let me = mob[mob.length - 1]; let me = mob[mob.length - 1];
me.isBoss = true; me.isBoss = true;
Matter.Body.setDensity(me, 0.0017 + 0.0002 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger Matter.Body.setDensity(me, 0.0018 + 0.00015 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.1 me.damageReduction = 0.11
me.stroke = "transparent"; //used for drawGhost me.stroke = "transparent"; //used for drawGhost
me.seeAtDistance2 = 2000000; me.seeAtDistance2 = 2000000;

View File

@@ -73,7 +73,7 @@ const tech = {
}, },
junkChance: 0, junkChance: 0,
addJunkTechToPool(percent) { //percent is number between 0-1 addJunkTechToPool(percent) { //percent is number between 0-1
simulation.makeTextLog(`<strong>+${(100 * percent).toFixed(0)}%</strong> <span class='color-text'>JUNK</span><span class='color-var'>tech</span> chance (${100 * tech.junkChance.toFixed(0)} total chance)`) simulation.makeTextLog(`<strong>+${(100 * percent).toFixed(0)}%</strong> <span class='color-text'>JUNK</span><span class='color-var'>tech</span> chance (${(100 * tech.junkChance).toFixed(0)} total chance)`)
// tech.junkChance += (1 - tech.junkChance) * percent // tech.junkChance += (1 - tech.junkChance) * percent
tech.junkChance += percent tech.junkChance += percent
if (tech.junkChance < 0.001 || tech.junkChance === undefined) tech.junkChance = 0 if (tech.junkChance < 0.001 || tech.junkChance === undefined) tech.junkChance = 0
@@ -207,12 +207,14 @@ const tech = {
damage: 1, //used for tech changes to player damage that don't have complex conditions damage: 1, //used for tech changes to player damage that don't have complex conditions
damageFromTech() { damageFromTech() {
let dmg = tech.damage * m.fieldDamage let dmg = tech.damage * m.fieldDamage
if (tech.isMaxHealthDamage && m.health === m.maxHealth) dmg *= 1.5
if (tech.isNoDefenseDamage && m.defense() === 1) dmg *= 2
if (tech.isImmunityDamage && m.immuneCycle > m.cycle) dmg *= 4 if (tech.isImmunityDamage && m.immuneCycle > m.cycle) dmg *= 4
if (tech.isPowerUpDamage) dmg *= 1 + 0.05 * powerUp.length if (tech.isPowerUpDamage) dmg *= 1 + 0.05 * powerUp.length
if (tech.isDamageCooldown) dmg *= m.lastKillCycle + tech.isDamageCooldownTime > m.cycle ? 0.5 : 4 if (tech.isDamageCooldown) dmg *= m.lastKillCycle + tech.isDamageCooldownTime > m.cycle ? 0.5 : 4
if (tech.isDamageAfterKillNoRegen && m.lastKillCycle + 300 > m.cycle) dmg *= 2 if (tech.isDamageAfterKillNoRegen && m.lastKillCycle + 300 > m.cycle) dmg *= 2
if (tech.isDivisor && b.activeGun !== undefined && b.activeGun !== null && b.guns[b.activeGun].ammo % 3 === 0) dmg *= 1.8 if (tech.isDivisor && b.activeGun !== undefined && b.activeGun !== null && b.guns[b.activeGun].ammo % 3 === 0) dmg *= 1.8
if (tech.isNoGroundDamage) dmg *= m.onGround ? 0.85 : 2 if (tech.isNoGroundDamage) dmg *= m.onGround ? 0.9 : 2
if (tech.isDilate) dmg *= 1.9 + 1.1 * Math.sin(m.cycle * 0.01) if (tech.isDilate) dmg *= 1.9 + 1.1 * Math.sin(m.cycle * 0.01)
if (tech.isGunChoice && tech.buffedGun === b.inventoryGun) dmg *= 1 + 0.3 * b.inventory.length if (tech.isGunChoice && tech.buffedGun === b.inventoryGun) dmg *= 1 + 0.3 * b.inventory.length
if (powerUps.boost.endCycle > m.cycle) dmg *= 1 + powerUps.boost.damage if (powerUps.boost.endCycle > m.cycle) dmg *= 1 + powerUps.boost.damage
@@ -227,12 +229,12 @@ const tech = {
if (tech.isRerollDamage) dmg *= 1 + Math.max(0, 0.05 * powerUps.research.count) if (tech.isRerollDamage) dmg *= 1 + Math.max(0, 0.05 * powerUps.research.count)
if (tech.isBotDamage) dmg *= 1 + 0.04 * b.totalBots() if (tech.isBotDamage) dmg *= 1 + 0.04 * b.totalBots()
if (tech.restDamage > 1 && player.speed < 1) dmg *= tech.restDamage if (tech.restDamage > 1 && player.speed < 1) dmg *= tech.restDamage
if (tech.isLowEnergyDamage) dmg *= 1 + Math.max(0, 1 - m.energy) if (tech.isLowEnergyDamage) dmg *= 1 + 0.5 * Math.max(0, m.maxEnergy - m.energy)
if (tech.energyDamage) dmg *= 1 + m.energy * 0.23 * tech.energyDamage; if (tech.energyDamage) dmg *= 1 + m.energy * 0.23 * tech.energyDamage;
if (tech.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.01 if (tech.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.01
if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 2 if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 2
if (tech.isSpeedDamage) dmg *= 1 + Math.min(1, (tech.speedAdded + player.speed) * 0.0193) if (tech.isSpeedDamage) dmg *= 1 + Math.min(1, (tech.speedAdded + player.speed) * 0.0193)
if (tech.isAxion && tech.isHarmMACHO) dmg *= (tech.isMoveMACHO ? 3 : 2) if (tech.isAxion && tech.isHarmDarkMatter) dmg *= ((tech.isMoveDarkMatter || tech.isNotDarkMatter) ? 3.2 : 2)
if (tech.isHarmDamage && m.lastHarmCycle + 480 > m.cycle) dmg *= 3; if (tech.isHarmDamage && m.lastHarmCycle + 480 > m.cycle) dmg *= 3;
if (tech.lastHitDamage && m.lastHit) dmg *= 1 + tech.lastHitDamage * m.lastHit if (tech.lastHitDamage && m.lastHit) dmg *= 1 + tech.lastHitDamage * m.lastHit
// if (tech.isLowHealthDmg) dmg *= 1 + 0.6 * Math.max(0, 1 - (tech.isEnergyHealth ? m.energy : m.health)) // if (tech.isLowHealthDmg) dmg *= 1 + 0.6 * Math.max(0, 1 - (tech.isEnergyHealth ? m.energy : m.health))
@@ -874,8 +876,6 @@ const tech = {
{ {
name: "Pareto efficiency", name: "Pareto efficiency",
descriptionFunction() { descriptionFunction() {
// return `for each <strong class='color-g'>gun</strong> randomly<br>gain <strong>5x</strong> or <strong>0.2x</strong> <strong class='color-ammo'>ammo</strong> per ${powerUps.orb.ammo(1)}`
// return `randomly adjust your <strong class='color-g'>guns</strong> by<br><strong>5x</strong> or <strong>0.2x</strong> <strong class='color-ammo'>ammo</strong> per ${powerUps.orb.ammo(1)}`
return `for each of your <strong class='color-g'>guns</strong><br>randomly get <strong>5x</strong> or <strong>0.2x</strong> <strong class='color-ammo'>ammo</strong> per ${powerUps.orb.ammo(1)}` return `for each of your <strong class='color-g'>guns</strong><br>randomly get <strong>5x</strong> or <strong>0.2x</strong> <strong class='color-ammo'>ammo</strong> per ${powerUps.orb.ammo(1)}`
}, },
maxCount: 1, maxCount: 1,
@@ -898,16 +898,6 @@ const tech = {
simulation.makeTextLog(`${(b.guns[index].ammoPack).toFixed(1)} <span ${scale < 1 ? 'style="color: #f00;"' : ''}>→</span> ${(b.guns[index].ammoPack * scale).toFixed(1)} average <strong class='color-ammo'>ammo</strong> per ${powerUps.orb.ammo(1)} for <strong class='color-g'>${b.guns[index].name}</strong>`, Infinity) simulation.makeTextLog(`${(b.guns[index].ammoPack).toFixed(1)} <span ${scale < 1 ? 'style="color: #f00;"' : ''}>→</span> ${(b.guns[index].ammoPack * scale).toFixed(1)} average <strong class='color-ammo'>ammo</strong> per ${powerUps.orb.ammo(1)} for <strong class='color-g'>${b.guns[index].name}</strong>`, Infinity)
b.guns[index].ammoPack *= scale b.guns[index].ammoPack *= scale
} }
// let options = []
// for (let i = 0; i < b.guns.length - 1; i++) options.push(i)
// options = shuffle(options)
// for (let i = 0; i < options.length; i++) {
// const index = options[i]
// const scale = (i < options.length / 2) ? 4 : 0.25
// simulation.makeTextLog(`${(b.guns[index].ammoPack).toFixed(1)} <span ${scale < 1 ? 'style="color: #f00;"' : ''}>→</span> ${(b.guns[index].ammoPack * scale).toFixed(1)} average <strong class='color-ammo'>ammo</strong> per ${powerUps.orb.ammo(1)} for <strong class='color-g'>${b.guns[index].name}</strong>`, Infinity)
// b.guns[index].ammoPack *= scale
// }
}, },
remove() { } remove() { }
}, },
@@ -932,7 +922,7 @@ const tech = {
{ {
name: "cache", name: "cache",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Cache_(computing)' class="link">cache</a>`, link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Cache_(computing)' class="link">cache</a>`,
description: `<strong>15x</strong> <strong class='color-ammo'>ammo</strong> per ${powerUps.orb.ammo()}, but<br>you can't <strong>store</strong> any more <strong class='color-ammo'>ammo</strong> than that`, description: `<strong>17x</strong> <strong class='color-ammo'>ammo</strong> per ${powerUps.orb.ammo()}, but<br>you can't <strong>store</strong> additional <strong class='color-ammo'>ammo</strong>`,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -942,7 +932,7 @@ const tech = {
}, },
requires: "not non-renewables", requires: "not non-renewables",
effect() { effect() {
tech.ammoCap = 15; tech.ammoCap = 17;
powerUps.ammo.effect() powerUps.ammo.effect()
}, },
remove() { remove() {
@@ -1115,12 +1105,13 @@ const tech = {
}, },
requires: "", requires: "",
effect() { effect() {
tech.isFarAwayDmg = true; //used in mob.damage() tech.isFarAwayDmg = true;
}, },
remove() { remove() {
tech.isFarAwayDmg = false; tech.isFarAwayDmg = false;
} }
}, },
{ {
name: "microstates", name: "microstates",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Microstate_(statistical_mechanics)' class="link">microstates</a>`, link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Microstate_(statistical_mechanics)' class="link">microstates</a>`,
@@ -2416,8 +2407,11 @@ const tech = {
} }
}, },
{ {
name: "MACHO", name: "dark matter",
description: "a massive compact halo object follows you<br><strong>0.4x</strong> <strong class='color-defense'>damage taken</strong> inside the <strong class='color-MACHO'>MACHO</strong>", //a MAssive Compact Halo Object follows you<br>
descriptionFunction() {
return `<strong class='color-dark-matter'>dark matter</strong> slowly gravitates <strong>towards</strong> you<br><strong>0.4x</strong> <strong class='color-defense'>damage taken</strong> <strong>${tech.isNotDarkMatter ? "outside" : "inside"}</strong> <strong class='color-dark-matter'>dark matter</strong>`
},
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -2427,46 +2421,30 @@ const tech = {
}, },
requires: "", requires: "",
effect() { effect() {
tech.isMACHO = true; //this harm reduction comes from the particle toggling tech.isHarmMACHO tech.isDarkMatter = true; //this harm reduction comes from the particle toggling tech.isHarmDarkMatter
spawn.MACHO() spawn.darkMatter()
}, },
remove() { remove() {
tech.isMACHO = false; tech.isDarkMatter = false;
tech.isHarmMACHO = false; tech.isHarmDarkMatter = false;
for (let i = 0, len = mob.length; i < len; i++) { for (let i = 0, len = mob.length; i < len; i++) {
if (mob[i].isMACHO) mob[i].alive = false; if (mob[i].isDarkMatter) mob[i].alive = false;
} }
} }
}, },
{
name: "entropic gravity",
description: "<strong>crouching</strong> pulls the <strong class='color-MACHO'>MACHO</strong> towards you<br> <strong>1.5x</strong> for all <strong class='color-MACHO'>MACHO</strong> effects",
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isMACHO
},
requires: "MACHO",
effect() {
tech.isMoveMACHO = true
},
remove() {
tech.isMoveMACHO = false
}
},
{ {
name: "axion", name: "axion",
description: "while inside the <strong class='color-MACHO'>MACHO</strong><br> <strong>2x</strong> <strong class='color-d'>damage</strong>", descriptionFunction() {
return `while <strong>${tech.isNotDarkMatter ? "outside" : "inside"}</strong> <strong class='color-dark-matter'>dark matter</strong><br> <strong>2x</strong> <strong class='color-d'>damage</strong>`
},
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return tech.isMACHO return tech.isDarkMatter
}, },
requires: "MACHO", requires: "dark matter",
effect() { effect() {
tech.isAxion = true tech.isAxion = true
}, },
@@ -2475,16 +2453,72 @@ const tech = {
} }
}, },
{ {
name: "dark star", name: "dark energy",
description: `mobs inside the <strong class='color-MACHO'>MACHO</strong> are <strong class='color-d'>damaged</strong><br><strong>1.3x</strong> <strong class='color-MACHO'>MACHO</strong> radius`, descriptionFunction() {
return `while <strong>${tech.isNotDarkMatter ? "outside" : "inside"}</strong> <strong class='color-dark-matter'>dark matter</strong><br>generate <strong>10</strong> <strong class='color-f'>energy</strong> per second`
},
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return tech.isMACHO return tech.isDarkMatter
}, },
requires: "MACHO", requires: "dark matter",
effect() {
tech.isDarkEnergy = true
},
remove() {
tech.isDarkEnergy = false
}
},
{
name: "MACHO",
description: "<span style = 'font-size:93%;'><strong class='color-dark-matter'>dark matter's</strong> effects are only active <strong>outside</strong> it's range<br><strong>1.6x</strong> to all <strong class='color-dark-matter'>dark matter</strong> effects</span>",
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isDarkMatter && !tech.isMoveDarkMatter && !tech.isDarkStar
},
requires: "dark matter, not entropic gravity, dark star",
effect() {
tech.isNotDarkMatter = true
},
remove() {
tech.isNotDarkMatter = false
}
},
{
name: "entropic gravity",
description: "<strong>crouching</strong> pulls <strong class='color-dark-matter'>dark matter</strong> towards you<br><strong>1.6x</strong> to all <strong class='color-dark-matter'>dark matter</strong> effects",
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isDarkMatter && !tech.isNotDarkMatter
},
requires: "dark matter, not MACHO",
effect() {
tech.isMoveDarkMatter = true
},
remove() {
tech.isMoveDarkMatter = false
}
},
{
name: "dark star",
description: `mobs <strong>inside</strong> <strong class='color-dark-matter'>dark matter</strong> are <strong class='color-d'>damaged</strong><br><strong>1.3x</strong> <strong class='color-dark-matter'>dark matter</strong> radius`,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isDarkMatter && !tech.isNotDarkMatter
},
requires: "dark matter, not MACHO",
effect() { effect() {
tech.isDarkStar = true tech.isDarkStar = true
}, },
@@ -2552,7 +2586,7 @@ const tech = {
}, },
{ {
name: "Pauli exclusion", name: "Pauli exclusion",
description: `for <strong>6</strong> seconds after mob <strong>collisions</strong><br>become <strong class="color-invulnerable">invulnerable</strong> and <em style="opacity: 0.3;">inhibit <strong class='color-f'>energy</strong> regen</em>`, description: `for <strong>8</strong> seconds after mob <strong>collisions</strong><br>become <strong class="color-invulnerable">invulnerable</strong> and <em style="opacity: 0.3;">inhibit <strong class='color-f'>energy</strong> regen</em>`,
maxCount: 9, maxCount: 9,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -2562,7 +2596,7 @@ const tech = {
}, },
requires: "", requires: "",
effect() { effect() {
m.collisionImmuneCycles += 360; m.collisionImmuneCycles += 480;
if (m.immuneCycle < m.cycle + m.collisionImmuneCycles) m.immuneCycle = m.cycle + m.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() {
@@ -2729,27 +2763,21 @@ const tech = {
{ {
name: "Gibbs free energy", name: "Gibbs free energy",
descriptionFunction() { descriptionFunction() {
return `use ${powerUps.orb.research(2)}<br><span style = 'font-size:94%;'><strong>1.01x</strong> <strong class='color-d'>damage</strong> per <strong class='color-f'>energy</strong> below <strong>100</strong> <em style ="float: right;">(${(1 + Math.max(0, 1 - m.energy)).toFixed(2)}x)</em></span>` return `<strong>1.005x</strong> <strong class='color-d'>damage</strong> for each missing <strong class='color-f'>energy</strong><br><em style ="float: right;">(${(1 + 0.5 * Math.max(0, m.maxEnergy - m.energy)).toFixed(2)}x)</em>`
}, },
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
allowed() { allowed() {
return powerUps.research.count > 1 || build.isExperimentSelection return true
}, },
requires: "", requires: "",
effect() { effect() {
tech.isLowEnergyDamage = true; tech.isLowEnergyDamage = true;
for (let i = 0; i < 2; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
}
}, },
remove() { remove() {
tech.isLowEnergyDamage = false; tech.isLowEnergyDamage = false;
if (this.count > 0) {
powerUps.research.changeRerolls(2)
}
} }
}, },
{ {
@@ -2780,7 +2808,7 @@ const tech = {
}, },
{ {
name: "Maxwells demon", name: "Maxwells demon",
description: "<strong class='color-f'>energy</strong> above max decays <strong>30x</strong> slower<br><strong>+5%</strong> <strong class='color-junk'>JUNK</strong><strong class='color-m'>tech</strong> chance", description: "<strong class='color-f'>energy</strong> above maximum decays <strong>30x</strong> slower<br><strong>+5%</strong> <strong class='color-junk'>JUNK</strong><strong class='color-m'>tech</strong> chance",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 2,
@@ -2868,7 +2896,7 @@ const tech = {
}, },
{ {
name: "waste heat recovery", name: "waste heat recovery",
description: "if a mob has <strong>died</strong> in the last <strong>5</strong> seconds<br>generate <strong>0.05x</strong> max <strong class='color-f'>energy</strong> every second", description: "if a mob has <strong>died</strong> in the last <strong>5</strong> seconds<br>generate <strong>0.05x</strong> maximum <strong class='color-f'>energy</strong> every second",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -2887,7 +2915,7 @@ const tech = {
{ {
name: "recycling", name: "recycling",
descriptionFunction() { descriptionFunction() {
return `if a mob has <strong>died</strong> in the last <strong>5</strong> seconds<br>recover <strong>0.005x</strong> max ${tech.isEnergyHealth ? "<strong class='color-f'>energy</strong>" : "<strong class='color-h'>health</strong>"} every second` return `if a mob has <strong>died</strong> in the last <strong>5</strong> seconds<br>recover <strong>0.005x</strong> maximum ${tech.isEnergyHealth ? "<strong class='color-f'>energy</strong>" : "<strong class='color-h'>health</strong>"} every second`
}, },
description: "", description: "",
maxCount: 1, maxCount: 1,
@@ -2924,6 +2952,66 @@ const tech = {
tech.isHarmReduceNoKill = false; tech.isHarmReduceNoKill = false;
} }
}, },
{
name: "stability",
descriptionFunction() {
return `<strong>0.3x</strong> <strong class='color-defense'>damage taken</strong><br>while your <strong class='color-h'>health</strong> is at maximum`
},
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
allowed() {
return true
},
requires: "",
effect() {
tech.isMaxHealthDefense = true;
},
remove() {
tech.isMaxHealthDefense = false;
}
},
{
name: "instability",
descriptionFunction() {
return `<strong>2x</strong> <strong class='color-d'>damage</strong> while your <strong class='color-defense'>damage taken</strong> is <strong>1.00x</strong><br><em style ="float: right;">(damage taken = ${(m.defense()).toFixed(2)}x)</em>`
},
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
allowed() {
return true
},
requires: "",
effect() {
tech.isNoDefenseDamage = true;
},
remove() {
tech.isNoDefenseDamage = false;
}
},
{
name: "control theory",
descriptionFunction() {
return `<strong>1.5x</strong> <strong class='color-d'>damage</strong><br>while your <strong class='color-h'>health</strong> is at maximum`
},
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
allowed() {
return true
},
requires: "",
effect() {
tech.isMaxHealthDamage = true;
},
remove() {
tech.isMaxHealthDamage = false;
}
},
{ {
name: "homeostasis", name: "homeostasis",
descriptionFunction() { descriptionFunction() {
@@ -3059,7 +3147,7 @@ const tech = {
allowed() { allowed() {
return m.maxHealth > 1; return m.maxHealth > 1;
}, },
requires: "max health above 100", requires: "maximum health above 100",
effect() { effect() {
tech.isAcidDmg = true; tech.isAcidDmg = true;
}, },
@@ -3070,7 +3158,7 @@ const tech = {
{ {
name: "induction brake", name: "induction brake",
descriptionFunction() { descriptionFunction() {
return `after using ${powerUps.orb.heal()} <strong class='color-s'>slow</strong> nearby mobs for <strong>17</strong> seconds` return `after using ${powerUps.orb.heal()}<br><strong class='color-s'>slow</strong> nearby mobs for <strong>17</strong> seconds`
}, },
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -3133,7 +3221,7 @@ const tech = {
{ {
name: "quenching", name: "quenching",
descriptionFunction() { descriptionFunction() {
return `${powerUps.orb.heal()} over<strong class='color-h'>healing</strong> results in <strong>2x</strong> <strong class='color-h'>health</strong> loss<br> and <strong>2x</strong> max <strong class='color-h'>health</strong> increase` return `${powerUps.orb.heal()} over<strong class='color-h'>healing</strong> results in <strong>2x</strong> <strong class='color-h'>health</strong> loss<br> and <strong>2x</strong> maximum <strong class='color-h'>health</strong> increase`
}, },
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -5029,7 +5117,7 @@ const tech = {
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return tech.isIceCrystals || tech.isSporeFreeze || (m.fieldMode === 4 && simulation.molecularMode === 2) || tech.isIceShot || tech.isNeedleIce || (m.coupling && (m.fieldMode === 3 || m.fieldMode === 0)) return tech.isIceCrystals || tech.isSporeFreeze || (m.fieldMode === 4 && simulation.molecularMode === 2) || tech.isIceShot || tech.isNeedleIce || (m.coupling && (m.fieldMode === 2 || m.fieldMode === 0))
}, },
requires: "a freeze effect", requires: "a freeze effect",
effect() { effect() {
@@ -5067,7 +5155,7 @@ const tech = {
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return (tech.isIceCrystals || tech.isSporeFreeze || (m.fieldMode === 4 && simulation.molecularMode === 2) || tech.isIceShot || tech.isNeedleIce || (m.coupling && (m.fieldMode === 3 || m.fieldMode === 0))) && !tech.sporesOnDeath && !tech.isExplodeMob && !tech.botSpawner && !tech.isMobBlockFling && !tech.nailsDeathMob return (tech.isIceCrystals || tech.isSporeFreeze || (m.fieldMode === 4 && simulation.molecularMode === 2) || tech.isIceShot || tech.isNeedleIce || (m.coupling && (m.fieldMode === 2 || m.fieldMode === 0))) && !tech.sporesOnDeath && !tech.isExplodeMob && !tech.botSpawner && !tech.isMobBlockFling && !tech.nailsDeathMob
}, },
requires: "a localized freeze effect, no other mob death tech", requires: "a localized freeze effect, no other mob death tech",
effect() { effect() {
@@ -5086,7 +5174,7 @@ const tech = {
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return (m.fieldMode === 4 && simulation.molecularMode === 2) || tech.isNeedleIce || (m.coupling && (m.fieldMode === 3 || m.fieldMode === 0)) || tech.iceIXOnDeath || tech.isIceShot return (m.fieldMode === 4 && simulation.molecularMode === 2) || tech.isNeedleIce || (m.coupling && (m.fieldMode === 2 || m.fieldMode === 0)) || tech.iceIXOnDeath || tech.isIceShot
}, },
requires: "ice IX", requires: "ice IX",
effect() { effect() {
@@ -5105,7 +5193,7 @@ const tech = {
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return tech.isIceCrystals || tech.isSporeFreeze || (m.fieldMode === 4 && simulation.molecularMode === 2) || tech.isNeedleIce || (m.coupling && (m.fieldMode === 3 || m.fieldMode === 0)) || tech.iceIXOnDeath || tech.isIceShot return tech.isIceCrystals || tech.isSporeFreeze || (m.fieldMode === 4 && simulation.molecularMode === 2) || tech.isNeedleIce || (m.coupling && (m.fieldMode === 2 || m.fieldMode === 0)) || tech.iceIXOnDeath || tech.isIceShot
}, },
requires: "a localized freeze effect", requires: "a localized freeze effect",
effect() { effect() {
@@ -5130,7 +5218,7 @@ const tech = {
// }, // },
// requires: "perfect diamagnetism", // requires: "perfect diamagnetism",
allowed() { allowed() {
return (tech.isIceCrystals || tech.isSporeFreeze || (m.fieldMode === 4 && simulation.molecularMode === 2) || tech.isIceShot || tech.isNeedleIce || (m.coupling && (m.fieldMode === 3 || m.fieldMode === 0))) return (tech.isIceCrystals || tech.isSporeFreeze || (m.fieldMode === 4 && simulation.molecularMode === 2) || tech.isIceShot || tech.isNeedleIce || (m.coupling && (m.fieldMode === 2 || m.fieldMode === 0)))
}, },
requires: "a localized freeze effect", requires: "a localized freeze effect",
effect() { effect() {
@@ -7423,7 +7511,7 @@ const tech = {
//************************************************** //**************************************************
{ {
name: "spherical harmonics", name: "spherical harmonics",
description: "<strong>1.5x</strong> <strong>standing wave</strong> deflection <strong class='color-f'>energy</strong> efficiency<br>shield deflection radius holds it's max range", //<strong>standing wave</strong> oscillates in a 3rd dimension<br> description: "<strong>1.5x</strong> <strong>standing wave</strong> deflection <strong class='color-f'>energy</strong> efficiency<br>shield deflection <strong>radius</strong> is stable", //<strong>standing wave</strong> oscillates in a 3rd dimension<br>
isFieldTech: true, isFieldTech: true,
maxCount: 9, maxCount: 9,
count: 0, count: 0,
@@ -7513,9 +7601,13 @@ const tech = {
} }
}, },
{ {
// descriptionFunction() {
// return `use ${powerUps.orb.research(2)}<br><span style = 'font-size:94%;'><strong>1.01x</strong> <strong class='color-d'>damage</strong> per <strong class='color-f'>energy</strong> below <strong>maximum</strong> <em style ="float: right;">(${(1 + Math.max(0, m.maxEnergy - m.energy)).toFixed(2)}x)</em></span>`
// },
name: "electronegativity", name: "electronegativity",
descriptionFunction() { descriptionFunction() {
return `<strong>1.0023x</strong> <strong class='color-d'>damage</strong> per <strong class='color-f'>energy</strong><br><em style ="float: right;">(${(1 + 0.23 * m.maxEnergy).toFixed(2)}x damage at max energy)</em>` return `<strong>1.0023x</strong> <strong class='color-d'>damage</strong> per <strong class='color-f'>energy</strong><br><em style ="float: right;">(${(1 + 0.23 * m.energy).toFixed(2)} at current energy, ${(1 + 0.23 * m.maxEnergy).toFixed(2)}x at maximum energy)</em>`
}, },
// description: "<strong>+1%</strong> <strong class='color-d'>damage</strong> per <strong>8</strong> stored <strong class='color-f'>energy</strong>", // description: "<strong>+1%</strong> <strong class='color-d'>damage</strong> per <strong>8</strong> stored <strong class='color-f'>energy</strong>",
isFieldTech: true, isFieldTech: true,
@@ -7653,7 +7745,7 @@ const tech = {
{ {
name: "dynamic equilibrium", name: "dynamic equilibrium",
descriptionFunction() { descriptionFunction() {
return `increase <strong class='color-d'>damage</strong> by your last ${tech.isEnergyHealth ? "<strong class='color-f'>energy</strong>" : "<strong class='color-h'>health</strong>"} loss<br> style ="float: right;">(${(1 + tech.lastHitDamage * m.lastHit).toFixed(2)}x damage)</em>` return `increase <strong class='color-d'>damage</strong> by your last ${tech.isEnergyHealth ? "<strong class='color-f'>energy</strong>" : "<strong class='color-h'>health</strong>"} loss<br> <em style ="float: right;">(${(1 + tech.lastHitDamage * m.lastHit).toFixed(2)}x damage)</em>`
}, },
isFieldTech: true, isFieldTech: true,
maxCount: 9, maxCount: 9,
@@ -7701,7 +7793,7 @@ const tech = {
}, },
{ {
name: "aerostat", name: "aerostat",
description: `<strong>2x</strong> <strong class='color-d'>damage</strong> while <strong>off</strong> the <strong>ground</strong><br><strong>0.85x</strong> <strong class='color-d'>damage</strong> while <strong>on</strong> the <strong>ground</strong>`, description: `<strong>2x</strong> <strong class='color-d'>damage</strong> while <strong>off</strong> the <strong>ground</strong><br><strong>0.9x</strong> <strong class='color-d'>damage</strong> while <strong>on</strong> the <strong>ground</strong>`,
isFieldTech: true, isFieldTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -8022,7 +8114,7 @@ const tech = {
}, },
{ {
name: "tokamak", name: "tokamak",
description: "throwing a <strong class='color-block'>block</strong> converts it into <strong class='color-f'>energy</strong><br>and a pulsed fusion <strong class='color-e'>explosion</strong>", description: "<strong class='color-tokamak'>tokamak</strong> converts thrown <strong class='color-block'>blocks</strong> into <strong class='color-f'>energy</strong><br>and a pulsed fusion <strong class='color-e'>explosion</strong>",
isFieldTech: true, isFieldTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -8039,6 +8131,47 @@ const tech = {
tech.isTokamak = false; tech.isTokamak = false;
} }
}, },
{
name: "stellarator",
descriptionFunction() {
return `the first <strong>5</strong> <strong class='color-block'>blocks</strong> detonated by <strong class='color-tokamak'>tokamak</strong><br>spawn ${powerUps.orb.heal(1)} proportional to <strong class='color-block'>block</strong> size`
},
isFieldTech: true,
maxCount: 1,
count: 0,
frequency: 3,
frequencyDefault: 3,
allowed() {
return tech.isTokamak && (m.fieldMode === 5 || m.fieldMode === 4 || m.fieldMode === 10)
},
requires: "tokamak",
effect() {
tech.isTokamakHeal = true;
tech.tokamakHealCount = 0
},
remove() {
tech.isTokamakHeal = false;
}
},
{
name: "inertial confinement",
description: "while holding a <strong class='color-block'>block</strong> charged with <strong class='color-tokamak'>tokamak</strong><br>you can use <strong class='color-f'>energy</strong> to <strong>fly</strong>", //and invulnerable?
isFieldTech: true,
maxCount: 1,
count: 0,
frequency: 3,
frequencyDefault: 3,
allowed() {
return tech.isTokamak && (m.fieldMode === 5 || m.fieldMode === 4 || m.fieldMode === 10)
},
requires: "tokamak",
effect() {
tech.isTokamakFly = true;
},
remove() {
tech.isTokamakFly = false;
}
},
{ {
name: "degenerate matter", name: "degenerate matter",
description: "if your <strong class='color-f'>field</strong> is active<br><strong>0.1x</strong> <strong class='color-defense'>damage taken</strong>", description: "if your <strong class='color-f'>field</strong> is active<br><strong>0.1x</strong> <strong class='color-defense'>damage taken</strong>",
@@ -11764,7 +11897,6 @@ const tech = {
isDroneRespawn: null, isDroneRespawn: null,
deathSpawns: null, deathSpawns: null,
isMobBlockFling: null, isMobBlockFling: null,
// blockingIce: null,
isPhaseVelocity: null, isPhaseVelocity: null,
waveBeamSpeed: null, waveBeamSpeed: null,
wavePacketAmplitude: null, wavePacketAmplitude: null,
@@ -11772,14 +11904,18 @@ const tech = {
iceIXOnDeath: null, iceIXOnDeath: null,
wimpCount: null, wimpCount: null,
isAddBlockMass: null, isAddBlockMass: null,
isMACHO: null, isDarkMatter: null,
isHarmMACHO: null, isHarmDarkMatter: null,
isMoveMACHO: null, isMoveDarkMatter: null,
isNotDarkMatter: null,
isSneakAttack: null, isSneakAttack: null,
isFallingDamage: null, isFallingDamage: null,
harmonics: null, harmonics: null,
isStandingWaveExpand: null, isStandingWaveExpand: null,
isTokamak: null, isTokamak: null,
isTokamakHeal: null,
tokamakHealCount: null,
isTokamakFly: null,
deflectEnergy: null, deflectEnergy: null,
superBallDelay: null, superBallDelay: null,
isBlockExplode: null, isBlockExplode: null,
@@ -11829,6 +11965,7 @@ const tech = {
isRewindField: null, isRewindField: null,
isCrouchRegen: null, isCrouchRegen: null,
isAxion: null, isAxion: null,
isDarkEnergy: null,
isDarkStar: null, isDarkStar: null,
isWormholeMapIgnore: null, isWormholeMapIgnore: null,
isLessDamageReduction: null, isLessDamageReduction: null,
@@ -11909,4 +12046,7 @@ const tech = {
interestRate: null, interestRate: null,
isImmunityDamage: null, isImmunityDamage: null,
isMobDeathImmunity: null, isMobDeathImmunity: null,
isMaxHealthDefense: null,
isNoDefenseDamage: null,
isMaxHealthDamage: null,
} }

View File

@@ -311,7 +311,7 @@ summary {
.sort-button { .sort-button {
border: 1px #333 solid; border: 1px #333 solid;
border-radius: 0.5em; border-radius: 0.4em;
background-color: #fff; background-color: #fff;
font-size: 0.5em; font-size: 0.5em;
/* padding: 0.3em; */ /* padding: 0.3em; */
@@ -872,11 +872,17 @@ summary {
text-shadow: 0px 0px 7px #000; text-shadow: 0px 0px 7px #000;
} }
.color-MACHO { .color-dark-matter {
color: #246; color: #246;
text-shadow: 0px 0px 7px #246; text-shadow: 0px 0px 7px #246;
} }
.color-tokamak {
color: #5c3ab8;
font-weight: 100;
text-shadow: 0px -5px 9px rgb(255, 0, 204);
}
.color-dup { .color-dup {
font-variant: small-caps; font-variant: small-caps;
letter-spacing: 1px; letter-spacing: 1px;

154
todo.txt
View File

@@ -1,37 +1,22 @@
******************************************************** NEXT PATCH ************************************************** ******************************************************** NEXT PATCH **************************************************
new community levels: (you can enable community maps in the settings) renamed MACHO -> dark matter
rings by thatLittleFrog tech: MACHO - dark matter is active when you are outside not inside it's range, 1.5 to dark matter effects
flappyGon by Digin tech: dark energy - inside dark matter regen 10 energy
trial by Cirryn and Tarantula Hawk tech: stability - 0.3x damage taken if health equals maxHealth
arena level updated by Whyisthisnotavalable tech: instability - 2x damage if damage taken is 1x
tech: control theory - 1.5x damage if health equals maxHealth
tech: inertial confinement - while charging tokamak you can fly, but energy drains
tech: stellarator - after firing a block with tokamak, spawn up to 5 heals
difficulty scaling: 0.84->0.85x player damage per level boss health nerf: almost every boss has ~0.8x less health
research spawn per level is no longer in the difficulty settings secondary bosses also spawn 2 ammo
instead players get 1 research for only the first few levels aerostat 0.85->0.9 damage on the ground
cell boss has less health at high difficulty Pauli exclusion 6->8 seconds of invulnerable after getting hit
Gibbs free energy 2->0 research cost, 1.01->1.05 damage scales with energy below 100->maxEnergy
cache 15->17x ammo
converted JUNK tech to additive, instead of the multiplicative several bug fixes
makes the first JUNK you take do the same, but if you take too much you can get to 100%
right aligned some text in tech descriptions
added some circles to the in-game console messages
renamed slow light -> delayed-choice - a single 0.4 second delayed 0.7x damage laser beam
also now works with reflection
plasma torch field gets 1.5x damage by default
molecular assembler coupling 0.8->0.6 energy per second
nail-bot upgrade 5->4x fire rate
foam-bot upgrade 3->2.5x size and fire rate
sound-bot upgrade 2.5->2x fire rate, damage, 1->2x wave packet length
boom-bot upgrade reduced range, bot acceleration
orbital-bot upgrade 1.5->2x radius
perimeter defense 0.95->0.96x damage taken per bot
network effect 1.05->1.04x damage per bot
tech: working mass - cleaned up physics and logic a bit
negative feedback scales with health below maxHealth, not health below 100
1.007->1.006x damage per missing health
homeostasis scales with missing health, not health below 100
limit of 0.2x at 0 health
******************************************************* DESIGN ****************************************************** ******************************************************* DESIGN ******************************************************
@@ -59,57 +44,19 @@ list of powerful synergies
*********************************************************** TODO ***************************************************** *********************************************************** TODO *****************************************************
figure out how to put controls in background on initial level snakeBoss - boss with a tail that grows longer
mouse smooth makes the text position jitter when it moves sub pixels improve behavior for when it can't see player
hide the jitter with artificial jitter to make it seem intentional wander around looking for power ups
make it look like the instructions are on a fuzzy TV screen what if it gets lost?
when player presses move buttons highlight the box/letter for those buttons eat power ups
eject them after you die
a few bosses have too much health get longer after eating
probably the ones that scale with simulation.difficulty eat mobs?
Matter.Body.setDensity(me, 0.00012 + 0.00001 * simulation.difficulty) // normal density is 0.001 eat blocks?
modes: recolor tail based on modes
hunting power ups -> small + fast : blue cyan
make player mass an adjustable var in the skin hunting player -> attack? : red/pink
does this mess with jump height or air control? slow high defense : white
increase mass and movement speed at the same time
increase jump differently because it scales extra with mass
m.defaultMass = 4.5
m.definePlayerMass()
possible player.mass bad interactions
grapple
tech: - if health === maxHealth take 0.6x damage
do 1.5x damage?
JUNK tech - player takes damage from block collisions
is this gonna contribute to lag?
tech: anthropic principle - cost 1 research to let you not die once per level
another tech that allows it to trigger multiple times
tokamak synergy tech
tech: stellarator - after firing a block with tokamak, heal (scale heal amount with block mass?)
tech: inertial confinement - while charging tokamak you can fly, and invulnerable
but energy drains
bullets should trigger shrinking platforms level element?
level element - player activated elevators
could be fast and throw player
could just rise up slow (slow might have a bad jerky animation)
tech: super balls split after 3 seconds
but they lost 50% less time
buff plasma torch
buff plasma tech?
buff plasma field defense?
buff plasma damage?
rework energy and health HUD
make both diegetic?
should health be red or green?
white laser white laser
what to name? not much in wikipedia what to name? not much in wikipedia
@@ -119,23 +66,42 @@ white laser
tech.laserColor = "#fff" tech.laserColor = "#fff"
tech.laserColorAlpha = "rgba(255, 255, 255, 0.5)" tech.laserColorAlpha = "rgba(255, 255, 255, 0.5)"
bug Newton's 1st law image not showing up on github server
shows up on n-gon, and landgreen github, but webp file isn't loading onto server?
try name change,
wait and see if next patch fixes it
tech: atomic pile - lose 1 health if you are above the maximum energy tech: atomic pile - lose 1 health if you are above the maximum energy
generate energy for each nearby mob? generate energy for each nearby mob?
do damage? do damage?
plasma torch tech? plasma torch tech?
boss mob - several squares that move like the snake in the game snake/light cycles make some explosions have less knock back?
moves towards player (is smell history pathing good enough?) annoying with flame test, boom bot?
doesn't have inertia/force? or it obeys normal physics kinda?
gets longer when figure out how to put instructions for controls in background on initial level
you hit it with bullets? mouse smooth makes the text position jitter when it moves sub pixels
it gets near a power up? hide the jitter with artificial jitter to make it seem intentional
it gets near mobs make it look like the instructions are on a fuzzy TV screen
when player presses move buttons highlight the box/letter for those buttons
make player mass an adjustable var in the skin
does this mess with jump height or air control?
increase mass and movement speed at the same time
increase jump differently because it scales extra with mass
m.defaultMass = 4.5
m.definePlayerMass()
possible player.mass bad interactions
grapple
JUNK tech - player takes damage from block collisions
is this gonna contribute to lag?
bullets should trigger shrinking platforms level element?
level element - player activated elevators
could be fast and throw player
could just rise up slow (slow might have a bad jerky animation)
rework energy and health HUD
make both diegetic?
how? not sure there is a good way to do this...
should health be red or green?
Boss mob - takes a snapshot of the positions of all mobs, player, blocks, power ups. Then 3 seconds later it teleports everything back to those spots. Boss mob - takes a snapshot of the positions of all mobs, player, blocks, power ups. Then 3 seconds later it teleports everything back to those spots.
after snap shot is stored draw outline of body positions for a second to show the change after snap shot is stored draw outline of body positions for a second to show the change
@@ -1328,6 +1294,8 @@ possible names for tech
Casimir effect - attractive force between two close conductive plates Casimir effect - attractive force between two close conductive plates
difference engine - early calculator/computer difference engine - early calculator/computer
cyanoacrylate - superglue use for a slowing effect? cyanoacrylate - superglue use for a slowing effect?
hysteresis - the dependence of the state of a system on its history
superposition - something with waves overlapping
******************************************************** IMAGES ******************************************************** ******************************************************** IMAGES ********************************************************