diff --git a/README.md b/README.md index e3b6caf..e2b8697 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ -2-d physics rogue-lite platformer shooter sidescroller +2-d physics rogue-lite platformer shooter -https://landgreen.github.io/sidescroller/ +https://landgreen.github.io/n-gon/ diff --git a/js/bullet.js b/js/bullet.js index 738a888..e0af122 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -179,7 +179,7 @@ const b = { //count how many gun tech you have and remove them let gunTechCount = 0 //2 bonus gun tech for (let i = 0, len = tech.tech.length; i < len; i++) { - if (tech.tech[i].isGunTech && tech.tech[i].count > 0 && !tech.tech[i].isNonRefundable && !tech.tech[i].isRemoveGun) { + if (tech.tech[i].isGunTech && tech.tech[i].count > 0 && !tech.tech[i].isInstant && !tech.tech[i].isRemoveGun) { const remove = tech.removeTech(i) gunTechCount += remove } @@ -287,9 +287,9 @@ const b = { setFireCD() { b.fireCDscale = tech.fireRate * tech.slowFire * tech.researchHaste * tech.aimDamage if (m.fieldMode === 6) b.fireCDscale *= 0.8 - if (tech.isFastTime) b.fireCDscale *= 0.5 - if (tech.isFireRateForGuns) b.fireCDscale *= Math.pow(0.8, Math.max(0, b.inventory.length - 1)) - if (tech.isFireMoveLock) b.fireCDscale *= 0.2 // 77% fire rate + if (tech.isFastTime) b.fireCDscale *= 0.666 + if (tech.isFireRateForGuns) b.fireCDscale *= Math.pow(0.76923, Math.max(0, b.inventory.length - 1)) + if (tech.isFireMoveLock) b.fireCDscale *= 0.25 }, fireAttributes(dir, rotate = true) { if (rotate) { @@ -398,11 +398,11 @@ const b = { //player damage if (Vector.magnitude(Vector.sub(where, player.position)) < radius) { - const DRAIN = (tech.isExplosionHarm ? 0.6 : 0.45) * (tech.isRadioactiveResistance ? 0.25 : 1) + const DRAIN = (tech.isExplosionHarm ? 0.6 : 0.45) * (tech.isRadioactiveResistance ? 0.2 : 1) if (m.immuneCycle < m.cycle) m.energy -= DRAIN if (m.energy < 0) { m.energy = 0 - if (simulation.dmgScale) m.damage(tech.radioactiveDamage * 0.03 * (tech.isRadioactiveResistance ? 0.25 : 1)); + if (simulation.dmgScale) m.damage(tech.radioactiveDamage * 0.03 * (tech.isRadioactiveResistance ? 0.2 : 1)); } } @@ -1030,12 +1030,12 @@ const b = { } else { //aoe damage to player if (Vector.magnitude(Vector.sub(player.position, this.position)) < this.damageRadius) { - const DRAIN = (tech.isRadioactiveResistance ? 0.0025 * 0.25 : 0.0025) + const DRAIN = (tech.isRadioactiveResistance ? 0.0025 * 0.2 : 0.0025) if (m.energy > DRAIN) { if (m.immuneCycle < m.cycle) m.energy -= DRAIN } else { m.energy = 0; - if (simulation.dmgScale) m.damage((tech.isRadioactiveResistance ? 0.00016 * 0.25 : 0.00016) * tech.radioactiveDamage) //0.00015 + if (simulation.dmgScale) m.damage((tech.isRadioactiveResistance ? 0.00016 * 0.2 : 0.00016) * tech.radioactiveDamage) //0.00015 } } //aoe damage to mobs @@ -3615,7 +3615,7 @@ const b = { if (m.immuneCycle < m.cycle) m.energy -= DRAIN } else { m.energy = 0; - if (simulation.dmgScale) m.damage((tech.isRadioactiveResistance ? 0.00005 : 0.0002) * tech.radioactiveDamage) //0.00015 + if (simulation.dmgScale) m.damage((tech.isRadioactiveResistance ? 0.00004 : 0.0002) * tech.radioactiveDamage) //0.00015 } } //aoe damage to mobs @@ -3777,7 +3777,7 @@ const b = { bullet[me] = Bodies.polygon(where.x, where.y, 12, radius, b.fireAttributes(dir, false)); Composite.add(engine.world, bullet[me]); //add bullet to world Matter.Body.setVelocity(bullet[me], velocity); - bullet[me].calcDensity = function () { return 0.0007 + 0.00065 * tech.isSuperHarm + 0.0004 * tech.isBulletTeleport } + bullet[me].calcDensity = function () { return 0.0007 + 0.0007 * tech.isSuperHarm + 0.0004 * tech.isBulletTeleport } Matter.Body.setDensity(bullet[me], bullet[me].calcDensity()); bullet[me].endCycle = simulation.cycle + Math.floor(270 + 90 * Math.random()); bullet[me].minDmgSpeed = 0; @@ -3790,7 +3790,8 @@ const b = { this.force.y += this.mass * 0.001; if (Matter.Query.collides(this, [player]).length) { this.endCycle = 0 - m.energy -= m.energy * 0.2 + m.energy -= 0.05 + if (m.energy < 0) m.energy = 0 simulation.drawList.push({ //add dmg to draw queue x: this.position.x, y: this.position.y, diff --git a/js/engine.js b/js/engine.js index eb2aae4..4e873b1 100644 --- a/js/engine.js +++ b/js/engine.js @@ -147,7 +147,7 @@ function collisionChecks(event) { } if (tech.isPiezo) m.energy += 20.48; if (tech.isCouplingNoHit && m.coupling > 0) { - m.couplingChange(-5) + m.couplingChange(-4) const unit = Vector.rotate({ x: 1, y: 0 }, 6.28 * Math.random()) let where = Vector.add(m.pos, Vector.mult(unit, 17)) @@ -182,27 +182,6 @@ function collisionChecks(event) { color: 'rgba(0, 171, 238, 0.7)', time: 32 }); - // simulation.drawList.push({ //add dmg to draw queue - // x: m.pos.x, - // y: m.pos.y, - // radius: 150, - // color: 'rgba(0, 171, 238, 0.33)', - // time: 6 - // }); - // simulation.drawList.push({ //add dmg to draw queue - // x: m.pos.x, - // y: m.pos.y, - // radius: 75, - // color: 'rgba(0, 171, 238, 0.5)', - // time: 16 - // }); - // simulation.drawList.push({ //add dmg to draw queue - // x: m.pos.x, - // y: m.pos.y, - // radius: 25, - // color: 'rgba(0, 171, 238, 0.75)', - // time: 25 - // }); } if (tech.isHarpoonDefense) { //fire harpoons at mobs after getting hit const maxCount = 10 + 3 * tech.extraHarpoons //scale the number of hooks fired diff --git a/js/index.js b/js/index.js index a919b26..2ca3580 100644 --- a/js/index.js +++ b/js/index.js @@ -191,7 +191,7 @@ let color = { //light // check for URL parameters to load an experimental game //********************************************************************** -//example https://landgreen.github.io/sidescroller/index.html? +//example https://landgreen.github.io/n-gon/index.html? // &gun1=minigun&gun2=laser // &tech1=laser-bot&tech2=mass%20driver&tech3=overcharge&tech4=laser-bot&tech5=laser-bot&field=phase%20decoherence%20field&difficulty=2 //add ? to end of url then for each power up add @@ -477,9 +477,9 @@ const build = {
-
damage: ${((tech.damageFromTech())).toPrecision(4)} difficulty: ${((m.dmgScale)).toPrecision(4)} -
damage taken: ${(m.defense()).toPrecision(4)} difficulty: ${(simulation.dmgScale).toPrecision(4)} -
fire rate: ${((1 - b.fireCDscale) * 100).toFixed(b.fireCDscale < 0.1 ? 2 : 0)}% +
damage: ${((tech.damageFromTech())).toPrecision(4)}x difficulty: ${((m.dmgScale)).toPrecision(4)}x +
damage taken: ${(m.defense()).toPrecision(4)}x difficulty: ${(simulation.dmgScale).toPrecision(4)}x +
fire rate: ${(1 / b.fireCDscale).toFixed(2)}x ${tech.duplicationChance() ? `
duplication: ${(tech.duplicationChance() * 100).toFixed(0)}%` : ""} ${m.coupling ? `
` + m.couplingDescription(m.coupling) + ` from ${(m.coupling).toFixed(0)} ${powerUps.orb.coupling(1)}` : ""} ${botText} @@ -562,8 +562,8 @@ ${simulation.isCheating ? "

lore disabled" : ""} if (tech.tech[i].count > 0) { const style = (localSettings.isHideImages || tech.tech[i].isJunk || tech.tech[i].isLore) ? `style="height:auto;"` : `style = "background-image: url('img/${tech.tech[i].name}.webp');"` const techCountText = tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : ""; - if (tech.tech[i].isNonRefundable) { - text += `
${tech.tech[i].link} ${techCountText}
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() : tech.tech[i].description}
` + if (tech.tech[i].isInstant) { + // text += `
${tech.tech[i].link} ${techCountText}
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() : tech.tech[i].description}
` } else if (tech.tech[i].isFieldTech) { text += `
` text += build.fieldTechText(i) + "
" @@ -689,7 +689,7 @@ ${simulation.isCheating ? "

lore disabled" : ""} } else if (find === 'energy') { tech.tech.sort(sortKeyword); } else if (find === 'input') { - find = document.getElementById("sort-input").value; + find = document.getElementById("sort-input").value.toLowerCase(); tech.tech.sort(sortKeyword); } if (isExperiment) { @@ -731,6 +731,12 @@ ${simulation.isCheating ? "

lore disabled" : ""}
  ${build.nameLink(tech.tech[i].name)} ${tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : ""}
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() : tech.tech[i].description}` }, + instantTechText(i) { + // + return `
+
  ${build.nameLink(tech.tech[i].name)} ${tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : ""}
+ ${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() : tech.tech[i].description}
` + }, skinTechText(i) { return `
@@ -803,10 +809,10 @@ ${simulation.isCheating ? "

lore disabled" : ""} } } else if (type === "tech") { if (tech.tech[index].count < tech.tech[index].maxCount) { - // if (!tech.tech[index].isLore && !tech.tech[index].isNonRefundable && !who.classList.contains("build-tech-selected")) who.classList.add("build-tech-selected"); + // if (!tech.tech[index].isLore && !tech.tech[index].isInstant && !who.classList.contains("build-tech-selected")) who.classList.add("build-tech-selected"); if (!document.getElementById("tech-" + index).classList.contains("build-tech-selected")) document.getElementById("tech-" + index).classList.add("build-tech-selected"); tech.giveTech(index) - } else if (!tech.tech[index].isNonRefundable) { + } else if (!tech.tech[index].isInstant) { // tech.totalCount -= tech.tech[index].count document.getElementById("tech-" + index).classList.remove("build-tech-selected"); tech.removeTech(index); @@ -835,6 +841,8 @@ ${simulation.isCheating ? "

lore disabled" : ""} } else if (tech.tech[i].isSkin) { techID.classList.remove('experiment-grid-hide'); techID.innerHTML = build.skinTechText(i) + } else if (tech.tech[i].isInstant) { + techID.innerHTML = build.instantTechText(i) } else { techID.innerHTML = build.techText(i) } @@ -860,6 +868,8 @@ ${simulation.isCheating ? "

lore disabled" : ""} techID.innerHTML = build.junkTechText(i) } else if (tech.tech[i].isSkin) { techID.innerHTML = build.skinTechText(i) + } else if (tech.tech[i].isInstant) { + techID.innerHTML = build.instantTechText(i) } else { techID.innerHTML = build.techText(i) } @@ -937,7 +947,7 @@ ${simulation.isCheating ? "

lore disabled" : ""} for (let i = 0, len = tech.tech.length; i < len; i++) { if ((!tech.tech[i].isJunk || localSettings.isJunkExperiment) && !tech.tech[i].isLore) { const style = (localSettings.isHideImages || tech.tech[i].isJunk) ? hideStyle : `style="background-image: url('img/${tech.tech[i].name}.webp');"` - if ((tech.tech[i].allowed() || tech.tech[i].count > 0) && (!tech.tech[i].isNonRefundable || localSettings.isJunkExperiment)) { // || tech.tech[i].name === "+1 cardinality") { //|| tech.tech[i].name === "leveraged investment" + if ((tech.tech[i].allowed() || tech.tech[i].count > 0) && (!tech.tech[i].isInstant || localSettings.isJunkExperiment)) { // || tech.tech[i].name === "+1 cardinality") { //|| tech.tech[i].name === "leveraged investment" text += `
` } else { //disabled text += `
` @@ -951,6 +961,8 @@ ${simulation.isCheating ? "

lore disabled" : ""} text += build.skinTechText(i) } else if (tech.tech[i].isJunk) { text += build.junkTechText(i) + } else if (tech.tech[i].isInstant) { + text += build.instantTechText(i) } else { text += build.techText(i) } @@ -1014,7 +1026,7 @@ ${simulation.isCheating ? "

lore disabled" : ""} document.getElementById("experiment-grid").style.display = "grid" }, shareURL(isCustom = false) { - let url = "https://landgreen.github.io/sidescroller/index.html?" + let url = "https://landgreen.github.io/n-gon/index.html?" url += `&seed=${Math.initialSeed}` let count = 0; for (let i = 0; i < b.inventory.length; i++) { @@ -1026,7 +1038,7 @@ ${simulation.isCheating ? "

lore disabled" : ""} count = 0; for (let i = 0; i < tech.tech.length; i++) { for (let j = 0; j < tech.tech[i].count; j++) { - if (!tech.tech[i].isLore && !tech.tech[i].isJunk && !tech.tech[i].isNonRefundable) { + if (!tech.tech[i].isLore && !tech.tech[i].isJunk && !tech.tech[i].isInstant) { url += `&tech${count}=${encodeURIComponent(tech.tech[i].name.trim())}` count++ } diff --git a/js/level.js b/js/level.js index 1d9c42b..af98f4d 100644 --- a/js/level.js +++ b/js/level.js @@ -29,6 +29,7 @@ const level = { // m.couplingChange(10) // m.setField("plasma torch") //1 standing wave 2 perfect diamagnetism 3 negative mass 4 molecular assembler 5 plasma torch 6 time dilation 7 metamaterial cloaking 8 pilot wave 9 wormhole 10 grappling hook // m.energy = 0 + // powerUps.research.count = 3 // tech.isHookWire = true // m.energy = 0 // simulation.molecularMode = 2 @@ -39,16 +40,16 @@ const level = { // 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.guns[8].ammo = 100000000 // requestAnimationFrame(() => { tech.giveTech("optical amplifier") }); - // for (let i = 0; i < 1; ++i) tech.giveTech("mass production") + // for (let i = 0; i < 1; ++i) tech.giveTech("combinatorial optimization") // tech.giveTech("Pareto efficiency") - // for (let i = 0; i < 1; ++i) tech.giveTech("reduced tolerances") - // for (let i = 0; i < 1; ++i) tech.giveTech("Newtons 1st law") - // for (let i = 0; i < 1; ++i) tech.giveTech("Newtons 2nd law") - // requestAnimationFrame(() => { for (let i = 0; i < 1; i++) tech.giveTech("paradigm shift") }); + // for (let i = 0; i < 1; ++i) tech.giveTech("Higgs mechanism") + // for (let i = 0; i < 1; ++i) tech.giveTech("active cooling") + // for (let i = 0; i < 1; ++i) tech.giveTech("heuristics") // requestAnimationFrame(() => { for (let i = 0; i < 10; i++) b.orbitBot(m.pos, false) }); + // requestAnimationFrame(() => { for (let i = 0; i < 1; i++) tech.giveTech("ersatz bots") }); // for (let i = 0; i < 1; i++) tech.giveTech("tungsten carbide") // m.lastKillCycle = m.cycle - // for (let i = 0; i < 1; ++i) tech.giveTech("deprecated") + // for (let i = 0; i < 1; ++i) tech.giveTech("Lorentz transformation") // for (let i = 0; i < 1; ++i) tech.giveTech("unified field theory") // for (let i = 0; i < 3; i++) powerUps.directSpawn(450, -50, "tech"); // for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "research"); @@ -1778,12 +1779,12 @@ const level = { if (this.height > 0 && Matter.Query.region([player], this).length) { if (m.immuneCycle < m.cycle) { - const DRAIN = 0.004 * (tech.isRadioactiveResistance ? 0.25 : 1) + const DRAIN = 0.004 * (tech.isRadioactiveResistance ? 0.2 : 1) if (m.energy > DRAIN) { m.energy -= DRAIN if (tech.isEnergyHealth && m.energy < 0) m.death() } else { - m.damage(damage * (tech.isRadioactiveResistance ? 0.25 : 1)) + m.damage(damage * (tech.isRadioactiveResistance ? 0.2 : 1)) } } @@ -12460,11 +12461,11 @@ const level = { // Trolled const hasCPT = tech.isRewindAvoidDeath; tech.isRewindAvoidDeath = false; - const DRAIN = 0.002 * (tech.isRadioactiveResistance ? 0.25 : 1) + 0.001; + const DRAIN = 0.002 * (tech.isRadioactiveResistance ? 0.2 : 1) + 0.001; if (m.energy > DRAIN && !tech.isEnergyHealth) { m.energy -= DRAIN; } - m.damage(0.00015 * (tech.isRadioactiveResistance ? 0.25 : 1)); + m.damage(0.00015 * (tech.isRadioactiveResistance ? 0.2 : 1)); if (tech.isEnergyHealth) { const previousEnergy = m.energy; m.regenEnergy(); diff --git a/js/mob.js b/js/mob.js index d3cf211..a284886 100644 --- a/js/mob.js +++ b/js/mob.js @@ -1228,7 +1228,10 @@ const mobs = { simulation.loop(); //ending with a wipe and normal loop fixes some very minor graphical issues where things are draw in the wrong locations }); //wrapping in animation frame prevents errors, probably } - if (tech.isEnergyLoss) m.energy *= 0.8; + if (tech.isEnergyLoss) { + m.energy -= 0.05; + if (m.energy < 0) m.energy = 0 + } powerUps.spawnRandomPowerUp(this.position.x, this.position.y); m.lastKillCycle = m.cycle; //tracks the last time a kill was made, mostly used in simulation.checks() mobs.mobDeaths++ diff --git a/js/powerup.js b/js/powerup.js index 469168a..e777344 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -483,7 +483,7 @@ const powerUps = { } if (tech.isRerollHaste) { if (powerUps.research.count === 0) { - tech.researchHaste = 0.66; + tech.researchHaste = 0.5; b.setFireCD(); } else { tech.researchHaste = 1; @@ -557,7 +557,7 @@ const powerUps = { }); } if (tech.isHealBrake) { - const totalTime = 900 + const totalTime = 1020 //check if you already have this effect let foundActiveEffect = false for (let i = 0; i < simulation.ephemera.length; i++) { @@ -771,6 +771,15 @@ const powerUps = {
  ${tech.tech[choose].name} ${techCountText}
${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}
` }, + instantTechText(choose, click) { + const techCountText = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count + 1}x)` : ""; + const style = localSettings.isHideImages || tech.tech[choose].isLore ? powerUps.hideStyle : `style="background-image: url('img/${tech.tech[choose].name}.webp');"` + //
+ return `
+
+
  ${tech.tech[choose].name} ${techCountText}
