animated level load
animated new level load graphics for reactor and final level autoZoom code rewritten to work with pause better using the ephemera system this might cause bugs, I already found a few intro level renamed initial extra ammo power ups on why difficulty for final and reactor levels removed falling off the map damage on levels that still had falling off damage mob: stinger - has speed that adjusts as it flaps it's wings and a short range laser tech: strange loop - +9% damage, removing it gives null hypothesis and strange attractor tech: martingale - +11% damage, removing this has a 50% chance to not remove and to double it's damage paradigm shift removes 6 health when it ejects a tech, but now has a 85->97% chance to work ammo, heal, research tech spawn extra power ups after each time you take them tungsten carbide skin has a hexagon look and +222->300 max health Bayesian statistics spawn 3->6 research ansatz spawns 2->3 research if you have no research Ψ(t) collapse 16->21 research futures exchange 4.3->4.7% duplication replication 9->10 duplication stimulated emission 17->19% duplication anthropic principle spawn 5->16 heals when you die supply chain: no long gives JUNK instead triples the frequency of finding applied science electronegativity 0.22->0.26% damage per energy non-renewables 88->97% damage anticorrelation 100->111% damage decorrelation 70->77% defense parasitism 83->93% damage torpor 66->74% defense bug fix: recycling works with mass-energy (although it doesn't do much) ternary wasn't working in many situations, but it should now fixed bubble fusion exploit that triggers on mobs in factory endlessly bot fabrication was making 1 extra bot and giving negative research sometimes
This commit is contained in:
BIN
img/martingale.webp
Normal file
BIN
img/martingale.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 70 KiB |
BIN
img/strange loop.webp
Normal file
BIN
img/strange loop.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 47 KiB |
85
index.html
85
index.html
@@ -242,91 +242,6 @@
|
||||
</details>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.fade-in {
|
||||
opacity: 0;
|
||||
animation: 2s ease 1.5s normal forwards 1 fadein;
|
||||
}
|
||||
|
||||
.fade-in-fast {
|
||||
opacity: 0;
|
||||
animation: 1.5s ease 1s normal forwards 1 fadein;
|
||||
}
|
||||
|
||||
@keyframes fadein {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes dash {
|
||||
to {
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.draw-lines {
|
||||
stroke-dasharray: 20;
|
||||
stroke-dashoffset: 20;
|
||||
animation: dash 2.4s ease-in forwards;
|
||||
}
|
||||
|
||||
.draw-lines-dash {
|
||||
stroke-dasharray: 4;
|
||||
stroke-dashoffset: 4;
|
||||
animation: dash 2.4s ease-in forwards;
|
||||
}
|
||||
|
||||
.draw-lines-o {
|
||||
stroke-dasharray: 11;
|
||||
stroke-dashoffset: 11;
|
||||
animation: dash 2.4s ease-in forwards;
|
||||
}
|
||||
|
||||
.draw-lines-g {
|
||||
stroke-dasharray: 17;
|
||||
stroke-dashoffset: 17;
|
||||
animation: dash 2.4s ease-in forwards;
|
||||
}
|
||||
|
||||
.draw-lines-box-1 {
|
||||
stroke-dasharray: 1000;
|
||||
stroke-dashoffset: 1000;
|
||||
animation: dash 5s ease-in forwards;
|
||||
animation-delay: 0s;
|
||||
}
|
||||
|
||||
.draw-lines-box-2 {
|
||||
stroke-dasharray: 1000;
|
||||
stroke-dashoffset: 1000;
|
||||
animation: dash 2.6s ease-in forwards;
|
||||
animation-delay: 1s;
|
||||
}
|
||||
|
||||
.draw-lines-box-3 {
|
||||
stroke-dasharray: 1000;
|
||||
stroke-dashoffset: 1000;
|
||||
animation: dash 1.15s ease-in forwards;
|
||||
animation-delay: 1.55s;
|
||||
}
|
||||
|
||||
.draw-lines3 {
|
||||
stroke-dasharray: 3000;
|
||||
stroke-dashoffset: 3000;
|
||||
animation: dash 3.1s ease-in forwards;
|
||||
}
|
||||
|
||||
.draw-lines4 {
|
||||
stroke-dasharray: 300;
|
||||
stroke-dashoffset: 300;
|
||||
animation: dash 2.5s ease-in forwards;
|
||||
}
|
||||
</style>
|
||||
<svg id='splash' class="intro ui" viewBox="0 0 800 800" onclick="simulation.startGame()">
|
||||
<g class="fade-in" transform="translate(100,210) scale(34)" fill='#afafaf' stroke='none'>
|
||||
<path d="M0 0 h1 v0.2 h1.7 l0.3 0.3 v2.6 h-1 v-1.7 h-1 v1.7 h-1 z" />
|
||||
|
||||
14
js/index.js
14
js/index.js
@@ -1409,14 +1409,16 @@ window.addEventListener("keydown", function (event) {
|
||||
if (event.key === "X") m.death(); //only uppercase
|
||||
switch (event.key.toLowerCase()) {
|
||||
case "o":
|
||||
simulation.isAutoZoom = false;
|
||||
simulation.zoomScale /= 0.9;
|
||||
simulation.setZoom();
|
||||
// simulation.isAutoZoom = false;
|
||||
// simulation.zoomScale /= 0.9;
|
||||
// simulation.setZoom();
|
||||
simulation.zoomTransition(simulation.zoomScale / 0.9)
|
||||
break;
|
||||
case "i":
|
||||
simulation.isAutoZoom = false;
|
||||
simulation.zoomScale *= 0.9;
|
||||
simulation.setZoom();
|
||||
// simulation.isAutoZoom = false;
|
||||
// simulation.zoomScale *= 0.9;
|
||||
// simulation.setZoom();
|
||||
simulation.zoomTransition(simulation.zoomScale * 0.9)
|
||||
break
|
||||
case "`":
|
||||
powerUps.directSpawn(simulation.mouseInGame.x, simulation.mouseInGame.y, "research");
|
||||
|
||||
195
js/level.js
195
js/level.js
@@ -9,7 +9,7 @@ const level = {
|
||||
onLevel: -1,
|
||||
levelsCleared: 0,
|
||||
// playableLevels: ["pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion"],
|
||||
//see level.populateLevels: (intro, ... , reservoir or factory, reactor, ... , subway, final) added later
|
||||
//see level.populateLevels: (initial, ... , reservoir or factory, reactor, ... , subway, final) added later
|
||||
playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber", "pavilion", "lock"],
|
||||
communityLevels: ["gauntlet", "stronghold", "basement", "crossfire", "vats", "run", "ngon", "house", "perplex", "coliseum", "tunnel", "islands", "temple", "dripp", "biohazard", "stereoMadness", "yingYang", "staircase", "fortress", "commandeer", "clock", "buttonbutton", "downpour", "superNgonBros", "underpass", "cantilever", "tlinat", "ruins", "ace", "crimsonTowers", "LaunchSite", "shipwreck", "unchartedCave", "dojo"],
|
||||
trainingLevels: ["walk", "crouch", "jump", "hold", "throw", "throwAt", "deflect", "heal", "fire", "nailGun", "shotGun", "superBall", "matterWave", "missile", "stack", "mine", "grenades", "harpoon", "diamagnetism"],
|
||||
@@ -36,22 +36,24 @@ const level = {
|
||||
// b.giveGuns("harpoon") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
|
||||
// b.guns[8].ammo = 100000000
|
||||
// requestAnimationFrame(() => { tech.giveTech("Higgs mechanism") });
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("Higgs mechanism")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("topological defect")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("Hilbert space")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("martingale")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("paradigm shift")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("bubble fusion")
|
||||
// requestAnimationFrame(() => { for (let i = 0; i < 10; i++) tech.giveTech("orbital-bot") });
|
||||
// requestAnimationFrame(() => { for (let i = 0; i < 10; i++) b.orbitBot(m.pos, false) });
|
||||
// m.skin.hexagon();
|
||||
|
||||
// for (let i = 0; i < 1; i++) tech.giveTech("cascading failure")
|
||||
|
||||
// for (let i = 0; i < 1; i++) tech.giveTech("tungsten carbide")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("induction furnace")
|
||||
// for (let i = 0; i < 1; ++i) tech.giveTech("autonomous defense")
|
||||
// for (let i = 0; i < 3; i++) powerUps.directSpawn(450, -50, "tech");
|
||||
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "research");
|
||||
// for (let i = 0; i < 100; i++) powerUps.directSpawn(1750, -500, "coupling");
|
||||
// level.skyscrapers();
|
||||
// level.testing();
|
||||
|
||||
// for (let i = 0; i < 4; ++i) spawn.hopMother(1900, -500)
|
||||
// for (let i = 0; i < 10; ++i) spawn.starter(1900, -500, 50)
|
||||
// for (let i = 0; i < 4; ++i) spawn.stinger(1900, -500)
|
||||
// for (let i = 0; i < 1; ++i) spawn.timeSkipBoss(1900, -2500)
|
||||
// spawn.beetleBoss(1900, -500, 25)
|
||||
// spawn.slasher2(2000, -1150)
|
||||
@@ -62,7 +64,7 @@ const level = {
|
||||
// spawn.tetherBoss(1900, -500, { x: 1900, y: -500 })
|
||||
// for (let i = 0; i < 40; ++i) tech.giveTech()
|
||||
|
||||
level[simulation.isTraining ? "walk" : "intro"]() //normal starting level **************************************************
|
||||
level[simulation.isTraining ? "walk" : "initial"]() //normal starting level **************************************************
|
||||
|
||||
// spawn.bodyRect(2425, -120, 200, 200);
|
||||
// console.log(body[body.length - 1].mass)
|
||||
@@ -74,9 +76,9 @@ const level = {
|
||||
// for (let i = 0; i < 20; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "ammo");
|
||||
// for (let i = 0; i < 2; i++) powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "field", false);
|
||||
//lore testing
|
||||
// simulation.isCheating = false //true;
|
||||
// for (let i = 0; i < 5; i++) tech.giveTech("undefined")
|
||||
// lore.techCount = 2
|
||||
// simulation.isCheating = false //true;
|
||||
// level.levelsCleared = 10
|
||||
// localSettings.loreCount = 5 //this sets what conversation is heard
|
||||
// if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
|
||||
@@ -284,6 +286,150 @@ const level = {
|
||||
tech.isDeathAvoidedThisLevel = false;
|
||||
simulation.updateTechHUD();
|
||||
simulation.clearNow = true; //triggers in simulation.clearMap to remove all physics bodies and setup for new map
|
||||
|
||||
|
||||
//pop up new level info screen for a few seconds
|
||||
if (!simulation.isChoosing && m.alive && (level.levels[level.onLevel] === "final" || level.levels[level.onLevel] === "reactor")) { //level.levels[level.onLevel] === "subway" ||
|
||||
//pause
|
||||
if (!simulation.paused) {
|
||||
simulation.paused = true;
|
||||
simulation.isChoosing = true; //stops p from un pausing on key down
|
||||
// build.pauseGrid()
|
||||
// document.body.style.cursor = "auto";
|
||||
}
|
||||
//build level info
|
||||
document.getElementById("choose-grid").style.gridTemplateColumns = "250px"
|
||||
let text = `<div><div class="card-background" style="height:auto; border: none; background-color: transparent; line-height: 160%; background-color: var(--card-color); font-size: 1.15em;"> <div class="card-text">`
|
||||
for (let i = 0; i < level.levels.length; i++) {
|
||||
if (i < level.levelsCleared) {
|
||||
text += `<div style="user-select: none;">${level.levels[i]}</div>`
|
||||
} else if (i === level.levelsCleared) {
|
||||
// text += `<div><strong class="fade-in-faster">${level.levels[i]}</strong></div>`
|
||||
text += `<div class="unblur" style="user-select: none;"><strong>${level.levels[i]}</strong></div>`
|
||||
} else {
|
||||
text += `<div class= "blurry-text" style="user-select: none;">${level.levels[i]}</div>` //blurry text
|
||||
// ???????? text
|
||||
// text += `<div style="user-select: none; color: #bbb;">`
|
||||
// for (let j = 0; j < level.levels[i].length; j++) text += `?`
|
||||
// text += `</div>`
|
||||
}
|
||||
}
|
||||
text += `</div> </div></div>`
|
||||
|
||||
document.getElementById("choose-grid").innerHTML = text
|
||||
//show level info
|
||||
document.getElementById("choose-grid").style.opacity = "1"
|
||||
document.getElementById("choose-grid").style.transitionDuration = "0.25s"; //how long is the fade in on
|
||||
document.getElementById("choose-grid").style.visibility = "visible"
|
||||
|
||||
simulation.draw.cons();
|
||||
simulation.draw.body();
|
||||
level.customTopLayer();
|
||||
let count = simulation.testing ? 0 : 240
|
||||
let newLevelDraw = () => {
|
||||
count--
|
||||
if (count > 0) {
|
||||
requestAnimationFrame(newLevelDraw);
|
||||
} else { //unpause
|
||||
// document.body.style.cursor = "none";
|
||||
if (m.immuneCycle < m.cycle + 15) m.immuneCycle = m.cycle + 30; //player is immune to damage for 30 cycles
|
||||
if (simulation.paused) requestAnimationFrame(cycle);
|
||||
if (m.alive) simulation.paused = false;
|
||||
simulation.isChoosing = false; //stops p from un pausing on key down
|
||||
build.unPauseGrid()
|
||||
document.getElementById("choose-grid").style.opacity = "0"
|
||||
setTimeout(() => {
|
||||
document.getElementById("choose-grid").style.visibility = "hidden"
|
||||
}, 1000);
|
||||
}
|
||||
//draw
|
||||
simulation.wipe();
|
||||
m.look();
|
||||
simulation.camera();
|
||||
// if (count < 30) {
|
||||
// }
|
||||
// if (count < 60) {
|
||||
// simulation.draw.cons();
|
||||
// simulation.draw.body();
|
||||
// level.customTopLayer();
|
||||
// simulation.draw.body();
|
||||
// simulation.draw.drawMapPath();
|
||||
// mobs.draw();
|
||||
// } else
|
||||
// if (count < 240) {
|
||||
simulation.draw.wireFrame();
|
||||
// }
|
||||
// else if (count === 91) { //hide text boss
|
||||
// document.getElementById("choose-grid").style.opacity = "0"
|
||||
// setTimeout(() => {
|
||||
// document.getElementById("choose-grid").style.visibility = "hidden"
|
||||
// }, 1000);
|
||||
// }
|
||||
ctx.restore();
|
||||
simulation.drawCursor();
|
||||
}
|
||||
requestAnimationFrame(newLevelDraw);
|
||||
|
||||
|
||||
// // clear
|
||||
// requestAnimationFrame(() => {
|
||||
// simulation.wipe();
|
||||
// });
|
||||
|
||||
// //wireframe
|
||||
// setTimeout(() => {
|
||||
// requestAnimationFrame(() => {
|
||||
// simulation.wipe();
|
||||
// simulation.camera();
|
||||
// simulation.draw.wireFrame();
|
||||
// ctx.restore();
|
||||
// });
|
||||
// }, 500);
|
||||
|
||||
// //almost normal draw
|
||||
// setTimeout(() => {
|
||||
// requestAnimationFrame(() => {
|
||||
// simulation.wipe();
|
||||
// simulation.camera();
|
||||
// // ctx.fillStyle = "rgba(0,0,0,0.66)"
|
||||
// // ctx.fill(simulation.draw.mapPath);
|
||||
// simulation.draw.drawMapPath();
|
||||
// ctx.restore();
|
||||
// });
|
||||
// }, 1000);
|
||||
|
||||
// //normal draw
|
||||
// setTimeout(() => {
|
||||
// requestAnimationFrame(() => {
|
||||
// simulation.wipe();
|
||||
// simulation.camera();
|
||||
// // level.custom();
|
||||
// simulation.draw.cons();
|
||||
// simulation.draw.body();
|
||||
// // m.draw();
|
||||
// // m.hold();
|
||||
// level.customTopLayer();
|
||||
// simulation.draw.drawMapPath();
|
||||
// ctx.restore();
|
||||
// });
|
||||
// }, 1500);
|
||||
|
||||
// //unpause
|
||||
// setTimeout(() => {
|
||||
// document.body.style.cursor = "none";
|
||||
// if (m.immuneCycle < m.cycle + 15) m.immuneCycle = m.cycle + 15; //player is immune to damage for 30 cycles
|
||||
// if (simulation.paused) requestAnimationFrame(cycle);
|
||||
// if (m.alive) simulation.paused = false;
|
||||
// simulation.isChoosing = false; //stops p from un pausing on key down
|
||||
// build.unPauseGrid()
|
||||
|
||||
// document.getElementById("choose-grid").style.opacity = "0"
|
||||
// // document.getElementById("choose-grid").style.visibility = "hidden"
|
||||
// setTimeout(() => {
|
||||
// document.getElementById("choose-grid").style.visibility = "hidden"
|
||||
// }, 1000);
|
||||
// }, 2000);
|
||||
}
|
||||
}
|
||||
},
|
||||
populateLevels() { //run a second time if URL is loaded
|
||||
@@ -335,7 +481,7 @@ const level = {
|
||||
level.levels.splice(Math.floor(Math.seededRandom(level.levels.length * 0.6, level.levels.length)), 0, Math.random() < 0.5 ? "factory" : "reservoir"); //add level to the back half of the randomized levels list
|
||||
level.levels.splice(Math.floor(Math.seededRandom(level.levels.length * 0.6, level.levels.length)), 0, "reactor"); //add level to the back half of the randomized levels list
|
||||
if (!build.isExperimentSelection || (build.hasExperimentalMode && !simulation.isCheating)) { //experimental mode is endless, unless you only have an experiment Tech
|
||||
level.levels.unshift("intro"); //add level to the start of the randomized levels list
|
||||
level.levels.unshift("initial"); //add level to the start of the randomized levels list
|
||||
level.levels.push("subway"); //add level to the end of the randomized levels list
|
||||
level.levels.push("final"); //add level to the end of the randomized levels list
|
||||
}
|
||||
@@ -1911,7 +2057,7 @@ const level = {
|
||||
powerUps.addResearchToLevel() //needs to run after mobs are spawned
|
||||
},
|
||||
testing() {
|
||||
simulation.enableConstructMode() //tech.giveTech('motion sickness') //used to build maps in testing mode
|
||||
// simulation.enableConstructMode() //tech.giveTech('motion sickness') //used to build maps in testing mode
|
||||
|
||||
document.body.style.backgroundColor = "#fff";
|
||||
// color.map = "#444" //custom map color
|
||||
@@ -2158,7 +2304,7 @@ const level = {
|
||||
spawn.mapRect(-500, -25, 25, 50); //edge shelf
|
||||
spawn.mapRect(475, -25, 25, 50); //edge shelf
|
||||
},
|
||||
intro() {
|
||||
initial() {
|
||||
if (level.levelsCleared === 0) { //if this is the 1st level of the game
|
||||
if (simulation.difficultyMode > 2) spawn.setSpawnList() // hard and why difficulty don't begin with starter mobs
|
||||
|
||||
@@ -2216,7 +2362,7 @@ const level = {
|
||||
} else {
|
||||
for (let i = 0; i < 60; i++) {
|
||||
setTimeout(() => {
|
||||
if (level.levels[level.onLevel] === "intro") spawn.sneaker(2100, -1500 - 50 * i);
|
||||
if (level.levels[level.onLevel] === "initial") spawn.sneaker(2100, -1500 - 50 * i);
|
||||
}, 2000 + 500 * i);
|
||||
}
|
||||
}
|
||||
@@ -2457,6 +2603,7 @@ const level = {
|
||||
document.body.style.backgroundColor = "#ddd";
|
||||
|
||||
for (let i = 0; i < 16; i++) powerUps.spawn(4600 + 40 * i, -30, "ammo");
|
||||
if (simulation.difficultyMode > 4) for (let i = 0; i < 8; i++) powerUps.spawn(4600 + 40 * i, -30, "ammo"); //extra ammo on why difficulty
|
||||
|
||||
spawn.mapRect(-1950, 0, 8200, 1800); //ground
|
||||
spawn.mapRect(-1950, -1500, 1800, 1900); //left wall
|
||||
@@ -3832,19 +3979,19 @@ const level = {
|
||||
for (let i = 0; i < 250; i++) spawn.starter(-2700 + 2400 * Math.random(), -1300 - 500 * Math.random())
|
||||
} else {
|
||||
if (Math.random() < 0.07 && simulation.difficulty > 35) {
|
||||
for (let i = 0, len = scale * 0.25 / 6; i < len; ++i) spawn.timeBoss(-1327 - 200 * i, -1525, 60, false); //spawn 1-2 at difficulty 15
|
||||
for (let i = 0, len = scale * 0.22 / 6; 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 / 6; i < len; ++i) spawn.bounceBoss(-1327 - 200 * i, -1525, 80, false);
|
||||
for (let i = 0, len = scale * 0.15 / 6; i < len; ++i) spawn.sprayBoss(-1327 - 200 * i, -1525, 30, false)
|
||||
for (let i = 0, len = scale * 0.26 / 6; i < len; ++i) spawn.mineBoss(-1327 - 200 * i, -1525, 50, false);
|
||||
for (let i = 0, len = scale * 0.13 / 6; i < len; ++i) spawn.sprayBoss(-1327 - 200 * i, -1525, 30, false)
|
||||
for (let i = 0, len = scale * 0.25 / 6; 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
|
||||
for (let i = 0, len = scale * 0.22; 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.15; i < len; ++i) spawn.sprayBoss(-1327 - 200 * i, -1525, 30, false) //spawn 2-3 at difficulty 15
|
||||
for (let i = 0, len = scale * 0.13; 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.26; i < len; ++i) spawn.mineBoss(-1327 - 200 * i, -1525, 50, false); //spawn 3-4 at difficulty 15
|
||||
for (let i = 0, len = scale * 0.25; i < len; ++i) spawn.mineBoss(-1327 - 200 * i, -1525, 50, false); //spawn 3-4 at difficulty 15
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3919,6 +4066,7 @@ const level = {
|
||||
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");
|
||||
if (simulation.difficultyMode > 4) for (let i = 0; i < 8; i++) powerUps.spawn(1200 + 550 * Math.random(), -1700, "ammo"); //extra ammo on why difficulty
|
||||
const scale = Math.pow(simulation.difficulty, 0.7) //hard around 30, why around 54
|
||||
if (mobs.mobDeaths < level.levelsCleared && !simulation.isCheating) {
|
||||
for (let i = 0; i < 250; i++) spawn.starter(300 + 2400 * Math.random(), -1300 - 500 * Math.random())
|
||||
@@ -12158,7 +12306,10 @@ const level = {
|
||||
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
|
||||
spawn.mapRect(1500, -10, 100, 20);
|
||||
level.defaultZoom = 1800
|
||||
simulation.setZoom(1200);
|
||||
// simulation.setZoom(1200);
|
||||
simulation.zoomTransition(1200)
|
||||
|
||||
|
||||
document.body.style.backgroundColor = "#daa69f";
|
||||
color.map = "#600";
|
||||
|
||||
@@ -12567,7 +12718,9 @@ const level = {
|
||||
level.exit.y = -2030;
|
||||
relocateTo(50, -2050);
|
||||
simulation.fallHeight = -1000;
|
||||
simulation.setZoom(1800);
|
||||
// simulation.setZoom(1800);
|
||||
simulation.zoomTransition(1800)
|
||||
|
||||
templePlayer.startAnim = -1;
|
||||
templePlayer.drawExit = false;
|
||||
}
|
||||
|
||||
@@ -1092,7 +1092,7 @@ const lore = {
|
||||
|
||||
() => {
|
||||
setTimeout(() => {
|
||||
lore.anand.text("How ever it thinks it can learn and, I think we showed it that nonviolence is an option,")
|
||||
lore.anand.text("How ever it thinks it can learn, and I think we showed it that nonviolence is an option,")
|
||||
}, 1000);
|
||||
},
|
||||
() => {
|
||||
@@ -1116,7 +1116,7 @@ const lore = {
|
||||
}, 1000);
|
||||
},
|
||||
() => {
|
||||
lore.anand.text("me too")
|
||||
lore.anand.text("Me too,")
|
||||
},
|
||||
() => {
|
||||
lore.anand.text("but I'm also pretty hungry, wanna go get some food?")
|
||||
|
||||
35
js/mob.js
35
js/mob.js
@@ -1350,16 +1350,7 @@ const mobs = {
|
||||
this.leaveBody = false; // no body since it turned into the bot
|
||||
}
|
||||
if (tech.isAddRemoveMaxHealth) {
|
||||
if (this.isBoss && this.isDropPowerUp) {
|
||||
powerUps.spawn(this.position.x + 20, this.position.y, "tech", false)
|
||||
powerUps.spawn(this.position.x - 20, this.position.y, "research", false)
|
||||
powerUps.spawn(this.position.x - 40, this.position.y, "research", false)
|
||||
powerUps.spawn(this.position.x + 40, this.position.y, "research", false)
|
||||
powerUps.spawn(this.position.x, this.position.y + 20, "research", false)
|
||||
powerUps.spawn(this.position.x, this.position.y - 20, "heal", false)
|
||||
powerUps.spawn(this.position.x, this.position.y + 40, "heal", false)
|
||||
powerUps.spawn(this.position.x, this.position.y - 40, "heal", false)
|
||||
} else {
|
||||
if (!this.isBoss) {
|
||||
const amount = 0.005
|
||||
if (tech.isEnergyHealth) {
|
||||
if (m.maxEnergy > amount) {
|
||||
@@ -1371,12 +1362,34 @@ const mobs = {
|
||||
m.setMaxHealth();
|
||||
}
|
||||
}
|
||||
|
||||
// if (this.isBoss && this.isDropPowerUp) {
|
||||
// powerUps.spawn(this.position.x + 20, this.position.y, "tech", false)
|
||||
// powerUps.spawn(this.position.x - 20, this.position.y, "research", false)
|
||||
// powerUps.spawn(this.position.x - 40, this.position.y, "research", false)
|
||||
// powerUps.spawn(this.position.x + 40, this.position.y, "research", false)
|
||||
// powerUps.spawn(this.position.x, this.position.y + 20, "research", false)
|
||||
// powerUps.spawn(this.position.x, this.position.y - 20, "heal", false)
|
||||
// powerUps.spawn(this.position.x, this.position.y + 40, "heal", false)
|
||||
// powerUps.spawn(this.position.x, this.position.y - 40, "heal", false)
|
||||
// } else {
|
||||
// const amount = 0.005
|
||||
// if (tech.isEnergyHealth) {
|
||||
// if (m.maxEnergy > amount) {
|
||||
// tech.healMaxEnergyBonus -= amount
|
||||
// m.setMaxEnergy();
|
||||
// }
|
||||
// } else if (m.maxHealth > amount) {
|
||||
// tech.extraMaxHealth -= amount //decrease max health
|
||||
// m.setMaxHealth();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
if (tech.cloakDuplication && !this.isBoss) {
|
||||
tech.cloakDuplication -= 0.01
|
||||
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
|
||||
}
|
||||
} else if (tech.isShieldAmmo && this.shield && !this.isExtraShield) {
|
||||
} else if (tech.isShieldAmmo && this.shield && !this.isExtraShield && this.isDropPowerUp) {
|
||||
let type = tech.isEnergyNoAmmo ? "heal" : "ammo"
|
||||
if (Math.random() < 0.4) {
|
||||
type = "heal"
|
||||
|
||||
131
js/player.js
131
js/player.js
@@ -539,7 +539,7 @@ const m = {
|
||||
},
|
||||
baseHealth: 1,
|
||||
setMaxHealth() {
|
||||
m.maxHealth = m.baseHealth + tech.extraMaxHealth + 2.22 * tech.isFallingDamage + 4 * tech.isFlipFlop * tech.isFlipFlopOn * tech.isFlipFlopHealth
|
||||
m.maxHealth = m.baseHealth + tech.extraMaxHealth + 3 * tech.isFallingDamage + 4 * tech.isFlipFlop * tech.isFlipFlopOn * tech.isFlipFlopHealth
|
||||
document.getElementById("health-bg").style.width = `${Math.floor(300 * m.maxHealth)}px`
|
||||
simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-h'>maxHealth</span> <span class='color-symbol'>=</span> ${m.maxHealth.toFixed(2)}`)
|
||||
if (m.health > m.maxHealth) m.health = m.maxHealth;
|
||||
@@ -564,7 +564,7 @@ const m = {
|
||||
// if (tech.healthDrain) dmg *= 1 + 3.33 * tech.healthDrain //tech.healthDrain = 0.03 at one stack //cause more damage
|
||||
if (m.fieldMode === 0 || m.fieldMode === 3) dmg *= 0.973 ** m.coupling
|
||||
if (tech.isLowHealthDefense) dmg *= 1 - Math.max(0, 1 - m.health) * 0.8
|
||||
if (tech.isHarmReduceNoKill && m.lastKillCycle + 300 < m.cycle) dmg *= 0.33
|
||||
if (tech.isHarmReduceNoKill && m.lastKillCycle + 300 < m.cycle) dmg *= 0.26
|
||||
if (tech.squirrelFx !== 1) dmg *= 0.78//Math.pow(0.78, (tech.squirrelFx - 1) / 0.4)
|
||||
if (tech.isAddBlockMass && m.isHolding) dmg *= 0.1
|
||||
if (tech.isSpeedHarm && player.speed > 0.1) dmg *= 1 - Math.min(player.speed * 0.0193, 0.88) //capped at speed of 55
|
||||
@@ -572,7 +572,7 @@ const m = {
|
||||
if (tech.isNeutronium && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.05
|
||||
if (tech.isBotArmor) dmg *= 0.94 ** b.totalBots()
|
||||
if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.33;
|
||||
if (tech.isNoFireDefense && m.cycle > m.fireCDcycle + 120) dmg *= 0.3
|
||||
if (tech.isNoFireDefense && m.cycle > m.fireCDcycle + 120) dmg *= 0.27
|
||||
if (tech.isTurret && m.crouch) dmg *= 0.34;
|
||||
if (tech.isFirstDer && b.inventory[0] === b.activeGun) dmg *= 0.85 ** b.inventory.length
|
||||
if (tech.isEnergyHealth) {
|
||||
@@ -725,7 +725,7 @@ const m = {
|
||||
tech.isDeathAvoidedThisLevel = true
|
||||
powerUps.research.changeRerolls(-1)
|
||||
simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-r'>research</span><span class='color-symbol'>--</span><br>${powerUps.research.count}`)
|
||||
for (let i = 0; i < 5; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "heal", false);
|
||||
for (let i = 0; i < 16; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "heal", false);
|
||||
m.energy = m.maxEnergy + 0.1
|
||||
if (m.immuneCycle < m.cycle + 300) m.immuneCycle = m.cycle + 300 //disable this.immuneCycle bonus seconds
|
||||
simulation.wipe = function () { //set wipe to have trails
|
||||
@@ -755,7 +755,7 @@ const m = {
|
||||
powerUps.research.changeRerolls(-1)
|
||||
simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-r'>research</span><span class='color-symbol'>--</span>
|
||||
<br>${powerUps.research.count}`)
|
||||
for (let i = 0; i < 5; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "heal", false);
|
||||
for (let i = 0; i < 16; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "heal", false);
|
||||
if (m.immuneCycle < m.cycle + 300) m.immuneCycle = m.cycle + 300 //disable this.immuneCycle bonus seconds
|
||||
simulation.wipe = function () { //set wipe to have trails
|
||||
ctx.fillStyle = "rgba(255,255,255,0.03)";
|
||||
@@ -1274,23 +1274,29 @@ const m = {
|
||||
m.drawLeg("#5f5f5f");
|
||||
m.calcLeg(0, 1);
|
||||
m.drawLeg("#555");
|
||||
ctx.rotate(m.angle);
|
||||
|
||||
const size = 33
|
||||
ctx.beginPath();
|
||||
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
|
||||
ctx.lineTo(size * 1, size * 0)
|
||||
ctx.lineTo(size * 0.5, size * 0.866)
|
||||
ctx.lineTo(size * -0.5, size * 0.866)
|
||||
ctx.lineTo(size * -1, size * 0)
|
||||
ctx.lineTo(size * -0.5, size * -0.866)
|
||||
ctx.lineTo(size * 0.5, size * -0.866)
|
||||
ctx.lineTo(size * 1, size * 0)
|
||||
ctx.lineTo(size * 0.5, size * 0)
|
||||
ctx.fillStyle = m.bodyGradient
|
||||
ctx.fill();
|
||||
// ctx.fillStyle = grdRad
|
||||
// ctx.fill();
|
||||
ctx.strokeStyle = "#000";
|
||||
ctx.strokeStyle = "#333";
|
||||
ctx.lineWidth = 1.5;
|
||||
ctx.rotate(m.angle);
|
||||
ctx.beginPath();
|
||||
ctx.arc(15, 0, 4, 0, 2 * Math.PI);
|
||||
ctx.fillStyle = "#fff"
|
||||
ctx.fill();
|
||||
ctx.beginPath();
|
||||
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
|
||||
ctx.arc(15, 0, 4, 0, 2 * Math.PI);
|
||||
ctx.stroke();
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.arc(15, 0, 3, 0, 2 * Math.PI);
|
||||
ctx.fillStyle = "#333"
|
||||
ctx.fill();
|
||||
|
||||
ctx.restore();
|
||||
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
|
||||
powerUps.boost.draw()
|
||||
@@ -1482,8 +1488,6 @@ const m = {
|
||||
|
||||
// console.log(simulation.zoomScale)
|
||||
simulation.setZoom(1800 + 400 * Math.sin(m.cycle * 0.0075))
|
||||
|
||||
|
||||
}
|
||||
},
|
||||
dilate2() {
|
||||
@@ -1645,6 +1649,95 @@ const m = {
|
||||
ctx.restore();
|
||||
}
|
||||
},
|
||||
hexagon() {
|
||||
m.isAltSkin = true
|
||||
m.color = {
|
||||
hue: 0,
|
||||
sat: 0,
|
||||
light: 100,
|
||||
}
|
||||
// m.setFillColors();
|
||||
m.fillColor = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light}%)`
|
||||
m.fillColorDark = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light - 35}%)`
|
||||
let grd = ctx.createLinearGradient(-30, 0, 30, 0);
|
||||
grd.addColorStop(0, m.fillColorDark);
|
||||
grd.addColorStop(0.7, m.fillColor);
|
||||
// grd.addColorStop(1, m.fillColor);
|
||||
m.bodyGradient = grd
|
||||
|
||||
m.draw = function () {
|
||||
ctx.fillStyle = m.fillColor;
|
||||
m.walk_cycle += m.flipLegs * m.Vx;
|
||||
ctx.save();
|
||||
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5 //|| (m.cycle % 40 > 20)
|
||||
ctx.translate(m.pos.x, m.pos.y);
|
||||
m.calcLeg(Math.PI, -3);
|
||||
m.drawLeg("#4a4a4a");
|
||||
m.calcLeg(0, 0);
|
||||
m.drawLeg("#333");
|
||||
ctx.rotate(m.angle);
|
||||
|
||||
const size = 32
|
||||
ctx.beginPath();
|
||||
ctx.lineTo(size * 1, size * 0)
|
||||
ctx.lineTo(size * 0.5, size * 0.866)
|
||||
ctx.lineTo(size * -0.5, size * 0.866)
|
||||
ctx.lineTo(size * -1, size * 0)
|
||||
ctx.lineTo(size * -0.5, size * -0.866)
|
||||
ctx.lineTo(size * 0.5, size * -0.866)
|
||||
ctx.lineTo(size * 1, size * 0)
|
||||
ctx.fillStyle = m.bodyGradient
|
||||
ctx.fill();
|
||||
ctx.arc(15, 0, 4, 0, 2 * Math.PI);
|
||||
ctx.strokeStyle = "#333";
|
||||
ctx.lineWidth = 2;
|
||||
ctx.stroke();
|
||||
ctx.restore();
|
||||
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
|
||||
powerUps.boost.draw()
|
||||
}
|
||||
m.drawLeg = function (stroke) {
|
||||
// if (simulation.mouseInGame.x > m.pos.x) {
|
||||
if (m.angle > -Math.PI / 2 && m.angle < Math.PI / 2) {
|
||||
m.flipLegs = 1;
|
||||
} else {
|
||||
m.flipLegs = -1;
|
||||
}
|
||||
ctx.save();
|
||||
ctx.scale(m.flipLegs, 1); //leg lines
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(m.hip.x, m.hip.y);
|
||||
ctx.lineTo(m.knee.x, m.knee.y);
|
||||
ctx.lineTo(m.foot.x, m.foot.y);
|
||||
ctx.strokeStyle = stroke;
|
||||
ctx.lineWidth = 6;
|
||||
ctx.stroke();
|
||||
|
||||
//toe lines
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(m.foot.x, m.foot.y);
|
||||
ctx.lineTo(m.foot.x - 15, m.foot.y + 5);
|
||||
ctx.moveTo(m.foot.x, m.foot.y);
|
||||
ctx.lineTo(m.foot.x + 15, m.foot.y + 5);
|
||||
ctx.lineWidth = 3;
|
||||
ctx.stroke();
|
||||
|
||||
//hip joint
|
||||
ctx.beginPath();
|
||||
ctx.arc(m.hip.x, m.hip.y, 11, 0, 2 * Math.PI);
|
||||
//knee joint
|
||||
ctx.moveTo(m.knee.x + 5, m.knee.y);
|
||||
ctx.arc(m.knee.x, m.knee.y, 5, 0, 2 * Math.PI);
|
||||
//foot joint
|
||||
ctx.moveTo(m.foot.x + 5, m.foot.y);
|
||||
ctx.arc(m.foot.x, m.foot.y, 5, 0, 2 * Math.PI);
|
||||
ctx.fillStyle = "#000";
|
||||
ctx.fill();
|
||||
// ctx.lineWidth = 2;
|
||||
// ctx.stroke();
|
||||
ctx.restore();
|
||||
}
|
||||
},
|
||||
stubs() {
|
||||
m.isAltSkin = true
|
||||
m.draw = function () {
|
||||
|
||||
@@ -326,7 +326,7 @@ const powerUps = {
|
||||
return
|
||||
}
|
||||
if (tech.isCancelDuplication) {
|
||||
tech.duplication += 0.043
|
||||
tech.duplication += 0.047
|
||||
tech.maxDuplicationEvent()
|
||||
simulation.makeTextLog(`tech.duplicationChance() <span class='color-symbol'>+=</span> ${0.043}`)
|
||||
simulation.circleFlare(0.043);
|
||||
@@ -361,7 +361,7 @@ const powerUps = {
|
||||
// }
|
||||
}
|
||||
if (tech.isAnsatz && powerUps.research.count < 1) {
|
||||
for (let i = 0; i < 2; i++) powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false);
|
||||
for (let i = 0; i < 3; i++) powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false);
|
||||
}
|
||||
// document.getElementById("choose-grid").style.display = "none"
|
||||
document.getElementById("choose-grid").style.visibility = "hidden"
|
||||
@@ -466,28 +466,30 @@ const powerUps = {
|
||||
if (m.alive && powerUps.research.count >= cost) {
|
||||
requestAnimationFrame(cycle);
|
||||
this.isMakingBots = true
|
||||
} else {
|
||||
this.isMakingBots = false
|
||||
}
|
||||
|
||||
if (!simulation.paused && !simulation.isChoosing && !(simulation.cycle % 60)) {
|
||||
powerUps.research.count -= cost
|
||||
b.randomBot()
|
||||
if (tech.renormalization) {
|
||||
for (let i = 0; i < cost; i++) {
|
||||
if (Math.random() < 0.46) {
|
||||
if (Math.random() < 0.47) {
|
||||
m.fieldCDcycle = m.cycle + 20;
|
||||
powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "research");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.isMakingBots = false
|
||||
}
|
||||
}
|
||||
requestAnimationFrame(cycle);
|
||||
}
|
||||
|
||||
if (tech.isDeathAvoid && document.getElementById("tech-anthropic")) {
|
||||
document.getElementById("tech-anthropic").innerHTML = `-${powerUps.research.count}`
|
||||
}
|
||||
if (tech.renormalization && Math.random() < 0.46 && amount < 0) {
|
||||
if (tech.renormalization && Math.random() < 0.47 && amount < 0) {
|
||||
for (let i = 0, len = -amount; i < len; i++) powerUps.spawn(m.pos.x, m.pos.y, "research");
|
||||
}
|
||||
if (tech.isRerollHaste) {
|
||||
@@ -1412,6 +1414,31 @@ const powerUps = {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (tech.isAddRemoveMaxHealth) {
|
||||
powerUps.spawn(x + 20, y, "tech", false)
|
||||
powerUps.spawn(x - 20, y, "research", false)
|
||||
powerUps.spawn(x - 40, y, "research", false)
|
||||
powerUps.spawn(x + 40, y, "research", false)
|
||||
powerUps.spawn(x, y + 20, "research", false)
|
||||
powerUps.spawn(x, y - 20, "heal", false)
|
||||
powerUps.spawn(x, y + 40, "heal", false)
|
||||
powerUps.spawn(x, y - 40, "heal", false)
|
||||
// if (this.isBoss && this.isDropPowerUp) {
|
||||
// } else {
|
||||
// const amount = 0.005
|
||||
// if (tech.isEnergyHealth) {
|
||||
// if (m.maxEnergy > amount) {
|
||||
// tech.healMaxEnergyBonus -= amount
|
||||
// m.setMaxEnergy();
|
||||
// }
|
||||
// } else if (m.maxHealth > amount) {
|
||||
// tech.extraMaxHealth -= amount //decrease max health
|
||||
// m.setMaxHealth();
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
},
|
||||
chooseRandomPowerUp(x, y) { //100% chance to drop a random power up //used in spawn.debris
|
||||
@@ -1501,11 +1528,11 @@ const powerUps = {
|
||||
},
|
||||
pauseEjectTech(index) {
|
||||
if ((tech.isPauseEjectTech || simulation.testing) && !simulation.isChoosing && !tech.tech[index].isNonRefundable) {
|
||||
if (Math.random() < 0.2 || tech.tech[index].isFromAppliedScience || (tech.tech[index].bonusResearch !== undefined && tech.tech[index].bonusResearch > powerUps.research.count)) {
|
||||
if (Math.random() < 0.03 || tech.tech[index].isFromAppliedScience || (tech.tech[index].bonusResearch !== undefined && tech.tech[index].bonusResearch > powerUps.research.count)) {
|
||||
tech.removeTech(index)
|
||||
// powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false);
|
||||
} else {
|
||||
powerUps.ejectTech(index)
|
||||
m.damage(0.06)
|
||||
}
|
||||
document.getElementById(`${index}-pause-tech`).style.textDecoration = "line-through"
|
||||
document.getElementById(`${index}-pause-tech`).style.animation = ""
|
||||
|
||||
101
js/simulation.js
101
js/simulation.js
@@ -24,7 +24,6 @@ const simulation = {
|
||||
mobs.healthBar();
|
||||
m.draw();
|
||||
m.hold();
|
||||
// v.draw(); //working on visibility work in progress
|
||||
level.customTopLayer();
|
||||
simulation.draw.drawMapPath();
|
||||
b.fire();
|
||||
@@ -33,10 +32,8 @@ const simulation = {
|
||||
if (!m.isBodiesAsleep) b.bulletDo();
|
||||
simulation.drawCircle();
|
||||
simulation.runEphemera();
|
||||
// simulation.clip();
|
||||
ctx.restore();
|
||||
simulation.drawCursor();
|
||||
// simulation.pixelGraphics();
|
||||
},
|
||||
testingLoop() {
|
||||
simulation.gravity();
|
||||
@@ -505,47 +502,52 @@ const simulation = {
|
||||
simulation.zoom = canvas.height / zoomScale; //sets starting zoom scale
|
||||
},
|
||||
zoomTransition(newZoomScale, step = 2) {
|
||||
//old version
|
||||
// if (simulation.isAutoZoom) {
|
||||
// const isBigger = (newZoomScale - simulation.zoomScale > 0) ? true : false;
|
||||
// requestAnimationFrame(zLoop);
|
||||
// const currentLevel = level.onLevel
|
||||
|
||||
// function zLoop() {
|
||||
// if (currentLevel !== level.onLevel || simulation.isAutoZoom === false) return //stop the zoom if player goes to a new level
|
||||
|
||||
// if (isBigger) {
|
||||
// simulation.zoomScale += step
|
||||
// if (simulation.zoomScale >= newZoomScale) {
|
||||
// simulation.setZoom(newZoomScale);
|
||||
// return
|
||||
// }
|
||||
// } else {
|
||||
// simulation.zoomScale -= step
|
||||
// if (simulation.zoomScale <= newZoomScale) {
|
||||
// simulation.setZoom(newZoomScale);
|
||||
// return
|
||||
// }
|
||||
// }
|
||||
|
||||
// simulation.setZoom();
|
||||
// requestAnimationFrame(zLoop);
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
//rewrite using the ephemera system
|
||||
if (simulation.isAutoZoom) {
|
||||
const isBigger = (newZoomScale - simulation.zoomScale > 0) ? true : false;
|
||||
requestAnimationFrame(zLoop);
|
||||
const currentLevel = level.onLevel
|
||||
|
||||
function zLoop() {
|
||||
if (currentLevel !== level.onLevel || simulation.isAutoZoom === false) return //stop the zoom if player goes to a new level
|
||||
|
||||
if (isBigger) {
|
||||
simulation.ephemera.push({
|
||||
name: "zoom",
|
||||
count: simulation.testing ? 0 : 120, //cycles before it self removes
|
||||
currentLevel: level.onLevel,
|
||||
do() {
|
||||
this.count--
|
||||
const step = (newZoomScale - simulation.zoomScale) / this.count
|
||||
simulation.zoomScale += step
|
||||
if (simulation.zoomScale >= newZoomScale) {
|
||||
simulation.setZoom(newZoomScale);
|
||||
return
|
||||
}
|
||||
} else {
|
||||
simulation.zoomScale -= step
|
||||
if (simulation.zoomScale <= newZoomScale) {
|
||||
simulation.setZoom(newZoomScale);
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
simulation.setZoom();
|
||||
requestAnimationFrame(zLoop);
|
||||
}
|
||||
if (this.count < 1 && this.currentLevel === level.onLevel && simulation.isAutoZoom) {
|
||||
simulation.zoomScale = newZoomScale
|
||||
simulation.removeEphemera(this.name)
|
||||
}
|
||||
simulation.setZoom(simulation.zoomScale);
|
||||
},
|
||||
zoomInFactor: 0,
|
||||
startZoomIn(time = 180) {
|
||||
simulation.zoom = 0;
|
||||
let count = 0;
|
||||
requestAnimationFrame(zLoop);
|
||||
|
||||
function zLoop() {
|
||||
simulation.zoom += canvas.height / simulation.zoomScale / time;
|
||||
count++;
|
||||
if (count < time) {
|
||||
requestAnimationFrame(zLoop);
|
||||
} else {
|
||||
simulation.setZoom();
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
translatePlayerAndCamera(where) {
|
||||
@@ -974,8 +976,8 @@ const simulation = {
|
||||
} else {
|
||||
Matter.Body.setVelocity(player, { x: 0, y: 0 });
|
||||
Matter.Body.setPosition(player, { x: level.enter.x + 50, y: level.enter.y - 20 });
|
||||
m.damage(0.05 * simulation.difficultyMode);
|
||||
m.energy -= 0.05 * simulation.difficultyMode
|
||||
// m.damage(0.02 * simulation.difficultyMode);
|
||||
// m.energy -= 0.02 * simulation.difficultyMode
|
||||
// move bots
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
if (bullet[i].botType) {
|
||||
@@ -1003,6 +1005,18 @@ const simulation = {
|
||||
});
|
||||
}
|
||||
if (tech.isHealthRecovery) {
|
||||
if (tech.isEnergyHealth) {
|
||||
if (m.immuneCycle < m.cycle) {
|
||||
m.energy += m.maxEnergy * 0.005
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
x: m.pos.x,
|
||||
y: m.pos.y,
|
||||
radius: Math.sqrt(m.maxEnergy * 0.02) * 60,
|
||||
color: "rgba(0, 204, 255,0.4)", //#0cf
|
||||
time: 4
|
||||
});
|
||||
}
|
||||
} else {
|
||||
const heal = 0.005 * m.maxHealth
|
||||
m.addHealth(heal)
|
||||
simulation.drawList.push({ //add dmg to draw queue
|
||||
@@ -1014,6 +1028,7 @@ const simulation = {
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(m.cycle % 420)) { //once every 7 seconds
|
||||
//check if player is inside the map
|
||||
@@ -1355,7 +1370,7 @@ const simulation = {
|
||||
ctx.textAlign = "center";
|
||||
ctx.fillText(`(${simulation.mouseInGame.x.toFixed(1)}, ${simulation.mouseInGame.y.toFixed(1)})`, simulation.mouse.x, simulation.mouse.y - 20);
|
||||
},
|
||||
sight: { //credit to Cornbread for adding this algorithm to n-gon
|
||||
sight: { //credit to Cornbread2100 for adding this algorithm to n-gon
|
||||
// square: 0,
|
||||
intersectMap: [], //this is precalculated in simulation.draw.lineOfSightPrecalculation()
|
||||
getIntersection(v1, v1End, domain) {
|
||||
|
||||
201
js/spawn.js
201
js/spawn.js
@@ -22,9 +22,10 @@ const spawn = {
|
||||
fullPickList: [
|
||||
"slasher", "slasher", "slasher2", "slasher3",
|
||||
"hopper", "hopper", "hopMother", "hopMother",
|
||||
"flutter", "flutter", "flutter",
|
||||
"stabber", "stabber", "stabber",
|
||||
"springer", "springer", "springer",
|
||||
"stinger", "stinger", "stinger",
|
||||
"flutter", "flutter",
|
||||
"shooter", "shooter",
|
||||
"grenadier", "grenadier",
|
||||
"striker", "striker",
|
||||
@@ -34,7 +35,7 @@ const spawn = {
|
||||
],
|
||||
mobTypeSpawnOrder: [], //preset list of mob names calculated at the start of a run by the randomSeed
|
||||
mobTypeSpawnIndex: 0, //increases as the mob type cycles
|
||||
allowedGroupList: ["spinner", "striker", "springer", "laser", "focuser", "beamer", "exploder", "spawner", "shooter", "launcher", "launcherOne", "stabber", "sniper", "pulsar", "grenadier", "slasher", "flutter"],
|
||||
allowedGroupList: ["spinner", "striker", "springer", "laser", "focuser", "beamer", "exploder", "spawner", "shooter", "launcher", "launcherOne", "stabber", "sniper", "pulsar", "grenadier", "slasher", "flutter", "stinger"],
|
||||
setSpawnList() { //this is run at the start of each new level to determine the possible mobs for the level
|
||||
spawn.pickList.splice(0, 1);
|
||||
const push = spawn.mobTypeSpawnOrder[spawn.mobTypeSpawnIndex++ % spawn.mobTypeSpawnOrder.length]
|
||||
@@ -3837,6 +3838,202 @@ const spawn = {
|
||||
// }
|
||||
};
|
||||
},
|
||||
stinger(x, y, radius = 18 + 4 * Math.random()) {
|
||||
const color = '#5bc'
|
||||
mobs.spawn(x, y, 7, radius, color);
|
||||
let me = mob[mob.length - 1];
|
||||
Matter.Body.setDensity(me, 0.0025); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
// me.damageReduction = 0.04 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1)
|
||||
|
||||
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
|
||||
Matter.Body.rotate(me, Math.random() * Math.PI * 2);
|
||||
me.accelMag = 0.0015 + 0.0007 * Math.sqrt(simulation.accelScale);
|
||||
me.frictionAir = 0.04;
|
||||
// me.seePlayerFreq = 40 + Math.floor(13 * Math.random())
|
||||
me.memory = 240;
|
||||
me.restitution = 0.8;
|
||||
me.frictionStatic = 0;
|
||||
me.friction = 0;
|
||||
me.lookTorque = 0.000001 * (Math.random() > 0.5 ? -1 : 1);
|
||||
me.fireDir = { x: 0, y: 0 }
|
||||
spawn.shield(me, x, y);
|
||||
|
||||
// me.onDeath = function() {};
|
||||
me.flapRate = 0.06 + 0.03 * Math.random()
|
||||
me.flapRadius = 40 + radius * 3
|
||||
me.do = function () {
|
||||
this.seePlayerByHistory()
|
||||
this.checkStatus();
|
||||
if (this.seePlayer.recall) {
|
||||
this.force.x += Math.cos(this.angle) * this.accelMag * this.mass
|
||||
this.force.y += Math.sin(this.angle) * this.accelMag * this.mass
|
||||
|
||||
//set direction to turn to fire
|
||||
if (!(simulation.cycle % this.seePlayerFreq)) {
|
||||
this.fireDir = Vector.normalise(Vector.sub(this.seePlayer.position, this.position));
|
||||
//dot product can't tell if mob is facing directly away or directly towards, so check if pointed directly away from player every few cycles
|
||||
const mod = (a, n) => a - Math.floor(a / n) * n
|
||||
const sub = Vector.sub(m.pos, this.position) //check by comparing different between angles. Give this a nudge if angles are 180 degree different
|
||||
const diff = mod(Math.atan2(sub.y, sub.x) - this.angle + Math.PI, 2 * Math.PI) - Math.PI
|
||||
if (Math.abs(diff) > 2.8) this.torque += 0.0002 * this.inertia * Math.random();
|
||||
}
|
||||
|
||||
//rotate towards fireDir
|
||||
const angle = this.angle + Math.PI / 2;
|
||||
c = Math.cos(angle) * this.fireDir.x + Math.sin(angle) * this.fireDir.y;
|
||||
const threshold = 0.4;
|
||||
const turn = 0.00002 * this.inertia
|
||||
if (c > threshold) {
|
||||
this.torque += turn;
|
||||
} else if (c < -threshold) {
|
||||
this.torque -= turn;
|
||||
}
|
||||
|
||||
// this.accelMag = 0.0006 + 0.0007 * Math.sqrt(simulation.accelScale);
|
||||
this.frictionAir = 0.11 + 0.09 * Math.sin(simulation.cycle * this.flapRate - Math.PI / 2)
|
||||
|
||||
const flapArc = 0.8 //don't go past 1.57 for normal flaps
|
||||
ctx.fillStyle = `hsla(${160 + 40 * Math.random()}, 100%, ${25 + 25 * Math.random() * Math.random()}%, 0.2)`; //"rgba(0,235,255,0.3)"; // ctx.fillStyle = `hsla(44, 79%, 31%,0.4)`; //"rgba(0,235,255,0.3)";
|
||||
this.wing(this.angle + 2.1 + flapArc * Math.sin(simulation.cycle * this.flapRate), this.flapRadius)
|
||||
this.wing(this.angle - 2.1 - flapArc * Math.sin(simulation.cycle * this.flapRate), this.flapRadius)
|
||||
|
||||
const seeRange = 550 + 35 * simulation.difficultyMode;
|
||||
if (this.distanceToPlayer() < seeRange) {
|
||||
const vertexCollision = function (v1, v1End, domain) {
|
||||
for (let i = 0; i < domain.length; ++i) {
|
||||
let vertices = domain[i].vertices;
|
||||
const len = vertices.length - 1;
|
||||
for (let j = 0; j < len; j++) {
|
||||
results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
|
||||
if (results.onLine1 && results.onLine2) {
|
||||
const dx = v1.x - results.x;
|
||||
const dy = v1.y - results.y;
|
||||
const dist2 = dx * dx + dy * dy;
|
||||
if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
|
||||
best = {
|
||||
x: results.x,
|
||||
y: results.y,
|
||||
dist2: dist2,
|
||||
who: domain[i],
|
||||
v1: vertices[j],
|
||||
v2: vertices[j + 1]
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
results = simulation.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
|
||||
if (results.onLine1 && results.onLine2) {
|
||||
const dx = v1.x - results.x;
|
||||
const dy = v1.y - results.y;
|
||||
const dist2 = dx * dx + dy * dy;
|
||||
if (dist2 < best.dist2) {
|
||||
best = {
|
||||
x: results.x,
|
||||
y: results.y,
|
||||
dist2: dist2,
|
||||
who: domain[i],
|
||||
v1: vertices[0],
|
||||
v2: vertices[len]
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
best = {
|
||||
x: null,
|
||||
y: null,
|
||||
dist2: Infinity,
|
||||
who: null,
|
||||
v1: null,
|
||||
v2: null
|
||||
};
|
||||
const seeRangeRandom = seeRange - 200 - 150 * Math.random()
|
||||
const look = {
|
||||
x: this.position.x + seeRangeRandom * Math.cos(this.angle),
|
||||
y: this.position.y + seeRangeRandom * Math.sin(this.angle)
|
||||
};
|
||||
vertexCollision(this.position, look, map);
|
||||
vertexCollision(this.position, look, body);
|
||||
if (!m.isCloak) vertexCollision(this.position, look, [playerBody, playerHead]);
|
||||
|
||||
// hitting player
|
||||
if ((best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) {
|
||||
const dmg = 0.002 * simulation.dmgScale;
|
||||
m.damage(dmg);
|
||||
//draw damage
|
||||
ctx.fillStyle = color;
|
||||
ctx.beginPath();
|
||||
ctx.arc(best.x, best.y, 5 + dmg * 1500, 0, 2 * Math.PI);
|
||||
ctx.fill();
|
||||
}
|
||||
//draw beam
|
||||
const vertex = 3
|
||||
if (best.dist2 === Infinity) best = look;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(this.vertices[vertex].x, this.vertices[vertex].y);
|
||||
ctx.lineTo(best.x, best.y);
|
||||
ctx.strokeStyle = color;
|
||||
ctx.lineWidth = 2;
|
||||
ctx.setLineDash([50 + 120 * Math.random(), 50 * Math.random()]);
|
||||
ctx.stroke();
|
||||
ctx.setLineDash([]);
|
||||
|
||||
// ctx.beginPath();
|
||||
// ctx.arc(this.vertices[vertex].x, this.vertices[vertex].y, 5, 0, 2 * Math.PI); //* this.fireCycle / this.fireDelay
|
||||
// ctx.fillStyle = color;
|
||||
// ctx.fill();
|
||||
}
|
||||
// else {
|
||||
// ctx.beginPath();
|
||||
// ctx.arc(this.vertices[1].x, this.vertices[1].y, 1 + 0.3 * (simulation.cycle % this.laserInterval), 0, 2 * Math.PI); //* this.fireCycle / this.fireDelay
|
||||
// ctx.fillStyle = color;
|
||||
// ctx.fill();
|
||||
// }
|
||||
}
|
||||
// else { //flocking behavior (not working yet)
|
||||
// this.force.x += Math.cos(this.angle) * this.accelMag * this.mass
|
||||
// this.force.y += Math.sin(this.angle) * this.accelMag * this.mass
|
||||
// //set direction to turn to fire
|
||||
// if (!(simulation.cycle % this.seePlayerFreq)) {
|
||||
// //find nearest mob and maintain a distance
|
||||
// let nearestMob = null
|
||||
// let nearestMobDistance = Infinity
|
||||
// for (let i = 0; i < mob.length; i++) {
|
||||
// const newMobDistance = Vector.magnitude(Vector.sub(this.position, mob[i].position))
|
||||
// if (mob[i].isDropPowerUp && mob[i].alive && newMobDistance < nearestMobDistance) { //&& !mob[i].isBoss
|
||||
// nearestMobDistance = newMobDistance
|
||||
// nearestMob = mob[i]
|
||||
// }
|
||||
// }
|
||||
// if (nearestMob) {
|
||||
// // console.log(nearestMob)
|
||||
// this.fireDir = Vector.normalise(Vector.sub(nearestMob.position, this.position));
|
||||
// //dot product can't tell if mob is facing directly away or directly towards, so check if pointed directly away from player every few cycles
|
||||
// const mod = (a, n) => {
|
||||
// return a - Math.floor(a / n) * n
|
||||
// }
|
||||
// const sub = Vector.sub(nearestMob.position, this.position) //check by comparing different between angles. Give this a nudge if angles are 180 degree different
|
||||
// const diff = mod(Math.atan2(sub.y, sub.x) - this.angle + Math.PI, 2 * Math.PI) - Math.PI
|
||||
// if (Math.abs(diff) > 2.8) this.torque += 0.0002 * this.inertia * Math.random();
|
||||
// }
|
||||
// }
|
||||
// //rotate towards fireDir
|
||||
// const angle = this.angle + Math.PI / 2;
|
||||
// c = Math.cos(angle) * this.fireDir.x + Math.sin(angle) * this.fireDir.y;
|
||||
// const threshold = 0.4;
|
||||
// const turn = 0.000025 * this.inertia
|
||||
// if (c > threshold) {
|
||||
// this.torque += turn;
|
||||
// } else if (c < -threshold) {
|
||||
// this.torque -= turn;
|
||||
// }
|
||||
// const flapArc = 0.7 //don't go past 1.57 for normal flaps
|
||||
// ctx.fillStyle = `hsla(${160 + 40 * Math.random()}, 100%, ${25 + 25 * Math.random() * Math.random()}%, 0.2)`; //"rgba(0,235,255,0.3)"; // ctx.fillStyle = `hsla(44, 79%, 31%,0.4)`; //"rgba(0,235,255,0.3)";
|
||||
// this.wing(this.angle + Math.PI / 2 + flapArc * Math.sin(simulation.cycle * this.flapRate), this.flapRadius)
|
||||
// this.wing(this.angle - Math.PI / 2 - flapArc * Math.sin(simulation.cycle * this.flapRate), this.flapRadius)
|
||||
// }
|
||||
};
|
||||
},
|
||||
beetleBoss(x, y, radius = 50) {
|
||||
mobs.spawn(x, y, 7, radius, '#16576b');
|
||||
let me = mob[mob.length - 1];
|
||||
|
||||
242
js/tech.js
242
js/tech.js
@@ -231,7 +231,7 @@ const tech = {
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
if (tech.isDivisor && b.activeGun && b.guns[b.activeGun].ammo % 3 === 0) dmg *= 1.77
|
||||
if (tech.isDivisor && b.activeGun !== undefined && b.activeGun !== null && b.guns[b.activeGun].ammo % 3 === 0) dmg *= 1.77
|
||||
if (tech.isNoGroundDamage) dmg *= m.onGround ? 0.85 : 2
|
||||
if (tech.isDilate) dmg *= 1.5 + 0.6 * Math.sin(m.cycle * 0.0075)
|
||||
if (tech.isGunChoice && tech.buffedGun === b.inventoryGun) dmg *= 1 + 0.31 * b.inventory.length
|
||||
@@ -250,11 +250,11 @@ const tech = {
|
||||
if (tech.isBotDamage) dmg *= 1 + 0.06 * b.totalBots()
|
||||
if (tech.restDamage > 1 && player.speed < 1) dmg *= tech.restDamage
|
||||
if (tech.isLowEnergyDamage) dmg *= 1 + 0.7 * Math.max(0, 1 - m.energy)
|
||||
if (tech.energyDamage) dmg *= 1 + m.energy * 0.22 * tech.energyDamage;
|
||||
if (tech.energyDamage) dmg *= 1 + m.energy * 0.26 * tech.energyDamage;
|
||||
if (tech.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.007
|
||||
if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 2
|
||||
if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 2.11
|
||||
if (tech.isSpeedDamage) dmg *= 1 + Math.min(0.88, player.speed * 0.0193)
|
||||
if (tech.isDamageAfterKillNoRegen && m.lastKillCycle + 300 > m.cycle) dmg *= 1.83
|
||||
if (tech.isDamageAfterKillNoRegen && m.lastKillCycle + 300 > m.cycle) dmg *= 1.93
|
||||
if (tech.isAxion && tech.isHarmMACHO) dmg *= 2 - m.defense()
|
||||
if (tech.isHarmDamage && m.lastHarmCycle + 480 > m.cycle) dmg *= 3;
|
||||
if (tech.lastHitDamage && m.lastHit) dmg *= 1 + tech.lastHitDamage * m.lastHit * (2 - m.defense()) // if (!simulation.paused) m.lastHit = 0
|
||||
@@ -314,7 +314,7 @@ const tech = {
|
||||
},
|
||||
tech: [{
|
||||
name: "tungsten carbide",
|
||||
description: "<strong>+222</strong> maximum <strong class='color-h'>health</strong><br><strong>lose</strong> <strong class='color-h'>health</strong> after hard <strong>landings</strong>",
|
||||
description: "<strong>+300</strong> maximum <strong class='color-h'>health</strong><br><strong>lose</strong> <strong class='color-h'>health</strong> after hard <strong>landings</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -328,7 +328,7 @@ const tech = {
|
||||
tech.hardLanding = 70
|
||||
tech.isFallingDamage = true;
|
||||
m.setMaxHealth();
|
||||
m.addHealth(2.22 / simulation.healScale)
|
||||
m.addHealth(3 / simulation.healScale)
|
||||
m.skin.tungsten()
|
||||
},
|
||||
remove() {
|
||||
@@ -402,9 +402,9 @@ const tech = {
|
||||
isAltRealityTech: true,
|
||||
isSkin: true,
|
||||
allowed() {
|
||||
return !tech.isResearchReality && !tech.isSwitchReality
|
||||
return !m.isAltSkin && !tech.isResearchReality && !tech.isSwitchReality
|
||||
},
|
||||
requires: "not Ψ(t) collapse, many-worlds",
|
||||
requires: "not skinned, Ψ(t) collapse, many-worlds",
|
||||
damage: 2.42,
|
||||
effect() {
|
||||
m.skin.anodize();
|
||||
@@ -672,6 +672,43 @@ const tech = {
|
||||
},
|
||||
remove() { }
|
||||
},
|
||||
{
|
||||
name: "supply chain",
|
||||
descriptionFunction() {
|
||||
return `<strong>double</strong> your current <strong class='color-ammo'>ammo</strong> for all your <strong class='color-g'>guns</strong><br><strong>triple</strong> the frequency of finding <strong>applied science</strong>`
|
||||
},
|
||||
maxCount: 9,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return true
|
||||
},
|
||||
requires: "",
|
||||
effect() {
|
||||
for (let i = 0; i < b.guns.length; i++) {
|
||||
if (b.guns[i].have) b.guns[i].ammo = Math.floor(2 * b.guns[i].ammo)
|
||||
}
|
||||
simulation.makeGunHUD();
|
||||
for (let i = 0, len = tech.tech.length; i < len; i++) {
|
||||
if (tech.tech[i].name === "applied science") tech.tech[i].frequency *= 3
|
||||
}
|
||||
},
|
||||
remove() {
|
||||
if (this.count) {
|
||||
for (let j = 0; j < this.count; j++) {
|
||||
for (let i = 0; i < b.guns.length; i++) {
|
||||
if (b.guns[i].have) b.guns[i].ammo = Math.floor(0.5 * b.guns[i].ammo)
|
||||
}
|
||||
}
|
||||
simulation.makeGunHUD();
|
||||
|
||||
for (let i = 0, len = tech.tech.length; i < len; i++) {
|
||||
if (tech.tech[i].name === "applied science") tech.tech[i].frequency = 2
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "applied science",
|
||||
description: `get a random <strong class='color-g'>gun</strong><strong class='color-m'>tech</strong><br>for each of your <strong class='color-g'>guns</strong>`, //spawn ${powerUps.orb.research(1)} and
|
||||
@@ -812,40 +849,6 @@ const tech = {
|
||||
// }
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "supply chain",
|
||||
descriptionFunction() {
|
||||
return `double your current <strong class='color-ammo'>ammo</strong><br><strong>+4%</strong> <strong class='color-junk'>JUNK</strong> to <strong class='color-m'>tech</strong> pool`
|
||||
},
|
||||
maxCount: 9,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return true
|
||||
},
|
||||
requires: "",
|
||||
effect() {
|
||||
for (let i = 0; i < b.guns.length; i++) {
|
||||
if (b.guns[i].have) b.guns[i].ammo = Math.floor(2 * b.guns[i].ammo)
|
||||
}
|
||||
simulation.makeGunHUD();
|
||||
this.refundAmount += tech.addJunkTechToPool(0.04)
|
||||
},
|
||||
refundAmount: 0,
|
||||
remove() {
|
||||
for (let j = 0; j < this.count; j++) {
|
||||
for (let i = 0; i < b.guns.length; i++) {
|
||||
if (b.guns[i].have) b.guns[i].ammo = Math.floor(0.5 * b.guns[i].ammo)
|
||||
}
|
||||
}
|
||||
simulation.makeGunHUD();
|
||||
if (this.count > 0 && this.refundAmount > 0) {
|
||||
tech.removeJunkTechFromPool(this.refundAmount)
|
||||
this.refundAmount = 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "logistics",
|
||||
description: `${powerUps.orb.ammo()} give <strong>80%</strong> more <strong class='color-ammo'>ammo</strong>, but<br>it's only added to your current <strong class='color-g'>gun</strong>`,
|
||||
@@ -909,7 +912,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "non-renewables",
|
||||
description: `<strong>+88%</strong> <strong class='color-d'>damage</strong><br>${powerUps.orb.ammo()} can't <strong>spawn</strong>`,
|
||||
description: `<strong>+97%</strong> <strong class='color-d'>damage</strong><br>${powerUps.orb.ammo()} can't <strong>spawn</strong>`,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -918,7 +921,7 @@ const tech = {
|
||||
return !tech.isAmmoFromHealth && !tech.isBoostReplaceAmmo
|
||||
},
|
||||
requires: "not catabolism, quasiparticles",
|
||||
damage: 1.88,
|
||||
damage: 1.97,
|
||||
effect() {
|
||||
tech.damage *= this.damage
|
||||
tech.isEnergyNoAmmo = true;
|
||||
@@ -2068,7 +2071,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "decorrelation",
|
||||
description: "if your <strong class='color-g'>gun</strong> or <strong class='color-f'>field</strong> are unused for <strong>2</strong> seconds<br><strong>+70%</strong> <strong class='color-defense'>defense</strong>",
|
||||
description: "if your <strong class='color-g'>gun</strong> or <strong class='color-f'>field</strong> are unused for <strong>2</strong> seconds<br><strong>+77%</strong> <strong class='color-defense'>defense</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -2086,7 +2089,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "anticorrelation",
|
||||
description: "if your <strong class='color-g'>gun</strong> or <strong class='color-f'>field</strong> are unused for <strong>2</strong> seconds<br><strong>+100%</strong> <strong class='color-d'>damage</strong>",
|
||||
description: "if your <strong class='color-g'>gun</strong> or <strong class='color-f'>field</strong> are unused for <strong>2</strong> seconds<br><strong>+111%</strong> <strong class='color-d'>damage</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -2785,7 +2788,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "overcharge",
|
||||
description: "<strong>+66</strong> maximum <strong class='color-f'>energy</strong><br><strong>+6%</strong> <strong class='color-junk'>JUNK</strong> to <strong class='color-m'>tech</strong> pool",
|
||||
description: "<strong>+66</strong> maximum <strong class='color-f'>energy</strong><br><strong>+5%</strong> <strong class='color-junk'>JUNK</strong> to <strong class='color-m'>tech</strong> pool",
|
||||
maxCount: 9,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -2797,7 +2800,7 @@ const tech = {
|
||||
effect() {
|
||||
tech.bonusEnergy += 0.66
|
||||
m.setMaxEnergy()
|
||||
this.refundAmount += tech.addJunkTechToPool(0.06)
|
||||
this.refundAmount += tech.addJunkTechToPool(0.05)
|
||||
},
|
||||
refundAmount: 0,
|
||||
remove() {
|
||||
@@ -2876,7 +2879,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "parasitism",
|
||||
description: "if a mob has <strong>died</strong> in the last <strong>5 seconds</strong><br><strong>+83%</strong> <strong class='color-d'>damage</strong>, inhibit <strong class='color-f'>energy</strong> generation",
|
||||
description: "if a mob has <strong>died</strong> in the last <strong>5 seconds</strong><br><strong>+93%</strong> <strong class='color-d'>damage</strong>, no passive <strong class='color-f'>energy</strong> generation",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -2917,7 +2920,10 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "recycling",
|
||||
description: "if a mob has <strong>died</strong> in the last <strong>5 seconds</strong><br>recover <strong>0.5%</strong> of max <strong class='color-h'>health</strong> per second",
|
||||
descriptionFunction() {
|
||||
return `if a mob has <strong>died</strong> in the last <strong>5 seconds</strong><br>recover <strong>0.5%</strong> of max ${tech.isEnergyHealth ? "<strong class='color-f'>energy</strong>" : "<strong class='color-h'>health</strong>"} per second`
|
||||
},
|
||||
description: "",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -2936,7 +2942,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "torpor",
|
||||
description: "if a mob has <strong>not died</strong> in the last <strong>5 seconds</strong><br><strong>+66%</strong> <strong class='color-defense'>defense</strong>",
|
||||
description: "if a mob has <strong>not died</strong> in the last <strong>5 seconds</strong><br><strong>+74%</strong> <strong class='color-defense'>defense</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -3280,7 +3286,7 @@ const tech = {
|
||||
}, 1000);
|
||||
},
|
||||
descriptionFunction() {
|
||||
return `once per level, instead of <strong>dying</strong><br>use ${powerUps.orb.research(1)} and spawn ${powerUps.orb.heal(5)}`
|
||||
return `once per level, instead of <strong>dying</strong><br>use ${powerUps.orb.research(1)} and spawn ${powerUps.orb.heal(16)}`
|
||||
},
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -3381,7 +3387,7 @@ const tech = {
|
||||
{
|
||||
name: "Ψ(t) collapse",
|
||||
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Wave_function_collapse' class="link">Ψ(t) collapse</a>`,
|
||||
description: `spawn ${powerUps.orb.research(16)}<br>after you <strong class='color-r'>research</strong> enter an <strong class='alt'>alternate reality</strong>`,
|
||||
description: `spawn ${powerUps.orb.research(21)}<br>after you <strong class='color-r'>research</strong> enter an <strong class='alt'>alternate reality</strong>`,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -3391,7 +3397,7 @@ const tech = {
|
||||
return !tech.isSwitchReality && !tech.isCollisionRealitySwitch && !tech.isJunkResearch
|
||||
},
|
||||
requires: "not many-worlds, Hilbert space, pseudoscience",
|
||||
bonusResearch: 16,
|
||||
bonusResearch: 21,
|
||||
effect() {
|
||||
tech.isResearchReality = true;
|
||||
for (let i = 0; i < this.bonusResearch; i++) powerUps.spawn(m.pos.x + Math.random() * 60, m.pos.y + Math.random() * 60, "research", false);
|
||||
@@ -3431,7 +3437,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "renormalization",
|
||||
description: `<strong>46%</strong> chance to spawn ${powerUps.orb.research(1)} after consuming ${powerUps.orb.research(1)}<br><strong>+3%</strong> <strong class='color-junk'>JUNK</strong> to <strong class='color-m'>tech</strong> pool`,
|
||||
description: `<strong>47%</strong> chance to spawn ${powerUps.orb.research(1)} after consuming ${powerUps.orb.research(1)}<br><strong>+5%</strong> <strong class='color-junk'>JUNK</strong> to <strong class='color-m'>tech</strong> pool`,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
@@ -3442,7 +3448,7 @@ const tech = {
|
||||
requires: "at least 4 research, not superdeterminism",
|
||||
effect() {
|
||||
tech.renormalization = true;
|
||||
this.refundAmount += tech.addJunkTechToPool(0.03)
|
||||
this.refundAmount += tech.addJunkTechToPool(0.05)
|
||||
|
||||
},
|
||||
refundAmount: 0,
|
||||
@@ -3481,7 +3487,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "ansatz",
|
||||
description: `after choosing a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>if you have no ${powerUps.orb.research(1)} in your inventory spawn ${powerUps.orb.research(2)}`,
|
||||
description: `after choosing a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>if you have no ${powerUps.orb.research(1)} in your inventory spawn ${powerUps.orb.research(3)}`,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -3501,17 +3507,17 @@ const tech = {
|
||||
name: "Bayesian statistics",
|
||||
// description: `for each ${powerUps.orb.research(1)} in your inventory<br><strong>+3.8%</strong> <strong class='color-d'>damage</strong>`,
|
||||
descriptionFunction() {
|
||||
return `spawn ${powerUps.orb.research(this.bonusResearch)}<br><strong>+3%</strong> <strong class='color-d'>damage</strong> per ${powerUps.orb.research(1)} <em>(${(3 * powerUps.research.count).toFixed(0)}%)</em>`
|
||||
return `spawn ${powerUps.orb.research(this.bonusResearch)}<br><strong>+3%</strong> <strong class='color-d'>damage</strong> per ${powerUps.orb.research(1)} in your inventory <em>(${(3 * powerUps.research.count).toFixed(0)}%)</em>`
|
||||
},
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return powerUps.research.count > 2 || build.isExperimentSelection
|
||||
return powerUps.research.count > 1 || build.isExperimentSelection
|
||||
},
|
||||
requires: "at least 3 research",
|
||||
bonusResearch: 3,
|
||||
requires: "at least 2 research",
|
||||
bonusResearch: 6,
|
||||
effect() {
|
||||
powerUps.spawnDelay("research", this.bonusResearch)
|
||||
tech.isRerollDamage = true;
|
||||
@@ -3526,7 +3532,7 @@ const tech = {
|
||||
{
|
||||
name: "mass production",
|
||||
descriptionFunction() {
|
||||
return `<strong class='color-m'>tech</strong> always have <strong>+3</strong> choices to spawn<br>${powerUps.orb.ammo(10)} ${powerUps.orb.heal(10)} or ${powerUps.orb.research(7)}`
|
||||
return `<strong class='color-m'>tech</strong> always have <strong>+3</strong> choices to spawn<br>options for ${powerUps.orb.ammo(1)} or ${powerUps.orb.heal(1)} or ${powerUps.orb.research(1)}`
|
||||
},
|
||||
// description: `<strong class='color-m'>tech</strong> always have <strong>+3</strong> choices to spawn<br>${powerUps.orb.ammo(8)} ${powerUps.orb.heal(8)} or ${powerUps.orb.research(5)}`,
|
||||
maxCount: 1,
|
||||
@@ -3544,8 +3550,10 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "research",
|
||||
description: `spawn ${powerUps.orb.research(7)}`,
|
||||
maxCount: 1,
|
||||
descriptionFunction() {
|
||||
return `spawn ${this.value > 36 ? this.value + powerUps.orb.research(1) : powerUps.orb.research(this.value)}<br>next time this effect is improved by ${powerUps.orb.research(5)}`
|
||||
},
|
||||
maxCount: 9,
|
||||
count: 0,
|
||||
frequency: 0,
|
||||
frequencyDefault: 0,
|
||||
@@ -3553,15 +3561,19 @@ const tech = {
|
||||
isMassProduction: true,
|
||||
allowed() { return true },
|
||||
requires: "",
|
||||
value: 8,
|
||||
effect() {
|
||||
powerUps.spawnDelay("research", 7);
|
||||
powerUps.spawnDelay("research", this.value);
|
||||
this.value += 5
|
||||
},
|
||||
remove() { }
|
||||
},
|
||||
{
|
||||
name: "ammo",
|
||||
description: `spawn ${powerUps.orb.ammo(10)}`,
|
||||
maxCount: 1,
|
||||
descriptionFunction() {
|
||||
return `spawn ${this.value > 33 ? this.value + powerUps.orb.ammo(1) : powerUps.orb.ammo(this.value)}<br>next time this effect is improved by ${powerUps.orb.ammo(7)}`
|
||||
},
|
||||
maxCount: 9,
|
||||
count: 0,
|
||||
frequency: 0,
|
||||
frequencyDefault: 0,
|
||||
@@ -3569,26 +3581,30 @@ const tech = {
|
||||
isMassProduction: true,
|
||||
allowed() { return true },
|
||||
requires: "",
|
||||
value: 10,
|
||||
effect() {
|
||||
powerUps.spawnDelay("ammo", 10);
|
||||
powerUps.spawnDelay("ammo", this.value);
|
||||
this.value += 7
|
||||
},
|
||||
remove() { }
|
||||
},
|
||||
{
|
||||
name: "heals",
|
||||
descriptionFunction() {
|
||||
return `spawn ${powerUps.orb.heal(10)}`
|
||||
return `spawn ${this.value > 30 ? this.value + powerUps.orb.heal(1) : powerUps.orb.heal(this.value)}<br>next time this effect is improved by ${powerUps.orb.heal(7)}`
|
||||
},
|
||||
maxCount: 1,
|
||||
maxCount: 9,
|
||||
count: 0,
|
||||
frequency: 0,
|
||||
frequencyDefault: 0,
|
||||
isNonRefundable: true,
|
||||
isMassProduction: true,
|
||||
allowed() { return true },
|
||||
requires: "mass production",
|
||||
requires: "",
|
||||
value: 10,
|
||||
effect() {
|
||||
powerUps.spawnDelay("heal", 10);
|
||||
powerUps.spawnDelay("heal", this.value);
|
||||
this.value += 7
|
||||
},
|
||||
remove() { }
|
||||
},
|
||||
@@ -3624,7 +3640,7 @@ const tech = {
|
||||
effect() {
|
||||
tech.isBrainstorm = true
|
||||
tech.isBrainstormActive = false
|
||||
tech.brainStormDelay = 1800 - simulation.difficultyMode * 100
|
||||
tech.brainStormDelay = 2000 - simulation.difficultyMode * 100
|
||||
},
|
||||
remove() {
|
||||
tech.isBrainstorm = false
|
||||
@@ -3921,7 +3937,11 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "paradigm shift",
|
||||
description: `when <strong>paused</strong> clicking a <strong class='color-m'>tech</strong> <strong>ejects</strong> it<br>with a <strong>20%</strong> chance to remove without <strong>ejecting</strong>`,
|
||||
// description: `when <strong>paused</strong> clicking a <strong class='color-m'>tech</strong> <strong>ejects</strong> it<br>with a <strong>20%</strong> chance to remove without <strong>ejecting</strong>`,
|
||||
// description: `when <strong>paused</strong> clicking a <strong class='color-m'>tech</strong> <strong>ejects</strong> it<br>and a <strong>20%</strong> chance to remove without <strong>ejecting</strong>`,
|
||||
descriptionFunction() {
|
||||
return `when <strong>paused</strong> clicking a <strong class='color-m'>tech</strong> <strong>ejects</strong> it<br><strong>–6</strong> ${tech.isEnergyHealth ? "<strong class='color-f'>energy</strong>" : "<strong class='color-h'>health</strong>"} each time and a <strong>3%</strong> chance to fail`
|
||||
},
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -4154,7 +4174,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "futures exchange",
|
||||
description: "clicking <strong class='color-cancel'>cancel</strong> for a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>gives <strong>+4.3%</strong> power up <strong class='color-dup'>duplication</strong> chance",
|
||||
description: "clicking <strong class='color-cancel'>cancel</strong> for a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>gives <strong>+4.7%</strong> power up <strong class='color-dup'>duplication</strong> chance",
|
||||
// descriptionFunction() {
|
||||
// return `clicking <strong style = 'font-size:150%;'>×</strong> to <strong>cancel</strong> a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>gives <strong>+${4.9 - 0.15*simulation.difficultyMode}%</strong> power up <strong class='color-dup'>duplication</strong> chance`
|
||||
// },
|
||||
@@ -4177,7 +4197,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "replication",
|
||||
description: "<strong>+9%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br><strong>+33%</strong> <strong class='color-junk'>JUNK</strong> to <strong class='color-m'>tech</strong> pool",
|
||||
description: "<strong>+10%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br><strong>+33%</strong> <strong class='color-junk'>JUNK</strong> to <strong class='color-m'>tech</strong> pool",
|
||||
maxCount: 9,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -4187,7 +4207,7 @@ const tech = {
|
||||
},
|
||||
requires: "below 100% duplication chance",
|
||||
effect() {
|
||||
tech.duplicateChance += 0.09
|
||||
tech.duplicateChance += 0.1
|
||||
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
|
||||
if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.11);
|
||||
this.refundAmount += tech.addJunkTechToPool(0.33)
|
||||
@@ -4204,7 +4224,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "stimulated emission",
|
||||
description: "<strong>+17%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong>,<br>but after a <strong>collision</strong> eject <strong>1</strong> <strong class='color-m'>tech</strong>",
|
||||
description: "<strong>+19%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong>,<br>but after a <strong>collision</strong> eject <strong>1</strong> <strong class='color-m'>tech</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -4328,6 +4348,34 @@ const tech = {
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "strange loop",
|
||||
// description: `<strong>+11%</strong> <strong class='color-d'>damage</strong><br><strong>removing</strong> this doubles it's damage if you take it again`,
|
||||
description: `<strong>+9%</strong> <strong class='color-d'>damage</strong><br><span style = 'font-size:87%;'><strong>removing</strong> this gives <strong>strange attractor</strong> and <strong>null hypothesis</strong></span>`,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
isBadRandomOption: true,
|
||||
allowed() {
|
||||
return true
|
||||
},
|
||||
requires: "",
|
||||
damage: 1.09,
|
||||
effect() {
|
||||
tech.damage *= this.damage
|
||||
},
|
||||
remove() {
|
||||
if (this.count > 0 && m.alive) {
|
||||
tech.damage /= this.damage
|
||||
this.frequency = 0
|
||||
requestAnimationFrame(() => {
|
||||
tech.giveTech("null hypothesis")
|
||||
tech.giveTech("strange attractor")
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "null hypothesis",
|
||||
description: `<strong>+8%</strong> <strong class='color-d'>damage</strong><br><strong>removing</strong> this spawns ${powerUps.orb.research(15)}`,
|
||||
@@ -4352,6 +4400,35 @@ const tech = {
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "martingale",
|
||||
descriptionFunction() {
|
||||
return `<span style = 'font-size:95%;'><strong>+${(100 * this.damage).toFixed(0)}%</strong> <strong class='color-d'>damage</strong>. After removing this there is a <strong>50%</strong><br>chance to get it back with <strong>double</strong> its <strong class='color-d'>damage</strong></span>`
|
||||
},
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
isBadRandomOption: true,
|
||||
allowed() {
|
||||
return true
|
||||
},
|
||||
requires: "",
|
||||
damage: 0.11,
|
||||
effect() {
|
||||
tech.damage *= 1 + this.damage
|
||||
},
|
||||
remove() {
|
||||
if (this.count > 0 && m.alive) {
|
||||
tech.damage /= 1 + this.damage
|
||||
if (Math.random() < 0.5) {
|
||||
this.damage *= 2
|
||||
requestAnimationFrame(() => { tech.giveTech("chaos theory") });
|
||||
}
|
||||
this.frequency = 0
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "Born rule",
|
||||
description: "<strong>remove</strong> all current <strong class='color-m'>tech</strong><br>spawn new <strong class='color-m'>tech</strong> to replace them",
|
||||
@@ -4744,6 +4821,8 @@ const tech = {
|
||||
b.guns[0].ammoPack = b.guns[0].defaultAmmoPack;
|
||||
if (b.guns[0].recordedAmmo) b.guns[0].ammo = b.guns[0].recordedAmmo
|
||||
simulation.updateGunHUD();
|
||||
|
||||
if (this.count) requestAnimationFrame(() => { simulation.updateGunHUD(); });
|
||||
}
|
||||
tech.isIceCrystals = false;
|
||||
if (b.guns[0].ammo === Infinity) b.guns[0].ammo = 0
|
||||
@@ -5377,6 +5456,7 @@ const tech = {
|
||||
if (this.count > 0 && b.guns[3].savedAmmo !== undefined) {
|
||||
b.guns[3].ammo = b.guns[3].savedAmmo
|
||||
simulation.updateGunHUD();
|
||||
requestAnimationFrame(() => { simulation.updateGunHUD(); });
|
||||
} else if (b.guns[3].ammo === Infinity) {
|
||||
b.guns[3].ammo = 0
|
||||
}
|
||||
@@ -7071,7 +7151,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "induction furnace",
|
||||
description: "after using <strong>harpoon</strong> or <strong>grapple</strong> to collect <strong>power ups</strong><br><strong>+77%</strong> <strong>harpoon</strong> or <strong>grapple</strong> <strong class='color-d'>damage</strong> for 8 seconds",
|
||||
description: "after using <strong>harpoon</strong>/<strong>grapple</strong> to collect <strong>power ups</strong><br><strong>+77%</strong> <strong>harpoon</strong> or <strong>grapple</strong> <strong class='color-d'>damage</strong> for 8 seconds",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -7091,7 +7171,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "brittle",
|
||||
description: "<strong>+88%</strong> <strong>harpoon</strong> and <strong>grapple</strong> <strong class='color-d'>damage</strong><br>to <strong>mobs</strong> at maximum <strong>health</strong>",
|
||||
description: "<strong>+88%</strong> <strong>harpoon</strong>/<strong>grapple</strong> <strong class='color-d'>damage</strong><br>to <strong>mobs</strong> at maximum <strong>health</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -7595,7 +7675,7 @@ const tech = {
|
||||
{
|
||||
name: "electronegativity",
|
||||
descriptionFunction() {
|
||||
return `<strong>+0.22%</strong> <strong class='color-d'>damage</strong> per current stored <strong class='color-f'>energy</strong><br><em>(+${(22 * m.maxEnergy).toFixed(0)}% damage at max energy)</em>`
|
||||
return `<strong>+0.26%</strong> <strong class='color-d'>damage</strong> per current stored <strong class='color-f'>energy</strong><br><em>(+${(27 * m.maxEnergy).toFixed(0)}% damage at max energy)</em>`
|
||||
},
|
||||
// description: "<strong>+1%</strong> <strong class='color-d'>damage</strong> per <strong>8</strong> stored <strong class='color-f'>energy</strong>",
|
||||
isFieldTech: true,
|
||||
|
||||
126
style.css
126
style.css
@@ -1377,3 +1377,129 @@ summary {
|
||||
.link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
/*
|
||||
.fade-ins {
|
||||
animation: 1.5s linear 1s fadeins;
|
||||
}
|
||||
|
||||
@keyframes fadeins {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
} */
|
||||
.blurry-text {
|
||||
color: transparent;
|
||||
text-shadow: 0 0 9px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.unblur {
|
||||
color: transparent;
|
||||
text-shadow: 0 0 9px rgba(0, 0, 0, 0.5);
|
||||
animation: 1.5s ease 1.2s normal forwards 1 unblur;
|
||||
}
|
||||
|
||||
@keyframes unblur {
|
||||
0% {
|
||||
color: transparent;
|
||||
text-shadow: 0 0 9px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
100% {
|
||||
/* font-weight: 800; */
|
||||
color: #000;
|
||||
text-shadow: 0 0 0px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
.fade-in {
|
||||
opacity: 0;
|
||||
animation: 2s ease 1.5s normal forwards 1 fadein;
|
||||
}
|
||||
|
||||
.fade-in-fast {
|
||||
opacity: 0;
|
||||
animation: 1.5s ease 1s normal forwards 1 fadein;
|
||||
}
|
||||
|
||||
.fade-in-faster {
|
||||
opacity: 0;
|
||||
animation: 2s ease 0.5s normal forwards 1 fadein;
|
||||
}
|
||||
|
||||
@keyframes fadein {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes dash {
|
||||
to {
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.draw-lines {
|
||||
stroke-dasharray: 20;
|
||||
stroke-dashoffset: 20;
|
||||
animation: dash 2.4s ease-in forwards;
|
||||
}
|
||||
|
||||
.draw-lines-dash {
|
||||
stroke-dasharray: 4;
|
||||
stroke-dashoffset: 4;
|
||||
animation: dash 2.4s ease-in forwards;
|
||||
}
|
||||
|
||||
.draw-lines-o {
|
||||
stroke-dasharray: 11;
|
||||
stroke-dashoffset: 11;
|
||||
animation: dash 2.4s ease-in forwards;
|
||||
}
|
||||
|
||||
.draw-lines-g {
|
||||
stroke-dasharray: 17;
|
||||
stroke-dashoffset: 17;
|
||||
animation: dash 2.4s ease-in forwards;
|
||||
}
|
||||
|
||||
.draw-lines-box-1 {
|
||||
stroke-dasharray: 1000;
|
||||
stroke-dashoffset: 1000;
|
||||
animation: dash 5s ease-in forwards;
|
||||
animation-delay: 0s;
|
||||
}
|
||||
|
||||
.draw-lines-box-2 {
|
||||
stroke-dasharray: 1000;
|
||||
stroke-dashoffset: 1000;
|
||||
animation: dash 2.6s ease-in forwards;
|
||||
animation-delay: 1s;
|
||||
}
|
||||
|
||||
.draw-lines-box-3 {
|
||||
stroke-dasharray: 1000;
|
||||
stroke-dashoffset: 1000;
|
||||
animation: dash 1.15s ease-in forwards;
|
||||
animation-delay: 1.55s;
|
||||
}
|
||||
|
||||
.draw-lines3 {
|
||||
stroke-dasharray: 3000;
|
||||
stroke-dashoffset: 3000;
|
||||
animation: dash 3.1s ease-in forwards;
|
||||
}
|
||||
|
||||
.draw-lines4 {
|
||||
stroke-dasharray: 300;
|
||||
stroke-dashoffset: 300;
|
||||
animation: dash 2.5s ease-in forwards;
|
||||
}
|
||||
53
todo.txt
53
todo.txt
@@ -1,55 +1,21 @@
|
||||
******************************************************** NEXT PATCH **************************************************
|
||||
|
||||
mob health tech
|
||||
tech: cascading failure - +222% damage to mobs below 25% health
|
||||
tech: yield stress - +55% damage to mobs at maximum health
|
||||
cloaking tech: topological defect - +88% damage to mobs at maximum health
|
||||
harpoon tech: brittle - +88% harpoon/grapple damage to mobs at maximum health
|
||||
|
||||
cloaking buffs
|
||||
50->66% defense while cloaked
|
||||
recloak 0.25s faster
|
||||
simplified cloaking field graphics
|
||||
boson composite drains much less energy while moving through mobs and shields
|
||||
fixed bug where mines and egg mobs were colliding with player while intangible
|
||||
patch no longer drains energy when you heal on cloaking
|
||||
metamaterial absorber gets 17->22% chance to spawn a power up for each mob alive
|
||||
no-cloning theorem changes to 45->40% duplication and 2->1% duplication loss on killing a mob
|
||||
|
||||
finalBoss phases:
|
||||
new: slow zone, antigravity pulse
|
||||
nerfed: laser, black hole, orbitals
|
||||
buffed: oscillation, mobs
|
||||
improved graphics: boulder
|
||||
|
||||
Hilbert space has a skin. 99->142% damage increase, but randomize tech after taking damage
|
||||
Higgs mechanism has a skin. +45->77% fire rate, player can't move while firing
|
||||
induction furnace gives +77% harpoon/grapple damage for 8 seconds after picking up a power up
|
||||
collider 50->100% chance to combine and randomize power ups
|
||||
quenching gives more bonus max health at high difficulty level (maybe around 30% more health)
|
||||
accretion gives 5->7 heal power ups
|
||||
dynamo bots follow player much closer when you have many of them
|
||||
scrap-bots don't follow the player as accurately or as quickly
|
||||
scrap bot duration 13->15 seconds
|
||||
JUNK tech: planned obsolescence - make 100 scrap bots that last for about 30 seconds
|
||||
|
||||
community map dojo by werid_pusheen
|
||||
fixed by Cornbread 2100
|
||||
|
||||
hard mode gets 1 less heal at the start
|
||||
hard and why difficulty don't begin with starter mobs
|
||||
hopBullet mobs last 2 seconds less time
|
||||
adjusted button heights on train station level to be consistently the same height
|
||||
|
||||
*********************************************************** TODO *****************************************************
|
||||
|
||||
hexagon head skin
|
||||
maybe give defense
|
||||
|
||||
|
||||
foam tech: increase size of foam and increase duration, but drop speed down, so they come to a stop and just hang
|
||||
allow them to harm player?
|
||||
this is probably just too annoying
|
||||
Foam slow down mobs twice as much and slowly pulls them towards the ground
|
||||
+30% foam damage
|
||||
Half foam velocity
|
||||
Foam is now effected by gravity
|
||||
Requires a source of foam and not aerogel
|
||||
https://en.m.wikipedia.org/wiki/Tungsten_hexafluoride
|
||||
|
||||
|
||||
make a flutter variant
|
||||
just move the wings to the back?
|
||||
@@ -1054,9 +1020,10 @@ add sounds
|
||||
|
||||
******************************************************** LORE ********************************************************
|
||||
|
||||
look up sci-fi science ideas here https://projectrho.com/public_html/rocket/
|
||||
|
||||
possible names for tech
|
||||
sidereal - with respect to the stars (an extra rotation for time keeping)
|
||||
strange loop
|
||||
holonomy - parallel transport of a vector leads to movement (applies to curved space)
|
||||
hypergolic - A hypergolic propellant combination used in a rocket engine is one whose components spontaneously ignite when they come into contact with each other.
|
||||
swarm intelligence - for a drone tech
|
||||
@@ -1103,8 +1070,8 @@ possible names for tech
|
||||
magnetorquers - produce spin by pushing on earth's magnetic field
|
||||
Josephson junction - superconducting junction
|
||||
Pyroelectricity - voltage from temp changes - upgrade from piezoelectricity
|
||||
perturbation
|
||||
Unruh effect - accelerating makes heat/thermal particles
|
||||
configuration space - holds the position of everything
|
||||
|
||||
******************************************************** CARS IMAGES ********************************************************
|
||||
|
||||
|
||||
Reference in New Issue
Block a user