laser delay
laser energy drain and damage now scale with fire delay effects no change for pulse since it already has a fire delay explosion harm to player no longer scales with explosion radius explosion damage will treat all explosions the same as a basic grenade explosion large radius explosions are much safer acetone peroxide 80->70% increased radius, 100->50% increase in harm from explosions CPT only triggers from damage above 1% per game cycle so no trigger from slime hazards or black holes or mob auras level: reactor has a horizontal flipped mode regression gives finalBoss(1.0005), Boss(1.0025), mob(1.05) increased damage taken JUNK tech: return - go back to the intro level, but keep your tech bug fixes
This commit is contained in:
@@ -185,7 +185,7 @@
|
||||
</a>
|
||||
Chat about n-gon in the <a href="https://discord.gg/JyfrKbXTfw">discord</a>.<br> Let me know about ideas, or bugs.
|
||||
<br><br><br>
|
||||
<a href="https://github.com/landgreen/n-gon">
|
||||
<a id="github" href="https://github.com/landgreen/n-gon">
|
||||
<svg viewBox="0 0 100 16" xmlns="http://www.w3.org/2000/svg" fill="#1B1F23">
|
||||
<path d="M8 0C3.58 0 0 3.58 0 8C0 11.54 2.29 14.53 5.47 15.59C5.87 15.66 6.02 15.42 6.02 15.21C6.02 15.02 6.01 14.39 6.01 13.72C4 14.09 3.48 13.23 3.32 12.78C3.23 12.55 2.84 11.84 2.5 11.65C2.22 11.5 1.82 11.13 2.49 11.12C3.12 11.11 3.57 11.7 3.72 11.94C4.44 13.15 5.59 12.81 6.05 12.6C6.12 12.08 6.33 11.73 6.56 11.53C4.78 11.33 2.92 10.64 2.92 7.58C2.92 6.71 3.23 5.99 3.74 5.43C3.66 5.23 3.38 4.41 3.82 3.31C3.82 3.31 4.49 3.1 6.02 4.13C6.66 3.95 7.34 3.86 8.02 3.86C8.7 3.86 9.38 3.95 10.02 4.13C11.55 3.09 12.22 3.31 12.22 3.31C12.66 4.41 12.38 5.23 12.3 5.43C12.81 5.99 13.12 6.7 13.12 7.58C13.12 10.65 11.25 11.33 9.47 11.53C9.76 11.78 10.01 12.26 10.01 13.01C10.01 14.08 10 14.94 10 15.21C10 15.42 10.15 15.67 10.55 15.59C13.71 14.53 16 11.53 16 8C16 3.58 12.42 0 8 0Z" />
|
||||
<g stroke='none' font-size="8px" font-family="Arial Black, sans-serif">
|
||||
|
||||
66
js/bullet.js
66
js/bullet.js
@@ -347,14 +347,14 @@ const b = {
|
||||
}
|
||||
},
|
||||
explosionRange() {
|
||||
return tech.explosiveRadius * (tech.isExplosionHarm ? 1.8 : 1) * (tech.isSmallExplosion ? 0.66 : 1) * (tech.isExplodeRadio ? 1.25 : 1)
|
||||
return tech.explosiveRadius * (tech.isExplosionHarm ? 1.7 : 1) * (tech.isSmallExplosion ? 0.66 : 1) * (tech.isExplodeRadio ? 1.25 : 1)
|
||||
},
|
||||
explosion(where, radius, color = "rgba(255,25,0,0.6)") { // typically explode is used for some bullets with .onEnd
|
||||
radius *= tech.explosiveRadius
|
||||
|
||||
let dist, sub, knock;
|
||||
let dmg = radius * 0.019 * (tech.isExplosionStun ? 0.7 : 1); //* 0.013 * (tech.isExplosionStun ? 0.7 : 1);
|
||||
if (tech.isExplosionHarm) radius *= 1.8 // 1/sqrt(2) radius -> area
|
||||
if (tech.isExplosionHarm) radius *= 1.7 // 1/sqrt(2) radius -> area
|
||||
if (tech.isSmallExplosion) {
|
||||
// color = "rgba(255,0,30,0.7)"
|
||||
radius *= 0.66
|
||||
@@ -375,7 +375,7 @@ const b = {
|
||||
|
||||
//player damage
|
||||
if (Vector.magnitude(Vector.sub(where, player.position)) < radius) {
|
||||
const DRAIN = (tech.isExplosionHarm ? 0.9 : 0.45) * (tech.isRadioactiveResistance ? 0.25 : 1)
|
||||
const DRAIN = (tech.isExplosionHarm ? 0.67 : 0.45) * (tech.isRadioactiveResistance ? 0.25 : 1)
|
||||
if (m.immuneCycle < m.cycle) m.energy -= DRAIN
|
||||
if (m.energy < 0) {
|
||||
m.energy = 0
|
||||
@@ -424,7 +424,7 @@ const b = {
|
||||
|
||||
if (dist < radius) {
|
||||
if (simulation.dmgScale) {
|
||||
const harm = radius * (tech.isExplosionHarm ? 0.00036 : 0.00018)
|
||||
const harm = tech.isExplosionHarm ? 0.075 : 0.05
|
||||
if (tech.isImmuneExplosion && m.energy > 0.15) {
|
||||
// const mitigate = Math.min(1, Math.max(1 - m.energy * 0.5, 0))
|
||||
m.energy -= 0.15
|
||||
@@ -458,14 +458,14 @@ const b = {
|
||||
body[i].force.y += knock.y;
|
||||
if (tech.isBlockExplode) {
|
||||
if (body[i] === m.holdingTarget) m.drop()
|
||||
const size = 20 + 350 * Math.pow(body[i].mass, 0.25)
|
||||
const size = 20 + 300 * Math.pow(body[i].mass, 0.25)
|
||||
const where = body[i].position
|
||||
const onLevel = level.onLevel //prevent explosions in the next level
|
||||
Matter.Composite.remove(engine.world, body[i]);
|
||||
body.splice(i, 1);
|
||||
setTimeout(() => {
|
||||
if (onLevel === level.onLevel) b.explosion(where, size); //makes bullet do explosive damage at end
|
||||
}, 150 + 300 * Math.random());
|
||||
}, 250 + 300 * Math.random());
|
||||
}
|
||||
} else if (dist < alertRange) {
|
||||
knock = Vector.mult(Vector.normalise(sub), -Math.sqrt(dmg) * body[i].mass * 0.011);
|
||||
@@ -2389,14 +2389,14 @@ const b = {
|
||||
}
|
||||
if (tech.isLaserPush) { //push mobs away
|
||||
const index = path.length - 1
|
||||
Matter.Body.setVelocity(best.who, { x: best.who.velocity.x * 0.95, y: best.who.velocity.y * 0.95 });
|
||||
const force = Vector.mult(Vector.normalise(Vector.sub(path[index], path[Math.max(0, index - 1)])), 0.005 * push * Math.min(6, best.who.mass))
|
||||
Matter.Body.setVelocity(best.who, { x: best.who.velocity.x * 0.97, y: best.who.velocity.y * 0.97 });
|
||||
const force = Vector.mult(Vector.normalise(Vector.sub(path[index], path[Math.max(0, index - 1)])), 0.003 * push * Math.min(6, best.who.mass))
|
||||
Matter.Body.applyForce(best.who, path[index], force)
|
||||
}
|
||||
} else if (tech.isLaserPush && best.who.classType === "body") {
|
||||
const index = path.length - 1
|
||||
Matter.Body.setVelocity(best.who, { x: best.who.velocity.x * 0.95, y: best.who.velocity.y * 0.95 });
|
||||
const force = Vector.mult(Vector.normalise(Vector.sub(path[index], path[Math.max(0, index - 1)])), 0.005 * push * Math.min(6, best.who.mass))
|
||||
Matter.Body.setVelocity(best.who, { x: best.who.velocity.x * 0.97, y: best.who.velocity.y * 0.97 });
|
||||
const force = Vector.mult(Vector.normalise(Vector.sub(path[index], path[Math.max(0, index - 1)])), 0.003 * push * Math.min(6, best.who.mass))
|
||||
Matter.Body.applyForce(best.who, path[index], force)
|
||||
}
|
||||
};
|
||||
@@ -4203,7 +4203,7 @@ const b = {
|
||||
}
|
||||
}
|
||||
|
||||
if (!m.isCloak) { //if time dilation isn't active
|
||||
if (!m.isCloak) { //if cloaking field isn't active
|
||||
const size = 33
|
||||
q = Matter.Query.region(mob, {
|
||||
min: {
|
||||
@@ -6957,8 +6957,15 @@ const b = {
|
||||
m.fireCDcycle = m.cycle + 100; // cool down if out of energy
|
||||
} else {
|
||||
m.fireCDcycle = m.cycle
|
||||
m.energy -= m.fieldRegen + tech.laserFieldDrain * tech.isLaserDiode
|
||||
b.laser();
|
||||
m.energy -= m.fieldRegen + tech.laserFieldDrain * tech.isLaserDiode / b.fireCDscale
|
||||
const where = {
|
||||
x: m.pos.x + 20 * Math.cos(m.angle),
|
||||
y: m.pos.y + 20 * Math.sin(m.angle)
|
||||
}
|
||||
b.laser(where, {
|
||||
x: where.x + 3000 * Math.cos(m.angle),
|
||||
y: where.y + 3000 * Math.sin(m.angle)
|
||||
}, tech.laserDamage / b.fireCDscale);
|
||||
}
|
||||
},
|
||||
firePulse() {
|
||||
@@ -6969,11 +6976,11 @@ const b = {
|
||||
m.fireCDcycle = m.cycle + 100; // cool down if out of energy
|
||||
} else {
|
||||
m.fireCDcycle = m.cycle
|
||||
m.energy -= m.fieldRegen + tech.laserFieldDrain * tech.isLaserDiode
|
||||
m.energy -= m.fieldRegen + tech.laserFieldDrain * tech.isLaserDiode / b.fireCDscale
|
||||
// const divergence = input.down ? 0.15 : 0.2
|
||||
// const scale = Math.pow(0.9, tech.beamSplitter)
|
||||
// const pushScale = scale * scale
|
||||
let dmg = tech.laserDamage // * scale //Math.pow(0.9, tech.laserDamage)
|
||||
let dmg = tech.laserDamage / b.fireCDscale // * scale //Math.pow(0.9, tech.laserDamage)
|
||||
const where = {
|
||||
x: m.pos.x + 20 * Math.cos(m.angle),
|
||||
y: m.pos.y + 20 * Math.sin(m.angle)
|
||||
@@ -6993,7 +7000,7 @@ const b = {
|
||||
m.fireCDcycle = m.cycle + 100; // cool down if out of energy
|
||||
} else {
|
||||
m.fireCDcycle = m.cycle
|
||||
m.energy -= m.fieldRegen + tech.laserFieldDrain * tech.isLaserDiode
|
||||
m.energy -= m.fieldRegen + tech.laserFieldDrain * tech.isLaserDiode / b.fireCDscale
|
||||
const range = {
|
||||
x: 5000 * Math.cos(m.angle),
|
||||
y: 5000 * Math.sin(m.angle)
|
||||
@@ -7006,7 +7013,7 @@ const b = {
|
||||
x: 7.5 * Math.cos(m.angle - Math.PI / 2),
|
||||
y: 7.5 * Math.sin(m.angle - Math.PI / 2)
|
||||
}
|
||||
const dmg = 0.70 * tech.laserDamage // 3.5 * 0.55 = 200% more damage
|
||||
const dmg = 0.70 * tech.laserDamage / b.fireCDscale // 3.5 * 0.55 = 200% more damage
|
||||
const where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }
|
||||
const eye = {
|
||||
x: m.pos.x + 15 * Math.cos(m.angle),
|
||||
@@ -7057,8 +7064,8 @@ const b = {
|
||||
m.fireCDcycle = m.cycle + 100; // cool down if out of energy
|
||||
} else {
|
||||
m.fireCDcycle = m.cycle
|
||||
m.energy -= m.fieldRegen + tech.laserFieldDrain * tech.isLaserDiode
|
||||
const dmg = 0.4 * tech.laserDamage // 3.5 * 0.55 = 200% more damage
|
||||
m.energy -= m.fieldRegen + tech.laserFieldDrain * tech.isLaserDiode / b.fireCDscale
|
||||
const dmg = 0.4 * tech.laserDamage / b.fireCDscale // 3.5 * 0.55 = 200% more damage
|
||||
const spacing = Math.ceil(4 - 0.3 * tech.historyLaser)
|
||||
ctx.beginPath();
|
||||
b.laser({
|
||||
@@ -7084,27 +7091,6 @@ const b = {
|
||||
ctx.stroke();
|
||||
}
|
||||
},
|
||||
// firePulse() {
|
||||
// m.fireCDcycle = m.cycle + Math.floor((tech.isPulseAim ? 25 : 50) * b.fireCDscale); // cool down
|
||||
// let energy = 0.3 * Math.min(m.energy, 1.5)
|
||||
// m.energy -= energy * tech.isLaserDiode
|
||||
// if (tech.beamSplitter) {
|
||||
// // energy *= Math.pow(0.9, tech.beamSplitter)
|
||||
// // b.pulse(energy, m.angle)
|
||||
// // for (let i = 1; i < 1 + tech.beamSplitter; i++) {
|
||||
// // b.pulse(energy, m.angle - i * 0.27)
|
||||
// // b.pulse(energy, m.angle + i * 0.27)
|
||||
// // }
|
||||
// const divergence = input.down ? 0.2 : 0.5
|
||||
// const angle = m.angle - tech.beamSplitter * divergence / 2
|
||||
// for (let i = 0; i < 1 + tech.beamSplitter; i++) {
|
||||
// b.pulse(energy, angle + i * divergence)
|
||||
// }
|
||||
|
||||
// } else {
|
||||
// b.pulse(energy, m.angle)
|
||||
// }
|
||||
// },
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -109,7 +109,7 @@ function collisionChecks(event) {
|
||||
let dmg = Math.min(Math.max(0.025 * Math.sqrt(mob[k].mass), 0.05), 0.3) * simulation.dmgScale; //player damage is capped at 0.3*dmgScale of 1.0
|
||||
if (m.isCloak) dmg *= 0.5
|
||||
mob[k].foundPlayer();
|
||||
if (tech.isRewindAvoidDeath && m.energy > 0.66) { //CPT reversal runs in m.damage, but it stops the rest of the collision code here too
|
||||
if (tech.isRewindAvoidDeath && m.energy > 0.66 && dmg > 0.01) { //CPT reversal runs in m.damage, but it stops the rest of the collision code here too
|
||||
m.damage(dmg);
|
||||
return
|
||||
}
|
||||
@@ -190,7 +190,7 @@ function collisionChecks(event) {
|
||||
time: simulation.drawTime
|
||||
});
|
||||
}
|
||||
if (tech.isLessDamageReduction && !mob[k].shield) mob[k].damageReduction *= mob[k].isBoss ? 1.0025 : 1.05
|
||||
if (tech.isLessDamageReduction && !mob[k].shield) mob[k].damageReduction *= mob[k].isBoss ? (mob[k].isFinalBoss ? 1.0005 : 1.0025) : 1.05
|
||||
return;
|
||||
}
|
||||
//mob + body collisions
|
||||
@@ -229,7 +229,7 @@ function collisionChecks(event) {
|
||||
}
|
||||
|
||||
const stunTime = dmg / Math.sqrt(obj.mass)
|
||||
if (stunTime > 0.5) mobs.statusStun(mob[k], 60 + 60 * Math.sqrt(stunTime))
|
||||
if (stunTime > 0.5 && mob[k].memory !== Infinity) mobs.statusStun(mob[k], 60 + 60 * Math.sqrt(stunTime))
|
||||
if (mob[k].alive && mob[k].distanceToPlayer2() < 1000000 && !m.isCloak) mob[k].foundPlayer();
|
||||
if (tech.fragments && obj.speed > 10 && !obj.hasFragmented) {
|
||||
obj.hasFragmented = true;
|
||||
|
||||
254
js/level.js
254
js/level.js
@@ -15,10 +15,10 @@ const level = {
|
||||
levels: [],
|
||||
start() {
|
||||
if (level.levelsCleared === 0) { //this code only runs on the first level
|
||||
// // simulation.isHorizontalFlipped = true
|
||||
// simulation.isHorizontalFlipped = true
|
||||
// m.addHealth(Infinity)
|
||||
// m.setField("time dilation")
|
||||
// b.giveGuns("spores")
|
||||
// b.giveGuns("laser")
|
||||
// tech.giveTech("closed timelike curve")
|
||||
// tech.giveTech("retrocausality")
|
||||
// tech.giveTech("clock gating")
|
||||
@@ -38,11 +38,7 @@ const level = {
|
||||
// level.difficultyIncrease(20) //30 is near max on hard //60 is near max on why
|
||||
// simulation.enableConstructMode() //used to build maps in testing mode
|
||||
// level.testing();
|
||||
// simulation.fpsCap = 30 //new fps
|
||||
// simulation.fpsInterval = 1000 / simulation.fpsCap;
|
||||
//how long to wait to return to normal fps
|
||||
// m.defaultFPSCycle = m.cycle + 20 + Math.min(90, Math.floor(200 * dmg))
|
||||
// spawn.timeSkipBoss(1900, -500)
|
||||
// spawn.starter(1900, -500, 200)
|
||||
// level.reactor(); //not in rotation, used for testing
|
||||
|
||||
if (simulation.isTraining) { level.walk(); } else { level.intro(); } //normal starting level ************************************************
|
||||
@@ -2697,8 +2693,6 @@ const level = {
|
||||
// spawn.randomMob(1600, -500)
|
||||
},
|
||||
reactor() {
|
||||
level.setPosToSpawn(-550, -800); //normal spawn
|
||||
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
|
||||
level.exit.x = 3500;
|
||||
level.exit.y = -42;
|
||||
spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 25);
|
||||
@@ -2708,8 +2702,7 @@ const level = {
|
||||
color.map = "#303639";
|
||||
// powerUps.spawnStartingPowerUps(1475, -1175);
|
||||
// spawn.debris(750, -2200, 3700, 16); //16 debris per level
|
||||
const button = level.button(1400, 0)
|
||||
button.isUp = true
|
||||
|
||||
spawn.bodyRect(250, -70, 100, 70, 1);
|
||||
spawn.mapRect(-425, 0, 4500, 2100);
|
||||
spawn.mapRect(-475, -2825, 4500, 1025);
|
||||
@@ -2735,90 +2728,169 @@ const level = {
|
||||
let isFightOver = false
|
||||
let isSpawnedBoss = false
|
||||
|
||||
level.custom = () => {
|
||||
if (isDoorsLocked) {
|
||||
if (player.position.x < -300) { //if player gets trapped inside starting room open up again
|
||||
isDoorsLocked = false
|
||||
doorIn.isClosing = false
|
||||
if (simulation.isHorizontalFlipped) { //flip the map horizontally
|
||||
level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit
|
||||
level.setPosToSpawn(550, -800); //normal spawn
|
||||
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
|
||||
|
||||
const button = level.button(-1500, 0)
|
||||
button.isUp = true
|
||||
|
||||
level.custom = () => {
|
||||
if (isDoorsLocked) {
|
||||
if (player.position.x > 300) { //if player gets trapped inside starting room open up again
|
||||
isDoorsLocked = false
|
||||
doorIn.isClosing = false
|
||||
}
|
||||
}
|
||||
}
|
||||
// else if (!isFightOver && player.position.x > 225) {
|
||||
// isDoorsLocked = true
|
||||
// doorIn.isClosing = true
|
||||
// doorOut.isClosing = true
|
||||
// }
|
||||
doorIn.openClose();
|
||||
doorOut.openClose();
|
||||
ctx.fillStyle = "#d5ebef"
|
||||
ctx.fillRect(2750, -375, 1050, 375)
|
||||
level.enter.draw();
|
||||
level.exit.drawAndCheck();
|
||||
button.draw();
|
||||
if (button.isUp) {
|
||||
button.query();
|
||||
} else if (!isSpawnedBoss) {
|
||||
if (player.position.x > 0) {
|
||||
if (!doorOut.isClosed() || !doorIn.isClosed()) {
|
||||
doorIn.isClosing = true
|
||||
doorOut.isClosing = true
|
||||
doorIn.openClose();
|
||||
doorOut.openClose();
|
||||
ctx.fillStyle = "#d5ebef"
|
||||
ctx.fillRect(-3800, -375, 1050, 375)
|
||||
level.enter.draw();
|
||||
level.exit.drawAndCheck();
|
||||
button.draw();
|
||||
if (button.isUp) {
|
||||
button.query();
|
||||
} else if (!isSpawnedBoss) {
|
||||
if (player.position.x < 0) {
|
||||
if (!doorOut.isClosed() || !doorIn.isClosed()) {
|
||||
doorIn.isClosing = true
|
||||
doorOut.isClosing = true
|
||||
} else {
|
||||
isSpawnedBoss = true
|
||||
isDoorsLocked = true
|
||||
for (let i = 0; i < 9; ++i) powerUps.spawn(-1800 + 550 * Math.random(), -1700, "ammo")
|
||||
for (let i = 0; i < 3; ++i) powerUps.spawn(-1800 + 550 * Math.random(), -1700, "heal");
|
||||
const scale = Math.pow(simulation.difficulty, 0.73) //hard around 30, why around 54
|
||||
if (Math.random() < 0.07 && simulation.difficulty > 24) {
|
||||
for (let i = 0, len = scale * 0.25 / 4; i < len; ++i) spawn.timeBoss(-1327 - 200 * i, -1525, 60, false); //spawn 1-2 at difficulty 15
|
||||
for (let i = 0, len = scale * 0.1 / 4; i < len; ++i) spawn.bounceBoss(-1327 - 200 * i, -1525, 80, false);
|
||||
for (let i = 0, len = scale * 0.16 / 4; i < len; ++i) spawn.sprayBoss(-1327 - 200 * i, -1525, 30, false)
|
||||
for (let i = 0, len = scale * 0.23 / 4; i < len; ++i) spawn.mineBoss(-1327 - 200 * i, -1525, 50, false);
|
||||
} else {
|
||||
if (Math.random() < 0.25) {
|
||||
for (let i = 0, len = scale * 0.25; i < len; ++i) spawn.timeBoss(-1327 - 200 * i, -1525, 80, false); //spawn 1-2 at difficulty 15
|
||||
} else if (Math.random() < 0.33) {
|
||||
for (let i = 0, len = scale * 0.1; i < len; ++i) spawn.bounceBoss(-1327 - 200 * i, -1525, 80, false); //spawn 1-2 at difficulty 15
|
||||
} else if (Math.random() < 0.5) {
|
||||
for (let i = 0, len = scale * 0.16; i < len; ++i) spawn.sprayBoss(-1327 - 200 * i, -1525, 30, false) //spawn 2-3 at difficulty 15
|
||||
} else {
|
||||
for (let i = 0, len = scale * 0.23; i < len; ++i) spawn.mineBoss(-1327 - 200 * i, -1525, 50, false); //spawn 3-4 at difficulty 15
|
||||
}
|
||||
}
|
||||
spawn.secondaryBossChance(-2300, -800)
|
||||
}
|
||||
} else {
|
||||
isSpawnedBoss = true
|
||||
isDoorsLocked = true
|
||||
for (let i = 0; i < 9; ++i) powerUps.spawn(1200 + 550 * Math.random(), -1700, "ammo")
|
||||
for (let i = 0; i < 3; ++i) powerUps.spawn(1200 + 550 * Math.random(), -1700, "heal");
|
||||
const scale = Math.pow(simulation.difficulty, 0.73) //hard around 30, why around 54
|
||||
for (let i = 0, len = scale * 0.23; i < len; ++i) spawn.mineBoss(1487 + 200 * i, -1525, 50, false); //spawn 3-4 at difficulty 15
|
||||
// if (Math.random() < 0.07 && simulation.difficulty > 24) {
|
||||
// for (let i = 0, len = scale * 0.25 / 4; i < len; ++i) spawn.timeBoss(1487 + 200 * i, -1525, 60, false); //spawn 1-2 at difficulty 15
|
||||
// for (let i = 0, len = scale * 0.1 / 4; i < len; ++i) spawn.bounceBoss(1487 + 200 * i, -1525, 80, false);
|
||||
// for (let i = 0, len = scale * 0.16 / 4; i < len; ++i) spawn.sprayBoss(1487 + 200 * i, -1525, 30, false)
|
||||
// for (let i = 0, len = scale * 0.23 / 4; i < len; ++i) spawn.mineBoss(1487 + 200 * i, -1525, 50, false);
|
||||
// } else {
|
||||
// if (Math.random() < 0.25) {
|
||||
// for (let i = 0, len = scale * 0.25; i < len; ++i) spawn.timeBoss(1487 + 200 * i, -1525, 80, false); //spawn 1-2 at difficulty 15
|
||||
// } else if (Math.random() < 0.33) {
|
||||
// for (let i = 0, len = scale * 0.1; i < len; ++i) spawn.bounceBoss(1487 + 200 * i, -1525, 80, false); //spawn 1-2 at difficulty 15
|
||||
// } else if (Math.random() < 0.5) {
|
||||
// for (let i = 0, len = scale * 0.16; i < len; ++i) spawn.sprayBoss(1487 + 200 * i, -1525, 30, false) //spawn 2-3 at difficulty 15
|
||||
// } else {
|
||||
// for (let i = 0, len = scale * 0.23; i < len; ++i) spawn.mineBoss(1487 + 200 * i, -1525, 50, false); //spawn 3-4 at difficulty 15
|
||||
// }
|
||||
// }
|
||||
spawn.secondaryBossChance(2200, -800)
|
||||
doorIn.isClosing = false
|
||||
}
|
||||
} else {
|
||||
doorIn.isClosing = false
|
||||
}
|
||||
} else if (!isFightOver && !(simulation.cycle % 180)) {
|
||||
let isFoundBoss = false
|
||||
for (let i = 0; i < mob.length; i++) {
|
||||
if (mob[i].isBoss) {
|
||||
isFoundBoss = true
|
||||
break
|
||||
} else if (!isFightOver && !(simulation.cycle % 180)) {
|
||||
let isFoundBoss = false
|
||||
for (let i = 0; i < mob.length; i++) {
|
||||
if (mob[i].isBoss) {
|
||||
isFoundBoss = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!isFoundBoss) {
|
||||
isFightOver = true
|
||||
doorIn.isClosing = false
|
||||
doorOut.isClosing = false
|
||||
powerUps.spawnBossPowerUp(-3600, -100)
|
||||
powerUps.spawn(-3650, -200, "tech")
|
||||
// if (player.position.x < 2760 && player.position.x > 210) {}
|
||||
}
|
||||
}
|
||||
if (!isFoundBoss) {
|
||||
isFightOver = true
|
||||
doorIn.isClosing = false
|
||||
doorOut.isClosing = false
|
||||
powerUps.spawnBossPowerUp(3600, -100)
|
||||
powerUps.spawn(3650, -200, "tech")
|
||||
// if (player.position.x < 2760 && player.position.x > 210) {}
|
||||
};
|
||||
|
||||
level.customTopLayer = () => {
|
||||
doorIn.draw();
|
||||
doorOut.draw();
|
||||
ctx.fillStyle = "rgba(0,0,0,0.1)"
|
||||
ctx.fillRect(-225, -1100, 1000, 350);
|
||||
};
|
||||
} else {
|
||||
level.setPosToSpawn(-550, -800); //normal spawn
|
||||
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
|
||||
|
||||
const button = level.button(1400, 0)
|
||||
button.isUp = true
|
||||
|
||||
level.custom = () => {
|
||||
if (isDoorsLocked) {
|
||||
if (player.position.x < -300) { //if player gets trapped inside starting room open up again
|
||||
isDoorsLocked = false
|
||||
doorIn.isClosing = false
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
level.customTopLayer = () => {
|
||||
// if (isDoorsLocked) {
|
||||
// ctx.fillStyle = "#333"
|
||||
// ctx.fillRect(2800, -375, 500, 375);
|
||||
// }
|
||||
doorIn.draw();
|
||||
doorOut.draw();
|
||||
ctx.fillStyle = "rgba(0,0,0,0.1)"
|
||||
ctx.fillRect(-775, -1100, 1000, 350);
|
||||
// ctx.fillStyle = "rgba(0,255,255,0.1)"
|
||||
// ctx.fillRect(2750, -375, 550, 375)
|
||||
};
|
||||
doorIn.openClose();
|
||||
doorOut.openClose();
|
||||
ctx.fillStyle = "#d5ebef"
|
||||
ctx.fillRect(2750, -375, 1050, 375)
|
||||
level.enter.draw();
|
||||
level.exit.drawAndCheck();
|
||||
button.draw();
|
||||
if (button.isUp) {
|
||||
button.query();
|
||||
} else if (!isSpawnedBoss) {
|
||||
if (player.position.x > 0) {
|
||||
if (!doorOut.isClosed() || !doorIn.isClosed()) {
|
||||
doorIn.isClosing = true
|
||||
doorOut.isClosing = true
|
||||
} else {
|
||||
isSpawnedBoss = true
|
||||
isDoorsLocked = true
|
||||
for (let i = 0; i < 9; ++i) powerUps.spawn(1200 + 550 * Math.random(), -1700, "ammo")
|
||||
for (let i = 0; i < 3; ++i) powerUps.spawn(1200 + 550 * Math.random(), -1700, "heal");
|
||||
const scale = Math.pow(simulation.difficulty, 0.73) //hard around 30, why around 54
|
||||
if (Math.random() < 0.07 && simulation.difficulty > 24) {
|
||||
for (let i = 0, len = scale * 0.25 / 4; i < len; ++i) spawn.timeBoss(1487 + 200 * i, -1525, 60, false); //spawn 1-2 at difficulty 15
|
||||
for (let i = 0, len = scale * 0.1 / 4; i < len; ++i) spawn.bounceBoss(1487 + 200 * i, -1525, 80, false);
|
||||
for (let i = 0, len = scale * 0.16 / 4; i < len; ++i) spawn.sprayBoss(1487 + 200 * i, -1525, 30, false)
|
||||
for (let i = 0, len = scale * 0.23 / 4; i < len; ++i) spawn.mineBoss(1487 + 200 * i, -1525, 50, false);
|
||||
} else {
|
||||
if (Math.random() < 0.25) {
|
||||
for (let i = 0, len = scale * 0.25; i < len; ++i) spawn.timeBoss(1487 + 200 * i, -1525, 80, false); //spawn 1-2 at difficulty 15
|
||||
} else if (Math.random() < 0.33) {
|
||||
for (let i = 0, len = scale * 0.1; i < len; ++i) spawn.bounceBoss(1487 + 200 * i, -1525, 80, false); //spawn 1-2 at difficulty 15
|
||||
} else if (Math.random() < 0.5) {
|
||||
for (let i = 0, len = scale * 0.16; i < len; ++i) spawn.sprayBoss(1487 + 200 * i, -1525, 30, false) //spawn 2-3 at difficulty 15
|
||||
} else {
|
||||
for (let i = 0, len = scale * 0.23; i < len; ++i) spawn.mineBoss(1487 + 200 * i, -1525, 50, false); //spawn 3-4 at difficulty 15
|
||||
}
|
||||
}
|
||||
spawn.secondaryBossChance(2200, -800)
|
||||
}
|
||||
} else {
|
||||
doorIn.isClosing = false
|
||||
}
|
||||
} else if (!isFightOver && !(simulation.cycle % 180)) {
|
||||
let isFoundBoss = false
|
||||
for (let i = 0; i < mob.length; i++) {
|
||||
if (mob[i].isBoss) {
|
||||
isFoundBoss = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!isFoundBoss) {
|
||||
isFightOver = true
|
||||
doorIn.isClosing = false
|
||||
doorOut.isClosing = false
|
||||
powerUps.spawnBossPowerUp(3600, -100)
|
||||
powerUps.spawn(3650, -200, "tech")
|
||||
// if (player.position.x < 2760 && player.position.x > 210) {}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
level.customTopLayer = () => {
|
||||
doorIn.draw();
|
||||
doorOut.draw();
|
||||
ctx.fillStyle = "rgba(0,0,0,0.1)"
|
||||
ctx.fillRect(-775, -1100, 1000, 350);
|
||||
};
|
||||
}
|
||||
|
||||
// if (simulation.difficulty > 1) spawn.randomLevelBoss(2200, -1300);
|
||||
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||
},
|
||||
@@ -3024,7 +3096,9 @@ const level = {
|
||||
spawn.mapRect(2025, 0, 150, 50); //lid to floor hole
|
||||
} else {
|
||||
for (let i = 0; i < 60; i++) {
|
||||
setTimeout(() => { spawn.sneaker(2100, -1500 - 50 * i); }, 2000 + 500 * i);
|
||||
setTimeout(() => {
|
||||
if (level.levels[level.onLevel] === "intro") spawn.sneaker(2100, -1500 - 50 * i);
|
||||
}, 2000 + 500 * i);
|
||||
}
|
||||
}
|
||||
const wires = new Path2D() //pre-draw the complex lighting path to save processing
|
||||
|
||||
18
js/mob.js
18
js/mob.js
@@ -115,13 +115,19 @@ const mobs = {
|
||||
who.isStunned = true;
|
||||
who.status.push({
|
||||
effect() {
|
||||
who.seePlayer.yes = false;
|
||||
who.seePlayer.recall = 0;
|
||||
who.seePlayer.position = {
|
||||
x: who.position.x + 100 * (Math.random() - 0.5),
|
||||
y: who.position.y + 100 * (Math.random() - 0.5)
|
||||
if (who.memory !== Infinity) {
|
||||
who.seePlayer.yes = false;
|
||||
who.seePlayer.recall = 0;
|
||||
who.seePlayer.position = {
|
||||
x: who.position.x + 100 * (Math.random() - 0.5),
|
||||
y: who.position.y + 100 * (Math.random() - 0.5)
|
||||
}
|
||||
} else {
|
||||
Matter.Body.setVelocity(who, {
|
||||
x: who.velocity.x * 0.6,
|
||||
y: who.velocity.y * 0.6
|
||||
});
|
||||
}
|
||||
// && !who.isBoss
|
||||
if (who.velocity.y < 2) who.force.y += who.mass * 0.0004 //extra gravity
|
||||
|
||||
//draw health bar
|
||||
|
||||
@@ -646,7 +646,7 @@ const m = {
|
||||
}
|
||||
},
|
||||
damage(dmg) {
|
||||
if (tech.isRewindAvoidDeath && m.energy > 0.6) {
|
||||
if (tech.isRewindAvoidDeath && m.energy > 0.6 && dmg > 0.01) {
|
||||
const steps = Math.floor(Math.min(299, 150 * m.energy))
|
||||
simulation.makeTextLog(`<span class='color-var'>m</span>.rewind(${steps})`)
|
||||
m.rewind(steps)
|
||||
@@ -981,6 +981,7 @@ const m = {
|
||||
},
|
||||
setMaxEnergy() {
|
||||
m.maxEnergy = (tech.isMaxEnergyTech ? 0.5 : 1) + tech.bonusEnergy + tech.healMaxEnergyBonus + tech.harmonicEnergy + 2 * tech.isGroundState + 3 * tech.isRelay * tech.isFlipFlopOn * tech.isRelayEnergy + 0.6 * (m.fieldUpgrades[m.fieldMode].name === "standing wave")
|
||||
// if (tech.isEnergyHealth) m.maxEnergy *= Math.sqrt(m.harmReduction())
|
||||
simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-f'>maxEnergy</span> <span class='color-symbol'>=</span> ${(m.maxEnergy.toFixed(2))}`)
|
||||
},
|
||||
fieldMeterColor: "#0cf",
|
||||
|
||||
@@ -848,7 +848,6 @@ const simulation = {
|
||||
m.fireCDcycle = 0
|
||||
m.drop();
|
||||
m.hole.isOn = false;
|
||||
level.zones = [];
|
||||
simulation.drawList = [];
|
||||
|
||||
if (tech.isDronesTravel && m.alive) {
|
||||
|
||||
@@ -289,6 +289,7 @@ const spawn = {
|
||||
Composite.add(engine.world, me.constraint);
|
||||
}, 2000); //add in a delay in case the level gets flipped left right
|
||||
me.isBoss = true;
|
||||
me.isFinalBoss = true;
|
||||
me.frictionAir = 0.01;
|
||||
me.memory = Infinity;
|
||||
me.hasRunDeathScript = false
|
||||
@@ -956,7 +957,7 @@ const spawn = {
|
||||
me.isCell = true;
|
||||
me.cellID = cellID
|
||||
me.accelMag = 0.000165 * simulation.accelScale;
|
||||
me.memory = 40;
|
||||
me.memory = Infinity;
|
||||
me.isVerticesChange = true
|
||||
me.frictionAir = 0.012
|
||||
me.seePlayerFreq = Math.floor(11 + 7 * Math.random())
|
||||
|
||||
106
js/tech.js
106
js/tech.js
@@ -93,6 +93,8 @@ const tech = {
|
||||
// console.log(count)
|
||||
// }
|
||||
// count total non junk tech
|
||||
id = "github"
|
||||
|
||||
let count = 0
|
||||
for (let i = 0, len = tech.tech.length; i < len; i++) {
|
||||
if (tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed() && !tech.tech[i].isJunk) count += tech.tech[i].frequency
|
||||
@@ -2223,6 +2225,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "mass-energy equivalence",
|
||||
// description: "<strong class='color-f'>energy</strong> protects you instead of <strong class='color-h'>health</strong><br>√ of <strong class='color-harm'>harm</strong> <strong>reduction</strong> reduces max <strong class='color-f'>energy</strong>",
|
||||
description: "<strong class='color-f'>energy</strong> protects you instead of <strong class='color-h'>health</strong><br><strong class='color-harm'>harm</strong> <strong>reduction</strong> effects provide <strong>no</strong> benefit",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -3675,11 +3678,13 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "strange attractor",
|
||||
description: `use ${powerUps.orb.research(2)} to spawn <strong>1</strong> <strong class='color-m'>tech</strong><br>with <strong>double</strong> your <strong class='color-dup'>duplication</strong> chance`,
|
||||
descriptionFunction() { return `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>` },
|
||||
|
||||
// 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,
|
||||
frequency: 1000,
|
||||
frequencyDefault: 1000,
|
||||
isNonRefundable: true,
|
||||
isBadRandomOption: true,
|
||||
allowed() {
|
||||
@@ -4613,7 +4618,7 @@ const tech = {
|
||||
allowed() {
|
||||
return tech.haveGunCheck("missiles") && tech.isMissileBig //&& !tech.isSmartRadius && !tech.isImmuneExplosion
|
||||
},
|
||||
requires: "missiles, cruse missile", //, not electric reactive armor, controlled explosions",
|
||||
requires: "missiles, cruse missile",
|
||||
effect() {
|
||||
tech.isMissileBiggest = true
|
||||
},
|
||||
@@ -4767,7 +4772,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "acetone peroxide",
|
||||
description: "increase <strong class='color-e'>explosive</strong> <strong>radius</strong> by <strong>80%</strong>, but<br>you take <strong>200%</strong> more <strong class='color-harm'>harm</strong> from <strong class='color-e'>explosions</strong>",
|
||||
description: "increase <strong class='color-e'>explosive</strong> <strong>radius</strong> by <strong>70%</strong>, but<br>you take <strong>50%</strong> more <strong class='color-harm'>harm</strong> from <strong class='color-e'>explosions</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -4857,9 +4862,9 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return !tech.isSmartRadius && !tech.isExplodeRadio && tech.hasExplosiveDamageCheck()
|
||||
return !tech.isSmartRadius && !tech.isExplodeRadio && tech.hasExplosiveDamageCheck() && !tech.isEnergyHealth
|
||||
},
|
||||
requires: "an explosive damage source, not iridium-192",
|
||||
requires: "an explosive damage source, not iridium-192, mass-energy",
|
||||
effect: () => {
|
||||
tech.isImmuneExplosion = true;
|
||||
},
|
||||
@@ -4916,9 +4921,9 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("grenades") && !tech.isNeutronBomb
|
||||
return tech.haveGunCheck("grenades") && !tech.isNeutronBomb && !tech.isBlockExplode
|
||||
},
|
||||
requires: "grenades, not neutron bomb",
|
||||
requires: "grenades, not neutron bomb, chain reaction",
|
||||
effect() {
|
||||
tech.isVacuumBomb = true;
|
||||
b.setGrenadeMode()
|
||||
@@ -4937,9 +4942,9 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("grenades") && !tech.isExplodeRadio && !tech.isNeutronBomb //tech.isVacuumBomb
|
||||
return tech.haveGunCheck("grenades") && !tech.isExplodeRadio && !tech.isNeutronBomb && !tech.isVacuumBomb
|
||||
},
|
||||
requires: "grenades, not iridium-192, neutron bomb",
|
||||
requires: "grenades, not iridium-192, neutron bomb, vacuum bomb",
|
||||
effect() {
|
||||
tech.isBlockExplode = true; //chain reaction
|
||||
},
|
||||
@@ -5013,9 +5018,9 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("grenades") && !tech.fragments && !tech.isVacuumBomb && !tech.isExplodeRadio && !tech.isBlockExplode && !tech.isClusterExplode
|
||||
return tech.haveGunCheck("grenades") && !tech.fragments && !tech.isVacuumBomb && !tech.isExplodeRadio && !tech.isBlockExplode && !tech.isClusterExplode && !tech.isPetalsExplode && !tech.isCircleExplode
|
||||
},
|
||||
requires: "grenades, not fragmentation, vacuum bomb, iridium-192, pyrotechnics",
|
||||
requires: "grenades, not fragmentation, vacuum bomb, iridium-192, pyrotechnics, fireworks, flame test",
|
||||
effect() {
|
||||
tech.isNeutronBomb = true;
|
||||
b.setGrenadeMode()
|
||||
@@ -6147,7 +6152,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return (tech.haveGunCheck("laser") || tech.isLaserBotUpgrade || tech.isLaserMine) && tech.laserDamage === 0.18
|
||||
return (tech.haveGunCheck("laser") || tech.isLaserBotUpgrade || tech.isLaserMine) && tech.laserDamage === 0.16
|
||||
},
|
||||
requires: "laser, not free-electron",
|
||||
effect() {
|
||||
@@ -6174,14 +6179,14 @@ const tech = {
|
||||
},
|
||||
requires: "laser, not pulse, diodes",
|
||||
effect() {
|
||||
tech.laserFieldDrain = 0.007 //base is 0.002
|
||||
tech.laserDamage = 0.54; //base is 0.18
|
||||
tech.laserFieldDrain = 0.0063 //base is 0.002
|
||||
tech.laserDamage = 0.48; //base is 0.16
|
||||
tech.laserColor = "#83f"
|
||||
tech.laserColorAlpha = "rgba(136, 51, 255,0.5)"
|
||||
},
|
||||
remove() {
|
||||
tech.laserFieldDrain = 0.002;
|
||||
tech.laserDamage = 0.18; //used in check on pulse and diode: tech.laserDamage === 0.16
|
||||
tech.laserFieldDrain = 0.0018;
|
||||
tech.laserDamage = 0.18; //used in check on pulse and diode: tech.laserDamage === 0.18
|
||||
tech.laserColor = "#f00"
|
||||
tech.laserColorAlpha = "rgba(255, 0, 0, 0.5)"
|
||||
}
|
||||
@@ -6348,7 +6353,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("laser") && tech.laserReflections < 3 && !tech.isWideLaser && tech.laserDamage === 0.18 && !tech.isStuckOn
|
||||
return tech.haveGunCheck("laser") && tech.laserReflections < 3 && !tech.isWideLaser && tech.laserDamage === 0.16 && !tech.isStuckOn
|
||||
},
|
||||
requires: "laser gun, not specular reflection, diffuse, free-electron laser, optical amplifier",
|
||||
effect() {
|
||||
@@ -7837,6 +7842,26 @@ const tech = {
|
||||
// },
|
||||
// remove() {}
|
||||
// },
|
||||
{
|
||||
name: "return",
|
||||
description: "return to the introduction level<br>reduce combat <strong>difficulty</strong> by <strong>2 levels</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 0,
|
||||
isJunk: true,
|
||||
isNonRefundable: true,
|
||||
allowed() {
|
||||
return true
|
||||
},
|
||||
requires: "",
|
||||
effect() {
|
||||
// level.levelsCleared = 0 //increases chance of power ups spawns, so shouldn't reset
|
||||
level.difficultyDecrease(simulation.difficultyMode * 2)
|
||||
level.onLevel = 0
|
||||
simulation.clearNow = true //end current level
|
||||
},
|
||||
remove() {}
|
||||
},
|
||||
{
|
||||
name: "panpsychism",
|
||||
description: "awaken all <strong class='color-block'>blocks</strong><br><strong class='color-block'>blocks</strong> have a chance to spawn power ups",
|
||||
@@ -7907,7 +7932,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "closed timelike curve",
|
||||
description: "spawn 5 <strong class='color-f'>field</strong> power ups, but every 12 seconds<br>teleport a second into your future<br>",
|
||||
description: "spawn 5 <strong class='color-f'>field</strong> power ups, but every 12 seconds<br>teleport a second into your future or past",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 0,
|
||||
@@ -7923,7 +7948,14 @@ const tech = {
|
||||
function loop() {
|
||||
if (!simulation.paused && m.alive) {
|
||||
if (!(simulation.cycle % 720)) {
|
||||
requestAnimationFrame(() => { simulation.timePlayerSkip(60) }); //wrapping in animation frame prevents errors, probably
|
||||
requestAnimationFrame(() => {
|
||||
if ((simulation.cycle % 1440) > 720) { //kinda alternate between each option
|
||||
m.rewind(60)
|
||||
m.energy += 0.4 //to make up for lost energy
|
||||
} else {
|
||||
simulation.timePlayerSkip(60)
|
||||
}
|
||||
}); //wrapping in animation frame prevents errors, probably
|
||||
}
|
||||
}
|
||||
requestAnimationFrame(loop);
|
||||
@@ -9065,7 +9097,10 @@ const tech = {
|
||||
allowed() { return true },
|
||||
requires: "",
|
||||
effect() {
|
||||
setInterval(() => { m.rewind(120) }, 10000);
|
||||
setInterval(() => {
|
||||
m.rewind(120)
|
||||
m.energy += 0.4
|
||||
}, 10000);
|
||||
// for (let i = 0; i < 24; i++) {
|
||||
// setTimeout(() => { m.rewind(120) }, i * 5000);
|
||||
// }
|
||||
@@ -9083,7 +9118,10 @@ const tech = {
|
||||
allowed() { return true },
|
||||
requires: "",
|
||||
effect() {
|
||||
setInterval(() => { m.rewind(30) }, 4000);
|
||||
setInterval(() => {
|
||||
m.rewind(30)
|
||||
m.energy += 0.2
|
||||
}, 4000);
|
||||
},
|
||||
remove() {}
|
||||
},
|
||||
@@ -9674,6 +9712,28 @@ const tech = {
|
||||
},
|
||||
remove() {}
|
||||
},
|
||||
// {
|
||||
// name: "JUNKie", //just crashes the game
|
||||
// description: "all junk",
|
||||
// maxCount: 1,
|
||||
// count: 0,
|
||||
// frequency: 1,
|
||||
// frequencyDefault: 1,
|
||||
// isNonRefundable: true,
|
||||
// isJunk: true,
|
||||
// allowed() { return true },
|
||||
// requires: "",
|
||||
// effect() {
|
||||
|
||||
// for (let i = 0, len = tech.tech.length; i < len; i++) {
|
||||
// if (tech.tech[i].isJunk && tech.tech[i].count < tech.tech[i].maxCount) tech.tech[i].effect()
|
||||
// }
|
||||
|
||||
// },
|
||||
// remove() {
|
||||
// tech.tooManyTechChoices = 0
|
||||
// }
|
||||
// },
|
||||
{
|
||||
name: "path integral",
|
||||
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Path_integral_formulation' class="link">path integral</a>`,
|
||||
|
||||
113
todo.txt
113
todo.txt
@@ -1,45 +1,32 @@
|
||||
******************************************************** NEXT PATCH **************************************************
|
||||
|
||||
boss orbitals and mineBoss mines are destroyed when you deflect them with your field
|
||||
drones, spores and other bullets that target mobs, will not target invulnerable mobs
|
||||
timeSKipBoss is a bit slower with a bit less time skipping
|
||||
fixed color to better match level background colors
|
||||
laser energy drain and damage now scale with fire delay effects
|
||||
no change for pulse since it already has a fire delay
|
||||
|
||||
JUNK tech: path integral - your next tech choice has almost all possible choices
|
||||
explosion harm to player no longer scales with explosion radius
|
||||
explosion damage will treat all explosions the same as a basic grenade explosion
|
||||
large radius explosions are much safer
|
||||
acetone peroxide 80->70% increased radius, 100->50% increase in harm from explosions
|
||||
|
||||
CPT only triggers from damage above 1% per game cycle
|
||||
so no trigger from slime hazards or black holes or mob auras
|
||||
level: reactor has a horizontal flipped mode
|
||||
regression gives finalBoss(1.0005), Boss(1.0025), mob(1.05) increased damage taken
|
||||
|
||||
JUNK tech: return - go back to the intro level, but keep your tech
|
||||
|
||||
bug fixes
|
||||
|
||||
|
||||
*********************************************************** TODO *****************************************************
|
||||
|
||||
timeskip flickers with tech: clock gating, and game pause after large hit
|
||||
probably not related to timeskip, related to graphics effect
|
||||
not a big problem, actually it's kinda neat effect
|
||||
only fix if there is a clear solution
|
||||
|
||||
JUNK tech show 20+ options in tech selection
|
||||
block manufacturing - molecular assembler tech
|
||||
Holding r-click will create a slowly increasing in size block, which will be thrown on release
|
||||
|
||||
bullets that can target the player
|
||||
occurs if no mobs targets around
|
||||
worms? drones? missiles? spores?
|
||||
all of the above?
|
||||
|
||||
BUG time skip probably led to player being able to move, and game not being paused for a few seconds while the death screen faded in
|
||||
also small chance it happened with rewind instead, but unlikely
|
||||
|
||||
block manufacturing - molecular assembler tech
|
||||
Holding r-click will create a slowly increasing in size block, which will be thrown on release
|
||||
|
||||
if a mob dies in skiptime it doesn't register?
|
||||
is this only for the ondeath event?
|
||||
so far, but needs more tests
|
||||
is this only for timeskip > 1
|
||||
yes I think
|
||||
|
||||
make MEE work with harm reduction
|
||||
how to nerf MEE
|
||||
maybe harm reduction could also reduce energy regen
|
||||
|
||||
Currently, the mob just deals higher damage on impact, which is annoying although not hard to compete with nor unique
|
||||
By "redesign" I mean replacing instances of the regular mob, since the same code is used for the tiny red projectiles (I think) just add a new mob and remove the old one from the rotation
|
||||
The new mob should be as such, a "real" exploding mob:
|
||||
@@ -53,11 +40,6 @@ Regular state: red
|
||||
About to explode: animation to dark red
|
||||
Exploding: several shockwaves from the explosion points and tiny trails given to the shrapnel for a second or two until they deaccelerate
|
||||
|
||||
make laser gain damage and energy drain from fire delay tech
|
||||
wording? put it in the gun description
|
||||
|
||||
reactor: add horizontal flip mode
|
||||
|
||||
pause time like invariant for other things...
|
||||
throwing blocks
|
||||
charging railgun
|
||||
@@ -139,32 +121,7 @@ tech: harpoons stick into enemies
|
||||
attaches mob to wall if possible
|
||||
firing while harpoon is stuck into an enemy rips it out of them, inflicting damage and stun and pulling them towards you
|
||||
|
||||
bug: often game puts player position at NaN
|
||||
try:
|
||||
cloaking/harpoon grapple on normal, continue past beating the final boss
|
||||
clues:
|
||||
maybe with vanish or other special blocks and grapple hook
|
||||
very high level for tech, duplication
|
||||
happened once with only 13 tech
|
||||
?&seed=7269&gun0=drones&gun1=matter%20wave&gun2=shotgun&tech0=arsenal&tech1=dead%20reckoning&tech2=regression&tech3=unified%20field%20theory&tech4=rivet%20gun&tech5=phonon&tech6=affine%20connection&field=wormhole&difficulty=2
|
||||
maybe not about JUNK though
|
||||
maybe on tons of bullets
|
||||
maybe grappling hook, Bulk modulus
|
||||
solution: just kill the player if they go NaN
|
||||
vanish elements shouldn't collide with mobs
|
||||
maybe they don't return if mobs are in the way?
|
||||
maybe they kill mobs in the way
|
||||
maybe they should go non-collide with mobs
|
||||
|
||||
bug: harpoon attack gave a mob really high levels of health
|
||||
recent events:
|
||||
had 3 harpoons at a time
|
||||
tech: immune with grappling hook, Bulk modulus
|
||||
cancel true colors with pure science
|
||||
attack with harpoon at slasher mobs
|
||||
they didn't die, but they should in one hit instead they got a huge health bar, then I just died for no reason after touching one
|
||||
|
||||
bug: maybe I can put in an event listener to reset inputs to false when you tab out to prevent key sticking
|
||||
|
||||
enemies stuck with foam receive upward force over time
|
||||
only form aerogel tech?
|
||||
@@ -195,19 +152,6 @@ setting to remove UI, except health bar
|
||||
except active gun? to see ammo
|
||||
checkbox in pause and in settings
|
||||
|
||||
bug - url sharing still broken sometimes
|
||||
|
||||
tech upgrade to anthropic principle to make it trigger at 50% life and 0% once per map
|
||||
|
||||
bug? cloaking field doesn't show energy over max
|
||||
|
||||
run more profiles of n-gon to fix performance issues
|
||||
|
||||
bug: possibly clearing away all bullets causes a problem
|
||||
bullet.js 255 (.do() is missing)
|
||||
I died and quantum immortality triggered (I had needles and ice-IX)
|
||||
game crashed but recovered
|
||||
|
||||
go non-collide with mobs when immune to damage?
|
||||
|
||||
mobs that are invulnerable from the front
|
||||
@@ -325,9 +269,6 @@ electric motors: increases movement speed and jump height, but jumping and movin
|
||||
mob that fires bullets in 4,5,6,7 different directions at once, no aiming
|
||||
grow a bit before it fires to indicate state
|
||||
|
||||
bug once: switching from shotgun to harpoon somehow set b.activeGun to not defined
|
||||
https://discord.com/channels/645222059647172618/646505973610971165/919116288008290324
|
||||
|
||||
quasarBoss: inverted pulsar boss that hits everything except where its aiming
|
||||
|
||||
intro map: diegeticly draw a mouse with field highlighted
|
||||
@@ -349,8 +290,6 @@ mob/boss that fires a laser at player, but give player time to avoid
|
||||
they target where player was 1 second ago
|
||||
they turn to face player?
|
||||
|
||||
bug - death while paused crashes game?
|
||||
|
||||
tech rocket jump - jumping produces an explosion at your feet that lets you jump extra high, but does some damage
|
||||
require electric reactive armor?
|
||||
|
||||
@@ -547,6 +486,28 @@ n-gon outreach ideas
|
||||
|
||||
******************************************************** BUGS ********************************************************
|
||||
|
||||
timeskip flickers with tech: clock gating, and game pause after large hit
|
||||
probably not related to timeskip, related to graphics effect
|
||||
not a big problem, actually it's kinda neat effect
|
||||
only fix if there is a clear solution
|
||||
|
||||
bug: maybe I can put in an event listener to reset inputs to false when you tab out to prevent key sticking
|
||||
|
||||
bug - url sharing still broken sometimes
|
||||
|
||||
tech upgrade to anthropic principle to make it trigger at 50% life and 0% once per map
|
||||
|
||||
bug? cloaking field doesn't show energy over max
|
||||
|
||||
run more profiles of n-gon to fix performance issues
|
||||
|
||||
bug - death while paused crashes game?
|
||||
|
||||
bug: possibly clearing away all bullets causes a problem
|
||||
bullet.js 255 (.do() is missing)
|
||||
I died and quantum immortality triggered (I had needles and ice-IX)
|
||||
game crashed but recovered
|
||||
|
||||
vanish element bug, crashes on touching element, happens for 1 person maybe with junk tech?
|
||||
|
||||
safari issues
|
||||
|
||||
Reference in New Issue
Block a user