super n-gon bros

new community level - superNgonBros by DesBoot

tech: induction brake - after using a heal slow nearby mobs for 15 seconds
tech: null hypothesis - +9 damage, spawn several research after removing
reworked: strange attractor - +7% damage, +10% duplication after removing

bremsstrahlung does 50% more damage
time crystals 200 -> 150% passive energy regen
  it also tells you how much energy regen you will get
aperture (-50 to +150) -> (-10 to +110) damage
diaphragm (-33 to +100) -> (+8 to +80) defense
tungsten carbide 200 -> 222 health
CPT symmetry 30 -> 20 energy per second of rewind
quenching gives more max health, but also does more damage per over heal

final boss has 50% faster armor decay
  so it takes even more damage the longer you fight it

a few more images
some bug fixes
This commit is contained in:
landgreen
2023-04-16 18:04:54 -07:00
parent 2e76b5c181
commit 1b23dec950
20 changed files with 762 additions and 135 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 53 KiB

BIN
img/induction brake.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 23 KiB

BIN
img/null hypothesis.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 55 KiB

View File

@@ -116,6 +116,7 @@
<option value="stereoMadness"> <option value="stereoMadness">
<option value="house"> <option value="house">
<option value="dripp"> <option value="dripp">
<option value="superNgonBros">
<option value="crossfire"> <option value="crossfire">
<option value="temple"> <option value="temple">
<option value="run"> <option value="run">

View File

@@ -1738,7 +1738,7 @@ const b = {
// m.fireCDcycle = m.cycle + 30; // cool down if out of energy // m.fireCDcycle = m.cycle + 30; // cool down if out of energy
m.fireCDcycle = m.cycle + 5 + 40 * b.fireCDscale + 60 * (m.energy < 0.05) m.fireCDcycle = m.cycle + 5 + 40 * b.fireCDscale + 60 * (m.energy < 0.05)
this.endCycle = simulation.cycle + 10 this.endCycle = simulation.cycle + 10
if (m.crouch) { //down if (input.down) { //down
dist = 0 dist = 0
player.force.y += 5 * player.mass * simulation.g; player.force.y += 5 * player.mass * simulation.g;
} }

View File

