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

@@ -458,6 +458,7 @@ const m = {
tech.isImmortal = false //disable future immortality
}, 6 * swapPeriod);
} 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,

View File

@@ -782,6 +782,8 @@ summary {
border-radius: 50%;
display: inline-block;
margin-bottom: -7px;
/* opacity: 0; */
/* transition: opacity 0.5s ease-in; */
}
.research-circle {

View File

@@ -1,26 +1,25 @@
******************************************************** NEXT PATCH **************************************************
finalBoss has a bit less health
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
laser lens has a glow effect
slow light has 11->7 unique beams
slow light has 38% more damage per beam
infrared diode 50->60% energy efficiency
dye laser 20->25% energy efficiency
20->25% laser damage
free-electron laser 190->200% laser damage
crit angle is smaller for iridescence and stress concentration on large mobs
ordnance has +5% JUNK
CPT uses 25% less energy and leaves you with about 10-20 energy
JUNK tech: placebo - +777% damage +777% defense
bug fixes
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
*********************************************************** TODO *****************************************************
tech increase max energy and energy to 5000, but you can no longer regen energy through any process
it would be nice if there was incentive to go slow when choosing tech so n-gon is more relaxing
add some css based visual effects for opening up a tech,gun,field
make a new coupling effect for perfect diamagnetism or standing wave
laserMines need a copy of laser-bot method
this is a very rare bug, so not a priority
@@ -50,15 +49,6 @@ finalBoss
counter with wormhole, negative mass
player targeted unless cloaking
tech - leave one of your tech at random, find it next run
store level name and position in local storage
requires local storage = true
store on power up pickup or on death?
make new power up type that gives specific tech with no choices
looks like smaller tech power up?
looks like a ghost, white color?
JUNK tech description that changes similar to cards in inscription
that changes based on mouse position
can you tell if mouse is over card?
@@ -70,11 +60,8 @@ tech that encourages gun swapping
+damage on that level
ammo, heals, research?
tech that gives permanent buff when ejected
buff: coupling, damage?
how to tell if it is ejected in the remove code?
tech - buff MACHO range, effect, move speed?
while you are inside MACHO it will damage mobs?
PWA?
https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps