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

View File

@@ -26,7 +26,7 @@ const level = {
// tech.tech[297].frequency = 100
// tech.addJunkTechToPool(0.5)
// 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
// powerUps.research.count = 3
// tech.isHookWire = true
@@ -43,9 +43,9 @@ const level = {
// b.guns[8].ammo = 100000000
// requestAnimationFrame(() => { tech.giveTech("optical amplifier") });
// tech.giveTech("1st ionization energy")
// for (let i = 0; i < 1; ++i) tech.giveTech("negative feedback")
// for (let i = 0; i < 2; ++i) tech.giveTech("delayed-choice")
// for (let i = 0; i < 1; ++i) tech.giveTech("pulse")
// for (let i = 0; i < 1; ++i) tech.giveTech("tokamak")
// for (let i = 0; i < 1; ++i) tech.giveTech("inertial confinement")
// for (let i = 0; i < 1; ++i) tech.giveTech("stellarator")
// 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 < 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 < 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 < 100; i++) powerUps.directSpawn(1750, -500, "coupling");
// spawn.mapRect(575, -700, 25, 425); //block mob line of site on testing
// level.arena();
// for (let i = 0; i < 1; ++i) spawn.snakeSpitBoss(1400, -500)
level.testing();
// 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 });
// for (let i = 0; i < 4; ++i) spawn.sucker(1300, -500 + 100 * Math.random())
// spawn.hopper(1900, -500)
@@ -68,11 +68,10 @@ const level = {
// spawn.tetherBoss(1900, -500, { x: 1900, y: -500 })
// 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 < 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)
// simulation.isAutoZoom = false; //look in close
// 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++) {
spawn.WIMP()
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
//used for generalist and pigeonhole principle
tech.cancelTechCount = 0
tech.tokamakHealCount = 0
tech.buffedGun++
if (tech.buffedGun > b.inventory.length - 1) tech.buffedGun = 0;
if (tech.isGunCycle && b.activeGun !== null && b.inventory.length) {
@@ -12651,7 +12651,7 @@ const level = {
Promise.resolve().then(() => {
// Clear all WIMPS and their research
for (let i = 0; i < mob.length; i++) {
if (mob[i] && !mob[i].isMACHO) {
if (mob[i] && !mob[i].isDarkMatter) {
mob[i].isWIMP = true;
}
}
@@ -13302,7 +13302,7 @@ const level = {
if (simulation.cycle % 4 === 0) {
let newMobPositions = [];
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,
y: i.position.y
});
@@ -13572,7 +13572,7 @@ const level = {
level.setPosToSpawn(x, y);
trapPlayer(x, y);
for (let i = 0; i < mob.length; i++) {
if (mob[i].isMACHO) {
if (mob[i].isDarkMatter) {
setPos(mob[i], {
x,
y

View File

@@ -547,10 +547,11 @@ const m = {
lastCalculatedDefense: 0, //used to decided if defense bar needs to be redrawn (in simulation.checks)
defense() {
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.isZeno) dmg *= 0.15
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 (m.fieldMode === 0 || m.fieldMode === 3) dmg *= 0.973 ** m.coupling
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.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 {
//draw charge
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)
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
//bullet-like collisions
m.holdingTarget.collisionFilter.category = cat.bullet
@@ -2962,7 +2993,7 @@ const m = {
drainCD: 0,
effect: () => {
m.fieldBlockCD = 0;
m.blockingRecoil = 1.5 //4 is normal
m.blockingRecoil = 1 //4 is normal
m.fieldRange = 185
m.fieldShieldingScale = 1.6 * Math.pow(0.5, (tech.harmonics - 2))
// 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
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) {

View File

@@ -116,13 +116,15 @@ const spawn = {
secondaryBossChance(x, y) {
if (simulation.difficultyMode > 2 && level.levelsCleared > 2) {
spawn.randomLevelBoss(x, y);
powerUps.directSpawn(x - 30, y, "ammo");
powerUps.directSpawn(x + 30, y, "ammo");
} else {
return false
}
},
//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");
let me = mob[mob.length - 1];
me.stroke = "transparent"
@@ -135,13 +137,14 @@ const spawn = {
me.collisionFilter.category = 0;
me.collisionFilter.mask = 0; //cat.player //| cat.body
me.chaseSpeed = 3.3
me.isMACHO = true;
me.isDarkMatter = true;
me.frictionAir = 0.006
me.onDeath = function () {
tech.isHarmMACHO = false;
tech.isHarmDarkMatter = false;
}
me.do = function () {
if (!simulation.isTimeSkipping) {
const scale = (tech.isMoveDarkMatter || tech.isNotDarkMatter) ? 1.6 : 1
const sine = Math.sin(simulation.cycle * 0.015)
this.radius = 111 * tech.isDarkStar + 370 * (1 + 0.1 * sine)
//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.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.y += force.y
if (mag < this.radius) { //buff to player when inside radius
tech.isHarmMACHO = 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.isNotDarkMatter) {
if (mag < this.radius) { //buff to player when inside radius
tech.isHarmDarkMatter = false;
} else {
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.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
ctx.beginPath();
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) {
if (mob[i].alive && !mob[i].isShielded) {
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);
simulation.drawList.push({ //add dmg to draw queue
x: mob[i].position.x,
@@ -1428,7 +1447,7 @@ const spawn = {
me.seeAtDistance2 = 1400000;
me.cellMassMax = 70
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
const k = 642 //k=r^2/m
@@ -1691,7 +1710,7 @@ const spawn = {
} else if (!m.isCloak) {
me.foundPlayer();
}
me.damageReduction = 0.2
me.damageReduction = 0.21
me.isInvulnerable = true
me.startingDamageReduction = me.damageReduction
me.damageReduction = 0
@@ -1769,7 +1788,7 @@ const spawn = {
me.foundPlayer();
}
me.damageReduction = 0.22
me.damageReduction = 0.23
me.isInvulnerable = true
me.startingDamageReduction = me.damageReduction
me.damageReduction = 0
@@ -2146,7 +2165,7 @@ const spawn = {
mobs.spawn(x, y, 5, radius, "rgb(0,200,180)");
let me = mob[mob.length - 1];
me.isBoss = true;
me.damageReduction = 0.09
me.damageReduction = 0.12
me.accelMag = 0.05; //jump height
me.g = 0.003; //required if using this.gravity
me.frictionAir = 0.01;
@@ -2470,7 +2489,7 @@ const spawn = {
// toMe(bullet, this.position, this.eventHorizon))
}
};
me.damageReduction = 0.25
me.damageReduction = 0.27
me.do = function () {
//keep it slow, to stop issues from explosion knock backs
if (this.speed > 1) {
@@ -2662,7 +2681,7 @@ const spawn = {
let me = mob[mob.length - 1];
me.babyList = [] //list of mobs that are apart of this boss
Matter.Body.setDensity(me, 0.0015); //extra dense //normal is 0.001 //makes effective life much larger and damage on collision
me.damageReduction = 0.13 //normal is 1, most bosses have 0.25
me.damageReduction = 0.14 //normal is 1, most bosses have 0.25
me.isBoss = true;
me.friction = 0;
@@ -2978,7 +2997,7 @@ const spawn = {
me.laserRange = 350;
me.seeAtDistance2 = 2000000;
me.isBoss = true;
me.damageReduction = 0.35 // me.damageReductionGoal
me.damageReduction = 0.38 // me.damageReductionGoal
me.showHealthBar = false; //drawn in this.awake
me.delayLimit = 60 + Math.floor(30 * Math.random());
@@ -3403,7 +3422,7 @@ const spawn = {
let me = mob[mob.length - 1];
me.isBoss = true;
Matter.Body.setDensity(me, 0.005); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.07
me.damageReduction = 0.08
me.startingDamageReduction = me.damageReduction
me.isInvulnerable = false
me.nextHealthThreshold = 0.75
@@ -3594,7 +3613,7 @@ const spawn = {
let me = mob[mob.length - 1];
me.isBoss = true;
Matter.Body.setDensity(me, 0.004); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.1
me.damageReduction = 0.12
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);
@@ -3686,7 +3705,7 @@ const spawn = {
mobs.spawn(x, y, 3, radius, "rgb(0,235,255)");
let me = mob[mob.length - 1];
me.isBoss = true;
me.damageReduction = 0.25
me.damageReduction = 0.27
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);
@@ -3792,7 +3811,7 @@ const spawn = {
Matter.Body.rotate(me, Math.PI * 0.1);
Matter.Body.setDensity(me, 0.002); //extra dense //normal is 0.001 //makes effective life much larger
me.isBoss = true;
me.damageReduction = 0.034
me.damageReduction = 0.038
me.frictionStatic = 0;
me.friction = 0;
@@ -3850,6 +3869,156 @@ const spawn = {
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) {
mobs.spawn(x, y, 3, radius, "#a0f");
let me = mob[mob.length - 1];
@@ -3890,7 +4059,7 @@ const spawn = {
me.do = function () {
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 () {
// this.armor();
this.checkStatus();
@@ -4263,7 +4432,7 @@ const spawn = {
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
};
Matter.Body.setDensity(me, 0.03); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.33
me.damageReduction = 0.36
me.startingDamageReduction = me.damageReduction
me.isInvulnerable = false
me.nextHealthThreshold = 0.75
@@ -4725,7 +4894,7 @@ const spawn = {
// spawn.shield(me, x, y, 1);
Matter.Body.setDensity(me, 0.005); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.12
me.damageReduction = 0.13
me.isBoss = true;
me.onDamage = function () { };
me.onDeath = function () {
@@ -4820,8 +4989,8 @@ const spawn = {
me.frictionAir = 0;
me.restitution = 1
// spawn.spawnOrbitals(me, radius + 50 + 125 * Math.random(), 1)
Matter.Body.setDensity(me, 0.002 + 0.0001 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.09
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.11
me.startingDamageReduction = me.damageReduction
me.isInvulnerable = false
me.nextHealthThreshold = 0.75
@@ -5274,7 +5443,7 @@ const spawn = {
let me = mob[mob.length - 1];
Matter.Body.rotate(me, 2 * Math.PI * Math.random());
me.isBoss = true;
me.damageReduction = 0.1
me.damageReduction = 0.11
me.startingDamageReduction = me.damageReduction
me.isInvulnerable = false
me.frictionAir = 0.02
@@ -5722,7 +5891,7 @@ const spawn = {
let me = mob[mob.length - 1];
Matter.Body.setDensity(me, 0.001); //extra dense //normal is 0.001 //makes effective life much larger
me.isBoss = true;
me.damageReduction = 0.15
me.damageReduction = 0.17
me.accelMag = 0.0017 * Math.sqrt(simulation.accelScale);
me.frictionAir = 0.01;
@@ -6030,7 +6199,7 @@ const spawn = {
let me = mob[mob.length - 1];
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.seeAtDistance2 = 1500000;
@@ -6057,7 +6226,7 @@ const spawn = {
me.onDeath = function () {
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
};
me.damageReduction = 0.2
me.damageReduction = 0.22
me.do = function () {
// this.armor();
this.seePlayerCheckByDistance();
@@ -6114,8 +6283,8 @@ const spawn = {
}, 2000); //add in a delay in case the level gets flipped left right
me.isBoss = true;
Matter.Body.setDensity(me, 0.01 + 0.0004 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.2
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.22
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
me.isVerticesChange = true
@@ -6472,8 +6641,8 @@ const spawn = {
mobs.spawn(x, y, 6, radius, "rgb(150,150,255)");
let me = mob[mob.length - 1];
me.isBoss = true;
Matter.Body.setDensity(me, 0.0022 + 0.0002 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.2
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.22
me.accelMag = 0.0001 * simulation.accelScale;
me.fireFreq = Math.floor(330 * simulation.CDScale)
@@ -6684,7 +6853,7 @@ const spawn = {
spawn.spawnOrbitals(me, radius + 50, 1);
spawn.spawnOrbitals(me, radius + 125, 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
setTimeout(() => { //fix mob in place, but allow rotation
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 () {
// this.armor();
if (this.grenadeLimiter > 1) this.grenadeLimiter--
@@ -6875,7 +7044,7 @@ const spawn = {
me.onDamage = function () {
this.cycle = 0
};
me.damageReduction = 0.35
me.damageReduction = 0.39
me.do = function () {
Matter.Body.rotate(this, 0.003) //gently spin around
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
};
me.onDamage = function () { };
me.damageReduction = 0.25
me.damageReduction = 0.28
me.do = function () {
// this.armor();
this.seePlayerCheck();
@@ -7393,7 +7562,7 @@ const spawn = {
mobs.spawn(x, y, 8, radius, "rgba(0,180,180,0.4)");
let me = mob[mob.length - 1];
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
// me.accelMag = 0.0007 * simulation.accelScale;
@@ -7432,8 +7601,8 @@ const spawn = {
mobs.spawn(x, y, 8, radius, "rgb(0,60,80)");
let me = mob[mob.length - 1];
me.isBoss = true;
Matter.Body.setDensity(me, 0.0005 + 0.0002 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.25
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.27
me.startingDamageReduction = me.damageReduction
me.isInvulnerable = false
me.nextHealthThreshold = 0.75
@@ -7682,8 +7851,8 @@ const spawn = {
mobs.spawn(x, y, nodes, radius, "rgb(255,0,150)");
let me = mob[mob.length - 1];
me.isBoss = true;
Matter.Body.setDensity(me, 0.0017 + 0.0002 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
me.damageReduction = 0.1
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.11
me.stroke = "transparent"; //used for drawGhost
me.seeAtDistance2 = 2000000;

View File

@@ -73,7 +73,7 @@ const tech = {
},
junkChance: 0,
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 += percent
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
damageFromTech() {
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.isPowerUpDamage) dmg *= 1 + 0.05 * powerUp.length
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.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.isGunChoice && tech.buffedGun === b.inventoryGun) dmg *= 1 + 0.3 * b.inventory.length
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.isBotDamage) dmg *= 1 + 0.04 * b.totalBots()
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.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.01
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.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.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))
@@ -874,8 +876,6 @@ const tech = {
{
name: "Pareto efficiency",
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)}`
},
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)
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() { }
},
@@ -932,7 +922,7 @@ const tech = {
{
name: "cache",
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,
count: 0,
frequency: 1,
@@ -942,7 +932,7 @@ const tech = {
},
requires: "not non-renewables",
effect() {
tech.ammoCap = 15;
tech.ammoCap = 17;
powerUps.ammo.effect()
},
remove() {
@@ -1115,12 +1105,13 @@ const tech = {
},
requires: "",
effect() {
tech.isFarAwayDmg = true; //used in mob.damage()
tech.isFarAwayDmg = true;
},
remove() {
tech.isFarAwayDmg = false;
}
},
{
name: "microstates",
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",
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>",
name: "dark matter",
//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,
count: 0,
frequency: 1,
@@ -2427,46 +2421,30 @@ const tech = {
},
requires: "",
effect() {
tech.isMACHO = true; //this harm reduction comes from the particle toggling tech.isHarmMACHO
spawn.MACHO()
tech.isDarkMatter = true; //this harm reduction comes from the particle toggling tech.isHarmDarkMatter
spawn.darkMatter()
},
remove() {
tech.isMACHO = false;
tech.isHarmMACHO = false;
tech.isDarkMatter = false;
tech.isHarmDarkMatter = false;
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",
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,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isMACHO
return tech.isDarkMatter
},
requires: "MACHO",
requires: "dark matter",
effect() {
tech.isAxion = true
},
@@ -2475,16 +2453,72 @@ const tech = {
}
},
{
name: "dark star",
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`,
name: "dark energy",
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,
count: 0,
frequency: 2,
frequencyDefault: 2,
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() {
tech.isDarkStar = true
},
@@ -2552,7 +2586,7 @@ const tech = {
},
{
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,
count: 0,
frequency: 1,
@@ -2562,7 +2596,7 @@ const tech = {
},
requires: "",
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
},
remove() {
@@ -2729,27 +2763,21 @@ const tech = {
{
name: "Gibbs free energy",
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,
count: 0,
frequency: 1,
frequencyDefault: 1,
allowed() {
return powerUps.research.count > 1 || build.isExperimentSelection
return true
},
requires: "",
effect() {
tech.isLowEnergyDamage = true;
for (let i = 0; i < 2; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
}
},
remove() {
tech.isLowEnergyDamage = false;
if (this.count > 0) {
powerUps.research.changeRerolls(2)
}
}
},
{
@@ -2780,7 +2808,7 @@ const tech = {
},
{
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,
count: 0,
frequency: 2,
@@ -2868,7 +2896,7 @@ const tech = {
},
{
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,
count: 0,
frequency: 1,
@@ -2887,7 +2915,7 @@ const tech = {
{
name: "recycling",
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: "",
maxCount: 1,
@@ -2924,6 +2952,66 @@ const tech = {
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",
descriptionFunction() {
@@ -3059,7 +3147,7 @@ const tech = {
allowed() {
return m.maxHealth > 1;
},
requires: "max health above 100",
requires: "maximum health above 100",
effect() {
tech.isAcidDmg = true;
},
@@ -3070,7 +3158,7 @@ const tech = {
{
name: "induction brake",
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,
count: 0,
@@ -3133,7 +3221,7 @@ const tech = {
{
name: "quenching",
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,
count: 0,
@@ -5029,7 +5117,7 @@ const tech = {
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isIceCrystals || tech.isSporeFreeze || (m.fieldMode === 4 && simulation.molecularMode === 2) || tech.isIceShot || tech.isNeedleIce || (m.coupling && (m.fieldMode === 3 || m.fieldMode === 0))
return tech.isIceCrystals || tech.isSporeFreeze || (m.fieldMode === 4 && simulation.molecularMode === 2) || tech.isIceShot || tech.isNeedleIce || (m.coupling && (m.fieldMode === 2 || m.fieldMode === 0))
},
requires: "a freeze effect",
effect() {
@@ -5067,7 +5155,7 @@ const tech = {
frequency: 2,
frequencyDefault: 2,
allowed() {
return (tech.isIceCrystals || tech.isSporeFreeze || (m.fieldMode === 4 && simulation.molecularMode === 2) || tech.isIceShot || tech.isNeedleIce || (m.coupling && (m.fieldMode === 3 || m.fieldMode === 0))) && !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",
effect() {
@@ -5086,7 +5174,7 @@ const tech = {
frequency: 2,
frequencyDefault: 2,
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",
effect() {
@@ -5105,7 +5193,7 @@ const tech = {
frequency: 2,
frequencyDefault: 2,
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",
effect() {
@@ -5130,7 +5218,7 @@ const tech = {
// },
// requires: "perfect diamagnetism",
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",
effect() {
@@ -7423,7 +7511,7 @@ const tech = {
//**************************************************
{
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,
maxCount: 9,
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",
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>",
isFieldTech: true,
@@ -7653,7 +7745,7 @@ const tech = {
{
name: "dynamic equilibrium",
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,
maxCount: 9,
@@ -7701,7 +7793,7 @@ const tech = {
},
{
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,
maxCount: 1,
count: 0,
@@ -8022,7 +8114,7 @@ const tech = {
},
{
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,
maxCount: 1,
count: 0,
@@ -8039,6 +8131,47 @@ const tech = {
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",
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,
deathSpawns: null,
isMobBlockFling: null,
// blockingIce: null,
isPhaseVelocity: null,
waveBeamSpeed: null,
wavePacketAmplitude: null,
@@ -11772,14 +11904,18 @@ const tech = {
iceIXOnDeath: null,
wimpCount: null,
isAddBlockMass: null,
isMACHO: null,
isHarmMACHO: null,
isMoveMACHO: null,
isDarkMatter: null,
isHarmDarkMatter: null,
isMoveDarkMatter: null,
isNotDarkMatter: null,
isSneakAttack: null,
isFallingDamage: null,
harmonics: null,
isStandingWaveExpand: null,
isTokamak: null,
isTokamakHeal: null,
tokamakHealCount: null,
isTokamakFly: null,
deflectEnergy: null,
superBallDelay: null,
isBlockExplode: null,
@@ -11829,6 +11965,7 @@ const tech = {
isRewindField: null,
isCrouchRegen: null,
isAxion: null,
isDarkEnergy: null,
isDarkStar: null,
isWormholeMapIgnore: null,
isLessDamageReduction: null,
@@ -11909,4 +12046,7 @@ const tech = {
interestRate: null,
isImmunityDamage: null,
isMobDeathImmunity: null,
isMaxHealthDefense: null,
isNoDefenseDamage: null,
isMaxHealthDamage: null,
}