+ ${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}
` + }, skinTechText(choose, click) { const techCountText = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count + 1}x)` : ""; const style = localSettings.isHideImages ? powerUps.hideStyle : `style="background-image: url('img/${tech.tech[choose].name}.webp');"` @@ -1060,6 +1069,8 @@ const powerUps = { text += powerUps.junkTechText(choose, `powerUps.choose('tech',${choose})`) } else if (tech.tech[choose].isSkin) { text += powerUps.skinTechText(choose, `powerUps.choose('tech',${choose})`) + } else if (tech.tech[choose].isInstant) { + text += powerUps.instantTechText(choose, `powerUps.choose('tech',${choose})`) } else { //normal tech text += powerUps.techText(choose, `powerUps.choose('tech',${choose})`) } @@ -1202,6 +1213,8 @@ const powerUps = { text += powerUps.junkTechText(choose, `powerUps.choose('tech',${choose})`) } else if (tech.tech[choose].isSkin) { text += powerUps.skinTechText(choose, `powerUps.choose('tech',${choose})`) + } else if (tech.tech[choose].isInstant) { + text += powerUps.instantTechTextTechText(choose, `powerUps.choose('tech',${choose})`) } else { //normal tech text += powerUps.techText(choose, `powerUps.choose('tech',${choose})`) } @@ -1327,8 +1340,6 @@ const powerUps = { } } } - - if (tech.isAddRemoveMaxHealth) { powerUps.spawn(x + 20, y, "tech", false) powerUps.spawn(x - 20, y, "research", false) @@ -1338,20 +1349,11 @@ const powerUps = { 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(); - // } - // } } + if (tech.isResearchReality) powerUps.spawnDelay("research", 5) + if (tech.isBanish) powerUps.spawnDelay("research", 2) + if (tech.isCouplingNoHit) powerUps.spawnDelay("coupling", 9) + // if (tech.isRerollDamage) powerUps.spawnDelay("research", 1) } }, chooseRandomPowerUp(x, y) { //100% chance to drop a random power up //used in spawn.debris @@ -1389,12 +1391,12 @@ const powerUps = { }, ejectTech(choose = 'random', isOverride = false) { if (!simulation.isChoosing || isOverride) { - // console.log(tech.tech[choose].name, tech.tech[choose].count, tech.tech[choose].isNonRefundable) + // console.log(tech.tech[choose].name, tech.tech[choose].count, tech.tech[choose].isInstant) //find which tech you have if (choose === 'random') { const have = [] for (let i = 0; i < tech.tech.length; i++) { - if (tech.tech[i].count > 0 && !tech.tech[i].isNonRefundable) have.push(i) + if (tech.tech[i].count > 0 && !tech.tech[i].isInstant) have.push(i) } // if (have.length === 0) { // for (let i = 0; i < tech.tech.length; i++) { @@ -1421,7 +1423,7 @@ const powerUps = { } else { return false } - } else if (tech.tech[choose].count && !tech.tech[choose].isNonRefundable) { + } else if (tech.tech[choose].count && !tech.tech[choose].isInstant) { simulation.makeTextLog(`tech.remove("${tech.tech[choose].name}")`) for (let i = 0; i < tech.tech[choose].count; i++) { @@ -1442,7 +1444,7 @@ const powerUps = { } }, pauseEjectTech(index) { - if ((tech.isPauseEjectTech || simulation.testing) && !simulation.isChoosing && !tech.tech[index].isNonRefundable) { + if ((tech.isPauseEjectTech || simulation.testing) && !simulation.isChoosing && !tech.tech[index].isInstant) { // if (tech.tech[index].bonusResearch !== undefined && tech.tech[index].bonusResearch > powerUps.research.count) { // tech.removeTech(index) // } else { diff --git a/js/simulation.js b/js/simulation.js index c362aa2..48a53d0 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -432,7 +432,7 @@ const simulation = { if (tech.tech[i].isLost) { if (text) text += "
" //add a new line, but not on the first line text += `${tech.tech[i].name}` - } else if (tech.tech[i].count > 0 && !tech.tech[i].isNonRefundable) { + } else if (tech.tech[i].count > 0 && !tech.tech[i].isInstant) { if (text) text += "
" //add a new line, but not on the first line text += tech.tech[i].name if (tech.tech[i].nameInfo) { diff --git a/js/spawn.js b/js/spawn.js index 02e296d..885fee2 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -254,12 +254,12 @@ const spawn = { //aoe damage to player if (m.immuneCycle < m.cycle && Vector.magnitude(Vector.sub(player.position, this.position)) < this.radius) { - const DRAIN = tech.isRadioactiveResistance ? 0.05 * 0.25 : 0.05 + const DRAIN = tech.isRadioactiveResistance ? 0.05 * 0.2 : 0.05 if (m.energy > DRAIN) { if (m.immuneCycle < m.cycle) m.energy -= DRAIN } else { m.energy = 0; - m.damage((tech.isRadioactiveResistance ? 0.005 * 0.25 : 0.005) * simulation.dmgScale) + m.damage((tech.isRadioactiveResistance ? 0.005 * 0.2 : 0.005) * simulation.dmgScale) simulation.drawList.push({ //add dmg to draw queue x: this.position.x, y: this.position.y, @@ -2089,8 +2089,8 @@ const spawn = { this.death(); //hit player if (Vector.magnitude(Vector.sub(this.position, player.position)) < this.explodeRange && m.immuneCycle < m.cycle) { - m.damage(0.01 * simulation.dmgScale * (tech.isRadioactiveResistance ? 0.25 : 1)); - m.energy -= 0.1 * (tech.isRadioactiveResistance ? 0.25 : 1) + m.damage(0.01 * simulation.dmgScale * (tech.isRadioactiveResistance ? 0.2 : 1)); + m.energy -= 0.1 * (tech.isRadioactiveResistance ? 0.2 : 1) if (m.energy < 0) m.energy = 0 } const range = this.explodeRange + 50 //mines get a slightly larger range to explode @@ -5060,8 +5060,8 @@ const spawn = { this.death(); //hit player if (Vector.magnitude(Vector.sub(this.position, player.position)) < this.explodeRange && m.immuneCycle < m.cycle) { - m.damage(0.02 * simulation.dmgScale * (tech.isRadioactiveResistance ? 0.25 : 1)); - m.energy -= 0.2 * (tech.isRadioactiveResistance ? 0.25 : 1) + m.damage(0.02 * simulation.dmgScale * (tech.isRadioactiveResistance ? 0.2 : 1)); + m.energy -= 0.2 * (tech.isRadioactiveResistance ? 0.2 : 1) if (m.energy < 0) m.energy = 0 } // mob[i].isInvulnerable = false //make mineBoss not invulnerable ? diff --git a/js/tech.js b/js/tech.js index b265f58..eb5b396 100644 --- a/js/tech.js +++ b/js/tech.js @@ -40,7 +40,7 @@ const tech = { if (index === 'random') { const have = [] //find which tech you have for (let i = 0; i < tech.tech.length; i++) { - if (tech.tech[i].count > 0 && !tech.tech[i].isNonRefundable) have.push(i) + if (tech.tech[i].count > 0 && !tech.tech[i].isInstant) have.push(i) } if (have.length) { index = have[Math.floor(Math.random() * have.length)] @@ -237,7 +237,7 @@ const tech = { if (tech.isDamageForGuns) dmg *= 1 + 0.22 * Math.max(0, b.inventory.length - 1) if (tech.isOneGun && b.inventory.length < 2) dmg *= 1.3 if (tech.isAcidDmg && m.health > 1) dmg *= 1.35; - if (tech.isRerollDamage) dmg *= 1 + Math.max(0, 0.03 * powerUps.research.count) + if (tech.isRerollDamage) dmg *= 1 + Math.max(0, 0.05 * powerUps.research.count) if (tech.isBotDamage) dmg *= 1 + 0.05 * b.totalBots() if (tech.restDamage > 1 && player.speed < 1) dmg *= tech.restDamage if (tech.isLowEnergyDamage) dmg *= 1 + Math.max(0, 1 - m.energy) @@ -253,7 +253,7 @@ const tech = { return dmg }, duplicationChance() { - return Math.min(1, Math.max(0, (tech.isPowerUpsVanish ? 0.13 : 0) + (tech.isStimulatedEmission ? 0.2 : 0) + tech.duplication + tech.duplicateChance + 0.05 * tech.isExtraGunField + m.duplicateChance + tech.fieldDuplicate + 0.08 * tech.isDuplicateMobs + tech.cloakDuplication + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.6 : 0))) + return Math.min(1, Math.max(0, (tech.isPowerUpsVanish ? 0.13 : 0) + (tech.isStimulatedEmission ? 0.2 : 0) + tech.duplication + tech.duplicateChance + 0.05 * tech.isExtraGunField + m.duplicateChance + tech.fieldDuplicate + 0.08 * tech.isDuplicateMobs + 0.03 * tech.isMassProduction + 0.03 * tech.isHealAttract + tech.cloakDuplication + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.6 : 0))) }, isScaleMobsWithDuplication: false, maxDuplicationEvent() { @@ -357,7 +357,7 @@ const tech = { }, { name: "Higgs mechanism", - description: "1.8x fire rate
while firing your position is fixed", + description: "4x fire rate
while firing your position is fixed", maxCount: 1, count: 0, frequency: 1, @@ -652,7 +652,7 @@ const tech = { count: 0, frequency: 1, frequencyDefault: 1, - isNonRefundable: true, + isInstant: true, isBadRandomOption: true, allowed: () => true, requires: "", @@ -674,7 +674,7 @@ const tech = { { name: "arsenal", descriptionFunction() { - return `1.22x damage per unequipped gun (${(22 * Math.max(0, b.inventory.length - 1)).toFixed(0)}%)` + return `1.25x damage per unequipped gun
(${(1 + 0.25 * Math.max(0, b.inventory.length - 1)).toFixed(2)}x)` }, maxCount: 1, count: 0, @@ -692,7 +692,7 @@ const tech = { { name: "active cooling", descriptionFunction() { - return `1.3x fire rate per unequipped gun` + return `1.25x fire rate per unequipped gun
(${(1 / Math.pow(0.8, Math.max(0, b.inventory.length - 1))).toFixed(2)}x)` }, //
but not including your equipped gun` }, maxCount: 1, count: 0, @@ -743,7 +743,7 @@ const tech = { count: 0, frequency: 1, frequencyDefault: 1, - isNonRefundable: true, + isInstant: true, isBadRandomOption: true, allowed() { return b.inventory.length < b.guns.length - 5 && b.inventory.length > 1 @@ -766,7 +766,7 @@ const tech = { count: 0, frequency: 1, frequencyDefault: 1, - isNonRefundable: true, + isInstant: true, allowed() { return b.inventory.length > 1 }, @@ -795,7 +795,7 @@ const tech = { description: `get a random guntech
for each of your guns`, //spawn ${powerUps.orb.research(1)} and maxCount: 1, count: 0, - isNonRefundable: true, + isInstant: true, frequency: 2, frequencyDefault: 2, allowed() { @@ -828,7 +828,7 @@ const tech = { const index = Math.floor(Math.random() * gunTechPool.length) console.log(gunTechPool, index, gunTechPool[index], tech.tech[gunTechPool[index]].name) simulation.makeTextLog(`tech.giveTech("${tech.tech[gunTechPool[index]].name}")`, 360) - // tech.tech[gunTechPool[index]].isNonRefundable = true //makes it not remove properly under paradigm shift + // tech.tech[gunTechPool[index]].isInstant = true //makes it not remove properly under paradigm shift tech.giveTech(gunTechPool[index]) // choose from the gun pool // console.log(gunTechPool, index, gunTechPool[index], tech.tech[gunTechPool[index]].name) // tech.tech[gunTechPool[index]].isFromAppliedScience = true //makes it not remove properly under paradigm shift @@ -841,11 +841,11 @@ const tech = { { name: "supply chain", descriptionFunction() { - return `spawn a gun
spawn 2x current ${powerUps.orb.ammo(1)}` + return `spawn a gun
spawn ${powerUps.orb.ammo(1)} equal to current ammo` }, maxCount: 9, count: 0, - isNonRefundable: true, + isInstant: true, frequency: 1, frequencyDefault: 1, allowed() { @@ -858,7 +858,6 @@ const tech = { for (let i = 0; i < b.guns.length; i++) { if (b.guns[i].have && b.guns[i].ammo !== Infinity) ammoCount += b.guns[i].ammo / b.guns[i].ammoPack } - console.log(ammoCount) powerUps.spawnDelay("ammo", Math.ceil(ammoCount)) powerUps.spawn(m.pos.x, m.pos.y, "gun"); // powerUps.spawnDelay("coupling", m.coupling * 2) @@ -889,7 +888,7 @@ const tech = { name: "marginal utility", descriptionFunction() { if (this.count === 0) this.gun = Math.floor(Math.random() * (b.guns.length - 1)) //don't pick laser - return `2x ammo per ${powerUps.orb.ammo(1)} for ${b.guns[this.gun].name}
spawn ${powerUps.orb.ammo(4)}` + return `2x ammo per ${powerUps.orb.ammo(1)} for ${b.guns[this.gun].name}` }, maxCount: 9, count: 0, @@ -905,7 +904,7 @@ const tech = { b.guns[this.gun].ammoPack *= 2 // simulation.makeTextLog(`${(tech.interestRate * 100).toFixed(0)}% interest on health = ${h > 20 ? h + powerUps.orb.heal(1) : powerUps.orb.heal(h)}`) - for (let i = 0; i < 4; i++) powerUps.spawn(m.pos.x + 10 * Math.random(), m.pos.y + 10 * Math.random(), "ammo"); + // for (let i = 0; i < 4; i++) powerUps.spawn(m.pos.x + 10 * Math.random(), m.pos.y + 10 * Math.random(), "ammo"); }, remove() { if (this.count) { @@ -1275,7 +1274,7 @@ const tech = { damage: 1.2, effect() { tech.damage *= this.damage - tech.slowFire = 1.2 + tech.slowFire = 1.25 b.setFireCD(); }, remove() { @@ -1318,7 +1317,7 @@ const tech = { }, { name: "heuristics", - description: "1.2x fire rate
spawn a gun", + description: "1.3x fire rate", maxCount: 9, count: 0, frequency: 1, @@ -1328,9 +1327,8 @@ const tech = { }, requires: "", effect() { - tech.fireRate *= 0.8 + tech.fireRate *= 0.77 b.setFireCD(); - powerUps.spawn(m.pos.x, m.pos.y, "gun"); }, remove() { tech.fireRate = 1; @@ -1454,7 +1452,7 @@ const tech = { { name: "collider", descriptionFunction() { - return `after mobs die random power ups
collide to form different power ups` + return `after mobs die existing power ups
collide to form new power ups` // return `after mobs die there is a +33% chance to convert
${powerUps.orb.heal()}, ${powerUps.orb.ammo()}, ${powerUps.orb.research(1)}, tech, field, gun into other types` }, @@ -2071,6 +2069,33 @@ const tech = { // this.description = `if you collect ${powerUps.orb.research(2 + Math.floor(0.2 * b.totalBots()))}use them to build a
random bot (+1 cost every 5 bots)` } }, + { + name: "open-source", + description: `tech, fields, and guns have +1 bot choice
3x bottech frequency`, + maxCount: 1, + count: 0, + frequency: 1, + frequencyDefault: 1, + isBotTech: true, + allowed() { + return b.totalBots() > 1 && !tech.isDeterminism + }, + requires: "at least 2 bots", + effect() { + tech.isExtraBotOption = true + for (let i = 0, len = tech.tech.length; i < len; i++) { + if (tech.tech[i].isBotTech) tech.tech[i].frequency *= 3 + } + }, + remove() { + if (this.count > 0) { + for (let i = 0, len = tech.tech.length; i < len; i++) { + if (tech.tech[i].isBotTech) tech.tech[i].frequency = Math.ceil(tech.tech[i].frequency / 3) + } + } + tech.isExtraBotOption = false + } + }, { name: "ersatz bots", link: `ersatz bots`, @@ -2080,7 +2105,7 @@ const tech = { frequency: 2, frequencyDefault: 2, isBotTech: true, - // isNonRefundable: true, + isInstant: true, isBadRandomOption: true, numberOfGunsLost: 0, allowed() { @@ -2122,79 +2147,151 @@ const tech = { tech.missileBotCount *= 2 }, remove() { - if (this.count) { - //return guns - for (let i = 0; i < this.numberOfGunsLost; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "gun"); - this.numberOfGunsLost = 0; + // if (this.count) { + // //return guns + // for (let i = 0; i < this.numberOfGunsLost; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "gun"); + // this.numberOfGunsLost = 0; - //half all current guns - tech.nailBotCount = Math.round(tech.nailBotCount / 2) - tech.laserBotCount = Math.round(tech.laserBotCount / 2) - tech.foamBotCount = Math.round(tech.foamBotCount / 2) - tech.soundBotCount = Math.round(tech.soundBotCount / 2) - tech.boomBotCount = Math.round(tech.boomBotCount / 2) - tech.orbitBotCount = Math.round(tech.orbitBotCount / 2) - tech.dynamoBotCount = Math.round(tech.dynamoBotCount / 2) - tech.plasmaBotCount = Math.round(tech.plasmaBotCount / 2) - tech.missileBotCount = Math.round(tech.missileBotCount / 2) - b.clearPermanentBots(); - b.respawnBots(); - } + // //half all current bots + // tech.nailBotCount = Math.round(tech.nailBotCount / 2) + // tech.laserBotCount = Math.round(tech.laserBotCount / 2) + // tech.foamBotCount = Math.round(tech.foamBotCount / 2) + // tech.soundBotCount = Math.round(tech.soundBotCount / 2) + // tech.boomBotCount = Math.round(tech.boomBotCount / 2) + // tech.orbitBotCount = Math.round(tech.orbitBotCount / 2) + // tech.dynamoBotCount = Math.round(tech.dynamoBotCount / 2) + // tech.plasmaBotCount = Math.round(tech.plasmaBotCount / 2) + // tech.missileBotCount = Math.round(tech.missileBotCount / 2) + // b.clearPermanentBots(); + // b.respawnBots(); + // } } }, { name: "robotics", - description: `spawn 2 random bots
tech, fields, and guns have +1 bot choice`, //tech have an extra bot tech option + description: `spawn 2 random bots`, maxCount: 1, count: 0, frequency: 1, frequencyDefault: 1, isBotTech: true, + isInstant: true, allowed() { - return b.totalBots() > 1 && !tech.isDeterminism + return b.totalBots() > 2 }, - requires: "at least 2 bots", + requires: "at least 3 bots", effect() { - tech.isExtraBotOption = true for (let i = 0; i < 2; i++) b.randomBot() }, remove() { - if (this.count > 0) { - for (let i = 0; i < 2; i++) b.removeBot() - b.clearPermanentBots(); - b.respawnBots(); - } - tech.isExtraBotOption = false } }, { - name: "open-source", - description: `spawn 3 random bots
3x bot tech frequency`, + name: "bot manufacturing", + description: `use ${powerUps.orb.research(2)} to build
3 random bots`, maxCount: 1, count: 0, - frequency: 0, - frequencyDefault: 0, + frequency: 1, + frequencyDefault: 1, isBotTech: true, + isInstant: true, allowed() { - return tech.isExtraBotOption + return b.totalBots() > 3 && powerUps.research.count > 1 }, - requires: "robotics", + requires: "at least 4 bots", effect() { - for (let i = 0; i < 3; i++) b.randomBot() - for (let i = 0, len = tech.tech.length; i < len; i++) { - if (tech.tech[i].isBotTech) tech.tech[i].frequency *= 3 + for (let i = 0; i < 2; i++) { + if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) } + // m.energy = 0.01; + b.randomBot() + b.randomBot() + b.randomBot() }, - remove() { - if (this.count > 0) { - for (let i = 0; i < 3; i++) b.removeBot() - b.clearPermanentBots(); - b.respawnBots(); - for (let i = 0, len = tech.tech.length; i < len; i++) { - if (tech.tech[i].isBotTech) tech.tech[i].frequency = Math.ceil(tech.tech[i].frequency / 3) + remove() { } + }, + { + name: "bot prototypes", + description: `use ${powerUps.orb.research(3)}to build 2 random bots
and upgrade all bots to a random type`, + maxCount: 1, + count: 0, + frequency: 1, + frequencyDefault: 1, + isBotTech: true, + isInstant: true, + allowed() { + return b.totalBots() > 5 && powerUps.research.count > 2 + }, + requires: "at least 6 bots", + effect() { + requestAnimationFrame(() => { + for (let i = 0; i < 3; i++) { + if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) } - } - } + //fill array of available bots + const notUpgradedBots = [] + const num = 2 + notUpgradedBots.push(() => { + tech.giveTech("nail-bot upgrade") + for (let i = 0; i < num; i++) { + b.nailBot() + tech.nailBotCount++; + } + simulation.makeTextLog(`tech.isNailBotUpgrade = true`) + }) + notUpgradedBots.push(() => { + tech.giveTech("foam-bot upgrade") + for (let i = 0; i < num; i++) { + b.foamBot() + tech.foamBotCount++; + } + simulation.makeTextLog(`tech.isFoamBotUpgrade = true`) + }) + notUpgradedBots.push(() => { + tech.giveTech("sound-bot upgrade") + for (let i = 0; i < num; i++) { + b.soundBot() + tech.soundBotCount++; + } + simulation.makeTextLog(`tech.isSoundBotUpgrade = true`) + }) + notUpgradedBots.push(() => { + tech.giveTech("boom-bot upgrade") + for (let i = 0; i < num; i++) { + b.boomBot() + tech.boomBotCount++; + } + simulation.makeTextLog(`tech.isBoomBotUpgrade = true`) + }) + notUpgradedBots.push(() => { + tech.giveTech("laser-bot upgrade") + for (let i = 0; i < num; i++) { + b.laserBot() + tech.laserBotCount++; + } + simulation.makeTextLog(`tech.isLaserBotUpgrade = true`) + }) + notUpgradedBots.push(() => { + tech.giveTech("orbital-bot upgrade") + for (let i = 0; i < num; i++) { + b.orbitBot() + tech.orbitBotCount++; + } + simulation.makeTextLog(`tech.isOrbitalBotUpgrade = true`) + }) + notUpgradedBots.push(() => { + tech.giveTech("dynamo-bot upgrade") + for (let i = 0; i < num; i++) { + b.dynamoBot() + tech.dynamoBotCount++; + } + simulation.makeTextLog(`tech.isDynamoBotUpgrade = true`) + }) + + notUpgradedBots[Math.floor(Math.random() * notUpgradedBots.length)]() //choose random function from the array and run it + }) + }, + remove() { } }, { name: "decorrelation", @@ -2607,7 +2704,7 @@ const tech = { { name: "first derivative", descriptionFunction() { - return `while your first gun is equipped
0.85x damage taken per gun (${(100 * (1 - 0.85 ** b.inventory.length)).toFixed(0)}%)` + return `while your first gun is equipped
0.85x damage taken per gun (${(0.85 ** b.inventory.length).toFixed(2)}x)` }, maxCount: 1, count: 0, @@ -2866,7 +2963,7 @@ const tech = { }, { name: "exothermic process", - description: "1.6x damage
after mobs die –20% energy", + description: "1.6x damage
after mobs die –5 energy", maxCount: 1, count: 0, frequency: 1, @@ -3226,9 +3323,8 @@ const tech = { { name: "induction brake", descriptionFunction() { - return `after using ${powerUps.orb.heal()} slow nearby mobs for 15 seconds
spawn ${powerUps.orb.heal(4)}` + return `after using ${powerUps.orb.heal()} slow nearby mobs for 17 seconds` }, - // description: `after using ${powerUps.orb.heal()} slow nearby mobs for 15 seconds
spawn ${powerUps.orb.heal(4)}`, maxCount: 1, count: 0, frequency: 1, @@ -3239,7 +3335,6 @@ const tech = { requires: "not eddy current brake", effect() { tech.isHealBrake = true; - for (let i = 0; i < 4; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "heal"); }, remove() { tech.isHealBrake = false; @@ -3312,9 +3407,8 @@ const tech = { { name: "accretion", descriptionFunction() { - return `${powerUps.orb.heal(1)} follow you, even between levels
spawn ${powerUps.orb.heal(7)}` + return `${powerUps.orb.heal(1)} follow you, even between levels
+3% chance to duplicate spawned power ups` }, - // description: `${powerUps.orb.heal(1)} follow you, even between levels
spawn ${powerUps.orb.heal(5)}`, maxCount: 1, count: 0, frequency: 1, @@ -3327,7 +3421,6 @@ const tech = { effect() { tech.isHealAttract = true powerUps.setPowerUpMode(); - for (let i = 0; i < 7; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "heal"); }, remove() { tech.isHealAttract = false @@ -3358,13 +3451,13 @@ const tech = { { name: "maintenance", descriptionFunction() { - return `2x healing tech frequency
spawn ${powerUps.orb.heal(13)}` + return `2x healtech frequency
spawn ${powerUps.orb.heal(13)}` }, maxCount: 1, count: 0, frequency: 1, frequencyDefault: 1, - isNonRefundable: true, + isInstant: true, isBadRandomOption: true, allowed() { return true @@ -3530,7 +3623,7 @@ const tech = { { name: "Ψ(t) collapse", link: `Ψ(t) collapse`, - description: `spawn ${powerUps.orb.research(21)}
after you research enter an alternate reality`, + description: `after a boss dies spawn ${powerUps.orb.research(5)}
after you research enter an alternate reality`, maxCount: 1, count: 0, frequency: 1, @@ -3543,11 +3636,37 @@ const tech = { 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); + // for (let i = 0; i < this.bonusResearch; i++) powerUps.spawn(m.pos.x + Math.random() * 60, m.pos.y + Math.random() * 60, "research", false); }, remove() { tech.isResearchReality = false; - if (this.count > 0) powerUps.research.changeRerolls(-this.bonusResearch) + // if (this.count > 0) powerUps.research.changeRerolls(-this.bonusResearch) + } + }, + { + name: "decoherence", + description: `after a boss dies spawn ${powerUps.orb.research(2)}
tech options you don't choose won't reoccur`, + maxCount: 1, + count: 0, + frequency: 1, + frequencyDefault: 1, + allowed() { + return !tech.isSuperDeterminism + }, + requires: "not superdeterminism", + bonusResearch: 7, + effect() { + tech.isBanish = true + }, + remove() { + if (tech.isBanish) { + tech.isBanish = false + //reset banish list + for (let i = 0; i < tech.tech.length; i++) { + if (tech.tech[i].isBanished) tech.tech[i].isBanished = false + } + } + tech.isBanish = false } }, { @@ -3563,15 +3682,9 @@ const tech = { requires: "at least 2 research, not superdeterminism", effect() { tech.isResearchDamage = true; - // this.refundAmount += tech.addJunkTechToPool(0.03) }, - // refundAmount: 0, remove() { tech.isResearchDamage = false; - // if (this.count > 0 && this.refundAmount > 0) { - // tech.removeJunkTechFromPool(this.refundAmount) - // this.refundAmount = 0 - // } } }, { @@ -3592,34 +3705,6 @@ const tech = { tech.isJunkResearch = false; } }, - { - name: "decoherence", - description: `tech options you don't choose won't reoccur
spawn ${powerUps.orb.research(7)}`, - maxCount: 1, - count: 0, - frequency: 1, - frequencyDefault: 1, - allowed() { - return !tech.isSuperDeterminism - }, - requires: "not superdeterminism", - bonusResearch: 7, - effect() { - tech.isBanish = true - for (let i = 0; i < this.bonusResearch; i++) powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false); - }, - remove() { - if (tech.isBanish) { - tech.isBanish = false - //reset banish list - for (let i = 0; i < tech.tech.length; i++) { - if (tech.tech[i].isBanished) tech.tech[i].isBanished = false - } - powerUps.research.changeRerolls(-this.bonusResearch) - } - tech.isBanish = false - } - }, { name: "renormalization", description: `+5% JUNKtech chance
47% chance to spawn ${powerUps.orb.research(1)} after consuming ${powerUps.orb.research(1)}`, @@ -3647,7 +3732,7 @@ const tech = { }, { name: "perturbation theory", - description: `if you have no ${powerUps.orb.research(1)} in your inventory
1.6x fire rate`, + description: `if you have no ${powerUps.orb.research(1)} in your inventory
2x fire rate`, maxCount: 1, count: 0, frequency: 1, @@ -3658,7 +3743,7 @@ const tech = { requires: "no research", effect() { tech.isRerollHaste = true; - tech.researchHaste = 0.4; //+60% fire rate + powerUps.research.changeRerolls(0) b.setFireCD(); }, remove() { @@ -3667,6 +3752,26 @@ const tech = { b.setFireCD(); } }, + { + name: "Bayesian statistics", + descriptionFunction() { + return `1.05x damage per ${powerUps.orb.research(1)} in your inventory
(${(1 + Math.max(0, 0.05 * powerUps.research.count)).toFixed(2)}x)` + }, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return powerUps.research.count > 1 || build.isExperimentSelection + }, + requires: "at least 2 research", + effect() { + tech.isRerollDamage = true; + }, + remove() { + tech.isRerollDamage = false; + } + }, { name: "ansatz", description: `after choosing a field, tech, or gun
if you have no ${powerUps.orb.research(1)} in your inventory spawn ${powerUps.orb.research(3)}`, @@ -3675,7 +3780,7 @@ const tech = { frequency: 1, frequencyDefault: 1, allowed() { - return powerUps.research.count < 1 && !tech.isSuperDeterminism && !tech.isRerollHaste && !tech.isResearchReality + return powerUps.research.count < 1 && !tech.isSuperDeterminism && !tech.isRerollHaste }, requires: "no research, not superdeterminism, Ψ(t) collapse, perturbation theory", effect() { @@ -3685,31 +3790,6 @@ const tech = { tech.isAnsatz = false; } }, - { - name: "Bayesian statistics", - descriptionFunction() { - return `spawn ${powerUps.orb.research(this.bonusResearch)}
1.03x damage per ${powerUps.orb.research(1)} in your inventory (${(1 + Math.max(0, 0.03 * powerUps.research.count)).toFixed(2)}x)` - }, - maxCount: 1, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return powerUps.research.count > 1 || build.isExperimentSelection - }, - requires: "at least 2 research", - bonusResearch: 6, - effect() { - powerUps.spawnDelay("research", this.bonusResearch) - tech.isRerollDamage = true; - }, - remove() { - tech.isRerollDamage = false; - if (this.count) { - powerUps.research.changeRerolls(-this.bonusResearch) - } - } - }, { name: "unified field theory", description: `when paused you can click to switch fields
2x fieldtech frequency`, @@ -3826,7 +3906,7 @@ const tech = { count: 0, frequency: 1, frequencyDefault: 1, - isNonRefundable: true, + isInstant: true, // isJunk: true, allowed() { return !tech.isDeterminism && !tech.isBrainstorm @@ -3854,7 +3934,7 @@ const tech = { frequency: 1, frequencyDefault: 1, isBadRandomOption: true, - isNonRefundable: true, + isInstant: true, allowed() { return !tech.extraChoices && !tech.isExtraGunField && !tech.isFlipFlopChoices && !tech.isExtraBotOption }, @@ -3876,7 +3956,7 @@ const tech = { frequency: 3, frequencyDefault: 3, isBadRandomOption: true, - isNonRefundable: true, + isInstant: true, allowed() { return tech.isDeterminism && !tech.isAnsatz && !tech.isJunkResearch && !tech.isBrainstorm }, @@ -4015,7 +4095,7 @@ const tech = { { name: "mass production", descriptionFunction() { - return `spawn ${powerUps.orb.ammo(3)}${powerUps.orb.heal(3)}  ${powerUps.orb.research(2)}
tech have extra choices to spawn ${powerUps.orb.ammo(1)},  ${powerUps.orb.heal(1)},  or  ${powerUps.orb.research(1)}` + return `tech have extra choices to spawn ${powerUps.orb.ammo(1)},  ${powerUps.orb.heal(1)},  or  ${powerUps.orb.research(1)}
+3% chance to duplicate spawned power ups` }, // description: `< strong class='color-m' > tech always have < strong > +3 choices to spawn < br > ${ powerUps.orb.ammo(8) } ${ powerUps.orb.heal(8) } & nbsp;& nbsp; or ${ powerUps.orb.research(5) } `, maxCount: 1, @@ -4026,9 +4106,6 @@ const tech = { requires: "", effect() { tech.isMassProduction = true - powerUps.spawnDelay("ammo", 4); - powerUps.spawnDelay("heal", 4); - powerUps.spawnDelay("research", 2); }, remove() { tech.isMassProduction = false @@ -4043,7 +4120,7 @@ const tech = { count: 0, frequency: 1, frequencyDefault: 1, - isNonRefundable: true, + isInstant: true, isMassProduction: true, allowed() { return true }, requires: "", @@ -4064,7 +4141,7 @@ const tech = { count: 0, frequency: 1, frequencyDefault: 1, - isNonRefundable: true, + isInstant: true, isMassProduction: true, allowed() { return true }, requires: "", @@ -4085,7 +4162,7 @@ const tech = { count: 0, frequency: 1, frequencyDefault: 1, - isNonRefundable: true, + isInstant: true, isMassProduction: true, allowed() { return true }, requires: "", @@ -4106,6 +4183,7 @@ const tech = { count: 0, frequency: 1, frequencyDefault: 1, + isInstant: true, allowed() { return true }, @@ -4114,7 +4192,7 @@ const tech = { powerUps.spawnDelay("coupling", 10) }, remove() { - if (this.count) m.couplingChange(-this.count * 10) + // if (this.count) m.couplingChange(-this.count * 10) } }, { @@ -4206,22 +4284,22 @@ const tech = { name: "fine-structure constant", descriptionFunction() { // return `spawn ${this.value} ${powerUps.orb.coupling(1)} that each give +0.1 coupling
-0.5 coupling after mob collisions`//
${m.couplingDescription(1)} ${m.fieldMode === 0 ? "" : "per coupling"} - return `spawn ${this.value} ${powerUps.orb.coupling(1)}, but lose ${powerUps.orb.coupling(5)} after mob collisions
${m.couplingDescription(1)} per ${powerUps.orb.coupling(1)}` + return `after a boss dies spawn ${powerUps.orb.coupling(9)}
lose ${powerUps.orb.coupling(4)} after mob collisions`//
${m.couplingDescription(1)} per ${powerUps.orb.coupling(1)} }, maxCount: 1, count: 0, frequency: 1, frequencyDefault: 1, - isNonRefundable: true, + // isInstant: true, allowed: () => true, requires: "", value: 60, effect() { tech.isCouplingNoHit = true - powerUps.spawnDelay("coupling", this.value) + // powerUps.spawnDelay("coupling", this.value) }, remove() { - if (this.count) m.couplingChange(-this.value) + // if (this.count) m.couplingChange(-this.value) tech.isCouplingNoHit = false } }, @@ -4399,9 +4477,9 @@ const tech = { description: `when you reach 100% duplication
spawn 11 bosses with 2x durability`, maxCount: 1, count: 0, - frequency: 3, - frequencyDefault: 3, - isNonRefundable: true, + frequency: 2, + frequencyDefault: 2, + // isInstant: true, allowed() { return tech.duplicationChance() > 0.5 }, @@ -4630,30 +4708,42 @@ const tech = { count: 0, frequency: 1, frequencyDefault: 1, - isNonRefundable: true, + isInstant: true, isBadRandomOption: true, allowed() { return (tech.totalCount > 6) }, 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]); - bullet = []; - let count = 1 //count tech + // //remove active bullets //to get rid of bots + // for (let i = 0; i < bullet.length; ++i) Matter.Composite.remove(engine.world, bullet[i]); + // bullet = []; + // let count = 1 //count tech + // for (let i = 0, len = tech.tech.length; i < len; i++) { // spawn new tech power ups + // if (!tech.tech[i].isInstant) count += tech.tech[i].count + // } + // if (tech.isDeterminism) count -= 4 //remove the bonus tech + // if (tech.isSuperDeterminism) count -= 4 //remove the bonus tech + // const removeCount = tech.removeCount + // tech.setupAllTech(); // remove all tech + // tech.removeCount = removeCount + // if (simulation.isCheating) tech.setCheating(); + // lore.techCount = 0; + // // tech.addLoreTechToPool(); + // for (let i = 0; i < count; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "tech"); // spawn new tech power ups + // //have state is checked in m.death() + + + let count = 0 //count tech for (let i = 0, len = tech.tech.length; i < len; i++) { // spawn new tech power ups - if (!tech.tech[i].isNonRefundable) count += tech.tech[i].count + if (!tech.tech[i].isInstant && tech.tech[i].count) { + count += tech.tech[i].count + tech.removeTech(i) + // powerUps.ejectTech(index) + } } - if (tech.isDeterminism) count -= 4 //remove the bonus tech - if (tech.isSuperDeterminism) count -= 4 //remove the bonus tech - const removeCount = tech.removeCount - tech.setupAllTech(); // remove all tech - tech.removeCount = removeCount - if (simulation.isCheating) tech.setCheating(); - lore.techCount = 0; - // tech.addLoreTechToPool(); - for (let i = 0; i < count; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "tech"); // spawn new tech power ups - //have state is checked in m.death() + powerUps.spawnDelay("tech", count); + // for (let i = 0; i < count; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "tech"); // spawn new tech power ups }, remove() { } }, @@ -4667,7 +4757,7 @@ const tech = { count: 0, frequency: 1, frequencyDefault: 1, - isNonRefundable: true, + isInstant: true, isBadRandomOption: true, allowed() { return (tech.totalCount > 6) @@ -4679,7 +4769,7 @@ const tech = { effect() { let pool = [] for (let i = 0, len = tech.tech.length; i < len; i++) { // spawn new tech power ups - if (tech.tech[i].count && !tech.tech[i].isNonRefundable) pool.push(i) + if (tech.tech[i].count && !tech.tech[i].isInstant) pool.push(i) } pool = shuffle(pool); //shuffles order of maps let removeCount = 0 @@ -4698,7 +4788,7 @@ const tech = { count: 0, frequency: 1, frequencyDefault: 1, - isNonRefundable: true, + isInstant: true, isBadRandomOption: true, allowed() { return (tech.totalCount > 3) && !tech.isSuperDeterminism @@ -4707,7 +4797,7 @@ const tech = { effect() { const have = [] //find which tech you have for (let i = 0; i < tech.tech.length; i++) { - if (tech.tech[i].count > 0 && !tech.tech[i].isNonRefundable) have.push(i) + if (tech.tech[i].count > 0 && !tech.tech[i].isInstant) have.push(i) } const choose = have[Math.floor(Math.random() * have.length)] for (let i = 0; i < tech.tech[choose].count; i++) { @@ -4725,7 +4815,7 @@ const tech = { count: 0, frequency: 1, frequencyDefault: 1, - isNonRefundable: true, + isInstant: true, isBadRandomOption: true, allowed() { return (tech.totalCount > 3) && tech.duplicationChance() > 0 && !tech.isSuperDeterminism @@ -5328,6 +5418,33 @@ const tech = { tech.isAoESlow = false } }, + { + name: "triple point", + descriptionFunction() { + return `+5 second freeze duration` + }, + isGunTech: true, + maxCount: 3, + count: 0, + frequency: 1, + frequencyDefault: 1, + // allowed() { + // return (m.fieldMode === 2 && m.coupling > 0) || (tech.haveGunCheck("shotgun") && tech.isIceShot) + // }, + // requires: "perfect diamagnetism", + allowed() { + return (tech.isIceCrystals || tech.isSporeFreeze || (m.fieldMode === 4 && simulation.molecularMode === 2) || tech.isIceShot || tech.relayIce || tech.isNeedleIce || (m.coupling && (m.fieldMode === 3 || m.fieldMode === 0))) + }, + requires: "a localized freeze effect", + effect() { + tech.iceIXFreezeTime += 5 * 60 + // powerUps.spawnDelay("coupling", 10) + }, + remove() { + tech.iceIXFreezeTime = 150 + // if (this.count) m.couplingChange(-10 * this.count) + } + }, { name: "incendiary ammunition", description: "shotgun, rivets, super balls, and drones
are loaded with explosives", @@ -5368,7 +5485,7 @@ const tech = { }, { name: "Zectron", - description: `1.9x super ball density and damage, but
after colliding with super balls -25% energy`, + description: `2x super ball density and damage, but
after colliding with super balls -5 energy`, isGunTech: true, maxCount: 1, count: 0, @@ -5681,6 +5798,41 @@ const tech = { tech.isPhononWave = false } }, + { + name: "missile-bot", + link: `missile-bot`, + description: `use ${powerUps.orb.research(1)}to trade your missile gun
for a bot that fires missiles`, + // isGunTech: true, + isRemoveGun: true, + maxCount: 1, + count: 0, + frequency: 1, + frequencyDefault: 1, + isBot: true, + isBotTech: true, + isInstant: true, + allowed() { + return tech.haveGunCheck("missiles", false) && tech.missileFireCD === 45 && (build.isExperimentSelection || powerUps.research.count > 0) + }, + requires: "missiles, not launch system", + effect() { + tech.missileBotCount++; + b.missileBot(); + if (tech.haveGunCheck("missiles", false)) b.removeGun("missiles") //remove your last gun + for (let i = 0; i < 1; i++) { + if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) + } + }, + remove() { + // if (this.count) { + // tech.missileBotCount = 0; + // b.clearPermanentBots(); + // b.respawnBots(); + // if (!tech.haveGunCheck("missiles", false)) b.giveGuns("missiles") + // powerUps.research.changeRerolls(1) + // } + } + }, { name: "cruise missile", description: "2x missile explosive damage, radius
0.5x missile speed", @@ -5757,40 +5909,6 @@ const tech = { } } }, - { - name: "missile-bot", - link: `missile-bot`, - description: `use ${powerUps.orb.research(1)}to trade your missile gun
for a bot that fires missiles`, - isGunTech: true, - isRemoveGun: true, - maxCount: 1, - count: 0, - frequency: 1, - frequencyDefault: 1, - isBot: true, - isBotTech: true, - allowed() { - return tech.haveGunCheck("missiles", false) && tech.missileFireCD === 45 && (build.isExperimentSelection || powerUps.research.count > 0) - }, - requires: "missiles, not launch system", - effect() { - tech.missileBotCount++; - b.missileBot(); - if (tech.haveGunCheck("missiles", false)) b.removeGun("missiles") //remove your last gun - for (let i = 0; i < 1; i++) { - if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) - } - }, - remove() { - if (this.count) { - tech.missileBotCount = 0; - b.clearPermanentBots(); - b.respawnBots(); - if (!tech.haveGunCheck("missiles", false)) b.giveGuns("missiles") - powerUps.research.changeRerolls(1) - } - } - }, { name: "iridium-192", description: "explosions release gamma radiation
2x explosion damage over 4 seconds", @@ -6149,7 +6267,7 @@ const tech = { { name: "water shielding", link: `water shielding`, - description: "you are protected from 75% of radioactivity
neutron bomb, drones, explosions, slime", + description: "reduce radioactive effects on you by 0.8x
neutron bomb, drones, explosions, slime", isGunTech: true, maxCount: 1, count: 0, @@ -6539,6 +6657,52 @@ const tech = { tech.isDronesTravel = false } }, + { + name: "fault tolerance", + description: `use ${powerUps.orb.research(2)}to trade your drone gun
for 5 drones that last forever`, + // isGunTech: true, + isRemoveGun: true, + maxCount: 1, + count: 0, + frequency: 1, + frequencyDefault: 1, + isInstant: true, + allowed() { + return tech.haveGunCheck("drones", false) && !tech.isDroneRespawn && tech.bulletsLastLonger === 1 && !tech.isDronesTravel && (build.isExperimentSelection || powerUps.research.count > 1) + }, + requires: "drones, not drone repair, anti-shear topology, autonomous navigation", + effect() { + const num = 5 + tech.isForeverDrones += num + if (tech.haveGunCheck("drones", false)) b.removeGun("drones") + //spawn drones + if (tech.isDroneRadioactive) { + for (let i = 0; i < num * 0.25; i++) { + b.droneRadioactive({ + x: m.pos.x + 30 * (Math.random() - 0.5), + y: m.pos.y + 30 * (Math.random() - 0.5) + }, 5) + bullet[bullet.length - 1].endCycle = Infinity + } + } else { + for (let i = 0; i < num; i++) { + b.drone({ + x: m.pos.x + 30 * (Math.random() - 0.5), + y: m.pos.y + 30 * (Math.random() - 0.5) + }, 5) + bullet[bullet.length - 1].endCycle = Infinity + } + } + for (let i = 0; i < 2; i++) { + if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) + } + }, + remove() { + tech.isForeverDrones = 0 + // if (this.count && !tech.haveGunCheck("drones", false)) b.giveGuns("drones") + // if (this.count > 0) powerUps.research.changeRerolls(2) + } + }, { name: "reduced tolerances", link: `reduced tolerances`, @@ -6721,89 +6885,6 @@ const tech = { tech.isFastDrones = false } }, - { - name: "fault tolerance", - description: `use ${powerUps.orb.research(2)}to trade your drone gun
for 5 drones that last forever`, - isGunTech: true, - isRemoveGun: true, - maxCount: 1, - count: 0, - frequency: 1, - frequencyDefault: 1, - allowed() { - return tech.haveGunCheck("drones", false) && !tech.isDroneRespawn && tech.bulletsLastLonger === 1 && !tech.isDronesTravel && (build.isExperimentSelection || powerUps.research.count > 1) - }, - requires: "drones, not drone repair, anti-shear topology, autonomous navigation", - effect() { - const num = 5 - tech.isForeverDrones += num - if (tech.haveGunCheck("drones", false)) b.removeGun("drones") - //spawn drones - if (tech.isDroneRadioactive) { - for (let i = 0; i < num * 0.25; i++) { - b.droneRadioactive({ - x: m.pos.x + 30 * (Math.random() - 0.5), - y: m.pos.y + 30 * (Math.random() - 0.5) - }, 5) - bullet[bullet.length - 1].endCycle = Infinity - } - } else { - for (let i = 0; i < num; i++) { - b.drone({ - x: m.pos.x + 30 * (Math.random() - 0.5), - y: m.pos.y + 30 * (Math.random() - 0.5) - }, 5) - bullet[bullet.length - 1].endCycle = Infinity - } - } - for (let i = 0; i < 2; i++) { - if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) - } - }, - remove() { - tech.isForeverDrones = 0 - if (this.count && !tech.haveGunCheck("drones", false)) b.giveGuns("drones") - if (this.count > 0) powerUps.research.changeRerolls(2) - } - }, - { - name: "surfactant", - description: `use ${powerUps.orb.research(2)}to trade your foam gun
for 2 foam-bots and foam-bot upgrade`, - isGunTech: true, - isRemoveGun: true, - maxCount: 1, - count: 0, - frequency: 1, - frequencyDefault: 1, - isBot: true, - isBotTech: true, - isNonRefundable: true, - requires: "foam gun, not bot upgrades, fractionation, pressure vessel", - allowed() { - return tech.haveGunCheck("foam", false) && !b.hasBotUpgrade() && !tech.isAmmoFoamSize && !tech.isFoamPressure && (build.isExperimentSelection || powerUps.research.count > 1) - }, - effect() { - - requestAnimationFrame(() => { tech.giveTech("foam-bot upgrade") }) - for (let i = 0; i < 2; i++) { - b.foamBot() - tech.foamBotCount++; - } - simulation.makeTextLog(`tech.isFoamBotUpgrade = true`) - if (tech.haveGunCheck("foam", false)) b.removeGun("foam") - for (let i = 0; i < 2; i++) { - if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) - } - }, - remove() { - // if (this.count) { - // b.clearPermanentBots(); - // b.respawnBots(); - // if (!tech.haveGunCheck("foam")) b.giveGuns("foam") - // } - // if (this.count > 0) powerUps.research.changeRerolls(2) - } - }, { name: "electrostatic induction", description: "foam bubbles are electrically charged
causing attraction to nearby mobs", @@ -6842,6 +6923,44 @@ const tech = { tech.isBulletTeleport = false; } }, + { + name: "surfactant", + description: `use ${powerUps.orb.research(2)}to trade your foam gun
for 2 foam-bots and foam-bot upgrade`, + // isGunTech: true, + isRemoveGun: true, + maxCount: 1, + count: 0, + frequency: 1, + frequencyDefault: 1, + isBot: true, + isBotTech: true, + isInstant: true, + requires: "foam gun, not bot upgrades, fractionation, pressure vessel", + allowed() { + return tech.haveGunCheck("foam", false) && !b.hasBotUpgrade() && !tech.isAmmoFoamSize && !tech.isFoamPressure && (build.isExperimentSelection || powerUps.research.count > 1) + }, + effect() { + + requestAnimationFrame(() => { tech.giveTech("foam-bot upgrade") }) + for (let i = 0; i < 2; i++) { + b.foamBot() + tech.foamBotCount++; + } + simulation.makeTextLog(`tech.isFoamBotUpgrade = true`) + if (tech.haveGunCheck("foam", false)) b.removeGun("foam") + for (let i = 0; i < 2; i++) { + if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) + } + }, + remove() { + // if (this.count) { + // b.clearPermanentBots(); + // b.respawnBots(); + // if (!tech.haveGunCheck("foam")) b.giveGuns("foam") + // } + // if (this.count > 0) powerUps.research.changeRerolls(2) + } + }, { name: "aerogel", description: "foam bubbles float with 0.5x foam duration
2.8x foam damage", @@ -6924,7 +7043,7 @@ const tech = { }, { name: "ideal gas law", - description: `remove all current foam ammo
12x foam ammo per ${powerUps.orb.ammo(1)}`, + description: `6x foam ammo per ${powerUps.orb.ammo(1)}`, //remove all current foam ammo
isGunTech: true, maxCount: 1, count: 0, @@ -6934,17 +7053,17 @@ const tech = { return tech.haveGunCheck("foam") && !tech.isEnergyNoAmmo }, requires: "foam, not non-renewables", - ammoLost: 0, + // ammoLost: 0, effect() { - b.guns[8].ammoPack *= 12; - this.ammoLost = b.guns[8].ammo - b.guns[8].ammo = 0 + b.guns[8].ammoPack *= 6; + // this.ammoLost = b.guns[8].ammo + // b.guns[8].ammo = 0 simulation.updateGunHUD() }, remove() { if (this.count) { - b.guns[8].ammoPack /= 12 - b.guns[8].ammo += this.ammoLost + b.guns[8].ammoPack /= 8 + // b.guns[8].ammo += this.ammoLost simulation.updateGunHUD() } } @@ -7244,12 +7363,12 @@ const tech = { { name: "optical amplifier", description: "gain 3 random laser guntech
laser only turns off if you have no energy", - isGunTech: true, + // isGunTech: true, maxCount: 1, count: 0, frequency: 2, frequencyDefault: 2, - isNonRefundable: true, + isInstant: true, allowed() { return tech.haveGunCheck("laser") && !tech.isPulseLaser }, @@ -7776,29 +7895,6 @@ const tech = { tech.isStunField = 0; } }, - { - name: "triple point", - descriptionFunction() { - return `+1.5 second ice IX freeze and spawn ${powerUps.orb.coupling(10)}
${m.couplingDescription(1)} per ${powerUps.orb.coupling(1)}` - }, - isFieldTech: true, - maxCount: 3, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return m.fieldMode === 2 - }, - requires: "perfect diamagnetism", - effect() { - tech.iceIXFreezeTime += 90 - powerUps.spawnDelay("coupling", 10) - }, - remove() { - tech.iceIXFreezeTime = 150 - if (this.count) m.couplingChange(-10 * this.count) - } - }, { name: "eddy current brake", description: "perfect diamagnetism slows nearby mobs
effect radius scales with stored energy", @@ -7983,116 +8079,7 @@ const tech = { // tech.isFreezeMobs = false // } // }, - { - name: "bot manufacturing", - description: `use ${powerUps.orb.research(2)} to build
3 random bots`, - isFieldTech: true, - maxCount: 1, - count: 0, - frequency: 1, - frequencyDefault: 1, - isBotTech: true, - isNonRefundable: true, - allowed() { - return powerUps.research.count > 1 && (m.fieldMode === 4 || m.fieldMode === 10 || m.fieldMode === 8) - }, - requires: "molecular assembler, grappling hook, pilot wave", - effect() { - for (let i = 0; i < 2; i++) { - if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) - } - m.energy = 0.01; - b.randomBot() - b.randomBot() - b.randomBot() - }, - remove() { } - }, - { - name: "bot prototypes", - description: `use ${powerUps.orb.research(3)}to build 2 random bots
and upgrade all bots to that type`, - isFieldTech: true, - maxCount: 1, - count: 0, - frequency: 1, - frequencyDefault: 1, - isBotTech: true, - isNonRefundable: true, - allowed() { - return powerUps.research.count > 2 && (m.fieldMode === 4 || m.fieldMode === 10 || m.fieldMode === 8) - }, - requires: "molecular assembler, grappling hook, pilot wave", - effect() { - requestAnimationFrame(() => { - for (let i = 0; i < 3; i++) { - if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) - } - //fill array of available bots - const notUpgradedBots = [] - const num = 2 - notUpgradedBots.push(() => { - tech.giveTech("nail-bot upgrade") - for (let i = 0; i < num; i++) { - b.nailBot() - tech.nailBotCount++; - } - simulation.makeTextLog(`tech.isNailBotUpgrade = true`) - }) - notUpgradedBots.push(() => { - tech.giveTech("foam-bot upgrade") - for (let i = 0; i < num; i++) { - b.foamBot() - tech.foamBotCount++; - } - simulation.makeTextLog(`tech.isFoamBotUpgrade = true`) - }) - notUpgradedBots.push(() => { - tech.giveTech("sound-bot upgrade") - for (let i = 0; i < num; i++) { - b.soundBot() - tech.soundBotCount++; - } - simulation.makeTextLog(`tech.isSoundBotUpgrade = true`) - }) - notUpgradedBots.push(() => { - tech.giveTech("boom-bot upgrade") - for (let i = 0; i < num; i++) { - b.boomBot() - tech.boomBotCount++; - } - simulation.makeTextLog(`tech.isBoomBotUpgrade = true`) - }) - notUpgradedBots.push(() => { - tech.giveTech("laser-bot upgrade") - for (let i = 0; i < num; i++) { - b.laserBot() - tech.laserBotCount++; - } - simulation.makeTextLog(`tech.isLaserBotUpgrade = true`) - }) - notUpgradedBots.push(() => { - tech.giveTech("orbital-bot upgrade") - for (let i = 0; i < num; i++) { - b.orbitBot() - tech.orbitBotCount++; - } - simulation.makeTextLog(`tech.isOrbitalBotUpgrade = true`) - }) - for (let i = 0; i < 2; i++) { //double chance for dynamo-bot, since it's very good for assembler - notUpgradedBots.push(() => { - tech.giveTech("dynamo-bot upgrade") - for (let i = 0; i < num; i++) { - b.dynamoBot() - tech.dynamoBotCount++; - } - simulation.makeTextLog(`tech.isDynamoBotUpgrade = true`) - }) - } - notUpgradedBots[Math.floor(Math.random() * notUpgradedBots.length)]() //choose random function from the array and run it - }) - }, - remove() { } - }, + // { // name: "mycelium manufacturing", // link: `mycelium manufacturing`, @@ -8236,7 +8223,7 @@ const tech = { }, { name: "combinatorial optimization", - description: "1.35x damage
0.65x fire rate", + description: "1.35x damage
0.7x fire rate", isFieldTech: true, maxCount: 1, count: 0, @@ -8249,7 +8236,7 @@ const tech = { damage: 1.35, effect() { tech.damage *= this.damage - tech.aimDamage = 1.35 + tech.aimDamage = 1.42 b.setFireCD(); }, remove() { @@ -8300,7 +8287,8 @@ const tech = { name: "plasma-bot", link: `plasma-bot`, description: `use ${powerUps.orb.research(2)}to trade your field
for a bot that uses energy to emit plasma`, - isFieldTech: true, + // isFieldTech: true, + isInstant: true, maxCount: 1, count: 0, frequency: 3, @@ -8776,7 +8764,7 @@ const tech = { }, { name: "geodesics", - description: `your bullets can traverse wormholes
spawn 2 guns and ${powerUps.orb.ammo(4)}`, + description: `your bullets can traverse wormholes
1.5x damage`, isFieldTech: true, maxCount: 1, count: 0, @@ -8786,18 +8774,21 @@ const tech = { return m.fieldMode === 9 }, requires: "wormhole", + damage: 1.5, effect() { + tech.damage *= this.damage tech.isWormHoleBullets = true - for (let i = 0; i < 2; i++) powerUps.spawn(m.pos.x + 200 * (Math.random() - 0.5), m.pos.y + 200 * (Math.random() - 0.5), "gun"); - for (let i = 0; i < 4; i++) powerUps.spawn(m.pos.x + 200 * (Math.random() - 0.5), m.pos.y + 200 * (Math.random() - 0.5), "ammo"); + // for (let i = 0; i < 2; i++) powerUps.spawn(m.pos.x + 200 * (Math.random() - 0.5), m.pos.y + 200 * (Math.random() - 0.5), "gun"); + // for (let i = 0; i < 4; i++) powerUps.spawn(m.pos.x + 200 * (Math.random() - 0.5), m.pos.y + 200 * (Math.random() - 0.5), "ammo"); }, remove() { - if (tech.isWormHoleBullets) { - for (let i = 0; i < 2; i++) { - if (b.inventory.length) b.removeGun(b.guns[b.inventory[b.inventory.length - 1]].name) //remove your last gun - } - tech.isWormHoleBullets = false; - } + // if (tech.isWormHoleBullets) { + // for (let i = 0; i < 2; i++) { + // if (b.inventory.length) b.removeGun(b.guns[b.inventory[b.inventory.length - 1]].name) //remove your last gun + // } + // } + if (this.count && m.alive) tech.damage /= this.damage + tech.isWormHoleBullets = false; } }, { @@ -8994,7 +8985,7 @@ const tech = { // maxCount: 1, // count: 0, // frequency: 0, - // isNonRefundable: true, + // isInstant: true, // isBadRandomOption: true, // isExperimentalMode: true, // allowed() { @@ -9145,7 +9136,7 @@ const tech = { // maxCount: 9, // count: 0, // frequency: 0, - // isNonRefundable: true, + // isInstant: true, // isJunk: true, // allowed() { // return true @@ -9163,7 +9154,7 @@ const tech = { count: 0, frequency: 0, isJunk: true, - isNonRefundable: true, + isInstant: true, allowed() { return true }, @@ -9189,7 +9180,7 @@ const tech = { // count: 0, // frequency: 0, // isJunk: true, - // isNonRefundable: true, + // isInstant: true, // allowed() { // return true // }, @@ -9244,7 +9235,7 @@ const tech = { count: 0, frequency: 0, isJunk: true, - isNonRefundable: true, + isInstant: true, allowed() { return !build.isExperimentSelection }, @@ -9346,7 +9337,7 @@ const tech = { count: 0, frequency: 0, isJunk: true, - isNonRefundable: true, + isInstant: true, allowed: () => true, requires: "", effect() { @@ -9363,7 +9354,7 @@ const tech = { count: 0, frequency: 0, isJunk: true, - isNonRefundable: true, + isInstant: true, allowed: () => true, requires: "", effect() { @@ -9387,7 +9378,7 @@ const tech = { count: 0, frequency: 0, isJunk: true, - isNonRefundable: true, + isInstant: true, allowed: () => true, requires: "", effect() { @@ -9450,7 +9441,7 @@ const tech = { count: 0, frequency: 0, isJunk: true, - isNonRefundable: true, + isInstant: true, allowed: () => true, requires: "", effect() { @@ -9476,7 +9467,7 @@ const tech = { count: 0, frequency: 0, isJunk: true, - isNonRefundable: true, + isInstant: true, allowed: () => true, requires: "", effect() { @@ -9508,7 +9499,7 @@ const tech = { // count: 0, // frequency: 0, // isJunk: true, - // isNonRefundable: true, + // isInstant: true, // allowed() { // return true // }, @@ -9553,7 +9544,7 @@ const tech = { count: 0, frequency: 0, isJunk: true, - isNonRefundable: true, + isInstant: true, allowed: () => true, requires: "", effect() { @@ -9569,7 +9560,7 @@ const tech = { // maxCount: 1, // count: 0, // frequency: 0, - // isNonRefundable: true, + // isInstant: true, // isJunk: true, // allowed() { // return true @@ -9589,7 +9580,7 @@ const tech = { frequency: 0, frequencyDefault: 0, isJunk: true, - isNonRefundable: true, + isInstant: true, allowed: () => true, requires: "", effect() { @@ -9623,7 +9614,7 @@ const tech = { frequency: 0, frequencyDefault: 0, isJunk: true, - isNonRefundable: true, + isInstant: true, allowed: () => true, requires: "", effect() { @@ -9668,7 +9659,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return !tech.isFallingDamage && !tech.isOverHeal && !tech.isEnergyHealth @@ -9688,7 +9679,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - // isNonRefundable: true, + // isInstant: true, isJunk: true, allowed() { return true @@ -9719,7 +9710,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - // isNonRefundable: true, + // isInstant: true, isJunk: true, allowed() { return true @@ -9752,7 +9743,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -9886,7 +9877,7 @@ const tech = { count: 0, frequency: 0, isJunk: true, - isNonRefundable: true, + isInstant: true, allowed() { return true }, @@ -9962,7 +9953,7 @@ const tech = { count: 0, frequency: 0, isJunk: true, - isNonRefundable: true, + isInstant: true, allowed() { return true }, @@ -10081,7 +10072,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -10101,7 +10092,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -10128,7 +10119,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return m.fieldMode !== 8 && m.fieldMode !== 9 && !tech.isTokamak @@ -10147,7 +10138,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return !m.isShipMode @@ -10176,7 +10167,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true }, requires: "", @@ -10198,7 +10189,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return tech.deathSpawns === 0 @@ -10217,7 +10208,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -10242,7 +10233,7 @@ const tech = { // count: 0, // frequency: 0, // isExperimentHide: true, - // isNonRefundable: true, + // isInstant: true, // isJunk: true, // allowed() { // return !m.isShipMode @@ -10291,7 +10282,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return b.inventory.length > 0 @@ -10310,7 +10301,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -10341,7 +10332,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -10371,7 +10362,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -10391,7 +10382,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -10411,7 +10402,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -10430,7 +10421,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -10447,7 +10438,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -10481,7 +10472,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -10505,7 +10496,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -10522,7 +10513,7 @@ const tech = { // maxCount: 9, // count: 0, // frequency: 0, - // isNonRefundable: true, + // isInstant: true, // isExperimentHide: true, // isJunk: true, // allowed() { @@ -10543,7 +10534,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -10562,7 +10553,7 @@ const tech = { // maxCount: 1, // count: 0, // frequency: 0, - // isNonRefundable: true, + // isInstant: true, // isJunk: true, // allowed() { return true }, // requires: "", @@ -10626,7 +10617,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -10644,7 +10635,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -10661,7 +10652,7 @@ const tech = { maxCount: 9, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -10684,7 +10675,7 @@ const tech = { maxCount: 9, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -10704,7 +10695,7 @@ const tech = { maxCount: 9, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -10728,7 +10719,7 @@ const tech = { maxCount: 9, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -10745,7 +10736,7 @@ const tech = { maxCount: 3, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -10771,7 +10762,7 @@ const tech = { maxCount: 9, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -10789,7 +10780,7 @@ const tech = { maxCount: 9, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -10814,7 +10805,7 @@ const tech = { maxCount: 9, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -10839,7 +10830,7 @@ const tech = { maxCount: 9, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -10869,7 +10860,7 @@ const tech = { count: 0, frequency: 0, isJunk: true, - isNonRefundable: true, + isInstant: true, allowed() { return !m.isShipMode }, @@ -10960,7 +10951,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return !m.isShipMode @@ -10998,7 +10989,7 @@ const tech = { count: 0, frequency: 0, isJunk: true, - isNonRefundable: true, + isInstant: true, allowed() { return !m.isShipMode }, @@ -11017,7 +11008,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -11060,7 +11051,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return !m.isShipMode && !m.isAltSkin && m.fieldUpgrades[m.fieldMode].name !== "negative mass" @@ -11083,7 +11074,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return m.isShipMode @@ -11114,7 +11105,7 @@ const tech = { count: 0, frequency: 0, isBotTech: true, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return b.totalBots() > 2 @@ -11176,7 +11167,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -11193,7 +11184,7 @@ const tech = { maxCount: 9, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -11210,7 +11201,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -11238,7 +11229,7 @@ const tech = { maxCount: 9, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return powerUps.research.count > 3 @@ -11256,7 +11247,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return powerUps.research.count > 3 @@ -11279,7 +11270,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true }, requires: "", @@ -11300,7 +11291,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -11470,7 +11461,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -11529,7 +11520,7 @@ const tech = { maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + isInstant: true, isJunk: true, allowed() { return true @@ -11566,7 +11557,7 @@ const tech = { frequency: 0, frequencyDefault: 0, isJunk: true, - isNonRefundable: true, + isInstant: true, allowed() { return !localSettings.isJunkExperiment }, @@ -11586,7 +11577,7 @@ const tech = { count: 0, frequency: 0, isJunk: true, - isNonRefundable: true, + isInstant: true, allowed: () => true, requires: "", effect() { @@ -11733,7 +11724,7 @@ const tech = { // count: 0, // frequency: 2, // isLore: true, - // isNonRefundable: true, + // isInstant: true, // isExperimentHide: true, // allowed() { // return true diff --git a/style.css b/style.css index 0492298..98d20db 100644 --- a/style.css +++ b/style.css @@ -934,6 +934,16 @@ summary { margin-bottom: -0.3em; } +.circle-grid-instant { + width: 1.1em; + height: 1.1em; + border-radius: 50%; + border: 0.15em solid hsl(255, 100%, 71%); + display: inline-block; + margin-bottom: -0.35em; + /* background-color: hsla(255, 100%, 71%, 0.3); */ +} + .circle-grid-skin { width: 1.25em; height: 1.25em; diff --git a/todo.txt b/todo.txt index 92b2a01..1b9f918 100644 --- a/todo.txt +++ b/todo.txt @@ -1,23 +1,41 @@ ******************************************************** NEXT PATCH ************************************************** -switched github pages hosting folder - https://landgreen.github.io/sidescroller/ -> https://landgreen.github.io/n-gon/ - +adjusted text and math for the fire rate system to use the new "x" syntax +tech search is no longer case sensitive -player damage reduction adjustment: 0.905x -> 0.9x per level per difficulty mode (1,2,4,5) - on easy that's 0.30 -> 0.28 by level 12 (a 6% player damage nerf) - on why that's 0.0025 -> 0.001797 by level 12 (a 28% player damage nerf) +Zectron 1.9->2x damage, -25% -> -5 energy +exothermic process -20% -> -5 energy -you can only get applied science 9->1 time -supply chain - spawns a gun, but doesn't give applied science frequency - -bug fixes +instant/unRemovable tech has a unique icon and no longer shows up in the tech list + marginal utility - no longer spawns ammo + heuristics - no longer spawn a gun, 1.2->1.3 fire rate + open-source - gives 1 extra bot option and 3x bot tech frequency + robotics - now just spawns 2 bots + induction brake - doesn't spawn heals, but lasts 15->17 seconds + accretion - doesn't spawn heals, but gets 3% duplication + mass production - doesn't spawn power ups, but gets 3% duplication + Ψ(t) collapse - doesn't spawn research, spawns 5 research from bosses + decoherence - doesn't spawn research, spawns 2 research from bosses + fine-structure constant - doesn't spawn coupling, spawn 9 coupling from bosses + Bayesian statistics - 1.03->1.05x damage, doesn't spawn research + Born rule code rewritten, but it should have a similar effect as before + triple point - 1.5->5 second freeze, but no coupling spawn + geodesics - no longer spawns ammo and guns, but gives 1.5x damage + ideal gas law - doesn't remove ammo, 12->6x foam ammo per ammo power up *********************************************************** TODO ***************************************************** -removeJunkTechFromPool doesn't seem to remove the correct amount +after clicking on a new tech (or getting it in any way) animate adding the tech to your collection -make search not case sensitive +tech - getting caught in an explosion gives you _____ + damage for 10 seconds? + heals + +tech - limit total number of tech to like 10? + +tech - destroying blocks gives _____ + +removeJunkTechFromPool doesn't seem to remove the correct amount wormholes that end inside wall check to see if the space before the wall is safe and end there instead can use laser code @@ -34,11 +52,9 @@ make sure healing isn't effected by simulation.healScale tech - destroys a random tech each new level and gains +damage each time -tech - destroy all but active gun and convert ammo over to main gun - List of ways to break the game CPT + high energy regen - research->bot fabrication-> ersatz bots -> various bot upgrades + research -> bot fabrication -> ersatz bots -> various bot upgrades grappling hook + high fire rate + alternator + time dilation duplication 100% interest + coupling, research + peer review? @@ -1112,6 +1128,8 @@ possible names for tech sidereal - with respect to the stars (an extra rotation for time keeping) holonomy - parallel transport of a vector leads to movement (applies to curved space) holographic - 2-D surface can predict the 3-D space behind it? I think + entropic gravity - gravity is emergent in a holographic way + (maybe a field tech for negative mass) conformal - similar rules for small and big scales linked to holographic principle 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 @@ -1163,7 +1181,7 @@ possible names for tech radioisotope thermoelectric generator - retrovirus: these things make JUNK DNA so link it somehow to that tech? Upon infection with a retrovirus, a cell converts the retroviral RNA into DNA and sometimes the DNA will be passed on to progeny as JUNK DNA - + amalgam, amalgamation - the action, process, or result of combining or uniting. ******************************************************** CARS IMAGES ********************************************************