@@ -10,7 +10,7 @@ const level = {
// playableLevels: ["pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion"], // playableLevels: ["pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion"],
//see level.populateLevels: (intro, ... , reservoir or factory, reactor, ... , gauntlet, final) added later //see level.populateLevels: (intro, ... , reservoir or factory, reactor, ... , gauntlet, final) added later
playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber", "pavilion", "lock"], playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber", "pavilion", "lock"],
communityLevels: ["stronghold", "basement", "crossfire", "vats", "run", "ngon", "house", "perplex", "coliseum", "tunnel", "islands", "temple", "dripp", "biohazard", "stereoMadness", "yingYang", "staircase", "fortress", "commandeer", "clock", "buttonbutton", "downpour"], communityLevels: ["stronghold", "basement", "crossfire", "vats", "run", "ngon", "house", "perplex", "coliseum", "tunnel", "islands", "temple", "dripp", "biohazard", "stereoMadness", "yingYang", "staircase", "fortress", "commandeer", "clock", "buttonbutton", "downpour", "superNgonBros"],
trainingLevels: ["walk", "crouch", "jump", "hold", "throw", "throwAt", "deflect", "heal", "fire", "nailGun", "shotGun", "superBall", "matterWave", "missile", "stack", "mine", "grenades", "harpoon"], trainingLevels: ["walk", "crouch", "jump", "hold", "throw", "throwAt", "deflect", "heal", "fire", "nailGun", "shotGun", "superBall", "matterWave", "missile", "stack", "mine", "grenades", "harpoon"],
levels: [], levels: [],
start() { start() {
@@ -18,7 +18,7 @@ const level = {
// simulation.enableConstructMode() //tech.giveTech('motion sickness') //used to build maps in testing mode // simulation.enableConstructMode() //tech.giveTech('motion sickness') //used to build maps in testing mode
// simulation.isHorizontalFlipped = true // simulation.isHorizontalFlipped = true
// tech.giveTech("performance") // tech.giveTech("performance")
// level.difficultyIncrease(12 * 4) //30 is near max on hard //60 is near max on why // level.difficultyIncrease(4 * 4) //30 is near max on hard //60 is near max on why
// spawn.setSpawnList(); // spawn.setSpawnList();
// spawn.setSpawnList(); // spawn.setSpawnList();
// m.maxHealth = m.health = 100 // m.maxHealth = m.health = 100
@@ -31,26 +31,26 @@ const level = {
// m.energy = 0 // m.energy = 0
// simulation.molecularMode = 2 // simulation.molecularMode = 2
// m.damage(0.1); // m.damage(0.1);
// b.giveGuns("nail gun") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser // b.giveGuns("harpoon") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.giveGuns("foam") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser // b.giveGuns("foam") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.guns[3].ammo = 100000000 // b.guns[3].ammo = 100000000
// tech.giveTech("surface plasmons") // tech.giveTech("induction brake")
// tech.giveTech("relativistic momentum") // tech.giveTech("null hypothesis")
// for (let i = 0; i < 1; ++i) tech.giveTech("dye laser") // for (let i = 0; i < 1; ++i) tech.giveTech("dye laser")
// for (let i = 0; i < 1; ++i) tech.giveTech("free-electron laser") // for (let i = 0; i < 1; ++i) tech.giveTech("free-electron laser")
// for (let i = 0; i < 1; ++i) tech.giveTech("causality bots") // for (let i = 0; i < 1; ++i) tech.giveTech("waste heat recovery")
// requestAnimationFrame(() => { for (let i = 0; i < 1; i++) tech.giveTech("foam-bot") }); // requestAnimationFrame(() => { for (let i = 0; i < 1; i++) tech.giveTech("foam-bot") });
// for (let i = 0; i < 1; i++) tech.giveTech("foam-bot upgrade") // for (let i = 0; i < 1; i++) tech.giveTech("foam-bot upgrade")
// 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 < 10; i++) powerUps.directSpawn(1750, -500, "research"); // for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "research");
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "coupling"); // for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "coupling");
// level.testing(); // level.superNgonBros();
// spawn.nodeGroup(3200, -300, "sniper") // spawn.nodeGroup(3200, -300, "sniper")
// spawn.nodeGroup(2200, -300, "sniper") // spawn.nodeGroup(2200, -300, "sniper")
// spawn.nodeGroup(2200, -300, "sniper") // spawn.nodeGroup(2200, -300, "sniper")
// spawn.mantisBoss(1900, -500) // spawn.mantisBoss(1900, -500)
// spawn.cellBoss(1900, -500) // spawn.cellBoss(1900, -500)
// for (let i = 0; i < 5; ++i) spawn.sneaker(1900, -500, 50) // for (let i = 0; i < 5; ++i) spawn.starter(1900, -500, 50)
// spawn.sneaker(1900, -500, 25) // spawn.sneaker(1900, -500, 25)
// spawn.sniper(2000, -450) // spawn.sniper(2000, -450)
// spawn.zombie(1000 + 1000 * Math.random(), -500 + 300 * Math.random(), 30, 5, "white") // zombie(x, y, radius, sides, color) // spawn.zombie(1000 + 1000 * Math.random(), -500 + 300 * Math.random(), 30, 5, "white") // zombie(x, y, radius, sides, color)
@@ -67,7 +67,7 @@ const level = {
// simulation.setZoom(); // simulation.setZoom();
// for (let i = 0; i < 4; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "tech"); // for (let i = 0; i < 4; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "tech");
// for (let i = 0; i < 2; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "gun"); // for (let i = 0; i < 2; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "gun");
// for (let i = 0; i < 10; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "heal"); // for (let i = 0; i < 3; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "heal");
// for (let i = 0; i < 2; i++) powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "field", false); // for (let i = 0; i < 2; i++) powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "field", false);
//lore testing //lore testing
// for (let i = 0; i < 5; i++) tech.giveTech("undefined") // for (let i = 0; i < 5; i++) tech.giveTech("undefined")
@@ -3106,7 +3106,7 @@ const level = {
//??? //???
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why // level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
m.addHealth(Infinity) // m.addHealth(Infinity)
// spawn.starter(1900, -500, 200) //big boy // spawn.starter(1900, -500, 200) //big boy
// for (let i = 0; i < 10; ++i) spawn.launcher(1900, -500) // for (let i = 0; i < 10; ++i) spawn.launcher(1900, -500)
@@ -21047,7 +21047,525 @@ const level = {
const obj = { restoreBoss }; const obj = { restoreBoss };
Object.assign(spawn, obj); //ez Object.assign(spawn, obj); //ez
}, },
superNgonBros() {
simulation.makeTextLog(`<strong>Super N-gon Bros</strong> by <span class='color-var'>DesBoot</span>`);
let bowserKilled = 0
let flagY = -750
let flagReached = 0
const elevator1 = level.elevator(3975, -11650, 450, 50, -13100, 0.003)
const elevator2 = level.elevator(5575, -11650, 450, 50, -13100, 0.003)
let firstElevatorY = -11650
const portal = level.portal({ x: 3990, y: 100 }, 1.5 * Math.PI, { x: 100, y: -13500 }, -1.5 * Math.PI)
const portal2 = level.portal({ x: 7135, y: -12270 }, -1 * Math.PI, { x: 12325, y: -2000 }, -1.5 * Math.PI)
const bowser = function (x, y, radius = 150) { //define the mob the same as spawn mob code
mobs.spawn(x, y, 5, radius, "rgb(0,200,180)");
let me = mob[mob.length - 1];
me.accelMag = 0.05;
me.g = 0.002; //required if using this.gravity
me.frictionAir = 0.01;
me.friction = 1
me.frictionStatic = 1
me.restitution = 0;
me.delay = 80 * simulation.CDScale;
me.randomHopFrequency = 200 + Math.floor(Math.random() * 150);
me.randomHopCD = simulation.cycle + me.randomHopFrequency;
Matter.Body.rotate(me, Math.random() * Math.PI);
spawn.shield(me, x, y);
me.do = function () {
//spawn.grenade(me.position.x, me.position.y);
// //const v = 5 * simulation.accelScale;
// Matter.Body.setVelocity(mob[mob.length - 1], {
// x: this.velocity.x + this.fireDir.x * v + Math.random(),
// y: this.velocity.y + this.fireDir.y * v + Math.random()
// });
this.gravity();
this.seePlayerCheck();
this.checkStatus();
if (this.seePlayer.recall) {
if (this.cd < simulation.cycle && (Matter.Query.collides(this, map).length || Matter.Query.collides(this, body).length)) {
this.cd = simulation.cycle + this.delay;
const forceMag = (this.accelMag + this.accelMag * Math.random()) * this.mass;
const angle = Math.atan2(this.seePlayer.position.y - this.position.y, this.seePlayer.position.x - this.position.x);
this.force.x += forceMag * Math.cos(angle) * 0.5;
this.force.y += (forceMag * Math.sin(angle) - (Math.random() * 0.07 + 0.1) * this.mass) * 0.7; //antigravity
if (Math.random() < 0.5) {
spawn.grenade(me.position.x, me.position.y - 250 * Math.random(), 500);
Matter.Body.setVelocity(mob[mob.length - 1], {
x: -5,
y: 0
});
} else {
spawn.bullet(this.position.x, this.position.y, 25);
Matter.Body.setVelocity(mob[mob.length - 1], {
x: -25,
y: -25
});
}
}
} else {
//randomly hob if not aware of player
if (this.randomHopCD < simulation.cycle && (Matter.Query.collides(this, map).length || Matter.Query.collides(this, body).length)) {
this.randomHopCD = simulation.cycle + this.randomHopFrequency;
//slowly change randomHopFrequency after each hop
this.randomHopFrequency = Math.max(100, this.randomHopFrequency + (0.5 - Math.random()) * 200);
const forceMag = (this.accelMag + this.accelMag * Math.random()) * this.mass * (0.1 + Math.random() * 0.3);
const angle = -Math.PI / 2 + (Math.random() - 0.5) * Math.PI;
this.force.x += forceMag * Math.cos(angle);
this.force.y += forceMag * Math.sin(angle) - 0.07 * this.mass; //antigravity
spawn.grenade(me.position.x, me.position.y - 250 * Math.random(), 500);
Matter.Body.setVelocity(mob[mob.length - 1], {
x: -5,
y: 0
});
}
}
};
me.onDeath = function () {
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
bowserKilled = 1
}
}
bowser(20500, -400) //call the mob
//fire(15300, -200)
const brick = function (x, y, angle = Math.PI * 0.5, radius = 53) {//credit to Richard0820 for the code
mobs.spawn(x, y, 4, radius, "#ab6101");
let me = mob[mob.length - 1];
me.stroke = "transparent";
me.isDropPowerUp = false;
me.showHealthBar = false;
Matter.Body.setDensity(me, 999999)
me.collisionFilter.mask = cat.player | cat.mob | cat.bullet;
me.constraint = Constraint.create({
pointA: {
x: me.position.x,
y: me.position.y
},
bodyB: me,
stiffness: 0,
damping: 0
});
me.do = function () {
this.isStunned = true;
if (this.health < 1) {
this.health += 0.001; //regen
}
this.checkStatus();
Matter.Body.setAngle(me, angle);
if ((player.velocity.y < 0 && player.position.y > me.position.y || player.velocity.y > 30 && player.position.y < me.position.y) && Math.abs(player.position.x - me.position.x) < 50 && Math.abs(player.position.y - me.position.y) < 150) {
me.death()
}
};
me.onHit = function () {
if (player.velocity.y < 0 && player.position.y > me.position.y || player.velocity.y > 30 && player.position.y < me.position.y) {
me.death()
}
}
me.onDeath = function () {
if (Math.random() < 0.1) {
spawn.randomSmallMob(me.position.x, me.position.y - 75);
simulation.makeTextLog('mob')
} else {
if (Math.random() < 0.07) {
powerUps.spawn(me.position.x, me.position.y + (75 * (player.velocity.y / Math.abs(player.velocity.y))), "tech", true);
simulation.makeTextLog('tech')
} else {
if (Math.random() < 0.4) {
powerUps.spawn(me.position.x, me.position.y + (75 * (player.velocity.y / Math.abs(player.velocity.y))), "heal", true);
simulation.makeTextLog('heal')
} else {
//if (Math.random() < 0.8){
powerUps.spawn(me.position.x, me.position.y + (75 * (player.velocity.y / Math.abs(player.velocity.y))), "ammo", true);
simulation.makeTextLog('ammo')
//}
}
}
}
}
Composite.add(engine.world, me.constraint);
}
simulation.enableConstructMode()
let firstMobsSpawned = 1
let secondMobsSpawned = 0
let thirdMobsSpawned = 0
let fourthMobsSpawned = 0
let firstMobsReached = 0
let secondMobsReached = 0
let thirdMobsReached = 0
let fourthMobsReached = 0
let finalRoomReached = 0
let undergroundMobsSpawned = 0
let undergroundMobsReached = 0
level.setPosToSpawn(0, -50); //normal spawn
level.exit.x = 22100;
level.exit.y = -40;
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20); //bump for level entrance
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20); //bump for level exit
level.defaultZoom = 1800
simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#a2a5ff";
// color.map = "#444" //custom map color
level.custom = () => {
if (player.position.x > 14950 && flagReached == 0) {
flagReached = 1
}
if (flagReached == 1 && flagY < -150) {
flagY += 5
}
ctx.fillStyle = "rgba(64,64,64,0.97)"
ctx.fillRect(4200, -13100, 2, 1450)
ctx.fillRect(5800, -13100, 2, 1450)
if (firstElevatorY < -12099) {
firstElevatorY = -11650
} else {
firstElevatorY -= 5
}
//simulation.makeTextLog(firstElevatorY)
elevator1.move();
elevator2.move();
if (player.position.x > 0 && player.position.y < -9000 && player.position.y > -10000) {
//m.death()
m.damage(0.05 * simulation.difficultyMode)
Matter.Body.setPosition(player, {
x: 275,
y: -12175
});
}
portal[2].query()
portal[3].query()
portal2[2].query()
portal2[3].query()
//simulation.makeTextLog(firstBlockBroken)
level.exit.drawAndCheck();
if (player.position.x > 4100 && secondMobsReached == 0) {
secondMobsSpawned = 1
}
if (player.position.x > 7000 && thirdMobsReached == 0) {
thirdMobsSpawned = 1
}
if (player.position.x > 14300 && fourthMobsReached == 0) {
fourthMobsSpawned = 1
}
if (player.position.y < -11000 && undergroundMobsReached == 0) {
undergroundMobsSpawned = 1
}//player.position.x > 14300 &&
if (m.onGround) {
if (Math.abs(player.velocity.x) > 0.3) {
Matter.Body.setVelocity(player, {
x: player.velocity.x + (0.1 * (Math.abs(player.velocity.x) / player.velocity.x)),
y: player.velocity.y + 0.2
});
} else {
Matter.Body.setVelocity(player, {
x: player.velocity.x,
y: player.velocity.y + 0.2
});
}
} else {
if (input.down) {
Matter.Body.setVelocity(player, {
x: player.velocity.x,
y: player.velocity.y + 2
});
} else {
Matter.Body.setVelocity(player, {
x: player.velocity.x,
y: player.velocity.y + 0.2
});
}
}
level.enter.draw();
if (finalRoomReached == 0 && player.position.x > 21150) {
finalRoomReached = 1
simulation.makeTextLog('Thank you M, but our techs are in another castle!')
}
//mobs
if (firstMobsSpawned == 1 && firstMobsReached == 0) {
spawn.randomSmallMob(1260, -75);
spawn.randomMob(2100, -75, 0.4);
spawn.randomSmallMob(2400, -75);
spawn.randomSmallMob(2500, -75);
spawn.randomMob(2900, -75, 0.2);
spawn.randomMob(3400, -75, 0.4);
spawn.randomMob(3400, -75, 0.4);
firstMobsReached = 1
}
if (secondMobsSpawned == 1 && secondMobsReached == 0) {
spawn.randomSmallMob(4400, -75);
spawn.randomSmallMob(5500, -75);
spawn.randomSmallMob(5835.6, -402.4);
spawn.randomSmallMob(5835.6, -402.4);
spawn.randomSmallMob(6543.2, -730.0);
spawn.randomMob(6795.4, -162.4, 0.1);
spawn.randomMob(6795.4, -162.4, 0.1);
secondMobsReached = 1
}
if (thirdMobsSpawned == 1 && thirdMobsReached == 0) {
spawn.randomMob(8465.6, -469.9, 0.1);
spawn.randomMob(9839.6, -444.5, 0.4);
spawn.randomSmallMob(11033.2, -155.3);
spawn.randomMob(12161.3, -85.1, 0.3);
spawn.randomMob(12161.3, -85.1, 0.3);
spawn.randomMob(13399.8, -93.4, 0.4);
thirdMobsReached = 1
}
if (fourthMobsSpawned == 1 && fourthMobsReached == 0) {
spawn.randomSmallMob(16500, -400);
spawn.randomSmallMob(19278.9, -211.1);
spawn.randomMob(18839.0, -463.2, 0.3);
spawn.randomMob(18036.9, -205.9, 0.3);
spawn.randomMob(16950.4, -365.2, 0.4);
spawn.randomMob(16355.6, -390.8, 0.1);
fourthMobsReached = 1
}
if (undergroundMobsSpawned == 1 && undergroundMobsReached == 0) {
spawn.randomSmallMob(1140.0, -12228.0);
spawn.randomSmallMob(2429.9, -12371.2);
spawn.randomSmallMob(4899.4, -12139.6);
spawn.randomMob(18839.0, -463.2, 0.3);
spawn.randomMob(2844.5, -12281.0, 0.2);
spawn.randomMob(4967.5, -12550.8, 0.4);
spawn.randomMob(6696.9, -12437.9, 0.1);
undergroundMobsReached = 1
}
portal[0].draw();
portal[1].draw();
portal[2].draw();
portal[3].draw();
portal2[0].draw();
portal2[1].draw();
portal2[2].draw();
portal2[3].draw();
};
level.customTopLayer = () => {
//spawn.mapRect(886, firstElevatorY + 10000, 75, 5);
ctx.fillStyle = "rgba(64,64,64,0.97)"
ctx.fillRect(3928, -300, 120, 500)
//6940, -12360, 200, 5
ctx.fillRect(6940, -12350, 170, 120)
ctx.fillRect(7090, -12380, 120, 200)
ctx.fillRect(14980, -750, 10, 750)//flagpole
ctx.beginPath()
ctx.moveTo(14980, flagY)
ctx.lineTo(14905, flagY)
ctx.lineTo(14980, flagY + 75)
ctx.fill()
};
brick(923.5, -262);
spawn.mapRect(886, -304, 75, 5);
spawn.mapRect(886, -229, 75, 5);
spawn.mapRect(883, -304, 5, 80);
spawn.mapRect(958, -304, 5, 80);
brick(1250.5, -262);
spawn.mapRect(1138, -304, 375, 5);
spawn.mapRect(1138, -229, 375, 5);
brick(1400.5, -262);
brick(1325.5, -562);
spawn.mapRect(1288, -604, 75, 5);
spawn.mapRect(1288, -529, 75, 5);
spawn.mapRect(1285, -604, 5, 80);
spawn.mapRect(1360, -604, 5, 80);
brick(5787.5, -262);
spawn.mapRect(5675, -304, 225, 5);
spawn.mapRect(5675, -229, 225, 5);
brick(6987.5, -562);
spawn.mapRect(6725, -604, 300, 5);
spawn.mapRect(6725, -529, 300, 5);
spawn.mapRect(7025, -604, 5, 80);
brick(7887.5, -262);//4 separated blocks in the middle
spawn.mapRect(7850, -304, 75, 5);
spawn.mapRect(7850, -225, 75, 5);
spawn.mapRect(7850, -304, 5, 80);
spawn.mapRect(7925, -304, 5, 84);
brick(8112.5, -262);
spawn.mapRect(8075, -304, 75, 5);
spawn.mapRect(8075, -225, 75, 5);
spawn.mapRect(8075, -304, 5, 80);
spawn.mapRect(8150, -304, 5, 84);
brick(8337.5, -262);
spawn.mapRect(8300, -304, 75, 5);
spawn.mapRect(8300, -225, 75, 5);
spawn.mapRect(8300, -304, 5, 80);
spawn.mapRect(8375, -304, 5, 84);
brick(8112.5, -562);
spawn.mapRect(8075, -604, 75, 5);
spawn.mapRect(8075, -525, 75, 5);
spawn.mapRect(8075, -604, 5, 80);
spawn.mapRect(8150, -604, 5, 84);
brick(9612.5, -562);
spawn.mapRect(9500, -604, 300, 5);
spawn.mapRect(9500, -525, 300, 5);
spawn.mapRect(9647.5, -600, 5, 75);
brick(9687.5, -562);
brick(12887.5, -262);
spawn.mapRect(12700, -304, 300, 5);
spawn.mapRect(12700, -225, 300, 5);
brick(5212.5, -12337.5);
spawn.mapRect(4725, -12377, 525, 5);
spawn.mapRect(4725, -12303, 525, 5);
spawn.mapRect(5250, -12377, 5, 79);
spawn.mapRect(-100, 0, 4033, 2000);
spawn.mapRect(4043, 0, 882, 2000);
spawn.mapRect(3909.5, 203.6, 150, 2000);
spawn.mapRect(1138, -300, 75, 75);
spawn.mapRect(1288, -300, 75, 75);
spawn.mapRect(1438, -300, 75, 75);
spawn.mapRect(1738, -150, 150, 75);//pipe 1
spawn.mapRect(1753, -150, 120, 150);
spawn.mapRect(2488, -225, 150, 75);//pipe 2
spawn.mapRect(2503, -225, 120, 225);
spawn.mapRect(3088, -300, 150, 75);//pipe 3
spawn.mapRect(3103, -300, 120, 300);
spawn.mapRect(3913, -300, 20, 75);//pipe 4
spawn.mapRect(3928, -300, 5, 300);
spawn.mapRect(4043, -300, 20, 75);
spawn.mapRect(4043, -300, 5, 300);
spawn.mapRect(5225, 0, 1125, 2000);
spawn.mapRect(6575, 0, 4900, 2000);
spawn.mapRect(5675, -300, 75, 75);
spawn.mapRect(5825, -300, 75, 75);
spawn.mapRect(5900, -600, 600, 75);
spawn.mapRect(6725, -600, 225, 75);
spawn.mapRect(6950, -300, 75, 75);
spawn.mapRect(7400, -300, 150, 75);
spawn.mapRect(8750, -300, 75, 75);
spawn.mapRect(8975, -600, 225, 75);//raised platform
spawn.mapRect(9575, -300, 150, 75);
spawn.mapRect(9500, -600, 75, 75);//upper block with double bricks
spawn.mapRect(9725, -600, 75, 75);
spawn.mapRect(9950, -75, 300, 75);//staircase
spawn.mapRect(10025, -150, 225, 75);
spawn.mapRect(10100, -225, 150, 75);
spawn.mapRect(10175, -300, 75, 75);
spawn.mapRect(10475, -75, 300, 75);
spawn.mapRect(10475, -150, 225, 75);
spawn.mapRect(10475, -225, 150, 75);
spawn.mapRect(10475, -300, 75, 75);
spawn.mapRect(11100, -75, 375, 75);//staircase 2
spawn.mapRect(11175, -150, 300, 75);
spawn.mapRect(11250, -225, 225, 75);
spawn.mapRect(11325, -300, 150, 75);
spawn.mapRect(11725, -75, 300, 75);
spawn.mapRect(11725, -150, 225, 75);
spawn.mapRect(11725, -225, 150, 75);
spawn.mapRect(11725, -300, 75, 75);
spawn.mapRect(11725, 0, 5975, 2000);//platform after the staircase
spawn.mapRect(12325, -150, 150, 75);//exit pipe
spawn.mapRect(12340, -150, 120, 300);
spawn.mapRect(12700, -300, 150, 75);
spawn.mapRect(12925, -300, 75, 75);
spawn.mapRect(13525, -150, 150, 72);//final pipe
spawn.mapRect(13540, -150, 120, 150);
spawn.mapRect(13675, -75, 675, 75);//final staircase
spawn.mapRect(13750, -150, 600, 75);
spawn.mapRect(13825, -225, 525, 75);
spawn.mapRect(13900, -300, 450, 75);
spawn.mapRect(13975, -375, 375, 75);
spawn.mapRect(14050, -450, 300, 75);
spawn.mapRect(14125, -525, 225, 75);
spawn.mapRect(14200, -600, 150, 75);
//flag
spawn.mapRect(14950, -75, 75, 75);
spawn.mapRect(1750, -4600, 500, 25);//loss
spawn.mapRect(2000, -4850, 25, 500);
spawn.mapRect(1800, -4800, 25, 150);
spawn.mapRect(2075, -4800, 25, 150);
spawn.mapRect(2150, -4775, 25, 125);
spawn.mapRect(1875, -4550, 25, 150);
spawn.mapRect(1800, -4550, 25, 150);
spawn.mapRect(2075, -4550, 25, 150);
spawn.mapRect(2123, -4430, 100, 25);
// spawn.mapRect(-250, -600, 500, 25);
// spawn.mapRect(-250, -600, 500, 25);
//underground area
spawn.mapRect(0, -12000, 2025, 2000);
spawn.mapRect(2325, -12225, 150, 2000);
spawn.mapRect(2775, -12000, 900, 2000);
spawn.mapRect(3525, -12300, 150, 300);
spawn.mapRect(3450, -12225, 75, 300);
spawn.mapRect(3375, -12150, 75, 300);
spawn.mapRect(3300, -12075, 75, 300);
spawn.mapRect(4725, -12375, 450, 75);
spawn.mapRect(4725, -12000, 600, 2000);
spawn.mapRect(-100, -13500, 100, 3500);
spawn.mapRect(-100, -13500, 100, 3500);
spawn.mapRect(6375, -12225, 1650, 2000);
spawn.mapRect(7225, -13225, 2850, 3000);
spawn.mapRect(-100, -13700, 100, 200);//roof
spawn.mapRect(-100, -13700, 3775, 100);
spawn.mapRect(6450, -13225, 1000, 100);
spawn.mapRect(7090, -13225, 120, 885);//pipe
//spawn.mapRect(6940, -12360, 200, 120);
spawn.mapRect(6940, -12350, 200, 5);
spawn.mapRect(6950, -12240, 140, 5);
spawn.mapRect(6940, -12365, 75, 15);
spawn.mapRect(6940, -12235, 75, 15);
//castle
spawn.mapRect(17700, 0, 4975, 2000);
spawn.mapRect(18600, -225, 375, 2225);
spawn.mapRect(19500, -225, 450, 2225);
spawn.mapRect(19500, -825, 450, 225);
spawn.mapRect(15924, -1575, 6751, 750);
spawn.mapRect(19950, -225, 975, 75);
spawn.mapRect(20925, -300, 225, 300);
spawn.mapRect(21000, -825, 150, 300);
spawn.mapRect(15924, -225, 1776, 2225);
spawn.mapRect(17175, -825, 525, 225);
spawn.mapRect(22600, -825, 75, 825);
// powerUps.spawnStartingPowerUps(1475, -1175);
// spawn.debris(750, -2200, 3700, 16); //16 debris per level
// spawn.bodyRect(1540, -1110, 300, 25, 0.9);
// spawn.randomSmallMob(1300, -70);
// spawn.randomMob(2650, -975, 0.8);
// spawn.randomGroup(1700, -900, 0.4);
// if (simulation.difficulty > 1) spawn.randomLevelBoss(2200, -1300);
// spawn.secondaryBossChance(100, -1500)
powerUps.addResearchToLevel() //needs to run after mobs are spawned
},
// ******************************************************************************************************** // ********************************************************************************************************
// ******************************************************************************************************** // ********************************************************************************************************
// ***************************************** training levels ********************************************** // ***************************************** training levels **********************************************

View File

@@ -335,10 +335,7 @@ const m = {
if ( if (
!tech.tech[i].isNonRefundable && !tech.tech[i].isNonRefundable &&
!tech.tech[i].isFromAppliedScience && !tech.tech[i].isFromAppliedScience &&
tech.tech[i].name !== "many-worlds" && !tech.tech[i].isAltRealityTech
tech.tech[i].name !== "Ψ(t) collapse" &&
tech.tech[i].name !== "Hilbert space" &&
tech.tech[i].name !== "-quantum leap-"
) { ) {
totalTech += tech.tech[i].count totalTech += tech.tech[i].count
tech.tech[i].remove(); tech.tech[i].remove();
@@ -351,7 +348,7 @@ const m = {
// tech.removeLoreTechFromPool(); // tech.removeLoreTechFromPool();
// tech.addLoreTechToPool(); // tech.addLoreTechToPool();
// tech.removeJunkTechFromPool(); // tech.removeJunkTechFromPool();
tech.cancelCount = 0; tech.duplication = 0;
tech.extraMaxHealth = 0; tech.extraMaxHealth = 0;
tech.totalCount = 0; tech.totalCount = 0;
tech.countJunkTech(); tech.countJunkTech();
@@ -528,7 +525,7 @@ const m = {
}, },
baseHealth: 1, baseHealth: 1,
setMaxHealth() { setMaxHealth() {
m.maxHealth = m.baseHealth + tech.extraMaxHealth + 2 * tech.isFallingDamage + 4 * tech.isFlipFlop * tech.isFlipFlopOn * tech.isFlipFlopHealth //+ (m.fieldMode === 0 || m.fieldMode === 5) * 0.5 * m.coupling m.maxHealth = m.baseHealth + tech.extraMaxHealth + 2.22 * tech.isFallingDamage + 4 * tech.isFlipFlop * tech.isFlipFlopOn * tech.isFlipFlopHealth //+ (m.fieldMode === 0 || m.fieldMode === 5) * 0.5 * m.coupling
document.getElementById("health-bg").style.width = `${Math.floor(300 * m.maxHealth)}px` document.getElementById("health-bg").style.width = `${Math.floor(300 * m.maxHealth)}px`
simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-h'>maxHealth</span> <span class='color-symbol'>=</span> ${m.maxHealth.toFixed(2)}`) simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-h'>maxHealth</span> <span class='color-symbol'>=</span> ${m.maxHealth.toFixed(2)}`)
if (m.health > m.maxHealth) m.health = m.maxHealth; if (m.health > m.maxHealth) m.health = m.maxHealth;
@@ -544,7 +541,7 @@ const m = {
dmg *= m.fieldHarmReduction dmg *= m.fieldHarmReduction
// if (!tech.isFlipFlopOn && tech.isFlipFlopHealth) dmg *= 0.5 // if (!tech.isFlipFlopOn && tech.isFlipFlopHealth) dmg *= 0.5
// 1.25 + Math.sin(m.cycle * 0.01) // 1.25 + Math.sin(m.cycle * 0.01)
if (tech.isDiaphragm) dmg *= 0.66 + 0.66 * Math.sin(m.cycle * 0.0075); if (tech.isDiaphragm) dmg *= 0.56 + 0.36 * Math.sin(m.cycle * 0.0075);
if (tech.isZeno) dmg *= 0.15 if (tech.isZeno) dmg *= 0.15
if (tech.isFieldHarmReduction) dmg *= 0.5 if (tech.isFieldHarmReduction) dmg *= 0.5
if (tech.isHarmMACHO) dmg *= 0.4 if (tech.isHarmMACHO) dmg *= 0.4
@@ -641,7 +638,7 @@ const m = {
}); });
} }
} }
m.energy = Math.max(m.energy - steps / 250, 0.01) m.energy = Math.max(m.energy - steps / 330, 0.01)
if (m.immuneCycle < m.cycle + m.collisionImmuneCycles) m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage for 30 cycles if (m.immuneCycle < m.cycle + m.collisionImmuneCycles) m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage for 30 cycles
let isDrawPlayer = true let isDrawPlayer = true
@@ -1895,9 +1892,9 @@ const m = {
}, },
} }
}, },
setMaxEnergy() { setMaxEnergy(isMessage = true) {
m.maxEnergy = (tech.isMaxEnergyTech ? 0.5 : 1) + tech.bonusEnergy + tech.healMaxEnergyBonus + tech.harmonicEnergy + 2 * tech.isGroundState + 3 * tech.isRelay * tech.isFlipFlopOn * tech.isRelayEnergy + 1.5 * (m.fieldMode === 1) + (m.fieldMode === 0 || m.fieldMode === 1) * 0.5 * m.coupling + 0.4 * tech.isStandingWaveExpand m.maxEnergy = (tech.isMaxEnergyTech ? 0.5 : 1) + tech.bonusEnergy + tech.healMaxEnergyBonus + tech.harmonicEnergy + 2 * tech.isGroundState + 3 * tech.isRelay * tech.isFlipFlopOn * tech.isRelayEnergy + 1.5 * (m.fieldMode === 1) + (m.fieldMode === 0 || m.fieldMode === 1) * 0.5 * m.coupling + 0.4 * tech.isStandingWaveExpand
simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-f'>maxEnergy</span> <span class='color-symbol'>=</span> ${(m.maxEnergy.toFixed(2))}`) if (isMessage) simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-f'>maxEnergy</span> <span class='color-symbol'>=</span> ${(m.maxEnergy.toFixed(2))}`)
}, },
fieldMeterColor: "#0cf", fieldMeterColor: "#0cf",
drawRegenEnergy(bgColor = "rgba(0, 0, 0, 0.4)", range = 60) { drawRegenEnergy(bgColor = "rgba(0, 0, 0, 0.4)", range = 60) {
@@ -1950,7 +1947,7 @@ const m = {
} }
if (m.fieldMode === 0 || m.fieldMode === 4) m.fieldRegen += 0.00133 * m.coupling //return `generate <strong>${(6*couple).toFixed(0)}</strong> <strong class='color-f'>energy</strong> per second` if (m.fieldMode === 0 || m.fieldMode === 4) m.fieldRegen += 0.00133 * m.coupling //return `generate <strong>${(6*couple).toFixed(0)}</strong> <strong class='color-f'>energy</strong> per second`
if (tech.isTimeCrystals) { if (tech.isTimeCrystals) {
m.fieldRegen *= 3 m.fieldRegen *= 2.5
} else if (tech.isGroundState) { } else if (tech.isGroundState) {
m.fieldRegen *= 0.6 m.fieldRegen *= 0.6
} }
@@ -2269,7 +2266,7 @@ const m = {
minEnergyToDeflect: 0.05, minEnergyToDeflect: 0.05,
pushMass(who, fieldBlockCost = (0.025 + Math.sqrt(who.mass) * Vector.magnitude(Vector.sub(who.velocity, player.velocity)) * 0.002) * m.fieldShieldingScale) { pushMass(who, fieldBlockCost = (0.025 + Math.sqrt(who.mass) * Vector.magnitude(Vector.sub(who.velocity, player.velocity)) * 0.002) * m.fieldShieldingScale) {
if (m.energy > m.minEnergyToDeflect) { //shield needs at least some of the cost to block if (m.energy > m.minEnergyToDeflect) { //shield needs at least some of the cost to block
if (who.isShielded) fieldBlockCost *= 1.5; //shielded mobs take more energy to block if (who.isShielded) fieldBlockCost *= 2; //shielded mobs take more energy to block
m.energy -= fieldBlockCost m.energy -= fieldBlockCost
if (m.energy < m.minEnergyToDeflect) { if (m.energy < m.minEnergyToDeflect) {
m.energy = 0; m.energy = 0;
@@ -2319,7 +2316,7 @@ const m = {
} }
const step = 40 const step = 40
ctx.beginPath(); //draw electricity ctx.beginPath(); //draw electricity
for (let i = 0, len = 0.8 * tech.blockDmg; i < len; i++) { for (let i = 0, len = 0.5 * tech.blockDmg; i < len; i++) {
let x = m.pos.x - 20 * unit.x; let x = m.pos.x - 20 * unit.x;
let y = m.pos.y - 20 * unit.y; let y = m.pos.y - 20 * unit.y;
ctx.moveTo(x, y); ctx.moveTo(x, y);
@@ -2500,7 +2497,7 @@ const m = {
m.coupling = 0 //can't go negative m.coupling = 0 //can't go negative
} }
m.setMaxEnergy(); m.setMaxEnergy(false);
// m.setMaxHealth(); // m.setMaxHealth();
m.setFieldRegen() m.setFieldRegen()
mobs.setMobSpawnHealth(); mobs.setMobSpawnHealth();
@@ -2599,7 +2596,7 @@ const m = {
const fieldRange2 = (0.68 + 0.37 * Math.sin(m.cycle / 37)) * m.fieldRange * m.harmonicRadius const fieldRange2 = (0.68 + 0.37 * Math.sin(m.cycle / 37)) * m.fieldRange * m.harmonicRadius
const fieldRange3 = (0.7 + 0.35 * Math.sin(m.cycle / 47)) * m.fieldRange * m.harmonicRadius const fieldRange3 = (0.7 + 0.35 * Math.sin(m.cycle / 47)) * m.fieldRange * m.harmonicRadius
const netFieldRange = Math.max(fieldRange1, fieldRange2, fieldRange3) const netFieldRange = Math.max(fieldRange1, fieldRange2, fieldRange3)
ctx.fillStyle = "rgba(110,170,200," + Math.min(0.6, (0.04 + m.energy * (0.1 + 0.11 * Math.random()))) + ")"; ctx.fillStyle = "rgba(110,170,200," + Math.min(0.6, (0.04 + 0.7 * m.energy * (0.1 + 0.11 * Math.random()))) + ")";
ctx.beginPath(); ctx.beginPath();
ctx.arc(m.pos.x, m.pos.y, fieldRange1, 0, 2 * Math.PI); ctx.arc(m.pos.x, m.pos.y, fieldRange1, 0, 2 * Math.PI);
ctx.fill(); ctx.fill();
@@ -2629,7 +2626,7 @@ const m = {
const radius = m.fieldRange * m.harmonicRadius const radius = m.fieldRange * m.harmonicRadius
ctx.lineWidth = 1; ctx.lineWidth = 1;
ctx.strokeStyle = "rgba(110,170,200,0.8)" ctx.strokeStyle = "rgba(110,170,200,0.8)"
ctx.fillStyle = "rgba(110,170,200," + Math.min(0.6, m.energy * (0.11 + 0.1 * Math.random()) * (3 / tech.harmonics)) + ")"; ctx.fillStyle = "rgba(110,170,200," + Math.min(0.6, 0.7 * m.energy * (0.11 + 0.1 * Math.random()) * (3 / tech.harmonics)) + ")";
// ctx.fillStyle = "rgba(110,170,200," + Math.min(0.7, m.energy * (0.22 - 0.01 * tech.harmonics) * (0.5 + 0.5 * Math.random())) + ")"; // ctx.fillStyle = "rgba(110,170,200," + Math.min(0.7, m.energy * (0.22 - 0.01 * tech.harmonics) * (0.5 + 0.5 * Math.random())) + ")";
for (let i = 0; i < tech.harmonics; i++) { for (let i = 0; i < tech.harmonics; i++) {
ctx.beginPath(); ctx.beginPath();
@@ -2762,7 +2759,7 @@ const m = {
// } // }
const step = 40 const step = 40
ctx.beginPath(); ctx.beginPath();
for (let i = 0, len = 0.8 * tech.blockDmg; i < len; i++) { for (let i = 0, len = 0.5 * tech.blockDmg; i < len; i++) {
let x = m.fieldPosition.x - 20 * unit.x; let x = m.fieldPosition.x - 20 * unit.x;
let y = m.fieldPosition.y - 20 * unit.y; let y = m.fieldPosition.y - 20 * unit.y;
ctx.moveTo(x, y); ctx.moveTo(x, y);

View File

@@ -168,7 +168,11 @@ const powerUps = {
setPowerUpMode() { setPowerUpMode() {
if (tech.duplicationChance() > 0 || tech.isAnthropicTech) { if (tech.duplicationChance() > 0 || tech.isAnthropicTech) {
if (tech.isPowerUpsVanish) { if (tech.isPowerUpsVanish) {
powerUps.do = powerUps.doDuplicatesVanish if (this.tech.isHealAttract) {
powerUps.do = powerUps.doAttractDuplicatesVanish
} else {
powerUps.do = powerUps.doDuplicatesVanish
}
} else if (tech.isHealAttract) { } else if (tech.isHealAttract) {
powerUps.do = powerUps.doAttractDuplicates powerUps.do = powerUps.doAttractDuplicates
} else { } else {
@@ -221,6 +225,18 @@ const powerUps = {
} }
} }
}, },
doAttractDuplicatesVanish() {
powerUps.doDuplicatesVanish();
for (let i = 0; i < powerUp.length; i++) { //attract heal power ups to player
if (powerUp[i].name === "heal") {
//&& Vector.magnitudeSquared(Vector.sub(powerUp[i].position, m.pos)) < 500000
let attract = Vector.mult(Vector.normalise(Vector.sub(m.pos, powerUp[i].position)), 0.015 * powerUp[i].mass)
powerUp[i].force.x += attract.x;
powerUp[i].force.y += attract.y - powerUp[i].mass * simulation.g; //negate gravity
Matter.Body.setVelocity(powerUp[i], Vector.mult(powerUp[i].velocity, 0.7));
}
}
},
doDuplicates() { //draw power ups but give duplicates some electricity doDuplicates() { //draw power ups but give duplicates some electricity
ctx.globalAlpha = 0.4 * Math.sin(m.cycle * 0.15) + 0.6; ctx.globalAlpha = 0.4 * Math.sin(m.cycle * 0.15) + 0.6;
for (let i = 0, len = powerUp.length; i < len; ++i) { for (let i = 0, len = powerUp.length; i < len; ++i) {
@@ -355,7 +371,7 @@ const powerUps = {
return return
} }
if (tech.isCancelDuplication) { if (tech.isCancelDuplication) {
tech.cancelCount++ tech.duplication += 0.043
tech.maxDuplicationEvent() tech.maxDuplicationEvent()
simulation.makeTextLog(`tech.duplicationChance() <span class='color-symbol'>+=</span> ${0.043}`) simulation.makeTextLog(`tech.duplicationChance() <span class='color-symbol'>+=</span> ${0.043}`)
simulation.circleFlare(0.043); simulation.circleFlare(0.043);
@@ -547,8 +563,8 @@ const powerUps = {
m.addHealth(heal); m.addHealth(heal);
simulation.makeTextLog(`<span class='color-var'>m</span>.health <span class='color-symbol'>+=</span> ${(healOutput).toFixed(3)}`) // <br>${m.health.toFixed(3)} simulation.makeTextLog(`<span class='color-var'>m</span>.health <span class='color-symbol'>+=</span> ${(healOutput).toFixed(3)}`) // <br>${m.health.toFixed(3)}
if (tech.isOverHeal && overHeal > 0) { //tech quenching if (tech.isOverHeal && overHeal > 0) { //tech quenching
const scaledOverHeal = overHeal * 0.7 const scaledOverHeal = overHeal * 0.9
m.damage(scaledOverHeal*0.9); m.damage(scaledOverHeal);
simulation.makeTextLog(`<span class='color-var'>m</span>.health <span class='color-symbol'>-=</span> ${(scaledOverHeal).toFixed(3)}`) // <br>${m.health.toFixed(3)} simulation.makeTextLog(`<span class='color-var'>m</span>.health <span class='color-symbol'>-=</span> ${(scaledOverHeal).toFixed(3)}`) // <br>${m.health.toFixed(3)}
simulation.drawList.push({ //add dmg to draw queue simulation.drawList.push({ //add dmg to draw queue
x: m.pos.x, x: m.pos.x,
@@ -564,12 +580,54 @@ const powerUps = {
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, overHeal * 40 * (simulation.healScale ** 0.25))// directSpawn(x, y, target, moving = true, mode = null, size = powerUps[target].size()) {
}); });
} }
if (tech.isHealBrake) {
const totalTime = 900
//check if you already have this effect
let foundActiveEffect = false
for (let i = 0; i < simulation.ephemera.length; i++) {
if (simulation.ephemera[i].name === "healPush") {
foundActiveEffect = true
simulation.ephemera[i].count = 0.5 * simulation.ephemera[i].count + totalTime //add time
simulation.ephemera[i].scale = 0.5 * (simulation.ephemera[i].scale + Math.min(Math.max(0.6, heal * 6), 2.3)) //take average of scale
}
}
if (!foundActiveEffect) {
simulation.ephemera.push({
name: "healPush",
count: totalTime, //cycles before it self removes
range: 0,
scale: Math.min(Math.max(0.7, heal * 4), 2.2), //typically heal is 0.35
do() {
this.count--
if (this.count < 0) simulation.removeEphemera(this.name)
this.range = this.range * 0.99 + 0.01 * (300 * this.scale + 100 * Math.sin(m.cycle * 0.022))
if (this.count < 120) this.range -= 5 * this.scale
this.range = Math.max(this.range, 1) //don't go negative
// const range = 300 + 100 * Math.sin(m.cycle * 0.022)
for (let i = 0; i < mob.length; i++) {
const distance = Vector.magnitude(Vector.sub(m.pos, mob[i].position))
if (distance < this.range) {
const cap = mob[i].isShielded ? 3 : 1
if (mob[i].speed > cap && Vector.dot(mob[i].velocity, Vector.sub(m.pos, mob[i].position)) > 0) { // if velocity is directed towards player
Matter.Body.setVelocity(mob[i], Vector.mult(Vector.normalise(mob[i].velocity), cap)); //set velocity to cap, but keep the direction
}
}
}
ctx.beginPath();
ctx.arc(m.pos.x, m.pos.y, this.range, 0, 2 * Math.PI);
ctx.fillStyle = "hsla(200,50%,61%,0.18)";
ctx.fill();
},
})
}
}
} }
} }
if (powerUps.healGiveMaxEnergy) { if (powerUps.healGiveMaxEnergy) {
tech.healMaxEnergyBonus += 0.08 * tech.largerHeals * (tech.isHalfHeals ? 0.5 : 1) tech.healMaxEnergyBonus += 0.08 * tech.largerHeals * (tech.isHalfHeals ? 0.5 : 1)
m.setMaxEnergy(); m.setMaxEnergy();
} }
}, },
spawn(x, y, size) { //used to spawn a heal with a specific size / heal amount, not normally used spawn(x, y, size) { //used to spawn a heal with a specific size / heal amount, not normally used
powerUps.directSpawn(x, y, "heal", false, null, size) powerUps.directSpawn(x, y, "heal", false, null, size)

View File

@@ -766,7 +766,7 @@ const simulation = {
simulation.ephemera = [] simulation.ephemera = []
b.removeAllGuns(); b.removeAllGuns();
tech.setupAllTech(); //sets tech to default values tech.setupAllTech(); //sets tech to default values
tech.cancelCount = 0; tech.duplication = 0;
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "laser") b.guns[i].chooseFireMethod() if (b.guns[i].name === "laser") b.guns[i].chooseFireMethod()
if (b.guns[i].name === "nail gun") b.guns[i].chooseFireMethod() if (b.guns[i].name === "nail gun") b.guns[i].chooseFireMethod()
@@ -1181,7 +1181,7 @@ const simulation = {
} }
const damage = tech.damageFromTech() //update damage bar const damage = tech.damageFromTech() //update damage bar
if (m.lastCalculatedDamage !== damage) { if (m.lastCalculatedDamage !== damage) {
document.getElementById("damage-bar").style.height = Math.floor(Math.atan(0.25 * damage - 0.25) / 1.65 * canvas.height) + "px"; document.getElementById("damage-bar").style.height = Math.floor((Math.atan(0.25 * damage - 0.25) + 0.25) * 0.53 * canvas.height) + "px";
m.lastCalculatedDamage = damage m.lastCalculatedDamage = damage
} }
} }
@@ -1232,7 +1232,16 @@ const simulation = {
} }
if (isNaN(player.position.x)) m.death(); if (isNaN(player.position.x)) m.death();
if (m.lastKillCycle + 300 > m.cycle) { //effects active for 5 seconds after killing a mob if (m.lastKillCycle + 300 > m.cycle) { //effects active for 5 seconds after killing a mob
if (tech.isEnergyRecovery && m.immuneCycle < m.cycle) m.energy += m.maxEnergy * 0.05 if (tech.isEnergyRecovery && m.immuneCycle < m.cycle) {
m.energy += m.maxEnergy * 0.05
simulation.drawList.push({ //add dmg to draw queue
x: m.pos.x,
y: m.pos.y - 45,
radius: Math.sqrt(m.maxEnergy * 0.05) * 60,
color: "rgba(0, 204, 255,0.4)", //#0cf
time: 4
});
}
if (tech.isHealthRecovery) { if (tech.isHealthRecovery) {
const heal = 0.005 * m.maxHealth const heal = 0.005 * m.maxHealth
m.addHealth(heal) m.addHealth(heal)
@@ -1240,8 +1249,8 @@ const simulation = {
x: m.pos.x, x: m.pos.x,
y: m.pos.y, y: m.pos.y,
radius: Math.sqrt(heal) * 150, radius: Math.sqrt(heal) * 150,
color: "rgba(0,255,200,0.6)", color: "rgba(0,255,200,0.5)",
time: 8 time: 4
}); });
} }
} }

View File

@@ -97,8 +97,6 @@ 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].isDropPowerUp && mob[i].alive) { //&& !mob[i].isBoss // if (mob[i].isDropPowerUp && mob[i].alive) { //&& !mob[i].isBoss
// if (mob[i].isFinalBoss) { // if (mob[i].isFinalBoss) {
@@ -414,7 +412,7 @@ const spawn = {
} }
} }
me.damageReductionDecay = function () { //slowly make the boss take more damage over time //damageReduction resets with each invulnerability phase me.damageReductionDecay = function () { //slowly make the boss take more damage over time //damageReduction resets with each invulnerability phase
if (!(me.cycle % 60) && this.lastDamageCycle + 240 > this.cycle) this.damageReduction *= 1.02 //only decay once a second //only decay if the player has done damage in the last 4 seconds if (!(me.cycle % 60) && this.lastDamageCycle + 240 > this.cycle) this.damageReduction *= 1.04 //only decay once a second //only decay if the player has done damage in the last 4 seconds
} }
me.mobType = spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)] me.mobType = spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]
me.spawnMobs = function (index = 0) { me.spawnMobs = function (index = 0) {

View File

@@ -3,10 +3,10 @@ const tech = {
setupAllTech() { setupAllTech() {
tech.damage = 1 tech.damage = 1
for (let i = 0, len = tech.tech.length; i < len; i++) { for (let i = 0, len = tech.tech.length; i < len; i++) {
tech.tech[i].count = 0
tech.tech[i].isLost = false tech.tech[i].isLost = false
tech.tech[i].isBanished = false tech.tech[i].isBanished = false
tech.tech[i].remove(); tech.tech[i].remove();
tech.tech[i].count = 0
if (tech.tech[i].isJunk) { if (tech.tech[i].isJunk) {
tech.tech[i].frequency = 0 tech.tech[i].frequency = 0
} else if (tech.tech[i].frequencyDefault) { } else if (tech.tech[i].frequencyDefault) {
@@ -223,13 +223,13 @@ const tech = {
if (tech.isDivisor) { if (tech.isDivisor) {
for (let i = 0; i < b.inventory.length; i++) { for (let i = 0; i < b.inventory.length; i++) {
if (b.guns[b.inventory[i]].ammo % 3 === 0) { if (b.guns[b.inventory[i]].ammo % 3 === 0) {
dmg *= 1.4 dmg *= 1.44
break break
} }
} }
} }
if (tech.isNoGroundDamage) dmg *= m.onGround ? 0.78 : 1.88 if (tech.isNoGroundDamage) dmg *= m.onGround ? 0.78 : 1.88
if (tech.isDilate) dmg *= 1.5 + Math.sin(m.cycle * 0.0075) if (tech.isDilate) dmg *= 1.5 + 0.6 * Math.sin(m.cycle * 0.0075)
if (tech.isGunChoice && tech.buffedGun === b.inventoryGun) dmg *= 1 + 0.31 * b.inventory.length if (tech.isGunChoice && tech.buffedGun === b.inventoryGun) dmg *= 1 + 0.31 * 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
if (m.coupling && (m.fieldMode === 0 || m.fieldMode === 5)) dmg *= 1 + 0.15 * m.coupling if (m.coupling && (m.fieldMode === 0 || m.fieldMode === 5)) dmg *= 1 + 0.15 * m.coupling
@@ -258,7 +258,7 @@ const tech = {
return dmg return dmg
}, },
duplicationChance() { duplicationChance() {
return Math.min(1, Math.max(0, (tech.isPowerUpsVanish ? 0.12 : 0) + (tech.isStimulatedEmission ? 0.15 : 0) + tech.cancelCount * 0.043 + tech.duplicateChance + 0.05 * tech.isExtraGunField + m.duplicateChance + tech.fieldDuplicate + tech.cloakDuplication + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.5 : 0) + tech.isQuantumEraserDuplication * (1 - 0.016 * (simulation.difficultyMode ** 2)))) // + (m.fieldMode === 0 || m.fieldMode === 9) * 0.03 * m.coupling) return Math.min(1, Math.max(0, (tech.isPowerUpsVanish ? 0.12 : 0) + (tech.isStimulatedEmission ? 0.15 : 0) + tech.duplication + tech.duplicateChance + 0.05 * tech.isExtraGunField + m.duplicateChance + tech.fieldDuplicate + tech.cloakDuplication + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.5 : 0) + tech.isQuantumEraserDuplication * (1 - 0.016 * (simulation.difficultyMode ** 2)))) // + (m.fieldMode === 0 || m.fieldMode === 9) * 0.03 * m.coupling)
}, },
isScaleMobsWithDuplication: false, isScaleMobsWithDuplication: false,
maxDuplicationEvent() { maxDuplicationEvent() {
@@ -309,7 +309,7 @@ const tech = {
}, },
tech: [{ tech: [{
name: "tungsten carbide", name: "tungsten carbide",
description: "<strong>+200</strong> maximum <strong class='color-h'>health</strong><br><strong>lose</strong> <strong class='color-h'>health</strong> after hard <strong>landings</strong>", description: "<strong>+222</strong> maximum <strong class='color-h'>health</strong><br><strong>lose</strong> <strong class='color-h'>health</strong> after hard <strong>landings</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -362,7 +362,7 @@ const tech = {
}, },
{ {
name: "aperture", name: "aperture",
description: "every <strong>6</strong> seconds your <strong class='color-d'>damage</strong> cycles<br>between <strong>-50%</strong> and <strong>+150%</strong> <strong class='color-d'>damage</strong>", description: "every <strong>6</strong> seconds your <strong class='color-d'>damage</strong> cycles<br>between <strong>-10%</strong> and <strong>+110%</strong> <strong class='color-d'>damage</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -383,7 +383,7 @@ const tech = {
}, },
{ {
name: "diaphragm", name: "diaphragm",
description: "every <strong>6</strong> seconds your <strong class='color-defense'>defense</strong> cycles<br>between <strong>+100%</strong> and <strong>-33%</strong> <strong class='color-defense'>defense</strong>", description: "every <strong>6</strong> seconds your <strong class='color-defense'>defense</strong> cycles<br>between <strong>+8%</strong> and <strong>+80%</strong> <strong class='color-defense'>defense</strong>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 2,
@@ -452,8 +452,8 @@ const tech = {
}, },
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 3,
frequencyDefault: 2, frequencyDefault: 3,
allowed() { allowed() {
return tech.isEnergyHealth return tech.isEnergyHealth
}, },
@@ -479,7 +479,7 @@ const tech = {
// description: "<strong>charge</strong>, <strong>parity</strong>, and <strong>time</strong> invert to undo <strong class='color-defense'>defense</strong><br><strong class='color-rewind'>rewind</strong> <strong>(1.5—5)</strong> seconds for <strong>(66—220)</strong> <strong class='color-f'>energy</strong>", // description: "<strong>charge</strong>, <strong>parity</strong>, and <strong>time</strong> invert to undo <strong class='color-defense'>defense</strong><br><strong class='color-rewind'>rewind</strong> <strong>(1.5—5)</strong> seconds for <strong>(66—220)</strong> <strong class='color-f'>energy</strong>",
// description: "after losing <strong class='color-h'>health</strong>, if you have <strong>full</strong> <strong class='color-f'>energy</strong><br><strong>rewind</strong> time for <strong>44</strong> <strong class='color-f'>energy</strong> per second", // description: "after losing <strong class='color-h'>health</strong>, if you have <strong>full</strong> <strong class='color-f'>energy</strong><br><strong>rewind</strong> time for <strong>44</strong> <strong class='color-f'>energy</strong> per second",
descriptionFunction() { descriptionFunction() {
return `after losing <strong class='color-h'>health</strong>, if you have <strong>${(100 * Math.min(100, m.maxEnergy)).toFixed(0)}</strong> <strong class='color-f'>energy</strong><br><strong>rewind</strong> time for <strong>40</strong> <strong class='color-f'>energy</strong> per second` return `after losing <strong class='color-h'>health</strong>, if you have <strong>${(100 * Math.min(100, m.maxEnergy)).toFixed(0)}</strong> <strong class='color-f'>energy</strong><br><strong>rewind</strong> time for <strong>20</strong> <strong class='color-f'>energy</strong> per second`
}, },
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -541,7 +541,7 @@ const tech = {
{ {
name: "ternary", //"divisor", name: "ternary", //"divisor",
descriptionFunction() { descriptionFunction() {
return `<strong>+40%</strong> <strong class='color-d'>damage</strong> while one of your <strong class='color-g'>guns</strong><br>has <strong class='color-ammo'>ammo</strong> divisible by <strong>3</strong>` return `<strong>+44%</strong> <strong class='color-d'>damage</strong> while one of your <strong class='color-g'>guns</strong><br>has <strong class='color-ammo'>ammo</strong> divisible by <strong>3</strong>`
}, },
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -1247,18 +1247,18 @@ const tech = {
{ {
name: "collider", name: "collider",
descriptionFunction() { descriptionFunction() {
return `after mobs <strong>die</strong> there is a <strong>+33%</strong> chance to<br>collide <strong>power ups</strong> to form different <strong>power ups</strong>` return `after mobs <strong>die</strong> there is a <strong>+50%</strong> chance to<br>collide <strong>power ups</strong> to form different <strong>power ups</strong>`
// return `after mobs <strong>die</strong> there is a <strong>+33%</strong> chance to convert<br>${powerUps.orb.heal()}, ${powerUps.orb.ammo()}, ${powerUps.orb.research(1)}, <strong class='color-m'>tech</strong>, <strong class='color-f'>field</strong>, <strong class='color-g'>gun</strong> into other types` // return `after mobs <strong>die</strong> there is a <strong>+33%</strong> chance to convert<br>${powerUps.orb.heal()}, ${powerUps.orb.ammo()}, ${powerUps.orb.research(1)}, <strong class='color-m'>tech</strong>, <strong class='color-f'>field</strong>, <strong class='color-g'>gun</strong> into other types`
}, },
maxCount: 3, maxCount: 2,
count: 0, count: 0,
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
allowed: () => true, allowed: () => true,
requires: "", requires: "",
effect() { effect() {
tech.collidePowerUps += 0.33333 tech.collidePowerUps += 0.5
}, },
remove() { remove() {
tech.collidePowerUps = 0 tech.collidePowerUps = 0
@@ -2462,7 +2462,7 @@ const tech = {
}, },
{ {
name: "Pauli exclusion", name: "Pauli exclusion",
description: `after mob collisions<br>become <strong>invulnerable</strong> for <strong>+3</strong> seconds`, description: `after mob collisions<br>become <strong>invulnerable</strong> for <strong>+3.5</strong> seconds`,
maxCount: 9, maxCount: 9,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -2472,7 +2472,7 @@ const tech = {
}, },
requires: "", requires: "",
effect() { effect() {
m.collisionImmuneCycles += 180; m.collisionImmuneCycles += 210;
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() {
@@ -2481,7 +2481,7 @@ const tech = {
}, },
{ {
name: "spinstatistics theorem", name: "spinstatistics theorem",
description: `every <strong>7</strong> seconds<br>become <strong>invulnerable</strong> for <strong>+1.8</strong> seconds`, description: `every <strong>7</strong> seconds<br>become <strong>invulnerable</strong> for <strong>+1.9</strong> seconds`,
maxCount: 3, maxCount: 3,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -2491,7 +2491,7 @@ const tech = {
}, },
requires: "", requires: "",
effect() { effect() {
tech.cyclicImmunity += 108; tech.cyclicImmunity += 114;
}, },
remove() { remove() {
tech.cyclicImmunity = 0; tech.cyclicImmunity = 0;
@@ -2946,7 +2946,25 @@ const tech = {
tech.isAcidDmg = false; tech.isAcidDmg = false;
} }
}, },
{
name: "induction brake",
description: `after using ${powerUps.orb.heal()} <strong class='color-s'>slow</strong> nearby mobs for <strong>15</strong> seconds<br>spawn ${powerUps.orb.heal(3)}`,
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
allowed() {
return !tech.isPerfectBrake
},
requires: "not eddy current brake",
effect() {
tech.isHealBrake = true;
for (let i = 0; i < 3; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "heal");
},
remove() {
tech.isHealBrake = false;
}
},
{ {
name: "adiabatic healing", name: "adiabatic healing",
descriptionFunction() { descriptionFunction() {
@@ -3070,7 +3088,7 @@ const tech = {
}, },
requires: "", requires: "",
effect() { effect() {
tech.healthDrain += 0.02; tech.healthDrain += 0.023;
}, },
remove() { remove() {
tech.healthDrain = 0; tech.healthDrain = 0;
@@ -3193,6 +3211,7 @@ const tech = {
count: 0, count: 0,
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
isAltRealityTech: true,
allowed() { allowed() {
return !tech.isResearchReality && !tech.isSwitchReality return !tech.isResearchReality && !tech.isSwitchReality
}, },
@@ -3215,6 +3234,7 @@ const tech = {
count: 0, count: 0,
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
isAltRealityTech: true,
allowed() { allowed() {
return !tech.isResearchReality && !tech.isCollisionRealitySwitch return !tech.isResearchReality && !tech.isCollisionRealitySwitch
}, },
@@ -3234,6 +3254,7 @@ const tech = {
count: 0, count: 0,
frequency: 1, frequency: 1,
frequencyDefault: 1, frequencyDefault: 1,
isAltRealityTech: true,
allowed() { allowed() {
return !tech.isSwitchReality && !tech.isCollisionRealitySwitch && !tech.isJunkResearch return !tech.isSwitchReality && !tech.isCollisionRealitySwitch && !tech.isJunkResearch
}, },
@@ -3894,7 +3915,7 @@ const tech = {
}, },
requires: "below 100% duplication chance, not superdeterminism", requires: "below 100% duplication chance, not superdeterminism",
effect() { effect() {
tech.isCancelDuplication = true //search for tech.cancelCount to balance tech.isCancelDuplication = true //search for tech.duplication to balance
powerUps.setPowerUpMode(); //needed after adjusting duplication chance powerUps.setPowerUpMode(); //needed after adjusting duplication chance
}, },
remove() { remove() {
@@ -4027,6 +4048,57 @@ const tech = {
tech.is100Duplicate = false; tech.is100Duplicate = false;
} }
}, },
{
name: "strange attractor",
descriptionFunction() {
return `<strong>+7%</strong> <strong class='color-d'>damage</strong><br><strong>removing</strong> this increases <strong class='color-dup'>duplication</strong> by <strong>+10%</strong>`
},
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
isBadRandomOption: true,
allowed() {
return true
},
requires: "",
damage: 1.07,
effect() {
tech.damage *= this.damage
},
remove() {
if (this.count > 0) {
tech.duplication += 0.1
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
tech.damage /= this.damage
this.frequency = 0
}
}
},
{
name: "null hypothesis",
description: `<strong>+9%</strong> <strong class='color-d'>damage</strong><br><strong>removing</strong> this spawns ${powerUps.orb.research(15)}`,
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
isBadRandomOption: true,
allowed() {
return true
},
requires: "",
damage: 1.09,
effect() {
tech.damage *= this.damage
},
remove() {
if (this.count > 0) {
tech.damage /= this.damage
powerUps.spawnDelay("research", 15)
this.frequency = 0
}
}
},
{ {
name: "Born rule", name: "Born rule",
description: "<strong>remove</strong> all current <strong class='color-m'>tech</strong><br>spawn new <strong class='color-m'>tech</strong> to replace them", description: "<strong>remove</strong> all current <strong class='color-m'>tech</strong><br>spawn new <strong class='color-m'>tech</strong> to replace them",
@@ -4145,30 +4217,6 @@ const tech = {
}, },
remove() { } remove() { }
}, },
{
name: "strange attractor",
descriptionFunction() {
return `use ${powerUps.orb.research(2)} to spawn <strong>1</strong> <strong class='color-m'>tech</strong> with<br><strong>double</strong> your <strong class='color-dup'>duplication</strong> chance <em>(${(2 * tech.duplicationChance() * 100).toFixed(0)}%)</em>`
},
// description: `use ${powerUps.orb.research(2)} to spawn <strong>1</strong> <strong class='color-m'>tech</strong> with <strong>double</strong><br>your <strong class='color-dup'>duplication</strong> chance <em>(${(2*tech.duplicationChance()*100).toFixed(0)}%)</em>`,
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
isNonRefundable: true,
isBadRandomOption: true,
allowed() {
return !tech.isSuperDeterminism && tech.duplicationChance() > 0 && powerUps.research.count > 1
},
requires: "some duplication, not superdeterminism",
effect() {
powerUps.research.changeRerolls(-2)
simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-r'>research</span> <span class='color-symbol'>-=</span> 2`)
powerUps.directSpawn(m.pos.x, m.pos.y, "tech");
if (Math.random() < tech.duplicationChance() * 2) powerUps.directSpawn(m.pos.x + 10, m.pos.y + 5, "tech");
},
remove() { }
},
{ {
name: "reinforcement learning", name: "reinforcement learning",
description: "increase the <strong class='flicker'>frequency</strong> of finding copies of<br>your current <strong class='color-m'>tech</strong> by <strong>1000%</strong>", description: "increase the <strong class='flicker'>frequency</strong> of finding copies of<br>your current <strong class='color-m'>tech</strong> by <strong>1000%</strong>",
@@ -7189,7 +7237,7 @@ const tech = {
//************************************************** //**************************************************
{ {
name: "spherical harmonics", name: "spherical harmonics",
description: "<strong>+50%</strong> <strong>standing wave</strong> deflection efficiency", //<strong>standing wave</strong> oscillates in a 3rd dimension<br> description: "<strong>+50%</strong> <strong>standing wave</strong> deflection efficiency<br>shield deflection radius maintains it's maximum range", //<strong>standing wave</strong> oscillates in a 3rd dimension<br>
isFieldTech: true, isFieldTech: true,
maxCount: 9, maxCount: 9,
count: 0, count: 0,
@@ -7281,7 +7329,7 @@ const tech = {
{ {
name: "electronegativity", name: "electronegativity",
descriptionFunction() { descriptionFunction() {
return `<strong>+0.22%</strong> <strong class='color-d'>damage</strong> per current stored <strong class='color-f'>energy</strong><br><em>(up to +${(22 * m.maxEnergy).toFixed(0)}% damage at max energy)</em>` return `<strong>+0.22%</strong> <strong class='color-d'>damage</strong> per current stored <strong class='color-f'>energy</strong><br><em>(+${(22 * m.maxEnergy).toFixed(0)}% damage at max 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,
@@ -7313,7 +7361,7 @@ const tech = {
}, },
requires: "standing wave, perfect diamagnetism, pilot wave", requires: "standing wave, perfect diamagnetism, pilot wave",
effect() { effect() {
tech.blockDmg += 3 //if you change this value also update the for loop in the electricity graphics in m.pushMass tech.blockDmg += 5 //if you change this value also update the for loop in the electricity graphics in m.pushMass
}, },
remove() { remove() {
tech.blockDmg = 0; tech.blockDmg = 0;
@@ -7389,9 +7437,9 @@ const tech = {
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return m.fieldMode === 2 return m.fieldMode === 2 && !tech.isHealBrake
}, },
requires: "perfect diamagnetism", requires: "perfect diamagnetism, not induction brake",
effect() { effect() {
tech.isPerfectBrake = true; tech.isPerfectBrake = true;
}, },
@@ -8030,12 +8078,12 @@ const tech = {
requires: "time dilation, not CPT symmetry", requires: "time dilation, not CPT symmetry",
effect() { effect() {
tech.isRewindField = true; tech.isRewindField = true;
m.fieldUpgrades[m.fieldMode].set() m.fieldUpgrades[6].set()
m.wakeCheck(); m.wakeCheck();
}, },
remove() { remove() {
tech.isRewindField = false; tech.isRewindField = false;
if (this.count) m.fieldUpgrades[m.fieldMode].set() if (this.count) m.fieldUpgrades[6].set()
} }
}, },
{ {
@@ -8088,7 +8136,10 @@ const tech = {
}, },
{ {
name: "time crystals", name: "time crystals",
description: "<strong>+200%</strong> passive <strong class='color-f'>energy</strong> generation", // description: "<strong>+150%</strong> passive <strong class='color-f'>energy</strong> generation<br>${}",
descriptionFunction() {
return `<strong>+150%</strong> passive <strong class='color-f'>energy</strong> generation<br><em>(+${(150 * m.fieldRegen * 60).toFixed(1)} energy per second)</em>`
},
isFieldTech: true, isFieldTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
@@ -8101,10 +8152,16 @@ const tech = {
effect() { effect() {
tech.isTimeCrystals = true tech.isTimeCrystals = true
m.setFieldRegen() m.setFieldRegen()
this.descriptionFunction = function () {
return `<strong>+150%</strong> passive <strong class='color-f'>energy</strong> generation<br><em>(+${(60 * m.fieldRegen * 60).toFixed(1)} energy per second)</em>`
}
}, },
remove() { remove() {
tech.isTimeCrystals = false tech.isTimeCrystals = false
m.setFieldRegen() m.setFieldRegen()
this.descriptionFunction = function () {
return `<strong>+150%</strong> passive <strong class='color-f'>energy</strong> generation<br><em>(+${(150 * m.fieldRegen * 60).toFixed(1)} energy per second)</em>`
}
} }
}, },
{ {
@@ -8133,18 +8190,20 @@ const tech = {
{ {
name: "quantum eraser", name: "quantum eraser",
descriptionFunction() { descriptionFunction() {
return `<span style = 'font-size:90%;'>for each mob left <strong>alive</strong> after you exit a <strong>level</strong><br><strong>kill</strong> a mob as they spawn at <strong>+${100 - 1.6 * simulation.difficultyMode ** 2}%</strong> <strong class='color-dup'>duplication</strong></span>` return `<span style = 'font-size:90%;'>for each mob left <strong>alive</strong> after you exit a <strong>level</strong><br><strong>kill</strong> a mob as they spawn at <strong>+${(100 - 1.1 * simulation.difficultyMode ** 2).toFixed(0)}%</strong> <strong class='color-dup'>duplication</strong></span>`
}, },
// description: `<span style = 'font-size:90%;'>for each mob left <strong>alive</strong> after you exit a <strong>level</strong><br><strong>kill</strong> a mob as they spawn at <strong>100%</strong> <strong class='color-dup'>duplication</strong></span>`, // descriptionFunction() {
// return `for each mob left <strong>alive</strong> after you exit a <strong>level</strong><br>`
// },
isFieldTech: true, isFieldTech: true,
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 2, frequency: 2,
frequencyDefault: 2, frequencyDefault: 2,
allowed() { allowed() {
return (m.fieldMode === 7 || m.fieldMode === 6) && !tech.cloakDuplication return (m.fieldMode === 7) && !tech.cloakDuplication
}, },
requires: "cloaking or time dilation", requires: "cloaking",
effect() { effect() {
tech.quantumEraserCount = 0 tech.quantumEraserCount = 0
tech.isQuantumEraserDuplication = 0 tech.isQuantumEraserDuplication = 0
@@ -11292,7 +11351,7 @@ const tech = {
isSpeedDamage: null, isSpeedDamage: null,
isTimeSkip: null, isTimeSkip: null,
isCancelDuplication: null, isCancelDuplication: null,
cancelCount: null, duplication: null,
isCancelRerolls: null, isCancelRerolls: null,
isCancelTech: null, isCancelTech: null,
isBotDamage: null, isBotDamage: null,
@@ -11484,4 +11543,5 @@ const tech = {
isFoamCavitation: null, isFoamCavitation: null,
isHealAttract: null, isHealAttract: null,
isLaserField: null, isLaserField: null,
isHealBrake: null
} }

View File

@@ -1,41 +1,34 @@
******************************************************** NEXT PATCH ************************************************** ******************************************************** NEXT PATCH **************************************************
retrocausality drains 30% less energy as time rewinds, but each time you start to rewind you drain 30 energy new community level - superNgonBros by DesBoot
no longer provides immunity for 1 second after exiting rewind
spawns 20% fewer bots
deflecting changes tech: induction brake - after using a heal slow nearby mobs for 15 seconds
shielded mobs take 50% more energy to deflect tech: null hypothesis - +9 damage, spawn several research after removing
deflecting shielded mobs now only disables your shield for perfect diamagnetism and not for very long reworked: strange attractor - +7% damage, +10% duplication after removing
you can deflect any mob if you have at least 5% energy, but if deflecting brings you below that your shield is disabled for 1 second
also you can't passively regen energy while shield is disabled
standing wave rework bremsstrahlung does 50% more damage
coupling gives iceIX -> max energy time crystals 200 -> 150% passive energy regen
expansion gives deflection efficiency -> +50 max energy it also tells you how much energy regen you will get
spherical harmonics gives 40 -> 50% deflection efficiency aperture (-50 to +150) -> (-10 to +110) damage
electronegativity is a fieldTech for standing wave, wormhole, and pilot wave diaphragm (-33 to +100) -> (+8 to +80) defense
also 0.15 -> 0.22% damage per energy tungsten carbide 200 -> 222 health
dynamic equilibrium is no longer unlocked by standing wave CPT symmetry 30 -> 20 energy per second of rewind
quenching gives more max health, but also does more damage per over heal
tech: surface plasmons - after deflecting drains all your energy, shoot lasers in every direction final boss has 50% faster armor decay
so it takes even more damage the longer you fight it
added a generic system to add code that loops for a set time
Example code:
simulation.ephemera.push({
name: "uniqueName",
count: 60, //cycles before it self removes
do() {
this.count--
if (this.count < 0) simulation.removeEphemera(this.name)
//run code here
},
})
a few more images
some bug fixes some bug fixes
also new bugs probably
*********************************************************** TODO ***************************************************** *********************************************************** TODO *****************************************************
maybe use ⚆ in game text?
increase font?
rework quantum eraser
test bremsstrahlung damage
and make sure it actually does more damage with the dot tech
use ephemera to replace things use ephemera to replace things
JUNK? JUNK?
@@ -222,12 +215,6 @@ for tech power ups no tech options are displayed until you research once
or display only JUNK until you research once or display only JUNK until you research once
increase the number of options after each research increase the number of options after each research
Tech: Grandfather Paradox - After rewinding, +300 damage during rewinded time
maybe instead of +damage spawn a copy of player that shoots at things?
how... there is no way to reproduce firing
Requires: CPT symmetry, retrocausality
CPT adjacent tech is actually a bit too strong right now, maybe nerf a bit after testing
When receiving damage, in addition to becoming invulnerable to attacks, also become intangible for the set period of time When receiving damage, in addition to becoming invulnerable to attacks, also become intangible for the set period of time
tech increase max energy and energy to 5000, but you can no longer regen energy through any process tech increase max energy and energy to 5000, but you can no longer regen energy through any process
@@ -1170,7 +1157,6 @@ add sounds
possible names for tech possible names for tech
strange loop strange loop
homeostasis
holonomy - parallel transport of a vector leads to movement (applies to curved space) holonomy - parallel transport of a vector leads to movement (applies to curved space)
hypergolic - A hypergolic propellant combination used in a rocket engine is one whose components spontaneously ignite when they come into contact with each other. hypergolic - A hypergolic propellant combination used in a rocket engine is one whose components spontaneously ignite when they come into contact with each other.
swarm intelligence - for a drone tech swarm intelligence - for a drone tech
@@ -1201,7 +1187,6 @@ possible names for tech
superluminal signalling superluminal signalling
NP-complete NP-complete
lenticular lens: is an array of lenses, designed so that when viewed from slightly different angles, different parts of the image underneath are shown. lenticular lens: is an array of lenses, designed so that when viewed from slightly different angles, different parts of the image underneath are shown.
p-zombie
p-hacking JUNK tech p-hacking JUNK tech
https://en.wikipedia.org/wiki/High-entropy_alloys high yield strength and low ductility, high temp resistance https://en.wikipedia.org/wiki/High-entropy_alloys high yield strength and low ductility, high temp resistance
https://en.wikipedia.org/wiki/Refractory_metals hard, high temp resistance https://en.wikipedia.org/wiki/Refractory_metals hard, high temp resistance
@@ -1260,6 +1245,7 @@ if pause is pressed while selecting power ups, display pause menu on top of sele
harpoon - iron harpoon on a rope weapon art white background by Eiichiro Oda --no fish --ar 3:2 --v 5 --s 750 harpoon - iron harpoon on a rope weapon art white background by Eiichiro Oda --no fish --ar 3:2 --v 5 --s 750
mine - by Dan McPharlin mine - by Dan McPharlin
laser - complex optical scientific equipment laser - complex optical scientific equipment
knolling photography
guns, ammo - isometric clean pixel art image cutaway of , style of tekkonkinkreet guns, ammo - isometric clean pixel art image cutaway of , style of tekkonkinkreet
defensive - Paper cutout defensive - Paper cutout