timeSkip
new reactor boss: timeBoss - after taking some damage it speeds up the passage of time reactor level has big doors nonrefundable tech show up in the pause menu time dilation field - move, jump, and fire 25% faster JUNK tech: closed timelike curve - spawn 5 field power ups, but every 12 seconds teleport a second into your future
This commit is contained in:
@@ -271,7 +271,7 @@ const b = {
|
|||||||
},
|
},
|
||||||
fireCDscale: 1,
|
fireCDscale: 1,
|
||||||
setFireCD() {
|
setFireCD() {
|
||||||
b.fireCDscale = tech.fireRate * tech.slowFire * tech.researchHaste * tech.aimDamage
|
b.fireCDscale = tech.fireRate * tech.slowFire * tech.researchHaste * tech.aimDamage * m.fieldFireRate
|
||||||
if (tech.isFastTime) b.fireCDscale *= 0.5
|
if (tech.isFastTime) b.fireCDscale *= 0.5
|
||||||
if (tech.isFireRateForGuns) b.fireCDscale *= Math.pow(0.8, b.inventory.length)
|
if (tech.isFireRateForGuns) b.fireCDscale *= Math.pow(0.8, b.inventory.length)
|
||||||
if (tech.isFireMoveLock) b.fireCDscale *= 0.5
|
if (tech.isFireMoveLock) b.fireCDscale *= 0.5
|
||||||
|
|||||||
@@ -275,9 +275,11 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>": ""}
|
|||||||
|
|
||||||
const style = (tech.isPauseEjectTech && !simulation.isChoosing) ? 'style="animation: techColorCycle 1s linear infinite alternate;"' : ''
|
const style = (tech.isPauseEjectTech && !simulation.isChoosing) ? 'style="animation: techColorCycle 1s linear infinite alternate;"' : ''
|
||||||
for (let i = 0, len = tech.tech.length; i < len; i++) {
|
for (let i = 0, len = tech.tech.length; i < len; i++) {
|
||||||
if (tech.tech[i].count > 0 && !tech.tech[i].isNonRefundable) {
|
if (tech.tech[i].count > 0) {
|
||||||
const techCountText = tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : "";
|
const techCountText = tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : "";
|
||||||
if (tech.tech[i].isFieldTech) {
|
if (tech.tech[i].isNonRefundable) {
|
||||||
|
text += `<div class="pause-grid-module" id ="${i}-pause-tech" onclick="powerUps.pauseEjectTech(${i})" style = "border: 0px; opacity:0.5; font-size: 60%; line-height: 130%; padding-top: 6px; padding-bottom: 6px;"><div class="grid-title">${tech.tech[i].link} ${techCountText}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div></div>`
|
||||||
|
} else if (tech.tech[i].isFieldTech) {
|
||||||
text += `<div class="pause-grid-module" id ="${i}-pause-tech" onclick="powerUps.pauseEjectTech(${i})" ${style}><div class="grid-title">
|
text += `<div class="pause-grid-module" id ="${i}-pause-tech" onclick="powerUps.pauseEjectTech(${i})" ${style}><div class="grid-title">
|
||||||
<span style="position:relative;">
|
<span style="position:relative;">
|
||||||
<div class="circle-grid tech" style="position:absolute; top:0; left:0;opacity:0.8;"></div>
|
<div class="circle-grid tech" style="position:absolute; top:0; left:0;opacity:0.8;"></div>
|
||||||
|
|||||||
129
js/level.js
129
js/level.js
@@ -16,12 +16,13 @@ const level = {
|
|||||||
start() {
|
start() {
|
||||||
if (level.levelsCleared === 0) { //this code only runs on the first level
|
if (level.levelsCleared === 0) { //this code only runs on the first level
|
||||||
// // simulation.isHorizontalFlipped = true
|
// // simulation.isHorizontalFlipped = true
|
||||||
// m.setField("wormhole")
|
// m.addHealth(Infinity)
|
||||||
// b.giveGuns("matter wave")
|
// m.setField("standing wave")
|
||||||
// tech.giveTech("chain reaction")
|
// b.giveGuns("nail gun")
|
||||||
// tech.giveTech("fireworks")
|
// tech.giveTech("closed timelike curve")
|
||||||
// tech.giveTech("flame test")
|
// tech.giveTech("irradiated nails")
|
||||||
// tech.giveTech("pyrotechnics")
|
// tech.giveTech("pneumatic actuator")
|
||||||
|
// tech.giveTech("6s half-life")
|
||||||
// for (let i = 0; i < 10; i++) tech.giveTech("replication")
|
// for (let i = 0; i < 10; i++) tech.giveTech("replication")
|
||||||
// tech.giveTech("eternalism")
|
// tech.giveTech("eternalism")
|
||||||
// for (let i = 0; i < 10; i++) tech.giveTech("ammonium nitrate")
|
// for (let i = 0; i < 10; i++) tech.giveTech("ammonium nitrate")
|
||||||
@@ -30,18 +31,13 @@ const level = {
|
|||||||
// for (let i = 0; i < 15; i++) tech.giveTech()
|
// for (let i = 0; i < 15; i++) tech.giveTech()
|
||||||
// for (let i = 10; i < tech.tech.length; i++) { tech.tech[i].isBanished = true }
|
// for (let i = 10; i < tech.tech.length; i++) { tech.tech[i].isBanished = true }
|
||||||
// powerUps.research.changeRerolls(100000)
|
// powerUps.research.changeRerolls(100000)
|
||||||
// for (let i = 0; i < 5; i++) tech.giveTech("corona discharge")
|
|
||||||
// tech.tech[297].frequency = 100
|
// tech.tech[297].frequency = 100
|
||||||
// m.setField("plasma torch")
|
|
||||||
// tech.giveTech("plasma ball")
|
|
||||||
// tech.giveTech("extruder")
|
|
||||||
|
|
||||||
// m.immuneCycle = Infinity //you can't take damage
|
// m.immuneCycle = Infinity //you can't take damage
|
||||||
// level.difficultyIncrease(15) //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
|
||||||
// simulation.enableConstructMode() //used to build maps in testing mode
|
// simulation.enableConstructMode() //used to build maps in testing mode
|
||||||
// level.temple();
|
// level.testing();
|
||||||
// level.testing(); //not in rotation, used for testing
|
// level.reactor(); //not in rotation, used for testing
|
||||||
// spawn.slashBoss(1900, -500)
|
// spawn.timeBoss(1900, -500)
|
||||||
|
|
||||||
if (simulation.isTraining) { level.walk(); } else { level.intro(); } //normal starting level ************************************************
|
if (simulation.isTraining) { level.walk(); } else { level.intro(); } //normal starting level ************************************************
|
||||||
// powerUps.research.changeRerolls(3000)
|
// powerUps.research.changeRerolls(3000)
|
||||||
@@ -1054,6 +1050,9 @@ const level = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
isClosed() {
|
||||||
|
return this.position.y > y - 1
|
||||||
|
},
|
||||||
draw() {
|
draw() {
|
||||||
ctx.fillStyle = "#555"
|
ctx.fillStyle = "#555"
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
@@ -2596,7 +2595,11 @@ const level = {
|
|||||||
testing() {
|
testing() {
|
||||||
const button = level.button(1000, 0)
|
const button = level.button(1000, 0)
|
||||||
spawn.bodyRect(1000, -50, 50, 50);
|
spawn.bodyRect(1000, -50, 50, 50);
|
||||||
|
|
||||||
level.custom = () => {
|
level.custom = () => {
|
||||||
|
ctx.fillStyle = "#d4d4d4"
|
||||||
|
ctx.fillRect(2500, -475, 200, 300)
|
||||||
|
|
||||||
ctx.fillStyle = "rgba(0,255,255,0.1)";
|
ctx.fillStyle = "rgba(0,255,255,0.1)";
|
||||||
ctx.fillRect(6400, -550, 300, 350);
|
ctx.fillRect(6400, -550, 300, 350);
|
||||||
level.exit.drawAndCheck();
|
level.exit.drawAndCheck();
|
||||||
@@ -2605,6 +2608,8 @@ const level = {
|
|||||||
level.customTopLayer = () => {
|
level.customTopLayer = () => {
|
||||||
button.query();
|
button.query();
|
||||||
button.draw();
|
button.draw();
|
||||||
|
ctx.fillStyle = "rgba(0,0,0,0.1)"
|
||||||
|
ctx.fillRect(-150, -650, 900, 250)
|
||||||
};
|
};
|
||||||
level.setPosToSpawn(0, -450); //normal spawn
|
level.setPosToSpawn(0, -450); //normal spawn
|
||||||
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
|
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
|
||||||
@@ -2686,10 +2691,10 @@ const level = {
|
|||||||
// spawn.randomMob(1600, -500)
|
// spawn.randomMob(1600, -500)
|
||||||
},
|
},
|
||||||
reactor() {
|
reactor() {
|
||||||
level.setPosToSpawn(-50, -800); //normal spawn
|
level.setPosToSpawn(-550, -800); //normal spawn
|
||||||
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
|
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
|
||||||
level.exit.x = 3000;
|
level.exit.x = 3500;
|
||||||
level.exit.y = -35;
|
level.exit.y = -42;
|
||||||
spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 25);
|
spawn.mapRect(level.exit.x, level.exit.y + 25, 100, 25);
|
||||||
level.defaultZoom = 2000
|
level.defaultZoom = 2000
|
||||||
simulation.zoomTransition(level.defaultZoom)
|
simulation.zoomTransition(level.defaultZoom)
|
||||||
@@ -2699,25 +2704,26 @@ const level = {
|
|||||||
// spawn.debris(750, -2200, 3700, 16); //16 debris per level
|
// spawn.debris(750, -2200, 3700, 16); //16 debris per level
|
||||||
const button = level.button(1400, 0)
|
const button = level.button(1400, 0)
|
||||||
button.isUp = true
|
button.isUp = true
|
||||||
spawn.mapRect(-1525, -2825, 1250, 4925);
|
|
||||||
spawn.mapRect(-400, -2025, 625, 925);
|
|
||||||
spawn.mapRect(-400, -750, 625, 1200);
|
|
||||||
spawn.bodyRect(250, -70, 100, 70, 1);
|
spawn.bodyRect(250, -70, 100, 70, 1);
|
||||||
spawn.mapRect(-425, 0, 4200, 2100);
|
spawn.mapRect(-425, 0, 4500, 2100);
|
||||||
spawn.mapRect(175, -1250, 50, 300);
|
spawn.mapRect(-475, -2825, 4500, 1025);
|
||||||
spawn.mapRect(-475, -2825, 4250, 1025);
|
|
||||||
// spawn.mapRect(1200, -1300, 600, 800);
|
// spawn.mapRect(1200, -1300, 600, 800);
|
||||||
const a = 400 //side length
|
const a = 400 //side length
|
||||||
const c = 100 //corner offset
|
const c = 100 //corner offset
|
||||||
spawn.mapVertex(1487, -900, `${-a} ${-a+c} ${-a+c} ${-a} ${a-c} ${-a} ${a} ${-a+c} ${a} ${a-c} ${a-c} ${a} ${-a+c} ${a} ${-a} ${a-c}`); //square with edges cut off
|
spawn.mapVertex(1487, -900, `${-a} ${-a+c} ${-a+c} ${-a} ${a-c} ${-a} ${a} ${-a+c} ${a} ${a-c} ${a-c} ${a} ${-a+c} ${a} ${-a} ${a-c}`); //square with edges cut off
|
||||||
|
//entrance
|
||||||
|
spawn.mapRect(-2025, -2825, 1250, 4925);
|
||||||
|
spawn.mapRect(-900, -2825, 1125, 1725);
|
||||||
|
spawn.mapRect(-900, -750, 1125, 2850);
|
||||||
|
spawn.mapRect(-325, -1250, 550, 300);
|
||||||
//exit
|
//exit
|
||||||
spawn.mapRect(3300, -2825, 1125, 4925);
|
spawn.mapRect(3800, -2825, 1225, 4925);
|
||||||
spawn.mapRect(2750, -2150, 1025, 1775);
|
spawn.mapRect(2750, -2150, 1325, 1775);
|
||||||
spawn.mapRect(2750, -475, 50, 300);
|
spawn.mapRect(2750, -475, 550, 300);
|
||||||
|
spawn.mapRect(2750, -7, 1050, 150); //exit room floor
|
||||||
|
|
||||||
const doorIn = level.door(187, -950, 25, 200, 190, 2) //x, y, width, height, distance, speed = 1
|
const doorIn = level.door(-313, -950, 525, 200, 190, 2) //x, y, width, height, distance, speed = 1
|
||||||
const doorOut = level.door(2762, -175, 25, 200, 190, 2) //x, y, width, height, distance, speed = 1
|
const doorOut = level.door(2762, -175, 525, 200, 190, 2) //x, y, width, height, distance, speed = 1
|
||||||
// doorOut.isClosing = true
|
// doorOut.isClosing = true
|
||||||
let isDoorsLocked = false
|
let isDoorsLocked = false
|
||||||
let isFightOver = false
|
let isFightOver = false
|
||||||
@@ -2725,7 +2731,7 @@ const level = {
|
|||||||
|
|
||||||
level.custom = () => {
|
level.custom = () => {
|
||||||
if (isDoorsLocked) {
|
if (isDoorsLocked) {
|
||||||
if (player.position.x < 0) { //if player gets trapped inside starting room open up again
|
if (player.position.x < -300) { //if player gets trapped inside starting room open up again
|
||||||
isDoorsLocked = false
|
isDoorsLocked = false
|
||||||
doorIn.isClosing = false
|
doorIn.isClosing = false
|
||||||
}
|
}
|
||||||
@@ -2738,35 +2744,45 @@ const level = {
|
|||||||
doorIn.openClose();
|
doorIn.openClose();
|
||||||
doorOut.openClose();
|
doorOut.openClose();
|
||||||
ctx.fillStyle = "#d5ebef"
|
ctx.fillStyle = "#d5ebef"
|
||||||
ctx.fillRect(2750, -375, 550, 375)
|
ctx.fillRect(2750, -375, 1050, 375)
|
||||||
level.enter.draw();
|
level.enter.draw();
|
||||||
level.exit.drawAndCheck();
|
level.exit.drawAndCheck();
|
||||||
button.draw();
|
button.draw();
|
||||||
if (button.isUp) {
|
if (button.isUp) {
|
||||||
button.query();
|
button.query();
|
||||||
} else if (!isSpawnedBoss) {
|
} else if (!isSpawnedBoss) {
|
||||||
isSpawnedBoss = true
|
if (player.position.x > 0) {
|
||||||
isDoorsLocked = true
|
if (!doorOut.isClosed() || !doorIn.isClosed()) {
|
||||||
doorIn.isClosing = true
|
doorIn.isClosing = true
|
||||||
doorOut.isClosing = true
|
doorOut.isClosing = 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 > 22) {
|
|
||||||
for (let i = 0, len = scale * 0.1 / 3; i < len; ++i) spawn.bounceBoss(1487 + 200 * i, -1525, 80, false);
|
|
||||||
for (let i = 0, len = scale * 0.17 / 3; i < len; ++i) spawn.sprayBoss(1487 + 200 * i, -1525, 30, false)
|
|
||||||
for (let i = 0, len = scale * 0.23 / 3; i < len; ++i) spawn.mineBoss(1487 + 200 * i, -1525, 50, false);
|
|
||||||
} 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 {
|
} 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
|
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
|
||||||
}
|
}
|
||||||
spawn.secondaryBossChance(2200, -800)
|
} else if (!isFightOver && !(simulation.cycle % 180)) {
|
||||||
} else if (!isFightOver && !(simulation.cycle % 120)) { //once a second look for any bosses
|
|
||||||
let isFoundBoss = false
|
let isFoundBoss = false
|
||||||
for (let i = 0; i < mob.length; i++) {
|
for (let i = 0; i < mob.length; i++) {
|
||||||
if (mob[i].isBoss) {
|
if (mob[i].isBoss) {
|
||||||
@@ -2778,8 +2794,9 @@ const level = {
|
|||||||
isFightOver = true
|
isFightOver = true
|
||||||
doorIn.isClosing = false
|
doorIn.isClosing = false
|
||||||
doorOut.isClosing = false
|
doorOut.isClosing = false
|
||||||
powerUps.spawnBossPowerUp(2900, -100)
|
powerUps.spawnBossPowerUp(3600, -100)
|
||||||
powerUps.spawn(3050, -200, "tech")
|
powerUps.spawn(3650, -200, "tech")
|
||||||
|
// if (player.position.x < 2760 && player.position.x > 210) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -2790,8 +2807,8 @@ const level = {
|
|||||||
// }
|
// }
|
||||||
doorIn.draw();
|
doorIn.draw();
|
||||||
doorOut.draw();
|
doorOut.draw();
|
||||||
ctx.fillStyle = "rgba(0,0,0,0.05)"
|
ctx.fillStyle = "rgba(0,0,0,0.1)"
|
||||||
ctx.fillRect(-275, -1100, 500, 350);
|
ctx.fillRect(-775, -1100, 1000, 350);
|
||||||
// ctx.fillStyle = "rgba(0,255,255,0.1)"
|
// ctx.fillStyle = "rgba(0,255,255,0.1)"
|
||||||
// ctx.fillRect(2750, -375, 550, 375)
|
// ctx.fillRect(2750, -375, 550, 375)
|
||||||
};
|
};
|
||||||
@@ -4082,7 +4099,7 @@ const level = {
|
|||||||
spawn.randomMob(3600, 1725, 0.9);
|
spawn.randomMob(3600, 1725, 0.9);
|
||||||
spawn.randomMob(4100, 1225, 0.9);
|
spawn.randomMob(4100, 1225, 0.9);
|
||||||
spawn.randomMob(2825, 400, 0.9);
|
spawn.randomMob(2825, 400, 0.9);
|
||||||
if (simulation.difficulty > 1) spawn.randomLevelBoss(6000, 2300, ["spiderBoss", "launcherBoss", "laserTargetingBoss", "streamBoss", "historyBoss", "orbitalBoss", "grenadierBoss"]);
|
if (simulation.difficulty > 1) spawn.randomLevelBoss(6000, 2300, ["spiderBoss", "launcherBoss", "laserTargetingBoss", "blinkBoss", "streamBoss", "historyBoss", "orbitalBoss", "grenadierBoss", "blockBoss", "revolutionBoss", "slashBoss"]);
|
||||||
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||||
spawn.secondaryBossChance(7725, 2275)
|
spawn.secondaryBossChance(7725, 2275)
|
||||||
|
|
||||||
|
|||||||
117
js/player.js
117
js/player.js
@@ -77,8 +77,8 @@ const m = {
|
|||||||
setMovement() {
|
setMovement() {
|
||||||
// m.Fx = 0.08 / mass * tech.squirrelFx
|
// m.Fx = 0.08 / mass * tech.squirrelFx
|
||||||
// m.FxAir = 0.4 / mass / mass
|
// m.FxAir = 0.4 / mass / mass
|
||||||
m.Fx = tech.baseFx * tech.squirrelFx * (tech.isFastTime ? 1.5 : 1) / player.mass //base player mass is 5
|
m.Fx = tech.baseFx * m.fieldFx * tech.squirrelFx * (tech.isFastTime ? 1.5 : 1) / player.mass //base player mass is 5
|
||||||
m.jumpForce = tech.baseJumpForce * tech.squirrelJump * (tech.isFastTime ? 1.13 : 1) / player.mass / player.mass //base player mass is 5
|
m.jumpForce = tech.baseJumpForce * m.fieldJump * tech.squirrelJump * (tech.isFastTime ? 1.13 : 1) / player.mass / player.mass //base player mass is 5
|
||||||
},
|
},
|
||||||
FxAir: 0.016, // 0.4/5/5 run Force in Air
|
FxAir: 0.016, // 0.4/5/5 run Force in Air
|
||||||
yOff: 70,
|
yOff: 70,
|
||||||
@@ -893,6 +893,9 @@ const m = {
|
|||||||
holdingTarget: null,
|
holdingTarget: null,
|
||||||
timeSkipLastCycle: 0,
|
timeSkipLastCycle: 0,
|
||||||
// these values are set on reset by setHoldDefaults()
|
// these values are set on reset by setHoldDefaults()
|
||||||
|
fieldFx: 1,
|
||||||
|
fieldJump: 1,
|
||||||
|
fieldFireRate: 1,
|
||||||
blockingRecoil: 4,
|
blockingRecoil: 4,
|
||||||
grabPowerUpRange2: 0,
|
grabPowerUpRange2: 0,
|
||||||
isFieldActive: false,
|
isFieldActive: false,
|
||||||
@@ -951,6 +954,11 @@ const m = {
|
|||||||
m.isCloak = false;
|
m.isCloak = false;
|
||||||
player.collisionFilter.mask = cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield
|
player.collisionFilter.mask = cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield
|
||||||
m.airSpeedLimit = 125
|
m.airSpeedLimit = 125
|
||||||
|
m.fieldFireRate = 1
|
||||||
|
b.setFireCD();
|
||||||
|
m.fieldFx = 1
|
||||||
|
m.fieldJump = 1
|
||||||
|
m.setMovement();
|
||||||
m.drop();
|
m.drop();
|
||||||
m.holdingMassScale = 0.5;
|
m.holdingMassScale = 0.5;
|
||||||
m.fieldArc = 0.2; //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
|
m.fieldArc = 0.2; //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob)
|
||||||
@@ -1045,10 +1053,6 @@ const m = {
|
|||||||
m.holdingTarget = null;
|
m.holdingTarget = null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// setMovement() {
|
|
||||||
// m.Fx = tech.baseFx * tech.squirrelFx * (tech.isFastTime ? 1.5 : 1);
|
|
||||||
// m.jumpForce = tech.baseJumpForce * tech.squirrelJump * (tech.isFastTime ? 1.13 : 1)
|
|
||||||
// },
|
|
||||||
definePlayerMass(mass = m.defaultMass) {
|
definePlayerMass(mass = m.defaultMass) {
|
||||||
Matter.Body.setMass(player, mass);
|
Matter.Body.setMass(player, mass);
|
||||||
//reduce air and ground move forces
|
//reduce air and ground move forces
|
||||||
@@ -2514,8 +2518,13 @@ const m = {
|
|||||||
{
|
{
|
||||||
name: "time dilation",
|
name: "time dilation",
|
||||||
// description: "use <strong class='color-f'>energy</strong> to <strong style='letter-spacing: 1px;'>stop time</strong><br>while time is stopped you can <strong>move</strong> and <strong>fire</strong><br>and <strong>collisions</strong> do <strong>50%</strong> less <strong class='color-harm'>harm</strong>",
|
// description: "use <strong class='color-f'>energy</strong> to <strong style='letter-spacing: 1px;'>stop time</strong><br>while time is stopped you can <strong>move</strong> and <strong>fire</strong><br>and <strong>collisions</strong> do <strong>50%</strong> less <strong class='color-harm'>harm</strong>",
|
||||||
description: "use <strong class='color-f'>energy</strong> to <strong style='letter-spacing: 2px;'>stop time</strong><br>for everything except you<br>generate <strong>18</strong> <strong class='color-f'>energy</strong>/second",
|
description: "use <strong class='color-f'>energy</strong> to <strong style='letter-spacing: 2px;'>stop time</strong><br>move, jump, and fire <strong>25%</strong> faster<br>generate <strong>18</strong> <strong class='color-f'>energy</strong>/second",
|
||||||
set() {
|
set() {
|
||||||
|
m.fieldFireRate = 0.75
|
||||||
|
b.setFireCD();
|
||||||
|
m.fieldFx = 1.2
|
||||||
|
m.fieldJump = 1.09
|
||||||
|
m.setMovement();
|
||||||
if (tech.isRewindField) {
|
if (tech.isRewindField) {
|
||||||
this.rewindCount = 0
|
this.rewindCount = 0
|
||||||
m.grabPowerUpRange2 = 300000
|
m.grabPowerUpRange2 = 300000
|
||||||
@@ -2643,26 +2652,6 @@ const m = {
|
|||||||
sleep(bullet);
|
sleep(bullet);
|
||||||
|
|
||||||
simulation.cycle--; //pause all functions that depend on game cycle increasing
|
simulation.cycle--; //pause all functions that depend on game cycle increasing
|
||||||
// if (tech.isTimeSkip) {
|
|
||||||
// m.immuneCycle = 0;
|
|
||||||
// m.drain += 0.0000025
|
|
||||||
// m.regenEnergy(); //immunity disables normal regen, so turn off immunity for just this function
|
|
||||||
// m.immuneCycle = m.cycle + 10;
|
|
||||||
// simulation.isTimeSkipping = true;
|
|
||||||
// m.cycle++;
|
|
||||||
// simulation.gravity();
|
|
||||||
// if (tech.isFireMoveLock && input.fire) {
|
|
||||||
// player.force.x = 0
|
|
||||||
// player.force.y = 0
|
|
||||||
// }
|
|
||||||
// Engine.update(engine, simulation.delta);
|
|
||||||
// m.move();
|
|
||||||
// simulation.checks();
|
|
||||||
// m.walk_cycle += m.flipLegs * m.Vx;
|
|
||||||
// b.fire();
|
|
||||||
// b.bulletDo();
|
|
||||||
// simulation.isTimeSkipping = false;
|
|
||||||
// }
|
|
||||||
} else { //holding, but field button is released
|
} else { //holding, but field button is released
|
||||||
m.wakeCheck();
|
m.wakeCheck();
|
||||||
}
|
}
|
||||||
@@ -2678,80 +2667,6 @@ const m = {
|
|||||||
m.drawFieldMeter()
|
m.drawFieldMeter()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// } else {
|
|
||||||
// m.fieldFire = true;
|
|
||||||
// m.isBodiesAsleep = false;
|
|
||||||
// m.isTimeStopped = false;
|
|
||||||
// m.drain = 0.005
|
|
||||||
// let isFieldInputDown = false;
|
|
||||||
// m.hold = function() {
|
|
||||||
// if (m.isHolding) {
|
|
||||||
// m.drawHold(m.holdingTarget);
|
|
||||||
// m.holding();
|
|
||||||
// m.throwBlock();
|
|
||||||
// isFieldInputDown = false
|
|
||||||
// } else if (input.field && m.fieldCDcycle < m.cycle) { //not hold but field button is pressed
|
|
||||||
// if (!m.holdingTarget) isFieldInputDown = true;
|
|
||||||
// m.grabPowerUp();
|
|
||||||
// m.lookForPickUp();
|
|
||||||
// // if (m.energy > 0.05) { //deflecting
|
|
||||||
// // m.drawField();
|
|
||||||
// // m.pushMobsFacing();
|
|
||||||
// // }
|
|
||||||
// } else if (m.holdingTarget && m.fieldCDcycle < m.cycle) { //holding, but field button is released
|
|
||||||
// m.pickUp();
|
|
||||||
// } else {
|
|
||||||
// m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (isFieldInputDown && !input.field && !m.holdingTarget && !m.isHolding) {
|
|
||||||
// isFieldInputDown = false;
|
|
||||||
// m.isTimeStopped = true;
|
|
||||||
// }
|
|
||||||
// m.drawFieldMeter()
|
|
||||||
// if (m.energy < m.maxEnergy) { //extra energy regen
|
|
||||||
// m.regenEnergy();
|
|
||||||
// m.regenEnergy();
|
|
||||||
// }
|
|
||||||
// if (m.isTimeStopped) {
|
|
||||||
// if (m.energy > m.drain) {
|
|
||||||
// // if (player.speed > 0.01 || input.fire)
|
|
||||||
// m.energy -= m.drain;
|
|
||||||
// m.immuneCycle = m.cycle + 10; //immune to harm while time is stopped, this also disables regen
|
|
||||||
// simulation.cycle--; //pause all functions that depend on game cycle increasing
|
|
||||||
// m.isBodiesAsleep = true;
|
|
||||||
// ctx.globalCompositeOperation = "saturation" //draw field everywhere
|
|
||||||
// ctx.fillStyle = "#ccc";
|
|
||||||
// ctx.fillRect(-100000, -100000, 200000, 200000)
|
|
||||||
// ctx.globalCompositeOperation = "source-over"
|
|
||||||
|
|
||||||
// function sleep(who) {
|
|
||||||
// for (let i = 0, len = who.length; i < len; ++i) {
|
|
||||||
// if (!who[i].isSleeping) {
|
|
||||||
// who[i].storeVelocity = who[i].velocity
|
|
||||||
// who[i].storeAngularVelocity = who[i].angularVelocity
|
|
||||||
// }
|
|
||||||
// Matter.Sleeping.set(who[i], true)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// sleep(mob);
|
|
||||||
// sleep(body);
|
|
||||||
// sleep(bullet);
|
|
||||||
// } else { //restart time
|
|
||||||
// m.fieldCDcycle = m.cycle + 60;
|
|
||||||
// m.energy = 0;
|
|
||||||
// m.isTimeStopped = false
|
|
||||||
// m.wakeCheck();
|
|
||||||
// }
|
|
||||||
// if (simulation.isChoosing) {
|
|
||||||
// // m.fieldCDcycle = m.cycle + 60;
|
|
||||||
// m.isTimeStopped = false
|
|
||||||
// m.wakeCheck();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
},
|
},
|
||||||
effect() {
|
effect() {
|
||||||
this.set();
|
this.set();
|
||||||
|
|||||||
@@ -280,13 +280,11 @@ const powerUps = {
|
|||||||
if (!simulation.paused) {
|
if (!simulation.paused) {
|
||||||
if (tech.isNoDraftPause) {
|
if (tech.isNoDraftPause) {
|
||||||
|
|
||||||
const cycle = () => {
|
// const cycle = () => {
|
||||||
m.fireCDcycle = m.cycle + 5; //fire cooldown
|
// m.fireCDcycle = m.cycle + 1; //fire cooldown
|
||||||
if (simulation.isChoosing && m.alive) requestAnimationFrame(cycle)
|
// if (simulation.isChoosing && m.alive) requestAnimationFrame(cycle)
|
||||||
}
|
// }
|
||||||
|
// requestAnimationFrame(cycle);
|
||||||
requestAnimationFrame(cycle);
|
|
||||||
|
|
||||||
|
|
||||||
document.getElementById("choose-grid").style.opacity = "0.8"
|
document.getElementById("choose-grid").style.opacity = "0.8"
|
||||||
} else {
|
} else {
|
||||||
@@ -1081,7 +1079,7 @@ const powerUps = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
pauseEjectTech(index) {
|
pauseEjectTech(index) {
|
||||||
if ((tech.isPauseEjectTech || simulation.testing) && !simulation.isChoosing) {
|
if ((tech.isPauseEjectTech || simulation.testing) && !simulation.isChoosing && !tech.tech[index].isNonRefundable) {
|
||||||
if (Math.random() < 0.1 || tech.tech[index].isFromAppliedScience || (tech.tech[index].bonusResearch !== undefined && tech.tech[index].bonusResearch > powerUps.research.count)) {
|
if (Math.random() < 0.1 || tech.tech[index].isFromAppliedScience || (tech.tech[index].bonusResearch !== undefined && tech.tech[index].bonusResearch > powerUps.research.count)) {
|
||||||
tech.removeTech(index)
|
tech.removeTech(index)
|
||||||
powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false);
|
powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false);
|
||||||
|
|||||||
@@ -89,18 +89,35 @@ const simulation = {
|
|||||||
m.airControl()
|
m.airControl()
|
||||||
}
|
}
|
||||||
m.move();
|
m.move();
|
||||||
|
level.custom();
|
||||||
simulation.checks();
|
simulation.checks();
|
||||||
mobs.loop();
|
mobs.loop();
|
||||||
// m.draw();
|
|
||||||
m.walk_cycle += m.flipLegs * m.Vx;
|
m.walk_cycle += m.flipLegs * m.Vx;
|
||||||
|
|
||||||
m.hold();
|
m.hold();
|
||||||
|
level.customTopLayer();
|
||||||
b.fire();
|
b.fire();
|
||||||
b.bulletRemove();
|
b.bulletRemove();
|
||||||
b.bulletDo();
|
b.bulletDo();
|
||||||
}
|
}
|
||||||
simulation.isTimeSkipping = false;
|
simulation.isTimeSkipping = false;
|
||||||
},
|
},
|
||||||
|
timePlayerSkip(cycles = 60) {
|
||||||
|
simulation.isTimeSkipping = true;
|
||||||
|
for (let i = 0; i < cycles; i++) {
|
||||||
|
simulation.cycle++;
|
||||||
|
simulation.gravity();
|
||||||
|
Engine.update(engine, simulation.delta);
|
||||||
|
// level.custom();
|
||||||
|
// level.customTopLayer();
|
||||||
|
if (!m.isBodiesAsleep) {
|
||||||
|
simulation.checks();
|
||||||
|
mobs.loop();
|
||||||
|
}
|
||||||
|
b.bulletRemove();
|
||||||
|
if (!m.isBodiesAsleep) b.bulletDo();
|
||||||
|
}
|
||||||
|
simulation.isTimeSkipping = false;
|
||||||
|
},
|
||||||
mouse: {
|
mouse: {
|
||||||
x: canvas.width / 2,
|
x: canvas.width / 2,
|
||||||
y: canvas.height / 2
|
y: canvas.height / 2
|
||||||
|
|||||||
359
js/spawn.js
359
js/spawn.js
@@ -1,6 +1,6 @@
|
|||||||
//main object for spawning things in a level
|
//main object for spawning things in a level
|
||||||
const spawn = {
|
const spawn = {
|
||||||
nonCollideBossList: ["cellBossCulture", "bomberBoss", "powerUpBoss", "orbitalBoss", "spawnerBossCulture", "growBossCulture"],
|
nonCollideBossList: ["cellBossCulture", "bomberBoss", "powerUpBoss", "growBossCulture"],
|
||||||
// other bosses: suckerBoss, laserBoss, tetherBoss, mantisBoss, bounceBoss, sprayBoss //these need a particular level to work so they are not included in the random pool
|
// other bosses: suckerBoss, laserBoss, tetherBoss, mantisBoss, bounceBoss, sprayBoss //these need a particular level to work so they are not included in the random pool
|
||||||
randomBossList: ["shieldingBoss", "orbitalBoss", "historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss",
|
randomBossList: ["shieldingBoss", "orbitalBoss", "historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss",
|
||||||
"powerUpBoss", "powerUpBossBaby", "snakeBoss", "streamBoss", "pulsarBoss", "spawnerBossCulture", "grenadierBoss", "growBossCulture", "blinkBoss",
|
"powerUpBoss", "powerUpBossBaby", "snakeBoss", "streamBoss", "pulsarBoss", "spawnerBossCulture", "grenadierBoss", "growBossCulture", "blinkBoss",
|
||||||
@@ -1031,7 +1031,7 @@ const spawn = {
|
|||||||
|
|
||||||
me.isSpawnBoss = true;
|
me.isSpawnBoss = true;
|
||||||
me.spawnID = spawnID
|
me.spawnID = spawnID
|
||||||
me.accelMag = 0.00018 * simulation.accelScale;
|
me.accelMag = 0.00022 * simulation.accelScale;
|
||||||
me.memory = Infinity;
|
me.memory = Infinity;
|
||||||
me.showHealthBar = false;
|
me.showHealthBar = false;
|
||||||
me.isVerticesChange = true
|
me.isVerticesChange = true
|
||||||
@@ -1039,7 +1039,7 @@ const spawn = {
|
|||||||
me.seePlayerFreq = Math.floor(14 + 7 * Math.random())
|
me.seePlayerFreq = Math.floor(14 + 7 * Math.random())
|
||||||
me.seeAtDistance2 = 200000 //1400000;
|
me.seeAtDistance2 = 200000 //1400000;
|
||||||
me.stroke = "transparent"
|
me.stroke = "transparent"
|
||||||
me.collisionFilter.mask = cat.player | cat.bullet //| cat.body //| cat.map //"rgba(255,60,0,0.3)"
|
me.collisionFilter.mask = cat.player | cat.bullet | cat.body | cat.map //"rgba(255,60,0,0.3)"
|
||||||
// Matter.Body.setDensity(me, 0.0014) // normal density is 0.001
|
// Matter.Body.setDensity(me, 0.0014) // normal density is 0.001
|
||||||
Matter.Body.setAngularVelocity(me, 0.12 * (Math.random() - 0.5))
|
Matter.Body.setAngularVelocity(me, 0.12 * (Math.random() - 0.5))
|
||||||
// spawn.shield(me, x, y, 1);
|
// spawn.shield(me, x, y, 1);
|
||||||
@@ -1047,7 +1047,7 @@ const spawn = {
|
|||||||
me.onHit = function() { //run this function on hitting player
|
me.onHit = function() { //run this function on hitting player
|
||||||
this.explode();
|
this.explode();
|
||||||
};
|
};
|
||||||
me.damageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1);
|
me.damageReduction = 0.14 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1);
|
||||||
me.doAwake = function() {
|
me.doAwake = function() {
|
||||||
this.alwaysSeePlayer();
|
this.alwaysSeePlayer();
|
||||||
this.checkStatus();
|
this.checkStatus();
|
||||||
@@ -1741,6 +1741,68 @@ const spawn = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// timeBoss(x, y, radius = 25) {
|
||||||
|
// mobs.spawn(x, y, 12, radius, "#000");
|
||||||
|
// let me = mob[mob.length - 1];
|
||||||
|
// me.isBoss = true;
|
||||||
|
// me.stroke = "transparent"; //used for drawSneaker
|
||||||
|
// me.eventHorizon = 1100; //required for black hole
|
||||||
|
// me.eventHorizonGoal = 1100; //required for black hole
|
||||||
|
// me.seeAtDistance2 = (me.eventHorizon + 1200) * (me.eventHorizon + 1200); //vision limit is event horizon
|
||||||
|
// me.accelMag = 0.00006 * simulation.accelScale;
|
||||||
|
// // me.collisionFilter.mask = cat.player | cat.bullet //| cat.body
|
||||||
|
// // me.frictionAir = 0.005;
|
||||||
|
// me.memory = Infinity;
|
||||||
|
// Matter.Body.setDensity(me, 0.03); //extra dense //normal is 0.001 //makes effective life much larger
|
||||||
|
// me.onDeath = function() {
|
||||||
|
// powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||||
|
// };
|
||||||
|
// me.damageReduction = 0.23 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||||
|
// me.do = function() {
|
||||||
|
// //keep it slow, to stop issues from explosion knock backs
|
||||||
|
// if (!(simulation.cycle % this.seePlayerFreq)) {
|
||||||
|
// if (this.distanceToPlayer2() < this.seeAtDistance2) { //&& !m.isCloak ignore cloak for black holes
|
||||||
|
// this.locatePlayer();
|
||||||
|
// if (!this.seePlayer.yes) this.seePlayer.yes = true;
|
||||||
|
// } else if (this.seePlayer.recall) {
|
||||||
|
// this.lostPlayer();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// this.checkStatus();
|
||||||
|
// if (this.seePlayer.recall) {
|
||||||
|
// //accelerate towards the player
|
||||||
|
// const forceMag = this.accelMag * this.mass;
|
||||||
|
// const dx = this.seePlayer.position.x - this.position.x
|
||||||
|
// const dy = this.seePlayer.position.y - this.position.y
|
||||||
|
// const mag = Math.sqrt(dx * dx + dy * dy)
|
||||||
|
// this.force.x += forceMag * dx / mag;
|
||||||
|
// this.force.y += forceMag * dy / mag;
|
||||||
|
|
||||||
|
// //eventHorizon waves in and out
|
||||||
|
// const eventHorizon = this.eventHorizon * (1 + 0.2 * Math.sin(simulation.cycle * 0.008))
|
||||||
|
// // zoom camera in and out with the event horizon
|
||||||
|
|
||||||
|
// //draw darkness
|
||||||
|
// if (!simulation.isTimeSkipping) {
|
||||||
|
// ctx.beginPath();
|
||||||
|
// ctx.arc(this.position.x, this.position.y, eventHorizon, 0, 2 * Math.PI);
|
||||||
|
// ctx.fillStyle = "rgba(0,0,0,0.05)";
|
||||||
|
// ctx.fill();
|
||||||
|
// //when player is inside event horizon
|
||||||
|
// if (Vector.magnitude(Vector.sub(this.position, player.position)) < eventHorizon) {
|
||||||
|
// // if (!(simulation.cycle % 10)) simulation.timePlayerSkip(5)
|
||||||
|
// // if (!(simulation.cycle % 2)) simulation.timePlayerSkip(1)
|
||||||
|
// simulation.timePlayerSkip(2)
|
||||||
|
|
||||||
|
// // if (m.immuneCycle < m.cycle) {
|
||||||
|
// // if (m.energy > 0) m.energy -= 0.004
|
||||||
|
// // if (m.energy < 0.1) m.damage(0.00017 * simulation.dmgScale);
|
||||||
|
// // }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// },
|
||||||
suckerBoss(x, y, radius = 25) {
|
suckerBoss(x, y, radius = 25) {
|
||||||
mobs.spawn(x, y, 12, radius, "#000");
|
mobs.spawn(x, y, 12, radius, "#000");
|
||||||
let me = mob[mob.length - 1];
|
let me = mob[mob.length - 1];
|
||||||
@@ -1808,7 +1870,6 @@ const spawn = {
|
|||||||
y: this.velocity.y + velocity.y
|
y: this.velocity.y + velocity.y
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//accelerate towards the player
|
//accelerate towards the player
|
||||||
const forceMag = this.accelMag * this.mass;
|
const forceMag = this.accelMag * this.mass;
|
||||||
const dx = this.seePlayer.position.x - this.position.x
|
const dx = this.seePlayer.position.x - this.position.x
|
||||||
@@ -1816,11 +1877,8 @@ const spawn = {
|
|||||||
const mag = Math.sqrt(dx * dx + dy * dy)
|
const mag = Math.sqrt(dx * dx + dy * dy)
|
||||||
this.force.x += forceMag * dx / mag;
|
this.force.x += forceMag * dx / mag;
|
||||||
this.force.y += forceMag * dy / mag;
|
this.force.y += forceMag * dy / mag;
|
||||||
|
|
||||||
//eventHorizon waves in and out
|
//eventHorizon waves in and out
|
||||||
const eventHorizon = this.eventHorizon * (1 + 0.2 * Math.sin(simulation.cycle * 0.008))
|
const eventHorizon = this.eventHorizon * (1 + 0.2 * Math.sin(simulation.cycle * 0.008)) // zoom camera in and out with the event horizon
|
||||||
// zoom camera in and out with the event horizon
|
|
||||||
|
|
||||||
//draw darkness
|
//draw darkness
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
ctx.arc(this.position.x, this.position.y, eventHorizon * 0.2, 0, 2 * Math.PI);
|
ctx.arc(this.position.x, this.position.y, eventHorizon * 0.2, 0, 2 * Math.PI);
|
||||||
@@ -2229,88 +2287,88 @@ const spawn = {
|
|||||||
}
|
}
|
||||||
spawn.allowShields = true;
|
spawn.allowShields = true;
|
||||||
},
|
},
|
||||||
// timeSkipBoss(x, y, radius = 55) {
|
timeSkipBoss(x, y, radius = 55) {
|
||||||
// mobs.spawn(x, y, 6, radius, '#000');
|
mobs.spawn(x, y, 6, radius, '#000');
|
||||||
// let me = mob[mob.length - 1];
|
let me = mob[mob.length - 1];
|
||||||
// me.isBoss = true;
|
me.isBoss = true;
|
||||||
// // me.stroke = "transparent"; //used for drawSneaker
|
// me.stroke = "transparent"; //used for drawSneaker
|
||||||
// me.timeSkipLastCycle = 0
|
me.timeSkipLastCycle = 0
|
||||||
// me.eventHorizon = 1800; //required for black hole
|
me.eventHorizon = 1800; //required for black hole
|
||||||
// me.seeAtDistance2 = (me.eventHorizon + 2000) * (me.eventHorizon + 2000); //vision limit is event horizon + 2000
|
me.seeAtDistance2 = (me.eventHorizon + 2000) * (me.eventHorizon + 2000); //vision limit is event horizon + 2000
|
||||||
// me.accelMag = 0.0004 * simulation.accelScale;
|
me.accelMag = 0.0004 * simulation.accelScale;
|
||||||
// // me.frictionAir = 0.005;
|
// me.frictionAir = 0.005;
|
||||||
// // me.memory = 1600;
|
// me.memory = 1600;
|
||||||
// // Matter.Body.setDensity(me, 0.02); //extra dense //normal is 0.001 //makes effective life much larger
|
// Matter.Body.setDensity(me, 0.02); //extra dense //normal is 0.001 //makes effective life much larger
|
||||||
// Matter.Body.setDensity(me, 0.0005 + 0.00018 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
Matter.Body.setDensity(me, 0.0005 + 0.00018 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
||||||
// spawn.shield(me, x, y, 1);
|
spawn.shield(me, x, y, 1);
|
||||||
|
|
||||||
|
|
||||||
// me.onDeath = function() {
|
me.onDeath = function() {
|
||||||
// //applying forces to player doesn't seem to work inside this method, not sure why
|
//applying forces to player doesn't seem to work inside this method, not sure why
|
||||||
// powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||||
// };
|
};
|
||||||
// me.do = function() {
|
me.do = function() {
|
||||||
// //keep it slow, to stop issues from explosion knock backs
|
//keep it slow, to stop issues from explosion knock backs
|
||||||
// if (this.speed > 8) {
|
if (this.speed > 8) {
|
||||||
// Matter.Body.setVelocity(this, {
|
Matter.Body.setVelocity(this, {
|
||||||
// x: this.velocity.x * 0.99,
|
x: this.velocity.x * 0.99,
|
||||||
// y: this.velocity.y * 0.99
|
y: this.velocity.y * 0.99
|
||||||
// });
|
});
|
||||||
// }
|
}
|
||||||
// this.seePlayerCheck();
|
this.seePlayerCheck();
|
||||||
// this.checkStatus();
|
this.checkStatus();
|
||||||
// this.attraction()
|
this.attraction()
|
||||||
// if (!simulation.isTimeSkipping) {
|
if (!simulation.isTimeSkipping) {
|
||||||
// const compress = 1
|
const compress = 1
|
||||||
// if (this.timeSkipLastCycle < simulation.cycle - compress &&
|
if (this.timeSkipLastCycle < simulation.cycle - compress &&
|
||||||
// Vector.magnitude(Vector.sub(this.position, player.position)) < this.eventHorizon) {
|
Vector.magnitude(Vector.sub(this.position, player.position)) < this.eventHorizon) {
|
||||||
// this.timeSkipLastCycle = simulation.cycle
|
this.timeSkipLastCycle = simulation.cycle
|
||||||
// simulation.timeSkip(compress)
|
simulation.timeSkip(compress)
|
||||||
|
|
||||||
// this.fill = `rgba(0,0,0,${0.4+0.6*Math.random()})`
|
this.fill = `rgba(0,0,0,${0.4+0.6*Math.random()})`
|
||||||
// this.stroke = "#014"
|
this.stroke = "#014"
|
||||||
// this.isShielded = false;
|
this.isShielded = false;
|
||||||
// this.isDropPowerUp = true;
|
this.isDropPowerUp = true;
|
||||||
// this.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob; //can't touch bullets
|
this.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob; //can't touch bullets
|
||||||
|
|
||||||
// ctx.beginPath();
|
ctx.beginPath();
|
||||||
// ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI);
|
ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI);
|
||||||
// ctx.fillStyle = "#fff";
|
ctx.fillStyle = "#fff";
|
||||||
// ctx.globalCompositeOperation = "destination-in"; //in or atop
|
ctx.globalCompositeOperation = "destination-in"; //in or atop
|
||||||
// ctx.fill();
|
ctx.fill();
|
||||||
// ctx.globalCompositeOperation = "source-over";
|
ctx.globalCompositeOperation = "source-over";
|
||||||
// ctx.beginPath();
|
ctx.beginPath();
|
||||||
// ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI);
|
ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI);
|
||||||
// ctx.clip();
|
ctx.clip();
|
||||||
|
|
||||||
// // ctx.beginPath();
|
// ctx.beginPath();
|
||||||
// // ctx.arc(this.position.x, this.position.y, 9999, 0, 2 * Math.PI);
|
// ctx.arc(this.position.x, this.position.y, 9999, 0, 2 * Math.PI);
|
||||||
// // ctx.fillStyle = "#000";
|
// ctx.fillStyle = "#000";
|
||||||
// // ctx.fill();
|
// ctx.fill();
|
||||||
// // ctx.strokeStyle = "#000";
|
// ctx.strokeStyle = "#000";
|
||||||
// // ctx.stroke();
|
// ctx.stroke();
|
||||||
|
|
||||||
// // ctx.beginPath();
|
// ctx.beginPath();
|
||||||
// // ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI);
|
// ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI);
|
||||||
// // ctx.fillStyle = `rgba(0,0,0,${0.05*Math.random()})`;
|
// ctx.fillStyle = `rgba(0,0,0,${0.05*Math.random()})`;
|
||||||
// // ctx.fill();
|
// ctx.fill();
|
||||||
// // ctx.strokeStyle = "#000";
|
// ctx.strokeStyle = "#000";
|
||||||
// // ctx.stroke();
|
// ctx.stroke();
|
||||||
// } else {
|
} else {
|
||||||
// this.isShielded = true;
|
this.isShielded = true;
|
||||||
// this.isDropPowerUp = false;
|
this.isDropPowerUp = false;
|
||||||
// this.seePlayer.recall = false
|
this.seePlayer.recall = false
|
||||||
// this.fill = "transparent"
|
this.fill = "transparent"
|
||||||
// this.stroke = "transparent"
|
this.stroke = "transparent"
|
||||||
// this.collisionFilter.mask = cat.player | cat.map | cat.body | cat.mob; //can't touch bullets
|
this.collisionFilter.mask = cat.player | cat.map | cat.body | cat.mob; //can't touch bullets
|
||||||
// ctx.beginPath();
|
ctx.beginPath();
|
||||||
// ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI);
|
ctx.arc(this.position.x, this.position.y, this.eventHorizon, 0, 2 * Math.PI);
|
||||||
// ctx.fillStyle = `rgba(0,0,0,${0.05*Math.random()})`;
|
ctx.fillStyle = `rgba(0,0,0,${0.05*Math.random()})`;
|
||||||
// ctx.fill();
|
ctx.fill();
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// },
|
},
|
||||||
beamer(x, y, radius = 15 + Math.ceil(Math.random() * 15)) {
|
beamer(x, y, radius = 15 + Math.ceil(Math.random() * 15)) {
|
||||||
mobs.spawn(x, y, 4, radius, "rgb(255,0,190)");
|
mobs.spawn(x, y, 4, radius, "rgb(255,0,190)");
|
||||||
let me = mob[mob.length - 1];
|
let me = mob[mob.length - 1];
|
||||||
@@ -3456,33 +3514,6 @@ const spawn = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//invulnerable every other revolution
|
|
||||||
// me.isInvulnerable = false
|
|
||||||
// me.invulnerable = function() {
|
|
||||||
// //draw trigger angle
|
|
||||||
// if (this.laserAngle % (4 * Math.PI) > 2 * Math.PI) {
|
|
||||||
// if (!this.isInvulnerable) {
|
|
||||||
// this.isInvulnerable = true
|
|
||||||
// if (this.damageReduction) this.startingDamageReduction = this.damageReduction
|
|
||||||
// this.damageReduction = 0
|
|
||||||
// }
|
|
||||||
// } else if (this.isInvulnerable) {
|
|
||||||
// this.isInvulnerable = false
|
|
||||||
// this.damageReduction = this.startingDamageReduction
|
|
||||||
// }
|
|
||||||
// if (this.isInvulnerable) {
|
|
||||||
// ctx.beginPath();
|
|
||||||
// let vertices = this.vertices;
|
|
||||||
// ctx.moveTo(vertices[0].x, vertices[0].y);
|
|
||||||
// for (let j = 1; j < vertices.length; j++) ctx.lineTo(vertices[j].x, vertices[j].y);
|
|
||||||
// ctx.lineTo(vertices[0].x, vertices[0].y);
|
|
||||||
// ctx.lineWidth = 20;
|
|
||||||
// ctx.strokeStyle = "rgba(255,255,255,0.7)";
|
|
||||||
// ctx.stroke();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
me.do = function() {
|
me.do = function() {
|
||||||
this.invulnerable();
|
this.invulnerable();
|
||||||
this.checkStatus();
|
this.checkStatus();
|
||||||
@@ -3893,6 +3924,93 @@ const spawn = {
|
|||||||
// }
|
// }
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
timeBoss(x, y, radius = 50, isSpawnBossPowerUp = true) {
|
||||||
|
mobs.spawn(x, y, 0, radius, `hsl(0, 100%, 50%)`) // "rgb(201,202,225)");
|
||||||
|
let me = mob[mob.length - 1];
|
||||||
|
Matter.Body.rotate(me, 2 * Math.PI * Math.random());
|
||||||
|
me.isBoss = true;
|
||||||
|
Matter.Body.setDensity(me, 0.001); //normal is 0.001
|
||||||
|
me.inertia = Infinity;
|
||||||
|
me.damageReduction = 0.04 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||||
|
me.startingDamageReduction = me.damageReduction
|
||||||
|
me.isInvulnerable = false
|
||||||
|
me.frictionAir = 0.01
|
||||||
|
me.restitution = 1
|
||||||
|
me.friction = 0
|
||||||
|
me.collisionFilter.mask = cat.bullet | cat.player | cat.body | cat.map | cat.mob
|
||||||
|
Matter.Body.setVelocity(me, { x: 10 * (Math.random() - 0.5), y: 10 * (Math.random() - 0.5) });
|
||||||
|
me.seePlayer.recall = 1;
|
||||||
|
spawn.spawnOrbitals(me, radius + 15, 1)
|
||||||
|
|
||||||
|
// me.skipRate = 1 + Math.floor(simulation.difficulty*0.02)
|
||||||
|
// spawn.shield(me, x, y, 1);
|
||||||
|
|
||||||
|
me.onDamage = function() {
|
||||||
|
if (this.health < this.nextHealthThreshold) {
|
||||||
|
this.health = this.nextHealthThreshold - 0.01
|
||||||
|
this.nextHealthThreshold = Math.floor(this.health * 4) / 4 //0.75,0.5,0.25
|
||||||
|
this.invulnerableCount = 360 + simulation.difficulty * 4 //how long does invulnerable time last
|
||||||
|
this.isInvulnerable = true
|
||||||
|
this.damageReduction = 0
|
||||||
|
// requestAnimationFrame(() => { simulation.timePlayerSkip(300) }); //wrapping in animation frame prevents errors, probably
|
||||||
|
}
|
||||||
|
};
|
||||||
|
me.onDeath = function() {
|
||||||
|
if (isSpawnBossPowerUp) powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||||
|
requestAnimationFrame(() => { simulation.timePlayerSkip(30) }); //wrapping in animation frame prevents errors, probably
|
||||||
|
};
|
||||||
|
|
||||||
|
me.cycle = Math.floor(360 * Math.random())
|
||||||
|
me.nextHealthThreshold = 0.75
|
||||||
|
me.invulnerableCount = 0
|
||||||
|
// console.log(me.mass) //100
|
||||||
|
me.do = function() {
|
||||||
|
this.cycle++
|
||||||
|
this.fill = `hsl(${this.cycle*0.5}, 100%, 80%)`;
|
||||||
|
// this.fill = `hsl(${270 + 50*Math.sin(this.cycle*0.02)}, 100%, 60%)`;
|
||||||
|
this.seePlayer.recall = 1
|
||||||
|
//maintain speed //faster in the vertical to help avoid repeating patterns
|
||||||
|
if (this.speed < 0.01) {
|
||||||
|
const unit = Vector.sub(player.position, this.position)
|
||||||
|
Matter.Body.setVelocity(this, Vector.mult(Vector.normalise(unit), 0.1));
|
||||||
|
} else {
|
||||||
|
if (Math.abs(this.velocity.y) < 9) Matter.Body.setVelocity(this, { x: this.velocity.x, y: this.velocity.y * 1.02 });
|
||||||
|
if (Math.abs(this.velocity.x) < 6.5) Matter.Body.setVelocity(this, { x: this.velocity.x * 1.02, y: this.velocity.y });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.isInvulnerable) {
|
||||||
|
this.invulnerableCount--
|
||||||
|
if (this.invulnerableCount < 0) {
|
||||||
|
this.isInvulnerable = false
|
||||||
|
this.damageReduction = this.startingDamageReduction
|
||||||
|
}
|
||||||
|
//time dilation
|
||||||
|
if (!simulation.isTimeSkipping) {
|
||||||
|
requestAnimationFrame(() => { simulation.timePlayerSkip(1) }); //wrapping in animation frame prevents errors, probably
|
||||||
|
// if (!(simulation.cycle % 10))
|
||||||
|
|
||||||
|
//draw invulnerable
|
||||||
|
ctx.beginPath();
|
||||||
|
let vertices = this.vertices;
|
||||||
|
ctx.moveTo(vertices[0].x, vertices[0].y);
|
||||||
|
for (let j = 1; j < vertices.length; j++) ctx.lineTo(vertices[j].x, vertices[j].y);
|
||||||
|
ctx.lineTo(vertices[0].x, vertices[0].y);
|
||||||
|
ctx.lineWidth = 15 + 6 * Math.random();
|
||||||
|
ctx.strokeStyle = `rgba(255,255,255,${0.5+0.2*Math.random()})`;
|
||||||
|
ctx.stroke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.checkStatus();
|
||||||
|
//horizontal attraction
|
||||||
|
// const xMag = 0.0005
|
||||||
|
// if (player.position.x > this.position.x + 200) {
|
||||||
|
// this.force.x += xMag * this.mass;
|
||||||
|
// } else if (player.position.x < this.position.x - 200) {
|
||||||
|
// this.force.x -= xMag * this.mass;
|
||||||
|
// }
|
||||||
|
};
|
||||||
|
},
|
||||||
bounceBullet(x, y, velocity = { x: 0, y: 0 }, radius = 11, sides = 6) {
|
bounceBullet(x, y, velocity = { x: 0, y: 0 }, radius = 11, sides = 6) {
|
||||||
//bullets
|
//bullets
|
||||||
mobs.spawn(x, y, sides, radius, "rgb(255,0,155)");
|
mobs.spawn(x, y, sides, radius, "rgb(255,0,155)");
|
||||||
@@ -5668,7 +5786,7 @@ const spawn = {
|
|||||||
x: Math.cos(time),
|
x: Math.cos(time),
|
||||||
y: Math.sin(time)
|
y: Math.sin(time)
|
||||||
}
|
}
|
||||||
Matter.Body.setPosition(this, Vector.add(who.position, Vector.mult(orbit, radius))) //bullets move with player
|
Matter.Body.setPosition(this, Vector.add(Vector.add(who.position, who.velocity), Vector.mult(orbit, radius))) //bullets move with player
|
||||||
//damage player
|
//damage player
|
||||||
if (Matter.Query.collides(this, [player]).length > 0 && !(m.isCloak && tech.isIntangible) && m.immuneCycle < m.cycle) {
|
if (Matter.Query.collides(this, [player]).length > 0 && !(m.isCloak && tech.isIntangible) && m.immuneCycle < m.cycle) {
|
||||||
m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage for 30 cycles
|
m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage for 30 cycles
|
||||||
@@ -5685,26 +5803,24 @@ const spawn = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
orbitalBoss(x, y, radius = 88) {
|
orbitalBoss(x, y, radius = 70) {
|
||||||
const nodeBalance = Math.random()
|
const nodeBalance = Math.random()
|
||||||
const nodes = Math.min(15, Math.floor(2 + 4 * nodeBalance + 0.75 * Math.sqrt(simulation.difficulty)))
|
const nodes = Math.min(15, Math.floor(2 + 4 * nodeBalance + 0.75 * Math.sqrt(simulation.difficulty)))
|
||||||
mobs.spawn(x, y, nodes, radius, "rgb(255,0,150)");
|
mobs.spawn(x, y, nodes, radius, "rgb(255,0,150)");
|
||||||
let me = mob[mob.length - 1];
|
let me = mob[mob.length - 1];
|
||||||
me.isBoss = true;
|
me.isBoss = true;
|
||||||
|
|
||||||
Matter.Body.setDensity(me, 0.0017 + 0.0002 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
Matter.Body.setDensity(me, 0.0017 + 0.0002 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
||||||
|
|
||||||
me.stroke = "transparent"; //used for drawGhost
|
me.stroke = "transparent"; //used for drawGhost
|
||||||
me.seeAtDistance2 = 2000000;
|
me.seeAtDistance2 = 2000000;
|
||||||
|
me.collisionFilter.mask = cat.bullet | cat.player | cat.body | cat.map
|
||||||
me.memory = Infinity;
|
me.memory = Infinity;
|
||||||
me.frictionAir = 0.04;
|
me.frictionAir = 0.04;
|
||||||
me.accelMag = 0.0003 * simulation.accelScale
|
me.accelMag = 0.0007 * simulation.accelScale
|
||||||
me.collisionFilter.mask = cat.player | cat.bullet //| cat.body
|
|
||||||
spawn.shield(me, x, y, 1);
|
spawn.shield(me, x, y, 1);
|
||||||
|
|
||||||
const rangeInnerVsOuter = Math.random()
|
const rangeInnerVsOuter = Math.random()
|
||||||
let speed = (0.009 + 0.0011 * Math.sqrt(simulation.difficulty)) * ((Math.random() < 0.5) ? 1 : -1)
|
let speed = (0.009 + 0.0011 * Math.sqrt(simulation.difficulty)) * ((Math.random() < 0.5) ? 1 : -1)
|
||||||
let range = radius + 400 + 200 * rangeInnerVsOuter + nodes * 7
|
let range = radius + 300 + 200 * rangeInnerVsOuter + nodes * 7
|
||||||
for (let i = 0; i < nodes; i++) spawn.orbital(me, range, i / nodes * 2 * Math.PI, speed)
|
for (let i = 0; i < nodes; i++) spawn.orbital(me, range, i / nodes * 2 * Math.PI, speed)
|
||||||
const orbitalIndexes = [] //find indexes for all the current nodes
|
const orbitalIndexes = [] //find indexes for all the current nodes
|
||||||
for (let i = 0; i < nodes; i++) orbitalIndexes.push(mob.length - 1 - i)
|
for (let i = 0; i < nodes; i++) orbitalIndexes.push(mob.length - 1 - i)
|
||||||
@@ -5718,10 +5834,9 @@ const spawn = {
|
|||||||
me.onDeath = function() {
|
me.onDeath = function() {
|
||||||
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||||
};
|
};
|
||||||
me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
me.damageReduction = 0.18 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||||
me.do = function() {
|
me.do = function() {
|
||||||
// this.armor();
|
this.seePlayerByHistory();
|
||||||
this.seePlayerCheckByDistance();
|
|
||||||
this.checkStatus();
|
this.checkStatus();
|
||||||
this.attraction();
|
this.attraction();
|
||||||
};
|
};
|
||||||
|
|||||||
60
js/tech.js
60
js/tech.js
@@ -602,9 +602,9 @@ const tech = {
|
|||||||
frequency: 1,
|
frequency: 1,
|
||||||
frequencyDefault: 1,
|
frequencyDefault: 1,
|
||||||
allowed() {
|
allowed() {
|
||||||
return !tech.isAmmoFromHealth && !tech.isEnergyNoAmmo
|
return !tech.isAmmoFromHealth
|
||||||
},
|
},
|
||||||
requires: "not catabolism, ideal gas law",
|
requires: "not catabolism",
|
||||||
effect() {
|
effect() {
|
||||||
tech.isEnergyNoAmmo = true;
|
tech.isEnergyNoAmmo = true;
|
||||||
},
|
},
|
||||||
@@ -4661,9 +4661,9 @@ const tech = {
|
|||||||
frequency: 2,
|
frequency: 2,
|
||||||
frequencyDefault: 2,
|
frequencyDefault: 2,
|
||||||
allowed() {
|
allowed() {
|
||||||
return tech.implosion === -1 && tech.explosiveRadius === 1 && !tech.isSmallExplosion && !tech.isBlockExplode && !tech.fragments && (tech.haveGunCheck("missiles") || tech.missileBotCount || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.isPulseLaser || tech.isMissileField || tech.isBoomBotUpgrade || tech.isTokamak)
|
return tech.explosiveRadius === 1 && !tech.isSmallExplosion && !tech.isBlockExplode && !tech.fragments && (tech.haveGunCheck("missiles") || tech.missileBotCount || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.isPulseLaser || tech.isMissileField || tech.isBoomBotUpgrade || tech.isTokamak)
|
||||||
},
|
},
|
||||||
requires: "an explosive damage source, not ammonium nitrate, nitroglycerin, chain reaction, fragmentation, implosion",
|
requires: "an explosive damage source, not ammonium nitrate, nitroglycerin, chain reaction, fragmentation",
|
||||||
effect: () => {
|
effect: () => {
|
||||||
tech.isExplodeRadio = true; //iridium-192
|
tech.isExplodeRadio = true; //iridium-192
|
||||||
},
|
},
|
||||||
@@ -4976,9 +4976,9 @@ const tech = {
|
|||||||
frequency: 2,
|
frequency: 2,
|
||||||
frequencyDefault: 2,
|
frequencyDefault: 2,
|
||||||
allowed() {
|
allowed() {
|
||||||
return tech.haveGunCheck("grenades") && !tech.fragments && !tech.isVacuumBomb && !tech.isExplodeRadio && !tech.isBlockExplode && !tech.isClusterExplode && tech.implosion === -1
|
return tech.haveGunCheck("grenades") && !tech.fragments && !tech.isVacuumBomb && !tech.isExplodeRadio && !tech.isBlockExplode && !tech.isClusterExplode
|
||||||
},
|
},
|
||||||
requires: "grenades, not fragmentation, vacuum bomb, iridium-192, pyrotechnics, implosion",
|
requires: "grenades, not fragmentation, vacuum bomb, iridium-192, pyrotechnics",
|
||||||
effect() {
|
effect() {
|
||||||
tech.isNeutronBomb = true;
|
tech.isNeutronBomb = true;
|
||||||
b.setGrenadeMode()
|
b.setGrenadeMode()
|
||||||
@@ -7106,7 +7106,7 @@ const tech = {
|
|||||||
allowed() {
|
allowed() {
|
||||||
return m.fieldUpgrades[m.fieldMode].name === "time dilation" && !m.isShipMode && !tech.isRewindAvoidDeath && !tech.isEnergyHealth && !tech.isTimeSkip
|
return m.fieldUpgrades[m.fieldMode].name === "time dilation" && !m.isShipMode && !tech.isRewindAvoidDeath && !tech.isEnergyHealth && !tech.isTimeSkip
|
||||||
},
|
},
|
||||||
requires: "time dilation, not CPT symmetry, mass-energy, timelike",
|
requires: "time dilation, not CPT symmetry, mass-energy",
|
||||||
effect() {
|
effect() {
|
||||||
tech.isRewindField = true;
|
tech.isRewindField = true;
|
||||||
m.fieldUpgrades[m.fieldMode].set()
|
m.fieldUpgrades[m.fieldMode].set()
|
||||||
@@ -7117,25 +7117,6 @@ const tech = {
|
|||||||
if (this.count) m.fieldUpgrades[m.fieldMode].set()
|
if (this.count) m.fieldUpgrades[m.fieldMode].set()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// {
|
|
||||||
// name: "timelike",
|
|
||||||
// description: "<strong>time dilation</strong> doubles your relative time <strong>rate</strong><br>and makes you immune to <strong class='color-harm'>harm</strong>",
|
|
||||||
// isFieldTech: true,
|
|
||||||
// maxCount: 1,
|
|
||||||
// count: 0,
|
|
||||||
// frequency: 2,
|
|
||||||
// frequencyDefault: 2,
|
|
||||||
// allowed() {
|
|
||||||
// return m.fieldUpgrades[m.fieldMode].name === "time dilation" && !m.isShipMode && !tech.isRewindField
|
|
||||||
// },
|
|
||||||
// requires: "time dilation, not retrocausality",
|
|
||||||
// effect() {
|
|
||||||
// tech.isTimeSkip = true;
|
|
||||||
// },
|
|
||||||
// remove() {
|
|
||||||
// tech.isTimeSkip = false;
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
{
|
{
|
||||||
name: "Lorentz transformation",
|
name: "Lorentz transformation",
|
||||||
description: `use ${powerUps.orb.research(3)}to increase your time rate<br><strong>move</strong>, <strong>jump</strong>, and <strong>shoot</strong> <strong>50%</strong> faster`,
|
description: `use ${powerUps.orb.research(3)}to increase your time rate<br><strong>move</strong>, <strong>jump</strong>, and <strong>shoot</strong> <strong>50%</strong> faster`,
|
||||||
@@ -7887,6 +7868,33 @@ const tech = {
|
|||||||
},
|
},
|
||||||
remove() {}
|
remove() {}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
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>",
|
||||||
|
maxCount: 1,
|
||||||
|
count: 0,
|
||||||
|
frequency: 0,
|
||||||
|
isJunk: true,
|
||||||
|
isNonRefundable: true,
|
||||||
|
allowed() {
|
||||||
|
return true
|
||||||
|
},
|
||||||
|
requires: "",
|
||||||
|
effect() {
|
||||||
|
for (let i = 0; i < 5; i++) powerUps.spawn(m.pos.x + 10 * Math.random(), m.pos.y + 10 * Math.random(), "field");
|
||||||
|
|
||||||
|
function loop() {
|
||||||
|
if (!simulation.paused && m.alive) {
|
||||||
|
if (!(simulation.cycle % 720)) {
|
||||||
|
requestAnimationFrame(() => { simulation.timePlayerSkip(60) }); //wrapping in animation frame prevents errors, probably
|
||||||
|
}
|
||||||
|
}
|
||||||
|
requestAnimationFrame(loop);
|
||||||
|
}
|
||||||
|
requestAnimationFrame(loop);
|
||||||
|
},
|
||||||
|
remove() {}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "discount",
|
name: "discount",
|
||||||
description: "get 3 random <strong class='color-j'>JUNK</strong> <strong class='color-m'>tech</strong> for the price of 1!",
|
description: "get 3 random <strong class='color-j'>JUNK</strong> <strong class='color-m'>tech</strong> for the price of 1!",
|
||||||
|
|||||||
128
todo.txt
128
todo.txt
@@ -1,16 +1,69 @@
|
|||||||
******************************************************** NEXT PATCH **************************************************
|
******************************************************** NEXT PATCH **************************************************
|
||||||
|
|
||||||
ideal gas law - lose all your current foam ammo; foam gun gets 1200% more ammo from ammo power ups
|
new reactor boss: timeBoss - after taking some damage it speeds up the passage of time
|
||||||
pressure vessel - has 25% more charges produced as you hold
|
reactor level has big doors
|
||||||
|
|
||||||
slashBoss is a bit slower and has a bit longer between slashes
|
nonrefundable tech show up in the pause menu
|
||||||
reactor SprayBoss: slower to fire, slower to move, smaller bullets, fewer in number
|
time dilation field - move, jump, and fire 25% faster
|
||||||
just a tiny nerf though
|
JUNK tech: closed timelike curve - spawn 5 field power ups, but every 12 seconds teleport a second into your future
|
||||||
|
|
||||||
bug fixes
|
|
||||||
|
|
||||||
******************************************************** TODO ********************************************************
|
******************************************************** TODO ********************************************************
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
timeSkipBoss
|
||||||
|
sends out waves of 60s time skip every 5 seconds?
|
||||||
|
or 1 cycle skip every other cycle
|
||||||
|
only active when player is inside range
|
||||||
|
immune to harm outside range?
|
||||||
|
|
||||||
|
simulation.timeSkip(60)
|
||||||
|
skip every other cycle inside black holes?
|
||||||
|
maybe run simulation.timeSkip(60) in a map
|
||||||
|
in labs?
|
||||||
|
reactor boss
|
||||||
|
mob fires laser/bullets that timeSkip player
|
||||||
|
maybe an effect when in range of the historyBoss
|
||||||
|
JUNK tech simulation.timeSkip(60)
|
||||||
|
add CPT graphics to simulation.timeSkip(60)
|
||||||
|
for player
|
||||||
|
tech requires eternalism - 2x time while choosing, gain more damage
|
||||||
|
|
||||||
|
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:
|
||||||
|
Deals regular damage on impact, but breaks apart on touch into several red dots (like the ones thrown out by the going through walls boss) and a chance for also throwing a bomb or two (increases with difficulty)
|
||||||
|
If the mob is close to the player or heading into the player fast it will shatter as well (and the projectiles will inherit its speed)
|
||||||
|
By a formula such as
|
||||||
|
ShouldShatter(distToPlayer, speed) = distToPlayer * speed > threshold
|
||||||
|
Optionally (and a part I can do as I'm good at it and it doesn't revolve around a lot of functional code which you don't like other people doing):
|
||||||
|
Color changing based on the mob explosion status
|
||||||
|
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
|
||||||
|
charging anything?
|
||||||
|
|
||||||
|
give retrocausality a short delay before it rewinds, so you can pick up powerups without going back
|
||||||
|
|
||||||
tech expansion: should also make other fields do things
|
tech expansion: should also make other fields do things
|
||||||
how to make the description work
|
how to make the description work
|
||||||
change description based on your current field?
|
change description based on your current field?
|
||||||
@@ -24,9 +77,6 @@ tech expansion: should also make other fields do things
|
|||||||
reduces the cloaking vision effect?
|
reduces the cloaking vision effect?
|
||||||
needs more benefit?
|
needs more benefit?
|
||||||
|
|
||||||
nonrefundable tech don't display, this is confusing
|
|
||||||
maybe they can show up but greyed out or something
|
|
||||||
|
|
||||||
guntech fire a bullet that fires nail fragments after 1s in the same direction as the original bullet
|
guntech fire a bullet that fires nail fragments after 1s in the same direction as the original bullet
|
||||||
like overwatch roadhog
|
like overwatch roadhog
|
||||||
|
|
||||||
@@ -146,72 +196,14 @@ setting to remove UI, except health bar
|
|||||||
except active gun? to see ammo
|
except active gun? to see ammo
|
||||||
checkbox in pause and in settings
|
checkbox in pause and in settings
|
||||||
|
|
||||||
pause time like invariant for other things...
|
|
||||||
throwing blocks
|
|
||||||
charging railgun
|
|
||||||
charging anything?
|
|
||||||
|
|
||||||
bug - url sharing still broken sometimes
|
bug - url sharing still broken sometimes
|
||||||
|
|
||||||
maybe? timing QTE for charging effects, if you fire right before the charge gets full it's better
|
|
||||||
|
|
||||||
+damage for each different bot type you have
|
|
||||||
disables bot upgrades?
|
|
||||||
|
|
||||||
tech: doing damage to mobs refunds up to 50% of damage taken in last 10 seconds
|
|
||||||
use history[] to manage this?
|
|
||||||
|
|
||||||
make a seed/hash system that controls only the tech/guns/fields shown
|
|
||||||
URL sharing could include a seed
|
|
||||||
seed controls:
|
|
||||||
seeded random at start - random level boss, mob types list, level order, horizontal flip
|
|
||||||
seeded random during run - tech, gun, field choices
|
|
||||||
not seeded random - mob spawns, mob size, minor level differences, custom level boss choices, ammo rewards, tech effect randomness
|
|
||||||
better to only seed things at the start of the run so it doesn't mess with power up choices
|
|
||||||
make option for a daily seed: seed = day+year
|
|
||||||
give 1 extra tech for doing the daily seeded run
|
|
||||||
make the option for the daily run, a secret exit in the intro level?
|
|
||||||
|
|
||||||
tech upgrade to anthropic principle to make it trigger at 50% life and 0% once per map
|
tech upgrade to anthropic principle to make it trigger at 50% life and 0% once per map
|
||||||
|
|
||||||
tech: spontaneous collapse - very low chance of something to occur
|
|
||||||
JUNK tech
|
|
||||||
https://bindingofisaacrebirth.fandom.com/wiki/Damocles
|
|
||||||
|
|
||||||
bug? cloaking field doesn't show energy over max
|
bug? cloaking field doesn't show energy over max
|
||||||
|
|
||||||
run more profiles of n-gon to fix performance issues
|
run more profiles of n-gon to fix performance issues
|
||||||
|
|
||||||
reactor
|
|
||||||
life-like cellular automata boss
|
|
||||||
https://scratch.mit.edu/projects/77724260/
|
|
||||||
night/day?
|
|
||||||
boss on far right produces more "on" cells
|
|
||||||
tailBoss
|
|
||||||
story the last 5 seconds of position, draw damage circles over those positions, like a tail
|
|
||||||
limit mantis boss to only reactor?
|
|
||||||
laserBoss?
|
|
||||||
swoopBoss: hides in top center
|
|
||||||
take a lap around the map that you have to dodge
|
|
||||||
spawn mobs
|
|
||||||
fire sniper bullets?
|
|
||||||
remove center map element?
|
|
||||||
add some blocks to the reactor level
|
|
||||||
add ammo?
|
|
||||||
boss speeds up as time goes on?
|
|
||||||
slow bullet speed?
|
|
||||||
foam hits all the bullets and makes this fight easy
|
|
||||||
give map some background graphics
|
|
||||||
it's a little short
|
|
||||||
add alternate boss
|
|
||||||
add a boss that spawns after the first one dies
|
|
||||||
balance
|
|
||||||
boss damage reduction
|
|
||||||
bullet size
|
|
||||||
bullet spawn number
|
|
||||||
bounce speed
|
|
||||||
add horizontal flip mode
|
|
||||||
|
|
||||||
bug: possibly clearing away all bullets causes a problem
|
bug: possibly clearing away all bullets causes a problem
|
||||||
bullet.js 255 (.do() is missing)
|
bullet.js 255 (.do() is missing)
|
||||||
I died and quantum immortality triggered (I had needles and ice-IX)
|
I died and quantum immortality triggered (I had needles and ice-IX)
|
||||||
|
|||||||
Reference in New Issue
Block a user