diff --git a/img/Higgs mechanism.webp b/img/Higgs mechanism.webp index 9edf37b..4d7c71f 100644 Binary files a/img/Higgs mechanism.webp and b/img/Higgs mechanism.webp differ diff --git a/img/Newtons 1st law.webp b/img/Newtons 1st law.webp index 28dc360..82cf970 100644 Binary files a/img/Newtons 1st law.webp and b/img/Newtons 1st law.webp differ diff --git a/img/Newtons 2nd law.webp b/img/Newtons 2nd law.webp index 478236d..eb17dfe 100644 Binary files a/img/Newtons 2nd law.webp and b/img/Newtons 2nd law.webp differ diff --git a/img/desublimated ammunition.webp b/img/desublimated ammunition.webp index fab54cf..541e2a1 100644 Binary files a/img/desublimated ammunition.webp and b/img/desublimated ammunition.webp differ diff --git a/img/field/field emitter22.webp b/img/field/field emitter22.webp new file mode 100644 index 0000000..9c0e8a1 Binary files /dev/null and b/img/field/field emitter22.webp differ diff --git a/img/field/field emitter23.webp b/img/field/field emitter23.webp new file mode 100644 index 0000000..72adb69 Binary files /dev/null and b/img/field/field emitter23.webp differ diff --git a/img/field/field emitter24.webp b/img/field/field emitter24.webp new file mode 100644 index 0000000..9634dcb Binary files /dev/null and b/img/field/field emitter24.webp differ diff --git a/img/integrated armament.webp b/img/integrated armament.webp index b876da6..53dbad2 100644 Binary files a/img/integrated armament.webp and b/img/integrated armament.webp differ diff --git a/img/mechatronics.webp b/img/mechatronics.webp new file mode 100644 index 0000000..37d69f4 Binary files /dev/null and b/img/mechatronics.webp differ diff --git a/img/regression.webp b/img/regression.webp index 872bc5c..da119ef 100644 Binary files a/img/regression.webp and b/img/regression.webp differ diff --git a/img/simulated annealing.webp b/img/simulated annealing.webp index fbce888..bfc1ef4 100644 Binary files a/img/simulated annealing.webp and b/img/simulated annealing.webp differ diff --git a/index.html b/index.html index 58e7192..ecc9d7f 100644 --- a/index.html +++ b/index.html @@ -58,6 +58,12 @@ why ⚇ + + hide images + + + minimal HUD + limit frames per second: no cap @@ -67,33 +73,6 @@ 30 fps - classic n-gon: - - mech: 2014 - spacetime: 2015 - ballistics: 2015 - portal: 2016 - side scroller: 2016 - side scroller: 2016 - LandGame: 2017 - n-gon: 2018 - n-gon: summer-2019 - n-gon: fall-2019 - n-gon: summer-2020 - n-gon: spring-2021 - n-gon: fall-2022 - current version - - - randomization seed: - - - - - hide images - - - minimal HUD community maps @@ -145,6 +124,28 @@ --> + + classic n-gon: + + mech: 2014 + spacetime: 2015 + ballistics: 2015 + portal: 2016 + side scroller: 2016 + side scroller: 2016 + LandGame: 2017 + n-gon: 2018 + n-gon: summer-2019 + n-gon: fall-2019 + n-gon: summer-2020 + n-gon: spring-2021 + n-gon: fall-2022 + current version + + + randomization seed: + + diff --git a/js/engine.js b/js/engine.js index 2d53914..80b94bc 100644 --- a/js/engine.js +++ b/js/engine.js @@ -268,7 +268,7 @@ function collisionChecks(event) { if (tech.blockDmg) { //electricity Matter.Body.setVelocity(mob[k], { x: 0.5 * mob[k].velocity.x, y: 0.5 * mob[k].velocity.y }); if (tech.isBlockRadiation && !mob[k].isShielded && !mob[k].isMobBullet) { - mobs.statusDoT(mob[k], tech.blockDmg * m.dmgScale * 4 / 12, 360) //200% increase -> x (1+2) //over 7s -> 360/30 = 12 half seconds -> 3/12 + mobs.statusDoT(mob[k], tech.blockDmg * 0.42, 180) //200% increase -> x (1+2) //over 7s -> 360/30 = 12 half seconds -> 3/12 } else { mob[k].damage(tech.blockDmg * m.dmgScale) simulation.drawList.push({ diff --git a/js/index.js b/js/index.js index e1cc1eb..58adc99 100644 --- a/js/index.js +++ b/js/index.js @@ -336,6 +336,25 @@ const build = { }, pauseGrid() { // build.pixelDraw(); + + build.generatePauseLeft() //makes the left side of the pause menu with the tech + build.generatePauseRight() //makes the right side of the pause menu with the tech + + document.getElementById("tech").style.display = "none" + document.getElementById("guns").style.display = "none" + document.getElementById("field").style.display = "none" + document.getElementById("health").style.display = "none" + document.getElementById("health-bg").style.display = "none" + document.getElementById("defense-bar").style.display = "none" + document.getElementById("damage-bar").style.display = "none" + + + //show in game console + // document.getElementById("text-log").style.display = "inline" + simulation.lastLogTime = m.cycle //hide in game console + + }, + generatePauseLeft() { //used for junk estimation let junkCount = 0 let totalCount = 1 //start at one to avoid NaN issues @@ -358,17 +377,19 @@ const build = { let text = ` - - copy build url -PAUSED - - -hide images +PAUSED press ${input.key.pause} to resume - -minimal HUD +copy build url + + +hide images + + +minimal HUD + + damage: ${((tech.damageFromTech())).toPrecision(4)} difficulty: ${((m.dmgScale)).toPrecision(4)} defense: ${tech.isEnergyHealth ? (1 - Math.pow(m.defense(), 0.13)).toPrecision(5) : (1 - m.defense()).toPrecision(5)} difficulty: ${(1 / simulation.dmgScale).toPrecision(4)} fire rate: ${((1 - b.fireCDscale) * 100).toFixed(b.fireCDscale < 0.1 ? 2 : 0)}% @@ -395,15 +416,15 @@ ${simulation.isCheating ? "lore disabled" : ""} if (tech.isPauseSwitchField && !simulation.isChoosing) { const style = localSettings.isHideImages ? `style="height:auto;"` : `style="background-image: url('img/field/${m.fieldUpgrades[m.fieldMode].name}${m.fieldMode === 0 ? m.fieldUpgrades[0].imageNumber : ""}.webp');"` text += ` - - ${build.nameLink(m.fieldUpgrades[m.fieldMode].name)} - ${m.fieldUpgrades[m.fieldMode].description} ` + + ${build.nameLink(m.fieldUpgrades[m.fieldMode].name)} + ${m.fieldUpgrades[m.fieldMode].description} ` } else { const style = localSettings.isHideImages ? `style="height:auto;"` : `style="background-image: url('img/field/${m.fieldUpgrades[m.fieldMode].name}${m.fieldMode === 0 ? m.fieldUpgrades[0].imageNumber : ""}.webp');"` text += ` - - ${build.nameLink(m.fieldUpgrades[m.fieldMode].name)} - ${m.fieldUpgrades[m.fieldMode].description} ` + + ${build.nameLink(m.fieldUpgrades[m.fieldMode].name)} + ${m.fieldUpgrades[m.fieldMode].description} ` } // for (let i = 0, len = b.inventory.length; i < len; i++) { // text += ` ${build.nameLink(b.guns[b.inventory[i]].name)} - ${b.guns[b.inventory[i]].ammo} ${b.guns[b.inventory[i]].description}` @@ -411,16 +432,34 @@ ${simulation.isCheating ? "lore disabled" : ""} for (let i = 0, len = b.inventory.length; i < len; i++) { const style = localSettings.isHideImages ? `style="height:auto;"` : `style="background-image: url('img/gun/${b.guns[b.inventory[i]].name}.webp');"` text += ` - - ${build.nameLink(b.guns[b.inventory[i]].name)} - ${b.guns[b.inventory[i]].ammo} - ${b.guns[b.inventory[i]].description} ` + + ${build.nameLink(b.guns[b.inventory[i]].name)} - ${b.guns[b.inventory[i]].ammo} + ${b.guns[b.inventory[i]].description} ` } if (!localSettings.isHideHUD) text += `${document.getElementById("text-log").innerHTML}` //show last in game console message let el = document.getElementById("pause-grid-left") el.style.display = "grid" el.innerHTML = text + }, + generatePauseRight() { //right side - text = ""; + // + // damage + + // + // guntech + + // bot + let text = ` +damage +guntech +fieldtech +heal +defense +energy + +sort +`; // const style = (tech.isPauseEjectTech && !simulation.isChoosing) ? 'style="animation: techColorCycle 1s linear infinite alternate;"' : '' const ejectClass = (tech.isPauseEjectTech && !simulation.isChoosing) ? 'pause-eject' : '' for (let i = 0, len = tech.tech.length; i < len; i++) { @@ -470,23 +509,55 @@ ${simulation.isCheating ? "lore disabled" : ""} text += `${tech.tech[i].link}${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() : tech.tech[i].description}` } } - el = document.getElementById("pause-grid-right") + const el = document.getElementById("pause-grid-right") el.style.display = "grid" el.innerHTML = text + }, + sortTech(find) { + const sortKeyword = (a, b) => { + let aHasKeyword = (a.descriptionFunction ? a.descriptionFunction() : a.description).includes(find) || a.name.includes(find) + let bHasKeyword = (b.descriptionFunction ? b.descriptionFunction() : b.description).includes(find) || b.name.includes(find) + if ((aHasKeyword) && !bHasKeyword) return -1; + if (!aHasKeyword && bHasKeyword) return 1; + return 0; + } - document.getElementById("tech").style.display = "none" - document.getElementById("guns").style.display = "none" - document.getElementById("field").style.display = "none" - document.getElementById("health").style.display = "none" - document.getElementById("health-bg").style.display = "none" - document.getElementById("defense-bar").style.display = "none" - document.getElementById("damage-bar").style.display = "none" - - - //show in game console - // document.getElementById("text-log").style.display = "inline" - simulation.lastLogTime = m.cycle //hide in game console - + if (find === 'guntech') { + tech.tech.sort((a, b) => { + if (a.isGunTech && !b.isGunTech) return -1; //sort to the top + if (!a.isGunTech && b.isGunTech) return 1; //sort to the bottom + return 0; + }); + } else if (find === 'fieldtech') { + tech.tech.sort((a, b) => { + if (a.isFieldTech && !b.isFieldTech) return -1; //sort to the top + if (!a.isFieldTech && b.isFieldTech) return 1; //sort to the bottom + return 0; + }); + } else if (find === 'damage') { + tech.tech.sort(sortKeyword); + } else if (find === 'defense') { + tech.tech.sort(sortKeyword); + } else if (find === 'energy') { + tech.tech.sort(sortKeyword); + } else if (find === 'heal') { + tech.tech.sort((a, b) => { + if (a.isHealTech && !b.isHealTech) return -1; //sort to the top + if (!a.isHealTech && b.isHealTech) return 1; //sort to the bottom + return 0; + }); + } else if (find === 'bot') { + tech.tech.sort((a, b) => { + if (a.isBotTech && !b.isBotTech) return -1; //sort to the top + if (!a.isBotTech && b.isBotTech) return 1; //sort to the bottom + return 0; + }); + } else if (find === 'input') { + find = document.getElementById("sort-input").value; + tech.tech.sort(sortKeyword); + } + build.generatePauseRight() //makes the right side of the pause menu with the tech + document.getElementById("sort-input").value = find; //make the sorted string display in the keyword search input field }, unPauseGrid() { document.getElementById("guns").style.display = "inline" @@ -1158,7 +1229,7 @@ window.addEventListener("keydown", function (event) { } break case input.key.testing: - if (m.alive && localSettings.loreCount > 0) { + if (m.alive && localSettings.loreCount > 0 && !simulation.paused) { if (simulation.difficultyMode > 4) { simulation.makeTextLog("testing mode disabled for this difficulty"); break diff --git a/js/level.js b/js/level.js index 8a9c4be..8188210 100644 --- a/js/level.js +++ b/js/level.js @@ -27,24 +27,26 @@ const level = { // m.immuneCycle = Infinity //you can't take damage // tech.tech[297].frequency = 100 // m.couplingChange(10) - // m.setField("negative mass") //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 + // m.setField("standing wave") //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 // m.energy = 0 // simulation.molecularMode = 2 // m.damage(0.1); // 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.giveGuns("shotgun") //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[3].ammo = 100000000 - // tech.giveTech("accretion") - // tech.giveTech("surface plasmons") + // tech.giveTech("bremsstrahlung") + // tech.giveTech("cherenkov radiation") + // tech.giveTech("irradiated nails") // for (let i = 0; i < 6; ++i) tech.giveTech("Lorentz transformation") - // for (let i = 0; i < 1; ++i) tech.giveTech("waste heat recovery") + // for (let i = 0; i < 1; ++i) tech.giveTech("rivet gun") // requestAnimationFrame(() => { for (let i = 0; i < 1; i++) tech.giveTech("foam-bot") }); // for (let i = 0; i < 1; i++) tech.giveTech("foam-bot upgrade") - // for (let i = 0; i < 1; ++i) tech.giveTech("flatland") + // for (let i = 0; i < 1; ++i) tech.giveTech("ternary") + // for (let i = 0; i < 3; ++i) tech.giveTech("mechatronics") // for (let i = 0; i < 3; i++) powerUps.directSpawn(450, -50, "tech"); // for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "research"); // for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "coupling"); - // level.subway(); + // level.testing(); // spawn.nodeGroup(3200, -300, "sniper") // spawn.nodeGroup(2200, -300, "sniper") // spawn.nodeGroup(2200, -300, "sniper") @@ -1850,100 +1852,6 @@ const level = { testing() { simulation.enableConstructMode() //tech.giveTech('motion sickness') //used to build maps in testing mode - //clipping everything except LoS - //stroke around map - // simulation.ephemera.push({ - // name: "LoS", count: 0, do() { - // const pos = m.pos - // const radius = 5000 - // if (!simulation.isTimeSkipping) { - // const vertices = simulation.sight.circleLoS(pos, radius); - // if (vertices.length) { - // ctx.beginPath(); - // ctx.moveTo(vertices[0].x, vertices[0].y); - // for (var i = 1; i < vertices.length; i++) { - // var currentDistance = Math.sqrt((vertices[i - 1].x - pos.x) ** 2 + (vertices[i - 1].y - pos.y) ** 2); - // var newDistance = Math.sqrt((vertices[i].x - pos.x) ** 2 + (vertices[i].y - pos.y) ** 2); - // if (Math.abs(currentDistance - radius) < 1 && Math.abs(newDistance - radius) < 1) { - // const currentAngle = Math.atan2(vertices[i - 1].y - pos.y, vertices[i - 1].x - pos.x); - // const newAngle = Math.atan2(vertices[i].y - pos.y, vertices[i].x - pos.x); - // ctx.arc(pos.x, pos.y, radius, currentAngle, newAngle); - // } else { - // ctx.lineTo(vertices[i].x, vertices[i].y) - // } - // } - // newDistance = Math.sqrt((vertices[0].x - pos.x) ** 2 + (vertices[0].y - pos.y) ** 2); - // currentDistance = Math.sqrt((vertices[vertices.length - 1].x - pos.x) ** 2 + (vertices[vertices.length - 1].y - pos.y) ** 2); - // if (Math.abs(currentDistance - radius) < 1 && Math.abs(newDistance - radius) < 1) { - // const currentAngle = Math.atan2(vertices[vertices.length - 1].y - pos.y, vertices[vertices.length - 1].x - pos.x); - // const newAngle = Math.atan2(vertices[0].y - pos.y, vertices[0].x - pos.x); - // ctx.arc(pos.x, pos.y, radius, currentAngle, newAngle); - // } else { - // ctx.lineTo(vertices[0].x, vertices[0].y) - // } - // ctx.strokeStyle = "#000"; - // ctx.lineWidth = 20; - // ctx.stroke(simulation.draw.mapPath); - // ctx.globalCompositeOperation = "destination-in"; - // ctx.fillStyle = "#000"; - // ctx.fill(); - // ctx.globalCompositeOperation = "source-over"; - // ctx.clip(); - // } - // } - // }, - // }) - - //clipping everything except LoS - //redrawing map, so it's still visible - // simulation.ephemera.push({ - // name: "LoS", count: 0, do() { - // const pos = m.pos - // const radius = 3000 - // if (!simulation.isTimeSkipping) { - // const vertices = simulation.sight.circleLoS(pos, radius); - // if (vertices.length) { - // ctx.beginPath(); - // ctx.moveTo(vertices[0].x, vertices[0].y); - // for (var i = 1; i < vertices.length; i++) { - // var currentDistance = Math.sqrt((vertices[i - 1].x - pos.x) ** 2 + (vertices[i - 1].y - pos.y) ** 2); - // var newDistance = Math.sqrt((vertices[i].x - pos.x) ** 2 + (vertices[i].y - pos.y) ** 2); - // if (Math.abs(currentDistance - radius) < 1 && Math.abs(newDistance - radius) < 1) { - // const currentAngle = Math.atan2(vertices[i - 1].y - pos.y, vertices[i - 1].x - pos.x); - // const newAngle = Math.atan2(vertices[i].y - pos.y, vertices[i].x - pos.x); - // ctx.arc(pos.x, pos.y, radius, currentAngle, newAngle); - // } else { - // ctx.lineTo(vertices[i].x, vertices[i].y) - // } - // } - // newDistance = Math.sqrt((vertices[0].x - pos.x) ** 2 + (vertices[0].y - pos.y) ** 2); - // currentDistance = Math.sqrt((vertices[vertices.length - 1].x - pos.x) ** 2 + (vertices[vertices.length - 1].y - pos.y) ** 2); - // if (Math.abs(currentDistance - radius) < 1 && Math.abs(newDistance - radius) < 1) { - // const currentAngle = Math.atan2(vertices[vertices.length - 1].y - pos.y, vertices[vertices.length - 1].x - pos.x); - // const newAngle = Math.atan2(vertices[0].y - pos.y, vertices[0].x - pos.x); - // ctx.arc(pos.x, pos.y, radius, currentAngle, newAngle); - // } else { - // ctx.lineTo(vertices[0].x, vertices[0].y) - // } - - // ctx.strokeStyle = "#234"; - // ctx.lineWidth = 9; - // ctx.stroke(simulation.draw.mapPath); - - // ctx.globalCompositeOperation = "destination-in"; - // ctx.fillStyle = "#000"; - // ctx.fill(); - // ctx.globalCompositeOperation = "source-over"; - - // // ctx.fill(simulation.draw.mapPath); - // // ctx.fillStyle = "#000"; - - // ctx.clip(); - // } - // } - // }, - // }) - document.body.style.backgroundColor = "#fff"; // color.map = "#444" //custom map color // level.difficultyIncrease(14); //hard mode level 7 @@ -2033,10 +1941,10 @@ const level = { //??? - // level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why + level.difficultyIncrease(3 * 4) //30 is near max on hard //60 is near max on why // m.addHealth(Infinity) - // spawn.starter(1900, -500, 200) //big boy + spawn.starter(1900, -500, 200) //big boy // for (let i = 0; i < 10; ++i) spawn.launcher(1900, -500) // spawn.suckerBoss(1900, -500) // spawn.launcherBoss(3200, -500) diff --git a/js/mob.js b/js/mob.js index e736aed..090b17a 100644 --- a/js/mob.js +++ b/js/mob.js @@ -188,7 +188,8 @@ const mobs = { who.status.push({ effect() { if ((simulation.cycle - this.startCycle) % 30 === 0) { - let dmg = m.dmgScale * this.dmg * tech.radioactiveDamage + let dmg = m.dmgScale * tech.radioactiveDamage * this.dmg + console.log(dmg) who.damage(dmg); if (who.damageReduction) { simulation.drawList.push({ //add dmg to draw queue diff --git a/js/player.js b/js/player.js index dcbfbd5..21540ea 100644 --- a/js/player.js +++ b/js/player.js @@ -377,9 +377,9 @@ const m = { //randomize ammo based on ammo/ammoPack count for (let i = 0, len = b.inventory.length; i < len; i++) { - if (b.guns[b.inventory[i]].ammo !== Infinity) b.guns[b.inventory[i]].ammo = Math.max(0, Math.floor(ammoCount / b.inventory.length * b.guns[b.inventory[i]].ammoPack * (1.05 + 0.3 * (Math.random() - 0.5)))) + if (b.guns[b.inventory[i]].ammo !== Infinity) b.guns[b.inventory[i]].ammo = Math.max(0, Math.floor(ammoCount / b.inventory.length * b.guns[b.inventory[i]].ammoPack * (1.15 + 0.3 * (Math.random() - 0.5)))) } - + console.log(b.activeGun) //randomize tech for (let i = 0; i < totalTech; i++) { //find what tech I could get @@ -545,7 +545,7 @@ const m = { if (tech.isZeno) dmg *= 0.15 if (tech.isFieldHarmReduction) dmg *= 0.5 if (tech.isHarmMACHO) dmg *= 0.4 - if (tech.isImmortal) dmg *= 0.67 + if (tech.isImmortal) dmg *= 0.7 if (tech.energyRegen === 0) dmg *= 0.34 // if (tech.healthDrain) dmg *= 1 + 3.33 * tech.healthDrain //tech.healthDrain = 0.03 at one stack //cause more damage if (m.fieldMode === 0 || m.fieldMode === 3) dmg *= 0.973 ** m.coupling @@ -2317,7 +2317,7 @@ const m = { if (who.isMobBullet) { who.damage(tech.blockDmg * m.dmgScale * 3, true) } else { - mobs.statusDoT(who, tech.blockDmg * m.dmgScale * 4 / 12, 360) //200% increase -> x (1+2) //over 7s -> 360/30 = 12 half seconds -> 3/12 + mobs.statusDoT(who, tech.blockDmg * 0.42, 180) //200% increase -> x (1+2) //over 7s -> 360/30 = 12 half seconds -> 3/12 } } else { who.damage(tech.blockDmg * m.dmgScale, true) @@ -2531,7 +2531,7 @@ const m = { }, fieldUpgrades: [{ name: "field emitter", - imageNumber: Math.floor(Math.random() * 20), + imageNumber: Math.floor(Math.random() * 23), description: `use energy to deflect mobs generate 6 energy per second`, // 100 max energy effect: () => { @@ -2727,7 +2727,7 @@ const m = { if (mob[i].isMobBullet) { mob[i].damage(tech.blockDmg * m.dmgScale * 3, true) } else { - mobs.statusDoT(mob[i], tech.blockDmg * m.dmgScale * 4 / 12, 360) //200% increase -> x (1+2) //over 7s -> 360/30 = 12 half seconds -> 3/12 + mobs.statusDoT(mob[i], tech.blockDmg * m.dmgScale * 0.42, 180) //200% increase -> x (1+2) //over 7s -> 360/30 = 12 half seconds -> 3/12 } } else { mob[i].damage(tech.blockDmg * m.dmgScale, true) diff --git a/js/tech.js b/js/tech.js index f6d9657..c1d7aa8 100644 --- a/js/tech.js +++ b/js/tech.js @@ -254,7 +254,7 @@ const tech = { if (tech.isSpeedDamage) dmg *= 1 + Math.min(0.66, player.speed * 0.0165) if (tech.isDamageAfterKillNoRegen && m.lastKillCycle + 300 > m.cycle) dmg *= 1.6 if (tech.isAxion && tech.isHarmMACHO) dmg *= 2 - m.defense() - if (tech.isHarmDamage && m.lastHarmCycle + 600 > m.cycle) dmg *= 3; + if (tech.isHarmDamage && m.lastHarmCycle + 480 > m.cycle) dmg *= 3; if (tech.lastHitDamage && m.lastHit) dmg *= 1 + tech.lastHitDamage * m.lastHit * (2 - m.defense()) // if (!simulation.paused) m.lastHit = 0 if (tech.isLowHealthDmg) dmg *= 1 + 0.7 * Math.max(0, 1 - (tech.isEnergyHealth ? m.energy : m.health)) return dmg @@ -757,25 +757,6 @@ const tech = { // } } }, - { - name: "integrated armament", - link: `integrated armament`, - description: `+25% damage, but new gunsreplace your current gun and convert guntech`, - maxCount: 1, - count: 0, - frequency: 1, - frequencyDefault: 1, - allowed() { - return b.inventory.length === 1 - }, - requires: "only 1 gun", - effect() { - tech.isOneGun = true; - }, - remove() { - tech.isOneGun = false; - } - }, { name: "supply chain", descriptionFunction() { @@ -987,7 +968,52 @@ const tech = { } } }, - + { + name: "integrated armament", + link: `integrated armament`, + description: `+25% damage, but new guns replaceyour current gun and convert guntech`, + maxCount: 1, + count: 0, + frequency: 1, + frequencyDefault: 1, + allowed() { + return b.inventory.length === 1 + }, + requires: "only 1 gun", + effect() { + tech.isOneGun = true; + }, + remove() { + tech.isOneGun = false; + } + }, + { + name: "mechatronics", + descriptionFunction() { + let damageTotal = 1 + for (let i = 0; i < this.damageSoFar.length; i++) damageTotal *= this.damageSoFar[i] + let currentDamage = "" + if (this.count) currentDamage = `(+${(100 * (damageTotal - 1)).toFixed(0)}%)` + return `gain between +7% and +13% damage` + currentDamage + }, + maxCount: 9, + count: 0, + frequency: 1, + frequencyDefault: 1, + allowed() { return true }, + requires: "", + damage: 1.1, + damageSoFar: [], //tracks the random damage upgrades so it can be removed and in descriptionFunction + effect() { + const damage = (Math.floor((Math.random() * 0.07 + 0.07 + 1) * 100)) / 100 + tech.damage *= damage + this.damageSoFar.push(damage) + }, + remove() { + for (let i = 0; i < this.damageSoFar.length; i++) tech.damage /= this.damageSoFar[i] + this.damageSoFar.length = 0 + } + }, // { // name: "coyote", // description: "", @@ -1055,7 +1081,7 @@ const tech = { { name: "microstates", link: `microstates`, - description: "for each active bullet / bot+0.7% damage", + description: "for each active bullet or bot+0.7% damage", maxCount: 1, count: 0, frequency: 1, @@ -3166,7 +3192,7 @@ const tech = { }, { name: "quantum immortality", - description: "+33% defenseafter dying, continue in an alternate reality", + description: "+30% defenseafter dying, continue in an alternate reality", maxCount: 1, count: 0, frequency: 1, @@ -4068,7 +4094,7 @@ const tech = { }, { name: "null hypothesis", - description: `+9% damageremoving this spawns ${powerUps.orb.research(15)}`, + description: `+8% damageremoving this spawns ${powerUps.orb.research(15)}`, maxCount: 1, count: 0, frequency: 1, @@ -4078,7 +4104,7 @@ const tech = { return true }, requires: "", - damage: 1.09, + damage: 1.08, effect() { tech.damage *= this.damage }, @@ -7360,7 +7386,7 @@ const tech = { }, { name: "cherenkov radiation", //deflecting and blocks - description: "bremsstrahlung's effects are radioactive+300% damage over 6 seconds", + description: "bremsstrahlung's effects are radioactive+250% damage over 3 seconds", isFieldTech: true, maxCount: 1, count: 0, @@ -7483,7 +7509,7 @@ const tech = { }, { name: "radiative equilibrium", - description: "after losing health+200% damage for 10 seconds", + description: "after losing health+200% damage for 8 seconds", isFieldTech: true, maxCount: 1, count: 0, diff --git a/style.css b/style.css index 32ac370..f21783e 100644 --- a/style.css +++ b/style.css @@ -298,6 +298,27 @@ summary { font-size: 0.75em; } +.sort { + padding: 0.1em 0.3em; + border: 1px solid #444; + /* min-height: 88px; */ + line-height: 100%; + background-color: #fff; +} + +.sort-button { + border: 1px #333 solid; + border-radius: 0.5em; + background-color: #fff; + font-size: 0.5em; + /* padding: 0.3em; */ + +} + +.sort-button:hover { + background-color: #eee; +} + .pause-eject .card-text { animation: techColorCycle 1s linear infinite alternate; } diff --git a/todo.txt b/todo.txt index c5536ff..dd34c36 100644 --- a/todo.txt +++ b/todo.txt @@ -1,10 +1,21 @@ ******************************************************** NEXT PATCH ************************************************** -added a random station in subway -a few bug fixes +pause menu can sort tech by keywords + +tech: mechatronics - randomly add +(7 to 13)% damage + +a few new images +bug fixes + cherenkov radiation damage bug fixed it does much more damage and matches the description + *********************************************************** TODO ***************************************************** +extend sort to experiments + +aperture also increases and decreases vision range + I think messing with vision range causes problems with the start of level vision code + mob non-combat behaviors, like Rain World gathering blocks @@ -20,6 +31,8 @@ mob non-combat behaviors, like Rain World play fight other mobs +maybe reduce the fps on the line of sight graphics to make it look more like a sensor? + consider increasing the base player horizontal movement maybe only increase ground movement, air control seems fine @@ -30,6 +43,7 @@ level: subway - a map that uses the train level element and line of sight graphi teleport to far away rooms map elements that alternate between positions buttons and doors + maybe add mob mobs to each station? this makes it faster to clear the level boss spawn at the exit station? or at a random station? or at the station before the exit? spawn on the station after enough mobs have been killed? @@ -88,9 +102,6 @@ mobs attack mines rework quantum eraser -test bremsstrahlung damage - and make sure it actually does more damage with the dot tech - tech circular polarization - wave gun bullets move in a circle tech: choose next map by name after exiting current map @@ -163,8 +174,6 @@ tech: after bosses diethey spawn a research tech: +8% damage each time you kill a boss -tech: maybe missiles explode when they hit walls, but explosions only drain energy - tech: sticky grenades needs another effect to be good enough stick to mobs? @@ -268,8 +277,6 @@ mob status effect - emit - mobs fire lasers for a few seconds Tech: "Solid rocket motor": Missiles would start at 300% speed and 200% missile damage upon explosion, but the speed and damage would decrease to 40% speed and damage as time goes on tech: every time shotgun fires it's a different shotgun mode: nails, ice, needles, worms, fleas, rivets, ... but you get more ammo -try again - line of sight https://ncase.me/sight-and-light/ - for tech power ups no tech options are displayed until you research once or display only JUNK until you research once increase the number of options after each research @@ -281,8 +288,6 @@ tech increase max energy and energy to 5000, but you can no longer regen energy 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 freeze and __ not cause death at 50% health, but just 600% extra damage for that bullet - make a new coupling effect for perfect diamagnetism or standing wave make a faster smaller version of cell boss that also has map collisions @@ -341,8 +346,6 @@ replace field descriptions with a function call so they can have dynamic text Boss that shoots out a ring of bullets, then after a few seconds it gravitates the bullets back -JUNK: Placebo: double the power up spawn rate but make half of them do nothing - coupling put coupling description as 4th line on field description raw text no function call @@ -656,10 +659,6 @@ a mine tech that makes mines you can stand on or 3 seconds after you touch them benefits from all block tech -setting to remove UI, except health bar - except active gun? to see ammo - checkbox in pause and in settings - go non-collide with mobs when immune to damage? mobs that are invulnerable from the front @@ -674,8 +673,6 @@ add anticipation to more mob attacks can mob bullets damage other mob? maybe if they switch collisions and classType === "body" or obj.classType === "bullet" -path finding system - figure out how to get friction effects on map/body to apply to player also horizontal moving platform? @@ -749,9 +746,6 @@ balance time dilation with bose einstein (you can freeze everything and take no code is still there, need to balance balance with energy drain? -overflowing energy does harm? - or just reduces harm reduction? - make a line of constrained mobs move like a snake apply forces with directions determined by time and position on the snake @@ -883,18 +877,6 @@ https://developer.mozilla.org/en-US/docs/Web/API/Pointer_Lock_API https://www.vsynctester.com/game.html https://news.ycombinator.com/item?id=26530272 -mobile requirements: - detect mobile, flip to landscape - detect no keyboard, no mouse - auto aim? - limit items to ones that don't require aiming? - tap screen regions to move (WASD) - reduce font size - -add back in gamepad support? - but does anyone care? - https://github.com/landgreen/landgreen.github.io/search?q=gamepadconnected - tech: time dilation - when you exit time dilation rewind to the state you entered position, velocity, and health no energy cost