technology

when you die store a copy of all your tech
  they will show up at your location in the future as a power up
  this is probably buggy

CPT triggers at above 100 energy instead of above 68 energy
causality bots makes a few less bots

several tech with dynamic effects show the value of the effect in their description
This commit is contained in:
landgreen
2022-10-17 20:07:43 -07:00
parent d996c4f2a2
commit 2e476b46fe
8 changed files with 233 additions and 142 deletions

View File

@@ -1358,6 +1358,7 @@ document.getElementById("difficulty-select").addEventListener("input", () => {
lore.setTechGoal()
localSettings.difficultyMode = simulation.difficultyMode
localSettings.levelsClearedLastGame = 0 //after changing difficulty, reset run history
localSettings.axiom = undefined //after changing difficulty, reset stored tech
if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
});

View File

@@ -18,24 +18,24 @@ const level = {
// simulation.enableConstructMode() //used to build maps in testing mode
// simulation.isHorizontalFlipped = true
// tech.giveTech("performance")
// level.difficultyIncrease(13 * 4) //30 is near max on hard //60 is near max on why
// level.difficultyIncrease(2 * 4) //30 is near max on hard //60 is near max on why
// m.maxHealth = m.health = 100
// tech.isRerollDamage = true
// powerUps.research.changeRerolls(500)
// powerUps.research.changeRerolls(50)
// m.immuneCycle = Infinity //you can't take damage
// tech.tech[297].frequency = 100
// m.couplingChange(5)
// m.setField("standing wave") //molecular assembler standing wave time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass pilot wave
// simulation.molecularMode = 2
// m.damage(0.1);
// b.giveGuns("laser") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.giveGuns("nail gun") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.guns[0].ammo = 10000
// tech.giveTech("lens")
// for (let i = 0; i < 9; ++i) tech.giveTech("compound lens")
// tech.giveTech("ice crystal nucleation")
// for (let i = 0; i < 1; ++i) tech.giveTech("compound lens")
// tech.giveTech("dye laser")
// for (let i = 0; i < 1; ++i) tech.giveTech("iridescence")
// for (let i = 0; i < 1; i++) tech.giveTech("slow light")
// for (let i = 0; i < 1; ++i) tech.giveTech("CPT symmetry")
// for (let i = 0; i < 5; i++) tech.giveTech("laser-bot")
// for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "tech");
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "boost");
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "coupling");
@@ -44,14 +44,15 @@ const level = {
// spawn.starter(1900, -500, 200)
// spawn.starter(1900, -500)
// spawn.timeBoss(2538, -950)
// for (let i = 0; i < 33; ++i) spawn.sniper(1000 + 5000 * Math.random(), -500 + 300 * Math.random())
// for (let i = 0; i < 5; ++i) spawn.sniper(1000 + 5000 * Math.random(), -500 + 300 * Math.random())
// tech.addJunkTechToPool(0.5)
// tech.tech[322].frequency = 100
// spawn.tetherBoss(1900, -500, { x: 1900, y: -500 })
// for (let i = 0; i < 40; ++i) tech.giveTech()
// for (let i = 0; i < 13; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "research");
if (simulation.isTraining) { level.walk(); } else { level.intro(); } //normal starting level ************************************************
// for (let i = 0; i < 4; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "tech");
// powerUps.spawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "technology", false, ["lens", "nail-bot"]);
// for (let i = 0; i < 2; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "tech");
// for (let i = 0; i < 30; i++) powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "tech", false);
//lore testing
@@ -153,9 +154,15 @@ const level = {
}
if (tech.isSpawnExitTech) {
for (let i = 0; i < 2; i++) powerUps.spawn(level.exit.x + 10 * (Math.random() - 0.5), level.exit.y - 100 + 10 * (Math.random() - 0.5), "tech", false) //exit
// for (let i = 0; i < 2; i++) powerUps.spawn(player.position.x + 90 * (Math.random() - 0.5), player.position.y + 90 * (Math.random() - 0.5), "tech", false); //start
}
if (m.plasmaBall) m.plasmaBall.reset()
if (localSettings.axiom && localSettings.axiom.levelName === level.levels[level.onLevel]) {
console.log('hi')
const flip = localSettings.axiom.isHorizontalFlipped === simulation.isHorizontalFlipped ? 1 : -1
powerUps.spawn(flip * localSettings.axiom.position.x, localSettings.axiom.position.y, "technology", false, localSettings.axiom.techNames);
localSettings.axiom = undefined
if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
}
},
trainingText(say) {
simulation.lastLogTime = 0; //clear previous messages

View File

@@ -457,7 +457,8 @@ const m = {
simulation.makeTextLog("simulation.amplitude <span class='color-symbol'>=</span> null");
tech.isImmortal = false //disable future immortality
}, 6 * swapPeriod);
} else if (m.alive) { //normal death code here
} else if (m.alive) { //normal death code here
m.storeTech()
m.alive = false;
simulation.paused = true;
m.health = 0;
@@ -472,6 +473,28 @@ const m = {
}, 5000);
}
},
storeTech() { //store a copy of your tech, it will show up at your location next run
if (tech.totalCount > 0 && localSettings.isAllowed) {
const have = []
for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].count > 0 && !tech.tech[i].isNonRefundable) have.push(tech.tech[i].name)
}
if (have.length) {
localSettings.axiom = {
techNames: have,
position: { x: m.pos.x, y: m.pos.y },
levelName: level.levels[level.onLevel],
isHorizontalFlipped: simulation.isHorizontalFlipped
}
if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
// for (let i = 0; i < 6; i++) simulation.drawList.push({ x: m.pos.x, y: m.pos.y, radius: 40, color: `hsla(250,100%,62%,0.05)`, time: i * 120 }); //draw graphics to show that tech is stored
// simulation.makeTextLog(`<span class='color-var'>tech</span> <strong>${localSettings.axiom.techName}</strong> is stored at (${m.pos.x.toFixed(0)}, ${m.pos.y.toFixed(0)}) on ${level.levels[level.onLevel]}`, 360);
}
// else {
// simulation.makeTextLog(`no valid <span class='color-var'>tech</span> for <strong>axiom</strong>`, 360);
// }
}
},
health: 0,
maxHealth: 1, //set in simulation.reset()
drawHealth() {
@@ -539,9 +562,7 @@ const m = {
if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.33;
if (tech.isNoFireDefense && m.cycle > m.fireCDcycle + 120) dmg *= 0.3
if (tech.isTurret && m.crouch) dmg *= 0.34;
if (tech.isFirstOrder && b.inventory[0] === b.activeGun) {
for (let i = 0, len = b.inventory.length; i < len; i++) dmg *= 0.87 // 1 - 0.15
}
if (tech.isFirstDer && b.inventory[0] === b.activeGun) dmg *= 0.85 ** b.inventory.length
return dmg
},
rewind(steps) { // m.rewind(Math.floor(Math.min(599, 137 * m.energy)))
@@ -595,7 +616,7 @@ const m = {
// simulation.updateGunHUD();
// simulation.boldActiveGunHUD();
// move bots to player
// move bots to player's new position
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType) {
Matter.Body.setPosition(bullet[i], Vector.add(player.position, {
@@ -642,7 +663,7 @@ const m = {
simulation.fpsInterval = 1000 / simulation.fpsCap;
m.defaultFPSCycle = m.cycle
if (tech.isRewindBot) {
const len = steps * 0.07 * tech.isRewindBot
const len = steps * 0.05 * tech.isRewindBot
const botStep = Math.floor(steps / len)
for (let i = 0; i < len; i++) {
const where = m.history[Math.abs(m.cycle - i * botStep) % 600].position //spread out spawn locations along past history
@@ -650,13 +671,13 @@ const m = {
x: where.x + 20 * (Math.random() - 0.5),
y: where.y + 20 * (Math.random() - 0.5)
}, false, false)
bullet[bullet.length - 1].endCycle = simulation.cycle + 480 + Math.floor(120 * Math.random()) //8-10 seconds
bullet[bullet.length - 1].endCycle = simulation.cycle + 440 + Math.floor(120 * Math.random()) //8-10 seconds
}
}
},
collisionImmuneCycles: 30,
damage(dmg) {
if (tech.isRewindAvoidDeath && m.energy > 0.6 && dmg > 0.01) {
if (tech.isRewindAvoidDeath && (m.energy + 0.05) > Math.min(1, m.maxEnergy) && dmg > 0.01) {
const steps = Math.floor(Math.min(299, 150 * m.energy))
simulation.makeTextLog(`<span class='color-var'>m</span>.rewind(${steps})`)
m.rewind(steps)

View File

@@ -301,12 +301,6 @@ const powerUps = {
powerUps.endDraft(type);
},
showDraft() {
// document.getElementById("choose-grid").style.gridTemplateColumns = "repeat(2, minmax(370px, 1fr))"
// document.getElementById("choose-background").style.display = "inline"
// document.getElementById("choose-background").style.visibility = "visible"
// document.getElementById("choose-background").style.opacity = "0.8"
// document.getElementById("choose-grid").style.display = "grid"
//disable clicking for 1/2 a second to prevent mistake clicks
document.getElementById("choose-grid").style.pointerEvents = "none";
document.body.style.cursor = "none";
@@ -314,29 +308,17 @@ const powerUps = {
if (!tech.isNoDraftPause) document.body.style.cursor = "auto";
document.getElementById("choose-grid").style.pointerEvents = "auto";
document.getElementById("choose-grid").style.transitionDuration = "0s";
}, 500);
// if (tech.extraChoices) {
// document.body.style.overflowY = "scroll";
// document.body.style.overflowX = "hidden";
// }
}, 400);
simulation.isChoosing = true; //stops p from un pausing on key down
if (!simulation.paused) {
if (tech.isNoDraftPause) {
// const cycle = () => {
// m.fireCDcycle = m.cycle + 1; //fire cooldown
// if (simulation.isChoosing && m.alive) requestAnimationFrame(cycle)
// }
// requestAnimationFrame(cycle);
document.getElementById("choose-grid").style.opacity = "0.92"
} else {
simulation.paused = true;
document.getElementById("choose-grid").style.opacity = "1"
}
document.getElementById("choose-grid").style.transitionDuration = "0.25s";
document.getElementById("choose-grid").style.transitionDuration = "0.25s"; //how long is the fade in on
document.getElementById("choose-grid").style.visibility = "visible"
requestAnimationFrame(() => {
@@ -363,11 +345,13 @@ const powerUps = {
}
if (tech.isCancelRerolls) {
for (let i = 0, len = 5 + 5 * Math.random(); i < len; i++) {
let spawnType = ((m.health < 0.25 && !tech.isEnergyHealth) || tech.isEnergyNoAmmo) ? "heal" : "ammo"
if (Math.random() < 0.36) {
spawnType = "heal"
} else if (Math.random() < 0.4 && !tech.isSuperDeterminism) {
let spawnType
if (Math.random() < 0.4 && !tech.isEnergyNoAmmo) {
spawnType = "ammo"
} else if (Math.random() < 0.33 && !tech.isSuperDeterminism) {
spawnType = "research"
} else {
spawnType = "heal"
}
powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), spawnType, false);
}
@@ -1093,10 +1077,72 @@ const powerUps = {
}
document.getElementById("choose-grid").innerHTML = text
powerUps.showDraft();
//fade in all circles
// requestAnimationFrame(() => {
// var elements = document.getElementsByClassName('circle-grid');
// for (var i in elements) {
// if (elements.hasOwnProperty(i)) {
// elements[i].style.opacity = '1';
// }
// }
// });
}
}
},
},
technology: {
name: "technology",
color: "#fff", //"hsl(248,100%,65%)",
size() {
return 35;
},
mode: "", //name of tech given
effect() {
if (m.alive) {
let text = ""
text += `<div class='cancel' onclick='powerUps.endDraft("tech")'>✕</div>`
text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>technology</h3>`
for (let i = 0; i < this.mode.length; i++) {
let choose = null
for (let j = 0; j < tech.tech.length; j++) { //convert name into index
if (this.mode[i] === tech.tech[j].name) {
choose = j
break
}
}
const isCount = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count+1}x)` : "";
if (choose === null || tech.tech[choose].count + 1 > tech.tech[choose].maxCount || !tech.tech[choose].allowed()) {
text += `<div class="choose-grid-module"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[choose].name}</div><span style = "color: red;">incompatible</span></div>`
} else {
if (tech.tech[choose].isFieldTech) {
text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title">
<span style="position:relative;">
<div class="circle-grid tech" style="position:absolute; top:0; left:0;opacity:0.8;"></div>
<div class="circle-grid field" style="position:absolute; top:0; left:10px;opacity:0.65;"></div>
</span>
&nbsp; &nbsp; &nbsp; &nbsp; ${tech.tech[choose].name} ${isCount}</div>${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() :tech.tech[choose].description}</div></div>`
} else if (tech.tech[choose].isGunTech) {
text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title">
<span style="position:relative;">
<div class="circle-grid tech" style="position:absolute; top:0; left:0;opacity:0.8;"></div>
<div class="circle-grid gun" style="position:absolute; top:0; left:10px; opacity:0.65;"></div>
</span>
&nbsp; &nbsp; &nbsp; &nbsp; ${tech.tech[choose].name} ${isCount}</div>${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() :tech.tech[choose].description}</div></div>`
} else if (tech.tech[choose].isLore) {
text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title lore-text"><div class="circle-grid lore"></div> &nbsp; ${tech.tech[choose].name} ${isCount}</div>${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}</div>`
} else if (tech.tech[choose].isJunk) {
text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title"><div class="circle-grid junk"></div> &nbsp; ${tech.tech[choose].name} ${isCount}</div>${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}</div>`
} else {
text += `<div class="choose-grid-module" onclick="powerUps.choose('tech',${choose})"><div class="grid-title"><div class="circle-grid tech"></div> &nbsp; ${tech.tech[choose].name} ${isCount}</div>${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}</div>`
}
}
}
document.getElementById("choose-grid").innerHTML = text
powerUps.showDraft();
}
},
},
spawnDelay(type, num) {
let count = num
let cycle = () => {

View File

@@ -359,16 +359,6 @@ const simulation = {
// document.getElementById(b.activeGun).style.fontSize = "30px";
if (document.getElementById(b.activeGun)) document.getElementById(b.activeGun).style.opacity = "1";
}
if (tech.isFirstOrder && document.getElementById("tech-first-derivative")) {
if (b.inventory[0] === b.activeGun) {
let lessDamage = 1
for (let i = 0, len = b.inventory.length; i < len; i++) lessDamage *= 0.87 // 1 - 0.13
document.getElementById("tech-first-derivative").innerHTML = " " + ((1 - lessDamage) * 100).toFixed(0) + "%"
} else {
document.getElementById("tech-first-derivative").innerHTML = " 0%"
}
}
},
updateGunHUD() {
for (let i = 0, len = b.inventory.length; i < len; ++i) {

View File

@@ -237,7 +237,7 @@ const tech = {
return dmg
},
duplicationChance() {
return Math.max(0, (tech.isPowerUpsVanish ? 0.12 : 0) + (tech.isStimulatedEmission ? 0.15 : 0) + tech.cancelCount * 0.044 + tech.duplicateChance + 0.05 * tech.isExtraGunField + m.duplicateChance + tech.fieldDuplicate + tech.cloakDuplication + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.5 : 0) + tech.isQuantumEraserDuplication * (1 - 0.016 * (simulation.difficultyMode ** 2))) // + (m.fieldMode === 0 || m.fieldMode === 9) * 0.03 * m.coupling)
return Math.max(0, (tech.isPowerUpsVanish ? 0.12 : 0) + (tech.isStimulatedEmission ? 0.15 : 0) + tech.cancelCount * 0.043 + tech.duplicateChance + 0.05 * tech.isExtraGunField + m.duplicateChance + tech.fieldDuplicate + tech.cloakDuplication + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.5 : 0) + tech.isQuantumEraserDuplication * (1 - 0.016 * (simulation.difficultyMode ** 2))) // + (m.fieldMode === 0 || m.fieldMode === 9) * 0.03 * m.coupling)
},
isScaleMobsWithDuplication: false,
maxDuplicationEvent() {
@@ -315,7 +315,7 @@ const tech = {
{
name: "ad hoc",
descriptionFunction() {
return `for each <strong class='color-g'>gun</strong> in your inventory<br>spawn a ${powerUps.orb.heal()}, ${powerUps.orb.research(1)}, <strong class='color-f'>field</strong>, ${powerUps.orb.ammo(1)}, or <strong class='color-m'>tech</strong>`
return `spawn a ${powerUps.orb.heal()}, ${powerUps.orb.research(1)}, <strong class='color-f'>field</strong>, ${powerUps.orb.ammo(1)}, or <strong class='color-m'>tech</strong><br>for each of your <strong class='color-g'>guns</strong>`
},
maxCount: 1, //random power up
count: 0,
@@ -345,7 +345,7 @@ const tech = {
},
{
name: "applied science",
description: `for each <strong class='color-g'>gun</strong> in your inventory<br>get a random <strong class='color-g'>gun</strong><strong class='color-m'>tech</strong>`, //spawn ${powerUps.orb.research(1)} and
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
maxCount: 9,
count: 0,
isNonRefundable: true,
@@ -382,7 +382,7 @@ const tech = {
},
{
name: "arsenal",
description: "for each <strong class='color-g'>gun</strong> in your inventory<br><strong>+13%</strong> <strong class='color-d'>damage</strong>",
descriptionFunction() { return `<strong>+13%</strong> <strong class='color-d'>damage</strong> per <strong class='color-g'>gun</strong> <em>(${(13 * b.inventory.length).toFixed(0)}%)</em>` },
maxCount: 1,
count: 0,
frequency: 1,
@@ -398,7 +398,7 @@ const tech = {
},
{
name: "active cooling",
description: "for each <strong class='color-g'>gun</strong> in your inventory<br><strong>+18%</strong> <strong><em>fire rate</em></strong>",
descriptionFunction() { return `<strong>+18%</strong> <em>fire rate</em> per <strong class='color-g'>gun</strong> <em>(${(18 * b.inventory.length).toFixed(0)}%)</em>` },
maxCount: 1,
count: 0,
frequency: 1,
@@ -414,6 +414,22 @@ const tech = {
b.setFireCD();
}
},
{
name: "first derivative",
descriptionFunction() { return `while your <strong>first</strong> <strong class='color-g'>gun</strong> is equipped<br><strong>+15%</strong> <strong class='color-defense'>defense</strong> per <strong class='color-g'>gun</strong> <em>(${(100*(1-0.85 ** b.inventory.length)).toFixed(0)}%)</em>` },
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
allowed() { return true },
requires: "",
effect() {
tech.isFirstDer = true
},
remove() {
tech.isFirstDer = false;
}
},
{
name: "integrated armament",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Weapon' class="link">integrated armament</a>`,
@@ -433,32 +449,6 @@ const tech = {
tech.isOneGun = false;
}
},
{
name: "first derivative",
nameInfo: "<span id = 'tech-first-derivative'></span>",
addNameInfo() {
setTimeout(function() {
simulation.boldActiveGunHUD();
}, 1000);
},
description: "if your <strong>first</strong> <strong class='color-g'>gun</strong> is equipped<br><strong>+13%</strong> <strong class='color-defense'>defense</strong> for each of your <strong class='color-g'>guns</strong>",
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
allowed() { return true },
requires: "",
effect() {
tech.isFirstOrder = true
setTimeout(function() {
simulation.boldActiveGunHUD();
}, 1000);
},
remove() {
tech.isFirstOrder = false;
}
},
{
name: "generalist",
description: "spawn <strong>7</strong> <strong class='color-g'>guns</strong>, but you can't <strong>switch</strong> <strong class='color-g'>guns</strong><br><strong class='color-g'>guns</strong> cycle automatically with each new level",
@@ -2178,13 +2168,16 @@ const tech = {
{
name: "CPT symmetry",
// description: "<strong>charge</strong>, <strong>parity</strong>, and <strong>time</strong> invert to undo <strong class='color-defense'>defense</strong><br><strong class='color-rewind'>rewind</strong> <strong>(1.5—5)</strong> seconds for <strong>(66—220)</strong> <strong class='color-f'>energy</strong>",
description: "if you have <strong>66</strong> <strong class='color-f'>energy</strong> after losing <strong class='color-h'>health</strong><br><strong>rewind</strong> time for <strong>44</strong> <strong class='color-f'>energy</strong> per second",
// description: "after losing <strong class='color-h'>health</strong>, if you have <strong>full</strong> <strong class='color-f'>energy</strong><br><strong>rewind</strong> time for <strong>44</strong> <strong class='color-f'>energy</strong> per second",
descriptionFunction() {
return `after losing <strong class='color-h'>health</strong>, if you have <strong>${(100*Math.min(100,m.maxEnergy)).toFixed(0)}</strong> <strong class='color-f'>energy</strong><br><strong>rewind</strong> time for <strong>44</strong> <strong class='color-f'>energy</strong> per second`
},
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
allowed() {
return m.maxEnergy > 0.99 && m.fieldUpgrades[m.fieldMode].name !== "standing wave" && !tech.isRewindField && !tech.isEnergyHealth
return m.fieldUpgrades[m.fieldMode].name !== "standing wave" && !tech.isRewindField && !tech.isEnergyHealth
},
requires: "not standing wave, max energy reduction, retrocausality, mass-energy",
effect() {
@@ -2197,7 +2190,7 @@ const tech = {
{
name: "causality bots",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Causality' class="link">causality bots</a>`,
description: "after you <strong class='color-rewind'>rewind</strong>, build several <strong class='color-bot'>bots</strong><br>that protect you for about <strong>9</strong> seconds",
description: "when you <strong class='color-rewind'>rewind</strong> build scrap <strong class='color-bot'>bots</strong><br>that protect you for about <strong>9</strong> seconds",
maxCount: 3,
count: 0,
frequency: 2,
@@ -2217,7 +2210,7 @@ const tech = {
{
name: "causality bombs",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Causality' class="link">causality bombs</a>`,
description: "after you <strong class='color-rewind'>rewind</strong> drop several <strong>grenades</strong><br>become <strong>invulnerable</strong> until they <strong class='color-e'>explode</strong>",
description: "when you <strong class='color-rewind'>rewind</strong> drop several <strong>grenades</strong><br>become <strong>invulnerable</strong> until they <strong class='color-e'>explode</strong>",
maxCount: 1,
count: 0,
frequency: 2,
@@ -2356,7 +2349,10 @@ const tech = {
// },
{
name: "electronegativity",
description: "<strong>+1%</strong> <strong class='color-d'>damage</strong> per <strong>8</strong> stored <strong class='color-f'>energy</strong>",
descriptionFunction() {
return `<strong>+1%</strong> <strong class='color-d'>damage</strong> per <strong>8</strong> stored <strong class='color-f'>energy</strong> <em>(${(12.5*m.energy).toFixed(0)}%)</em>`
},
// description: "<strong>+1%</strong> <strong class='color-d'>damage</strong> per <strong>8</strong> stored <strong class='color-f'>energy</strong>",
maxCount: 1,
count: 0,
frequency: 1,
@@ -2400,9 +2396,7 @@ const tech = {
count: 0,
frequency: 1,
frequencyDefault: 1,
allowed() {
return !tech.isRewindAvoidDeath
},
allowed: () => true,
requires: "not CPT",
damage: 1.5,
effect() {
@@ -2652,7 +2646,9 @@ const tech = {
},
{
name: "homeostasis",
description: `for each <strong class='color-h'>health</strong> below <strong>100</strong><br><strong>+0.8%</strong> <strong class='color-defense'>defense</strong>`,
descriptionFunction() {
return `for each <strong class='color-h'>health</strong> below <strong>100</strong><br><strong>+0.8%</strong> <strong class='color-defense'>defense</strong> <em>(${(100*(Math.max(0, 1 - m.health) * 0.8)).toFixed(0)}%)</em>`
},
maxCount: 1,
count: 0,
frequency: 1,
@@ -3061,7 +3057,7 @@ const tech = {
},
{
name: "renormalization",
description: `using ${powerUps.orb.research(1)} for <strong>any</strong> purpose<br>has a <strong>40%</strong> chance to spawn ${powerUps.orb.research(1)}`,
description: `<strong>40%</strong> chance to spawn ${powerUps.orb.research(1)}<br>after consuming ${powerUps.orb.research(1)}`,
maxCount: 1,
count: 0,
frequency: 2,
@@ -3119,7 +3115,8 @@ 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>`,
// description: `for each ${powerUps.orb.research(1)} in your inventory<br><strong>+3.8%</strong> <strong class='color-d'>damage</strong>`,
descriptionFunction() { return `<strong>+3.8%</strong> <strong class='color-d'>damage</strong> per ${powerUps.orb.research(1)} <em>(${(3.8*powerUps.research.count).toFixed(0)}%)</em>` },
maxCount: 1,
count: 0,
frequency: 2,
@@ -3401,7 +3398,6 @@ const tech = {
powerUps.boost.damage = 1.25
}
},
{
name: "eternalism",
description: "<strong>+34%</strong> <strong class='color-d'>damage</strong><br><strong>time</strong> can't be <strong>paused</strong> <em>(time can be dilated)</em>",
@@ -3633,7 +3629,7 @@ const tech = {
},
{
name: "futures exchange",
description: "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.4%</strong> power up <strong class='color-dup'>duplication</strong> chance",
description: "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.3%</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`
// },
@@ -3656,7 +3652,7 @@ const tech = {
},
{
name: "replication",
description: "<strong>+10%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br><strong>+30%</strong> <strong class='color-j'>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-j'>JUNK</strong> to <strong class='color-m'>tech</strong> pool",
maxCount: 9,
count: 0,
frequency: 1,
@@ -3668,8 +3664,8 @@ const tech = {
effect() {
tech.duplicateChance += 0.1
powerUps.setDupChance(); //needed after adjusting duplication chance
if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.1);
this.refundAmount += tech.addJunkTechToPool(0.3)
if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.11);
this.refundAmount += tech.addJunkTechToPool(0.33)
},
refundAmount: 0,
remove() {
@@ -3704,7 +3700,7 @@ const tech = {
},
{
name: "metastability",
description: "<strong>+12%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br><strong class='color-dup'>duplicates</strong> <strong class='color-e'>explode</strong> with a <strong>3</strong> second <strong>half-life</strong>",
description: "<strong>+11%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br><strong class='color-dup'>duplicates</strong> <strong class='color-e'>explode</strong> with a <strong>3</strong> second <strong>half-life</strong>",
maxCount: 1,
count: 0,
frequency: 1,
@@ -3716,7 +3712,7 @@ const tech = {
effect() {
tech.isPowerUpsVanish = true
powerUps.setDupChance(); //needed after adjusting duplication chance
if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.12);
if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.11);
},
remove() {
tech.isPowerUpsVanish = false
@@ -3770,7 +3766,7 @@ const tech = {
allowed() {
return tech.duplicationChance() > 0.5
},
requires: "NOT EXPERIMENT MODE, duplication chance above 50%",
requires: "duplication chance above 50%",
effect() {
tech.is100Duplicate = true;
tech.maxDuplicationEvent()
@@ -3791,7 +3787,7 @@ const tech = {
allowed() {
return (tech.totalCount > 6)
},
requires: "NOT EXPERIMENT MODE, more than 6 tech",
requires: "more than 6 tech",
effect() {
//remove active bullets //to get rid of bots
for (let i = 0; i < bullet.length; ++i) Matter.Composite.remove(engine.world, bullet[i]);
@@ -3812,6 +3808,47 @@ const tech = {
},
remove() {}
},
// {
// name: "axiom",
// descriptionFunction() {
// if (localSettings.axiom) {
// return `your <strong class='color-m'>tech</strong> are saved at (${localSettings.axiom.position.x.toFixed(0)}, ${localSettings.axiom.position.y.toFixed(0)}) on ${localSettings.axiom.levelName}`
// } else {
// return "save a <strong>copy</strong> of your current <strong class='color-m'>tech</strong><br>choose 1 when you <strong>return</strong> to this location"
// }
// },
// maxCount: 1,
// count: 0,
// frequency: 1,
// frequencyDefault: 1,
// isNonRefundable: true,
// allowed() {
// return !build.isExperimentSelection && tech.totalCount > 0 && localSettings.isAllowed && !localSettings.axiom // && level.onLevel > 0// && !simulation.isCheating
// },
// requires: "1+ tech, local storage, not cheating, not already stored",
// effect() {
// const have = []
// for (let i = 0; i < tech.tech.length; i++) {
// if (tech.tech[i].count > 0 && !tech.tech[i].isNonRefundable) have.push(tech.tech[i].name)
// }
// if (have.length) {
// localSettings.axiom = {
// techNames: have,
// position: { x: m.pos.x, y: m.pos.y },
// levelName: level.levels[level.onLevel],
// isHorizontalFlipped: simulation.isHorizontalFlipped
// }
// if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
// simulation.makeTextLog(`<span class='color-var'>tech</span> <strong>${localSettings.axiom.techName}</strong> is stored at (${m.pos.x.toFixed(0)}, ${m.pos.y.toFixed(0)}) on ${level.levels[level.onLevel]}`, 360);
// for (let i = 0; i < 6; i++) simulation.drawList.push({ x: m.pos.x, y: m.pos.y, radius: 40, color: `hsla(250,100%,62%,0.05)`, time: i * 120 }); //draw graphics to show that tech is stored
// } else {
// simulation.makeTextLog(`no valid <span class='color-var'>tech</span> for <strong>axiom</strong>`, 360);
// }
// },
// remove() {
// }
// },
{
name: "Occam's razor",
descriptionFunction() {
@@ -3857,7 +3894,7 @@ const tech = {
allowed() {
return (tech.totalCount > 3) && !tech.isSuperDeterminism
},
requires: "NOT EXPERIMENT MODE, at least 4 tech, not superdeterminism",
requires: "at least 4 tech, not superdeterminism",
effect() {
const have = [] //find which tech you have
for (let i = 0; i < tech.tech.length; i++) {
@@ -3889,7 +3926,7 @@ const tech = {
allowed() {
return (tech.totalCount > 3) && tech.duplicationChance() > 0 && !tech.isSuperDeterminism
},
requires: "NOT EXPERIMENT MODE, some duplication, at least 4 tech, not superdeterminism",
requires: "some duplication, at least 4 tech, not superdeterminism",
effect() {
const removeTotal = tech.removeTech()
for (let i = 0; i < removeTotal + 1; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "tech");
@@ -3909,7 +3946,7 @@ const tech = {
allowed() {
return !tech.isSuperDeterminism && tech.duplicationChance() > 0 && powerUps.research.count > 1
},
requires: "NOT EXPERIMENT MODE, some duplication, not superdeterminism",
requires: "some duplication, not superdeterminism",
effect() {
powerUps.research.changeRerolls(-2)
simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-r'>research</span> <span class='color-symbol'>-=</span> 2`)
@@ -5869,7 +5906,7 @@ const tech = {
isBot: true,
isBotTech: true,
isNonRefundable: true,
requires: "at least 2 guns, foam gun, NOT EXPERIMENT MODE, bot upgrades, fractionation, pressure vessel",
requires: "at least 2 guns, foam gun, bot upgrades, fractionation, pressure vessel",
allowed() {
return b.inventory.length > 1 && tech.haveGunCheck("foam", false) && !b.hasBotUpgrade() && !tech.isAmmoFoamSize && !tech.isFoamPressure
},
@@ -6460,7 +6497,7 @@ const tech = {
},
{
name: "compound lens",
description: "<strong>+77%</strong> <strong class='color-laser'>laser</strong> lens <strong class='color-d'>damage</strong><br><strong>+10°</strong> lens arc",
description: "<strong>+50%</strong> <strong class='color-laser'>laser</strong> lens <strong class='color-d'>damage</strong><br><strong>+15°</strong> lens arc",
isGunTech: true,
maxCount: 9,
count: 0,
@@ -6471,8 +6508,8 @@ const tech = {
},
requires: "lens",
effect() {
b.guns[11].arcRange += 10 * Math.PI / 180 / 2
b.guns[11].lensDamageOn += 0.77
b.guns[11].arcRange += 15 * Math.PI / 180 / 2
b.guns[11].lensDamageOn += 0.5
},
remove() {
b.guns[11].arcRange = 90 * Math.PI / 180 / 2 //0.78 divded by 2 because of how it's drawn
@@ -7067,7 +7104,7 @@ const tech = {
allowed() {
return powerUps.research.count > 1 && (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || m.fieldUpgrades[m.fieldMode].name === "pilot wave")
},
requires: "NOT EXPERIMENT MODE, molecular assembler, pilot wave",
requires: "molecular assembler, pilot wave",
effect() {
for (let i = 0; i < 2; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
@@ -7092,7 +7129,7 @@ const tech = {
allowed() {
return powerUps.research.count > 2 && (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || m.fieldUpgrades[m.fieldMode].name === "pilot wave")
},
requires: "NOT EXPERIMENT MODE, molecular assembler, pilot wave",
requires: "molecular assembler, pilot wave",
effect() {
for (let i = 0; i < 3; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
@@ -10493,7 +10530,7 @@ const tech = {
isLowHealthDefense: null,
isLowHealthFireRate: null,
isFarAwayDmg: null,
isFirstOrder: null,
isFirstDer: null,
isMassEnergy: null,
extraChoices: null,
laserBotCount: null,