diff --git a/img/peer review.webp b/img/peer review.webp new file mode 100644 index 0000000..0a91809 Binary files /dev/null and b/img/peer review.webp differ diff --git a/index.html b/index.html index 0aa9e8c..f4b984a 100644 --- a/index.html +++ b/index.html @@ -62,7 +62,7 @@
- +
- +
-
damage: ${((tech.damageFromTech())).toPrecision(4)}     difficulty: ${((m.dmgScale)).toPrecision(4)} -
defense: ${(1 - m.defense()).toPrecision(5)}     difficulty: ${(1 / simulation.dmgScale).toPrecision(4)} +
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)}% ${tech.duplicationChance() ? `
duplication: ${(tech.duplicationChance() * 100).toFixed(0)}%` : ""} ${m.coupling ? `
` + m.couplingDescription(m.coupling) + ` from ${(m.coupling).toFixed(0)} ${powerUps.orb.coupling(1)}` : ""} @@ -552,7 +552,7 @@ ${simulation.isCheating ? "

lore disabled" : ""} - + @@ -876,7 +876,9 @@ ${simulation.isCheating ? "

lore disabled" : ""} - + + + @@ -1602,10 +1604,7 @@ window.addEventListener("keydown", function (event) { case "r": m.resetHistory(); Matter.Body.setPosition(player, simulation.mouseInGame); - Matter.Body.setVelocity(player, { - x: 0, - y: 0 - }); + Matter.Body.setVelocity(player, { x: 0, y: 0 }); // move bots to player for (let i = 0; i < bullet.length; i++) { if (bullet[i].botType) { diff --git a/js/level.js b/js/level.js index 884f39a..150df6d 100644 --- a/js/level.js +++ b/js/level.js @@ -11,7 +11,7 @@ const level = { // playableLevels: ["pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion"], //see level.populateLevels: (initial, ... , reservoir or factory, reactor, ... , subway, final) added later playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber", "pavilion", "lock"], - communityLevels: ["gauntlet", "stronghold", "basement", "crossfire", "vats", "run", "ngon", "house", "perplex", "coliseum", "tunnel", "islands", "temple", "dripp", "biohazard", "stereoMadness", "yingYang", "staircase", "fortress", "commandeer", "clock", "buttonbutton", "downpour", "superNgonBros", "underpass", "cantilever", "tlinat", "ruins", "ace", "crimsonTowers", "LaunchSite", "shipwreck", "unchartedCave", "dojo", 'arena'], + communityLevels: ["gauntlet", "stronghold", "basement", "crossfire", "vats", "run", "ngon", "house", "perplex", "coliseum", "tunnel", "islands", "temple", "dripp", "biohazard", "stereoMadness", "yingYang", "staircase", "fortress", "commandeer", "clock", "buttonbutton", "downpour", "superNgonBros", "underpass", "cantilever", "tlinat", "ruins", "ace", "crimsonTowers", "LaunchSite", "shipwreck", "unchartedCave", "dojo", "arena", "soft"], trainingLevels: ["walk", "crouch", "jump", "hold", "throw", "throwAt", "deflect", "heal", "fire", "nailGun", "shotGun", "superBall", "matterWave", "missile", "stack", "mine", "grenades", "harpoon"], levels: [], start() { @@ -51,7 +51,7 @@ const level = { // for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "research"); // for (let i = 0; i < 100; i++) powerUps.directSpawn(1750, -500, "coupling"); // spawn.mapRect(575, -700, 25, 425); //block mob line of site on testing - // level.testChamber(); + // level.testing(); // for (let i = 0; i < 1; ++i) spawn.laserLayer(1400, -500) // Matter.Body.setPosition(player, { x: -200, y: -3330 }); @@ -82,9 +82,9 @@ const level = { // localSettings.isTrainingNotAttempted = true // simulation.isCheating = false //true; // for (let i = 0; i < 5; i++) tech.giveTech("undefined") - // lore.techCount = 2 + // lore.techCount = 1 // level.levelsCleared = 10 - // localSettings.loreCount = 5 //this sets what conversation is heard + // localSettings.loreCount = 2 //this sets what conversation is heard // if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage // level.onLevel = -1 //this sets level.levels[level.onLevel] = undefined which is required to run the conversation // level.null() @@ -98,7 +98,6 @@ const level = { // powerUps.spawn(m.pos.x, m.pos.y, "entanglement", false); } else { spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns - // spawn.pickList = ["focuser", "focuser"] level[level.levels[level.onLevel]](); //picks the current map from the the levels array if (!simulation.isCheating && !build.isExperimentRun && !simulation.isTraining) { @@ -160,7 +159,7 @@ const level = { } if (tech.isGunChoice && Number.isInteger(tech.buffedGun) && b.inventory.length) { var gun = b.guns[b.inventory[tech.buffedGun]].name - simulation.makeTextLog(`pigeonhole principle: +${(31 * Math.max(0, b.inventory.length)).toFixed(0)}% damage for ${gun}`, 600); + simulation.makeTextLog(`pigeonhole principle: ${(1.3 * Math.max(0, b.inventory.length)).toFixed(2)}x damage for ${gun}`, 600); } if (tech.isSwitchReality && level.levelsCleared !== 0) { simulation.makeTextLog(`simulation.amplitude = ${Math.random()}`); @@ -170,9 +169,9 @@ const level = { } if (tech.isHealLowHealth) { if (tech.isEnergyHealth) { - var len = 4 * (1 - m.energy / m.maxEnergy) //as a percent + var len = 4 * Math.max(0, m.maxEnergy - m.energy) } else { - var len = 4 * (1 - m.health / m.maxHealth) //as a percent + var len = 4 * Math.max(0, m.maxHealth - m.health) } for (let i = 0; i < len; i++) powerUps.spawn(player.position.x + 90 * (Math.random() - 0.5), player.position.y + 90 * (Math.random() - 0.5), "heal", false); } @@ -31811,6 +31810,562 @@ const level = { } } }, + soft() { + simulation.makeTextLog(``); + simulation.makeTextLog(`soft by Richard0820`); + simulation.makeTextLog("The lasers deal less damage the higher level you are") + const portals = []; + portals.push(level.portal({ + x: -1525, + y: -250 + }, Math.PI / 2, { + x: 1100, + y: -1025 + }, Math.PI / 2)) + const soft = { + createCloth(x, y, radius, width, height, attachToPlayer = false, stayStill = false, options, touchPlayer = true, constrictionStrength = 0.001) { + const bodies = []; + const constraints = []; + const otherCons = []; + const bodyWidth = radius; + const bodyHeight = radius; + const numRows = Math.ceil(height / bodyHeight); + const numCols = Math.ceil(width / bodyWidth); + + for (let i = 0; i < numRows; i++) { + for (let j = 0; j < numCols; j++) { + const posX = x + j * bodyWidth + bodyWidth / 2; + const posY = y + i * bodyHeight + bodyHeight / 2; + + const rect = Matter.Bodies.circle(posX, posY, (bodyWidth + bodyHeight) / 4, options); + rect.collisionFilter.category = cat.body; + rect.collisionFilter.mask = (touchPlayer ? cat.player | cat.body | cat.bullet | cat.mob | cat.mobBullet : cat.body | cat.bullet | cat.mob | cat.mobBullet); + rect.classType = "body"; + + Composite.add(engine.world, rect); + + bodies.push(rect); + } + } + + for (let i = 0; i < numRows; i++) { + for (let j = 0; j < numCols; j++) { + const bodyIndexA = i * numCols + j; + if (j < numCols - 1) { + const bodyIndexB = i * numCols + (j + 1); + const constraint = Constraint.create({ + bodyA: bodies[bodyIndexA], + bodyB: bodies[bodyIndexB], + stiffness: 0.06, + damping: 0.001 + }); + Composite.add(engine.world, constraint); + constraints.push(constraint); + } + if (i < numRows - 1) { + const bodyIndexB = (i + 1) * numCols + j; + const constraint = Constraint.create({ + bodyA: bodies[bodyIndexA], + bodyB: bodies[bodyIndexB], + stiffness: 0.06, + damping: 0.001 + }); + Composite.add(engine.world, constraint); + constraints.push(constraint); + } + } + } + + for (let i = 0; i < numRows - 1; i++) { + for (let j = 0; j < numCols - 1; j++) { + const bodyA = bodies[i * numCols + j]; + const bodyB = bodies[(i + 1) * numCols + j + 1]; + const constraint = Constraint.create({ + bodyA: bodyA, + bodyB: bodyB, + stiffness: 0.02 + }); + constraints.push(constraint); + } + } + + for (let i = 0; i < numRows - 1; i++) { + for (let j = 1; j < numCols; j++) { + const bodyA = bodies[i * numCols + j]; + const bodyB = bodies[(i + 1) * numCols + j - 1]; + const constraint = Constraint.create({ + bodyA: bodyA, + bodyB: bodyB, + stiffness: 0.02 + }); + constraints.push(constraint); + } + } + if (stayStill) { + for (let i = 0; i < bodies.length; i++) { + const by = bodies[i]; + const spawnX = by.position.x + bodyWidth / 2; + const spawnY = by.position.y + bodyHeight / 2; + const isLastColumn = (i + 1) % numCols === 0; + const isFirstColumn = i % numCols === 0; + const stiffness = constrictionStrength * (isLastColumn || isFirstColumn ? 100 : 1); // Apply extra stiffness to first and last columns + + const cost = Constraint.create({ + bodyA: by, + pointB: { x: spawnX, y: spawnY }, + stiffness: stiffness, + length: 0 + }); + + Composite.add(engine.world, cost); + otherCons.push(cost); + } + } + if (attachToPlayer) { + for (let i = 0; i < bodies.length; i++) { + const cost = Constraint.create({ + bodyA: bodies[i], + pointB: player.position, + stiffness: 0.0005, + length: 0 + }); + Composite.add(engine.world, cost); + } + } + + return { bodies, constraints, otherCons }; + }, + clothOptions: { + frictionAir: 0.005, + }, + isOuterBoundary(body, bodies) { //unused + const neighbors = [ + { x: body.position.x + 1, y: body.position.y }, + { x: body.position.x - 1, y: body.position.y }, + { x: body.position.x, y: body.position.y + 1 }, + { x: body.position.x, y: body.position.y - 1 } + ]; + + for (let i = 0; i < neighbors.length; i++) { + const neighbor = neighbors[i]; + const isNeighbor = bodies.some(b => b.position.x === neighbor.x && b.position.y === neighbor.y); + if (!isNeighbor) { + return true; + } + } + return false; + }, + draw(cloth) { + ctx.beginPath(); + ctx.lineWidth = 2; + ctx.strokeStyle = "rgba(0,0,0,0.3)"; + ctx.fillStyle = "black"; + for (let i = 0, len = cloth.constraints.length; i < len; ++i) { + const constraint = cloth.constraints[i]; + ctx.moveTo(constraint.bodyA.position.x, constraint.bodyA.position.y); + ctx.lineTo(constraint.bodyB.position.x, constraint.bodyB.position.y); + } + ctx.closePath(); + ctx.fill(); + ctx.stroke(); + }, + addGravity(bodies, magnitude) { + for (var i = 0; i < bodies.length; i++) { + bodies[i].force.y += bodies[i].mass * magnitude; + } + }, + gravity(cloth) { + this.addGravity(cloth.bodies, simulation.g); + }, + breaker(cloth, percentage = 0.5) { + const totalConstraints = cloth.constraints.length; + const constraintsToRemove = Math.ceil(totalConstraints * percentage); + + for (let i = 0; i < constraintsToRemove; i++) { + const randomIndex = Math.floor(Math.random() * cloth.constraints.length); + + let removedConstraint = cloth.constraints.splice(randomIndex, 1)[0]; + Composite.remove(engine.world, removedConstraint); + } + }, + destroyer(cloth, percentage = 0.99999) { + const otherCons = cloth.otherCons.length; + const otherCons2Remove = Math.ceil(otherCons * percentage); + + for (let i = 0; i < otherCons2Remove; i++) { + const randomIndex = Math.floor(Math.random() * cloth.otherCons.length); + + let removedConstraint = cloth.otherCons.splice(randomIndex, 1)[0]; + Composite.remove(engine.world, removedConstraint); + } + }, + annihilate(cloth) { + const totalBodies = cloth.bodies.length; + for (let i = 0; i < totalBodies; i++) { + const removeBody = cloth.bodies[i]; + Composite.remove(engine.world, removeBody); + } + cloth.bodies.length = 0; // Clear the bodies array after removal + } + } + const clothArray = []; + clothArray.push(soft.createCloth(-100, 0, 50, 1000, 300, false, true, soft.clothOptions, true)) + clothArray.push(soft.createCloth(-2000, 2375, 50, 1525, 200, false, true, soft.clothOptions, true)) + clothArray.push(soft.createCloth(-3950, 125, 50, 1800, 125, false, true, soft.clothOptions, true)) + const annoyingStuff = { + lasers(where, angle) { + const vertexCollision = function (v1, v1End, domain) { + for (let i = 0; i < domain.length; ++i) { + let vertices = domain[i].vertices; + const len = vertices.length - 1; + for (let j = 0; j < len; j++) { + results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]); + if (results.onLine1 && results.onLine2) { + const dx = v1.x - results.x; + const dy = v1.y - results.y; + const dist2 = dx * dx + dy * dy; + if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) best = { + x: results.x, + y: results.y, + dist2: dist2, + who: domain[i], + v1: vertices[j], + v2: vertices[j + 1] + }; + } + } + results = simulation.checkLineIntersection(v1, v1End, vertices[0], vertices[len]); + if (results.onLine1 && results.onLine2) { + const dx = v1.x - results.x; + const dy = v1.y - results.y; + const dist2 = dx * dx + dy * dy; + if (dist2 < best.dist2) best = { + x: results.x, + y: results.y, + dist2: dist2, + who: domain[i], + v1: vertices[0], + v2: vertices[len] + }; + } + } + }; + + const seeRange = 7000; + best = { + x: null, + y: null, + dist2: Infinity, + who: null, + v1: null, + v2: null + }; + const look = { + x: where.x + seeRange * Math.cos(angle), + y: where.y + seeRange * Math.sin(angle) + }; + // vertexCollision(where, look, mob); + vertexCollision(where, look, map); + vertexCollision(where, look, body); + if (!m.isCloak) vertexCollision(where, look, [playerBody, playerHead]); + if (best.who && (best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) { + m.immuneCycle = m.cycle + m.collisionImmuneCycles + 60; //player is immune to damage for an extra second + const dmg = 0.5 / simulation.dmgScale; + m.damage(dmg); + simulation.drawList.push({ //add dmg to draw queue + x: best.x, + y: best.y, + radius: dmg * 1500, + color: "rgba(80,0,255,0.5)", + time: 20 + }); + } + //draw beam + if (best.dist2 === Infinity) best = look; + ctx.moveTo(where.x, where.y); + ctx.lineTo(best.x, best.y); + }, + laserBoss(x, y, radius = 30) { + mobs.spawn(x, y, 6, radius, "#f00"); + let me = mob[mob.length - 1]; + + setTimeout(() => { //fix mob in place, but allow rotation + me.constraint = Constraint.create({ + pointA: { + x: me.position.x, + y: me.position.y + }, + bodyB: me, + stiffness: 1, + damping: 1 + }); + Composite.add(engine.world, me.constraint); + }, 2000); //add in a delay in case the level gets flipped left right + me.count = 0; + me.frictionAir = 0.03; + // me.torque -= me.inertia * 0.002 + spawn.spawnOrbitals(me, radius + 50 + 200 * Math.random()) + Matter.Body.setDensity(me, 0.03); //extra dense //normal is 0.001 //makes effective life much larger + me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) + me.isBoss = true; + // spawn.shield(me, x, y, 1); //not working, not sure why + me.onDeath = function () { + powerUps.spawnBossPowerUp(this.position.x, this.position.y) + }; + me.rotateVelocity = -Math.min(0.0045, 0.0015 * simulation.accelScale * simulation.accelScale) * (level.levelsCleared > 8 ? 1 : -1) + me.do = function () { + this.fill = '#' + Math.random().toString(16).substr(-6); //flash colors + this.checkStatus(); + + if (!this.isStunned) { + //check if slowed + let slowed = false + for (let i = 0; i < this.status.length; i++) { + if (this.status[i].type === "slow") { + slowed = true + break + } + } + if (!slowed) { + this.count++ + Matter.Body.setAngle(this, this.count * this.rotateVelocity) + Matter.Body.setAngularVelocity(this, 0) + } + + ctx.beginPath(); + for (let i = 0; i < this.vertices.length; i++) { + if (Math.sin((2 * Math.PI * simulation.cycle) / (50 + i)) > 0) { + this.lasers(this.vertices[i], Math.atan2(this.vertices[i].y - this.position.y, this.vertices[i].x - this.position.x)); + } + } + ctx.strokeStyle = "#50f"; + ctx.lineWidth = 1.5; + ctx.setLineDash([70 + 300 * Math.random(), 55 * Math.random()]); + ctx.stroke(); // Draw it + ctx.setLineDash([]); + ctx.lineWidth = 20; + ctx.strokeStyle = "rgba(80,0,255,0.07)"; + ctx.stroke(); // Draw it + } + }; + me.lasers = function (where, angle) { + const vertexCollision = function (v1, v1End, domain) { + for (let i = 0; i < domain.length; ++i) { + let vertices = domain[i].vertices; + const len = vertices.length - 1; + for (let j = 0; j < len; j++) { + results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]); + if (results.onLine1 && results.onLine2) { + const dx = v1.x - results.x; + const dy = v1.y - results.y; + const dist2 = dx * dx + dy * dy; + if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) best = { + x: results.x, + y: results.y, + dist2: dist2, + who: domain[i], + v1: vertices[j], + v2: vertices[j + 1] + }; + } + } + results = simulation.checkLineIntersection(v1, v1End, vertices[0], vertices[len]); + if (results.onLine1 && results.onLine2) { + const dx = v1.x - results.x; + const dy = v1.y - results.y; + const dist2 = dx * dx + dy * dy; + if (dist2 < best.dist2) best = { + x: results.x, + y: results.y, + dist2: dist2, + who: domain[i], + v1: vertices[0], + v2: vertices[len] + }; + } + } + }; + + const seeRange = 7000; + best = { + x: null, + y: null, + dist2: Infinity, + who: null, + v1: null, + v2: null + }; + const look = { + x: where.x + seeRange * Math.cos(angle), + y: where.y + seeRange * Math.sin(angle) + }; + // vertexCollision(where, look, mob); + vertexCollision(where, look, map); + vertexCollision(where, look, body); + if (!m.isCloak) vertexCollision(where, look, [playerBody, playerHead]); + if (best.who && (best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) { + m.immuneCycle = m.cycle + m.collisionImmuneCycles + 60; //player is immune to damage for an extra second + const dmg = 0.5 / simulation.dmgScale; + m.damage(dmg); + simulation.drawList.push({ //add dmg to draw queue + x: best.x, + y: best.y, + radius: dmg * 1500, + color: "rgba(80,0,255,0.5)", + time: 20 + }); + } + //draw beam + if (best.dist2 === Infinity) best = look; + ctx.moveTo(where.x, where.y); + ctx.lineTo(best.x, best.y); + } + } + } + level.setPosToSpawn(-350, 0); + level.exit.x = 1075; + level.exit.y = 20; + spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20); //bump for level entrance + spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20); //bump for level exit + level.defaultZoom = 1800 + simulation.zoomTransition(level.defaultZoom) + document.body.style.backgroundColor = "#aaFFFF55"; + spawn.mapRect(900, 50, 425, 250); + // spawn.mapRect(900, -1050, 0.1, 1350); + spawn.mapRect(-475, 2375, 1800, 250); + spawn.mapRect(-4400, 2375, 2475, 250); + spawn.mapRect(-4400, -450, 250, 3075); + spawn.mapRect(-4400, -450, 2225, 250); + spawn.mapRect(-2425, -1300, 250, 1100); + spawn.mapRect(-2425, -1300, 3825, 250); + spawn.mapRect(1325, -1300, 250, 3925); + spawn.mapRect(-875, -1300, 250, 1375); + spawn.mapRect(-725, 50, 675, 250); + spawn.mapRect(-875, 175, 175, 125); + for (let i = 0; i < 6; i++) { + spawn.mapRect(-4175, 2000 - i * 375, 50, 125); + } + spawn.mapRect(-3925, 162.5, 50, 125); + spawn.mapRect(-2175, 162.5, 50, 125); + spawn.mapRect(300, 2025, 250, 600); + spawn.mapRect(-2150, 175, 50, 25); + spawn.mapRect(-2150, 250, 50, 25); + spawn.mapRect(-900, 175, 50, 25); + spawn.mapRect(-900, 250, 50, 25); + spawn.mapRect(-1600, 175, 50, 25); + spawn.mapRect(-1500, 175, 50, 25); + spawn.mapRect(-1600, 250, 50, 25); + spawn.mapRect(-1500, 250, 50, 25); + spawn.mapRect(-1925, 175, 50, 25); + spawn.mapRect(-1925, 250, 50, 25); + spawn.mapRect(-1200, 175, 50, 25); + spawn.mapRect(-1200, 250, 50, 25); + spawn.bodyRect(-2125, 200, 1250, 50); + spawn.debris(425, 200, 50); + spawn.debris(-650, 2100, 50); + spawn.debris(-3000, 1925, 50); + spawn.debris(-3825, 1550, 50); + spawn.debris(-2475, -50, 50); + + const bouncyBody = body[body.length - 1]; + bouncyBody.restitution = 0.9; + spawn.mapVertex(-2175 + 1300 / 2, -1050 + 1225 / 2, "0 -400 -100 -300 -100 0 100 0 100 -300"); + + spawn.mapVertex(-4150 + 1975 / 2, -200 + 2575 / 2, "0 -800 -200 -600 -200 0 0 200 200 0 200 -600 0 200"); + const mapWithVertex = map[map.length - 1]; + let index1 = 0; + level.custom = () => { + level.exit.drawAndCheck(); + + level.enter.draw(); + + if (player.position.x > 425 && index1 === 0) { + soft.breaker(clothArray[0], 0.7); + soft.destroyer(clothArray[0]); + index1++; + } + if (player.position.y > 1300 && index1 === 1) { + setTimeout(() => { + soft.breaker(clothArray[0], 1); + soft.annihilate(clothArray[0]); + clothArray.splice(0, 1); + }, 1000); //prevents bugs + simulation.makeTextLog("Couldn't be so simple, could it?", 2000 * Math.random()); + index1++; + } + }; + level.customTopLayer = () => { + for (let i = 0; i < portals.length; i++) { + portals[i][2].query(); + portals[i][3].query(); + portals[i][0].draw(); + portals[i][1].draw(); + portals[i][2].draw(); + portals[i][3].draw(); + } + ctx.beginPath(); + if (Math.sin((2 * Math.PI * simulation.cycle) / (50)) > 0) { + annoyingStuff.lasers(mapWithVertex.vertices[0], Math.atan2(mapWithVertex.vertices[0].y - mapWithVertex.position.y, mapWithVertex.vertices[0].x - mapWithVertex.position.x)); + annoyingStuff.lasers(mapWithVertex.vertices[3], Math.atan2(mapWithVertex.vertices[3].y - mapWithVertex.position.y, mapWithVertex.vertices[3].x - mapWithVertex.position.x)); + } + if (Math.sin((2 * Math.PI * simulation.cycle) / (51)) > 0) { + annoyingStuff.lasers(mapWithVertex.vertices[1], Math.atan2(mapWithVertex.vertices[1].y - mapWithVertex.position.y, mapWithVertex.vertices[1].x - mapWithVertex.position.x)); + annoyingStuff.lasers(mapWithVertex.vertices[4], Math.atan2(mapWithVertex.vertices[4].y - mapWithVertex.position.y, mapWithVertex.vertices[4].x - mapWithVertex.position.x)); + } + if (Math.sin((2 * Math.PI * simulation.cycle) / (52)) > 0) { + annoyingStuff.lasers(mapWithVertex.vertices[2], Math.atan2(mapWithVertex.vertices[2].y - mapWithVertex.position.y, mapWithVertex.vertices[2].x - mapWithVertex.position.x)); + annoyingStuff.lasers(mapWithVertex.vertices[5], Math.atan2(mapWithVertex.vertices[5].y - mapWithVertex.position.y, mapWithVertex.vertices[5].x - mapWithVertex.position.x)); + } + + ctx.strokeStyle = "#000"; + ctx.lineWidth = 1.5; + ctx.setLineDash([70 + 300 * Math.random(), 55 * Math.random()]); + ctx.stroke(); // Draw it + ctx.setLineDash([]); + ctx.lineWidth = 20; + ctx.strokeStyle = "rgba(0,0,0,0.07)"; + ctx.stroke(); // Draw it + + for (let i = 0; i < clothArray.length; i++) { + soft.draw(clothArray[i]); + soft.gravity(clothArray[i]); + } + + ctx.beginPath(); + ctx.fillStyle = "rgba(69, 69, 69, 0.1)"; + ctx.rect(-475, 175, 425, 2300); + ctx.rect(900, 175, 425, 2300); + ctx.rect(-875, 175, 400, 10000); + ctx.rect(-4200, -250, 2025, 2775); + ctx.fill(); + + ctx.beginPath(); + ctx.fillStyle = (m.pos.x < -725 && m.pos.y < 175) ? `rgba(68, 68, 68, ${Math.max(0.3, Math.min((-775 - m.pos.x) / 100, 0.99))})` : color.map; + ctx.rect(-875, 50, 175, 150); + ctx.fill(); + + }; + annoyingStuff.laserBoss(-1525, 1025); + spawn.pulsar(-1525, -850); + spawn.pulsar(1125, 1600); + spawn.pulsar(-250, 1600); + spawn.pulsar(-1450, 1600); + spawn.pulsar(-2950, 1750); + spawn.pulsar(-3375, 1750); + spawn.pulsar(-3825, 1300); + spawn.pulsar(-3825, 850); + spawn.pulsar(-3450, 50); + spawn.pulsar(-2925, 50); + spawn.pulsar(-1900, -400); + spawn.pulsar(-1200, -400); + + powerUps.addResearchToLevel() + powerUps.directSpawn(-775, 125, "tech"); + powerUp[powerUp.length - 1].collisionFilter.mask = cat.map | cat.body | cat.powerUp + spawn.bodyRect(-875, 75, 25, 100); + let hardBody = body[body.length - 1]; + hardBody.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.powerUp + }, // ******************************************************************************************************** // ******************************************************************************************************** // ***************************************** training levels ********************************************** diff --git a/js/mob.js b/js/mob.js index 349d687..d3cf211 100644 --- a/js/mob.js +++ b/js/mob.js @@ -1078,7 +1078,7 @@ const mobs = { }) } } else if (tech.isMobLowHealth && this.health < 0.25) { - dmg *= 3.22 + dmg *= 3 simulation.ephemera.push({ name: "damage outline", diff --git a/js/player.js b/js/player.js index e65d5af..2897a0d 100644 --- a/js/player.js +++ b/js/player.js @@ -556,24 +556,23 @@ const m = { dmg *= m.fieldHarmReduction // if (!tech.isFlipFlopOn && tech.isFlipFlopHealth) dmg *= 0.5 // 1.25 + Math.sin(m.cycle * 0.01) - if (tech.isDiaphragm) dmg *= 0.56 + 0.36 * Math.sin(m.cycle * 0.0075); + if (tech.isDiaphragm) dmg *= 0.55 + 0.35 * Math.sin(m.cycle * 0.0075); if (tech.isZeno) dmg *= 0.15 - if (tech.isFieldHarmReduction) dmg *= 0.65 + if (tech.isFieldHarmReduction) dmg *= 0.6 if (tech.isHarmMACHO) dmg *= 0.4 if (tech.isImmortal) dmg *= 0.7 - if (tech.energyRegen === 0) dmg *= 0.34 if (m.fieldMode === 0 || m.fieldMode === 3) dmg *= 0.973 ** m.coupling if (tech.isLowHealthDefense) dmg *= 1 - Math.max(0, 1 - m.health) * 0.8 - if (tech.isHarmReduceNoKill && m.lastKillCycle + 300 < m.cycle) dmg *= 0.26 - if (tech.squirrelFx !== 1) dmg *= 0.78//Math.pow(0.78, (tech.squirrelFx - 1) / 0.4) + if (tech.isHarmReduceNoKill && m.lastKillCycle + 300 < m.cycle) dmg *= 0.3 + if (tech.squirrelFx !== 1) dmg *= 0.8//Math.pow(0.78, (tech.squirrelFx - 1) / 0.4) if (tech.isAddBlockMass && m.isHolding) dmg *= 0.1 if (tech.isSpeedHarm && player.speed > 0.1) dmg *= 1 - Math.min(player.speed * 0.0193, 0.88) //capped at speed of 55 - if (tech.isHarmReduce && input.field) dmg *= 0.12 + if (tech.isHarmReduce && input.field) dmg *= 0.1 if (tech.isNeutronium && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.05 - if (tech.isBotArmor) dmg *= 0.94 ** b.totalBots() - if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.33; - if (tech.isNoFireDefense && m.cycle > m.fireCDcycle + 120) dmg *= 0.27 - if (tech.isTurret && m.crouch) dmg *= 0.34; + if (tech.isBotArmor) dmg *= 0.95 ** b.totalBots() + if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.3; + if (tech.isNoFireDefense && m.cycle > m.fireCDcycle + 120) dmg *= 0.3 + if (tech.isTurret && m.crouch) dmg *= 0.3; if (tech.isFirstDer && b.inventory[0] === b.activeGun) dmg *= 0.85 ** b.inventory.length return tech.isEnergyHealth ? Math.pow(dmg, 0.5) : dmg //defense has less effect }, @@ -2232,7 +2231,7 @@ const m = { } else { m.fieldRegen = 0.001 //6 energy per second } - if (m.fieldMode === 0 || m.fieldMode === 4) m.fieldRegen += 0.000133 * m.coupling //return `generate ${(6*couple).toFixed(0)} energy per second` + if (m.fieldMode === 0 || m.fieldMode === 4) m.fieldRegen += 0.000133 * m.coupling if (tech.isTimeCrystals) { m.fieldRegen *= 2.5 } else if (tech.isGroundState) { @@ -2861,17 +2860,17 @@ const m = { return `deflecting condenses ${(0.1 * couple).toFixed(2)} ice IX` // return `invulnerable +${2*couple} seconds post collision` case 3: //negative mass - return `+${(100 * (1 - 0.973 ** couple)).toFixed(1)}% defense` + return `${(100 * (1 - 0.973 ** couple)).toFixed(1)}% damage taken` case 4: //assembler - return `generate ${(0.8 * couple).toFixed(1)} energy per second` + return `+${(0.8 * couple).toFixed(1)} energy per second` case 5: //plasma - return `+${(1.5 * couple).toFixed(1)}% damage` + return `${(1 + 1.5 * couple).toFixed(3)}x damage` case 6: //time dilation return `+${(5 * couple).toFixed(0)}% longer stopped time` //movement, jumping, and case 7: //cloaking - return `+${(3.3 * couple).toFixed(1)}% ambush damage` + return `${(1 + 3.3 * couple).toFixed(3)}x ambush damage` case 8: //pilot wave - return `+${(4 * couple).toFixed(0)}% block collision damage` + return `+${(1 + 4 * couple).toFixed(2)}% block collision damage` case 9: //wormhole return `after eating blocks +${(2 * couple).toFixed(0)} energy` case 10: //grappling hook @@ -2923,7 +2922,7 @@ const m = { name: "field emitter", imageNumber: Math.floor(Math.random() * 26), //pick one of the 25 field emitter image files at random description: `initial field
use energy to deflect mobs and throw blocks -
generate 4 energy per second`, //
100 max energy +
4 energy per second`, //
100 max energy effect: () => { m.hold = function () { if (m.isHolding) { @@ -2952,7 +2951,7 @@ const m = { //deflecting protects you in every direction description: `3 oscillating shields are permanently active
+150 max energy -
generate 6 energy per second`, +
6 energy per second`, drainCD: 0, effect: () => { m.fieldBlockCD = 0; @@ -3054,10 +3053,7 @@ const m = { }, { name: "perfect diamagnetism", - description: "deflecting does not drain energy
maintains functionality while inactive
generate 5 energy per second", - //
attract power ups from far away - // description: "attract power ups from far away
deflecting doesn't drain energy
thrown blocks have", - // description: "gain energy when blocking
no recoil when blocking", + description: "deflecting does not drain energy
maintains functionality while inactive
5 energy per second", effect: () => { m.fieldMeterColor = "#48f" //"#0c5" m.eyeFillColor = m.fieldMeterColor @@ -3292,14 +3288,14 @@ const m = { { name: "negative mass", //
hold blocks as if they have a lower mass - description: "use energy to nullify  gravity
+55% defense
generate 6 energy per second", + description: "use energy to nullify  gravity
0.4x damage taken
6 energy per second", fieldDrawRadius: 0, effect: () => { m.fieldFire = true; m.holdingMassScale = 0.01; //can hold heavier blocks with lower cost to jumping m.fieldMeterColor = "#333" m.eyeFillColor = m.fieldMeterColor - m.fieldHarmReduction = 0.45; //55% reduction + m.fieldHarmReduction = 0.4; //55% reduction m.fieldDrawRadius = 0; m.hold = function () { @@ -3480,10 +3476,9 @@ const m = { }, { name: "molecular assembler", - description: `excess energy used to print ${simulation.molecularMode === 0 ? "spores" : simulation.molecularMode === 1 ? "missiles" : simulation.molecularMode === 2 ? "ice IX" : "drones"}
use energy to deflect mobs
generate 12 energy per second`, - // simulation.molecularMode: Math.floor(4 * Math.random()), //0 spores, 1 missile, 2 ice IX, 3 drones + description: `excess energy used to print ${simulation.molecularMode === 0 ? "spores" : simulation.molecularMode === 1 ? "missiles" : simulation.molecularMode === 2 ? "ice IX" : "drones"}
use energy to deflect mobs
12 energy per second`, setDescription() { - return `excess energy used to print ${simulation.molecularMode === 0 ? "spores" : simulation.molecularMode === 1 ? "missiles" : simulation.molecularMode === 2 ? "ice IX" : "drones"}
use energy to deflect mobs
generate 12 energy per second` + return `excess energy used to print ${simulation.molecularMode === 0 ? "spores" : simulation.molecularMode === 1 ? "missiles" : simulation.molecularMode === 2 ? "ice IX" : "drones"}
use energy to deflect mobs
12 energy per second` }, effect: () => { m.fieldMeterColor = "#ff0" @@ -3600,7 +3595,7 @@ const m = { }, { name: "plasma torch", - description: "use energy to emit short range plasma
damages and pushes mobs away
generate 10 energy per second", + description: "use energy to emit short range plasma
damages and pushes mobs away
10 energy per second", set() { b.isExtruderOn = false // m.fieldCDcycleAlternate = 0 @@ -4056,7 +4051,7 @@ const m = { }, { name: "time dilation", - description: "use energy to stop time
+20% movement and fire rate
generate 12 energy per second", + description: "use energy to stop time
1.2x movement and fire rate
12 energy per second", set() { // m.fieldMeterColor = "#0fc" // m.fieldMeterColor = "#ff0" @@ -4246,7 +4241,7 @@ const m = { }, effect() { if (tech.isTimeStop) { - m.fieldHarmReduction = 0.66; //33% reduction + m.fieldHarmReduction = 0.6; } else { m.fieldHarmReduction = 1; } @@ -4255,7 +4250,7 @@ const m = { }, { name: "metamaterial cloaking", - description: "+66% defense while cloaked
after decloaking +333% damage for 2 s
generate 6 energy per second", + description: "0.3x damage taken while cloaked
after decloaking 4.5x damage for 2 s
6 energy per second", effect: () => { m.fieldFire = true; m.fieldMeterColor = "#333"; @@ -4306,7 +4301,7 @@ const m = { if (!m.isCloak) { //&& m.energy > drain + 0.03 // m.energy -= drain m.isCloak = true //enter cloak - m.fieldHarmReduction = 0.33; //66% reduction + m.fieldHarmReduction = 0.3; m.enterCloakCycle = m.cycle if (tech.isCloakHealLastHit && m.lastHit > 0) { const heal = Math.min(0.75 * m.lastHit, m.energy) @@ -4417,7 +4412,7 @@ const m = { //
blocks can't collide with intangible mobs //field radius decreases out of line of sight //unlock tech from other fields - description: "use energy to guide blocks
tech, fields, and guns have +2 choices
generate 10 energy per second", + description: "use energy to guide blocks
tech, fields, and guns have +2 choices
10 energy per second", effect: () => { m.fieldMeterColor = "#333" m.eyeFillColor = m.fieldMeterColor @@ -4646,7 +4641,7 @@ const m = { { name: "wormhole", //wormholes attract blocks and power ups
- description: "use energy to tunnel through a wormhole
+7% chance to duplicate spawned power ups
generate 6 energy per second", //
bullets may also traverse wormholes + description: "use energy to tunnel through a wormhole
+7% chance to duplicate spawned power ups
6 energy per second", //
bullets may also traverse wormholes drain: 0, effect: function () { m.fieldMeterColor = "#bbf" //"#0c5" @@ -5194,15 +5189,13 @@ const m = { }, { name: "grappling hook", - // description: `use energy to pull yourself towards the map
generate 6 energy per second`, - description: `use energy to fire a hook that pulls player
damages mobs and grabs blocks
generate 9 energy per second`, + description: `use energy to fire a hook that pulls player
damages mobs and grabs blocks
9 energy per second`, effect: () => { m.fieldFire = true; // m.holdingMassScale = 0.01; //can hold heavier blocks with lower cost to jumping // m.fieldMeterColor = "#789"//"#456" m.eyeFillColor = m.fieldMeterColor m.grabPowerUpRange2 = 300000 //m.grabPowerUpRange2 = 200000; - // m.fieldHarmReduction = 0.45; //55% reduction m.hold = function () { if (m.isHolding) { diff --git a/js/powerup.js b/js/powerup.js index d70b30a..09dfc48 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -505,10 +505,14 @@ const powerUps = { currentRerollCount: 0, use(type) { //runs when you actually research a list of selections, type can be field, gun, or tech if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) { - tech.addJunkTechToPool(tech.junkResearchNumber * 0.01) + tech.addJunkTechToPool(0.01) } else { powerUps.research.changeRerolls(-1) } + if (tech.isResearchDamage) { + tech.damage *= 1.04 + simulation.makeTextLog(`1.04x damage from peer review`); + } powerUps.research.currentRerollCount++ // if (tech.isBanish && type === 'tech') { // banish researched tech // const banishLength = tech.isDeterminism ? 1 : 3 + tech.extraChoices * 2 @@ -699,11 +703,8 @@ const powerUps = { text += `
entanglement
` } else if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) { text += `
` // style = "margin-left: 192px; margin-right: -192px;" - tech.junkResearchNumber = Math.ceil(3 * Math.random()) text += `
` - for (let i = 0; i < tech.junkResearchNumber; i++) { - text += `
` - } + text += `
` text += `
  pseudoscience
` } else if (powerUps.research.count > 0) { text += `
` // style = "margin-left: 192px; margin-right: -192px;" @@ -721,11 +722,8 @@ const powerUps = { text += `entanglement` //‌ } else if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) { text += `` // style = "margin-left: 192px; margin-right: -192px;" - tech.junkResearchNumber = Math.ceil(3 * Math.random()) text += `
` - for (let i = 0, len = tech.junkResearchNumber; i < len; i++) { - text += `
` - } + text += `
` text += `
  ${tech.isResearchReality ? "alternate reality" : "research"}
` } else if (powerUps.research.count > 0) { text += `` // style = "margin-left: 192px; margin-right: -192px;" @@ -787,24 +785,6 @@ const powerUps = { } return text }, - // researchAndCancelText(type) { - // let text = "
" - // if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) { - // text += `
` // style = "margin-left: 192px; margin-right: -192px;" - // tech.junkResearchNumber = Math.ceil(4 * Math.random()) - // text += `
` - // for (let i = 0; i < tech.junkResearchNumber; i++) text += `
` - // text += `
  pseudoscience
` - // } else if (powerUps.research.count > 0) { - // text += `
` // style = "margin-left: 192px; margin-right: -192px;" - // text += `
` - // for (let i = 0, len = Math.min(powerUps.research.count, 30); i < len; i++) text += `
` - // text += `
  ${tech.isResearchReality?"alternate reality": "research"}
` - // } else { - // text += `
` - // } - // return text + '
' - // }, hideStyle: `style="height:auto; border: none; background-color: transparent;"`, gunText(choose, click) { const style = localSettings.isHideImages ? powerUps.hideStyle : `style="background-image: url('img/gun/${b.guns[choose].name}.webp');"` diff --git a/js/spawn.js b/js/spawn.js index 691729b..7f12bf2 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -974,7 +974,7 @@ const spawn = { if (!simulation.paused && !simulation.onTitlePage) { count++ if (count < 660) { - if (count === 1) simulation.makeTextLog(`//enter testing mode to set level.levels.length to Infinite`); + if (count === 1 && simulation.difficultyMode < 5) simulation.makeTextLog(`//enter testing mode to set level.levels.length to Infinite`); if (!(count % 60)) simulation.makeTextLog(`simulation.analysis = ${((count / 60 - Math.random()) * 0.1).toFixed(3)}`); } else if (count === 660) { simulation.makeTextLog(`simulation.analysis = 1 //analysis complete`); @@ -1011,7 +1011,7 @@ const spawn = { return } } - if (simulation.testing) { + if (simulation.testing || simulation.difficultyMode > 4) { unlockExit() setTimeout(function () { simulation.makeTextLog(`level.levels.length = Infinite`); diff --git a/js/tech.js b/js/tech.js index acd5cda..6d68916 100644 --- a/js/tech.js +++ b/js/tech.js @@ -233,34 +233,34 @@ const tech = { // } // } if (tech.isPowerUpDamage) dmg *= 1 + 0.05 * powerUp.length - if (tech.isDamageCooldown) dmg *= m.lastKillCycle + tech.isDamageCooldownTime > m.cycle ? 0.45 : 4.33 - if (tech.isDamageAfterKillNoRegen && m.lastKillCycle + 300 > m.cycle) dmg *= 1.93 - if (tech.isDivisor && b.activeGun !== undefined && b.activeGun !== null && b.guns[b.activeGun].ammo % 3 === 0) dmg *= 1.77 + if (tech.isDamageCooldown) dmg *= m.lastKillCycle + tech.isDamageCooldownTime > m.cycle ? 0.5 : 4 + if (tech.isDamageAfterKillNoRegen && m.lastKillCycle + 300 > m.cycle) dmg *= 2 + if (tech.isDivisor && b.activeGun !== undefined && b.activeGun !== null && b.guns[b.activeGun].ammo % 3 === 0) dmg *= 1.8 if (tech.isNoGroundDamage) dmg *= m.onGround ? 0.85 : 2 - if (tech.isDilate) dmg *= 1.5 + 0.6 * Math.sin(m.cycle * 0.0075) - if (tech.isGunChoice && tech.buffedGun === b.inventoryGun) dmg *= 1 + 0.31 * b.inventory.length + if (tech.isDilate) dmg *= 1.5 + 0.5 * Math.sin(m.cycle * 0.0075) + if (tech.isGunChoice && tech.buffedGun === b.inventoryGun) dmg *= 1 + 0.3 * b.inventory.length if (powerUps.boost.endCycle > m.cycle) dmg *= 1 + powerUps.boost.damage if (m.coupling && (m.fieldMode === 0 || m.fieldMode === 5)) dmg *= 1 + 0.015 * m.coupling - if (m.isSneakAttack && m.sneakAttackCycle + Math.min(100, 0.66 * (m.cycle - m.enterCloakCycle)) > m.cycle) dmg *= 4.33 * (1 + 0.033 * m.coupling) + if (m.isSneakAttack && m.sneakAttackCycle + Math.min(100, 0.66 * (m.cycle - m.enterCloakCycle)) > m.cycle) dmg *= 4.5 * (1 + 0.033 * m.coupling) if (tech.deathSkipTime) dmg *= 1 + 0.6 * tech.deathSkipTime - if (tech.isTechDebt) dmg *= tech.totalCount > 20 ? Math.pow(0.85, tech.totalCount - 20) : 4 - 0.15 * tech.totalCount // if (tech.isTechDebt) dmg *= Math.min(Math.pow(0.85, tech.totalCount - 20), 4 - 0.15 * tech.totalCount) + if (tech.isTechDebt) dmg *= tech.totalCount > 20 ? Math.pow(0.85, tech.totalCount - 20) : 4 - 0.15 * tech.totalCount if (tech.isFlipFlopDamage && tech.isFlipFlopOn) dmg *= 1.555 - if (tech.isAnthropicDamage && tech.isDeathAvoidedThisLevel) dmg *= 2.3703599 + if (tech.isAnthropicDamage && tech.isDeathAvoidedThisLevel) dmg *= 2.71828 if (tech.isDupDamage) dmg *= 1 + Math.min(1, tech.duplicationChance()) if (tech.isDamageForGuns) dmg *= 1 + 0.22 * Math.max(0, b.inventory.length - 1) - if (tech.isOneGun && b.inventory.length < 2) dmg *= 1.25 + 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.isBotDamage) dmg *= 1 + 0.06 * b.totalBots() + if (tech.isBotDamage) dmg *= 1 + 0.05 * b.totalBots() if (tech.restDamage > 1 && player.speed < 1) dmg *= tech.restDamage - if (tech.isLowEnergyDamage) dmg *= 1 + 0.7 * Math.max(0, 1 - m.energy) + if (tech.isLowEnergyDamage) dmg *= 1 + Math.max(0, 1 - m.energy) if (tech.energyDamage) dmg *= 1 + m.energy * 0.23 * tech.energyDamage; - if (tech.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.007 - if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 2.11 + if (tech.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.01 + if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 2 if (tech.isSpeedDamage) dmg *= 1 + Math.min(0.88, player.speed * 0.0193) - if (tech.isAxion && tech.isHarmMACHO) dmg *= 2 - m.defense() + if (tech.isAxion && tech.isHarmMACHO) dmg *= 2 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.lastHitDamage && m.lastHit) dmg *= 1 + tech.lastHitDamage * m.lastHit if (tech.isLowHealthDmg) dmg *= 1 + 0.7 * Math.max(0, 1 - (tech.isEnergyHealth ? m.energy : m.health)) if (tech.isJunkDNA) dmg *= 1 + 2 * tech.junkChance return dmg @@ -343,7 +343,7 @@ const tech = { }, { name: "nitinol", - description: "+33% movement and jumping
+22% defense", + description: "1.3x movement and jumping
0.8x damage taken", maxCount: 1, count: 0, frequency: 1, @@ -370,7 +370,7 @@ const tech = { }, { name: "Higgs mechanism", - description: "+77% fire rate
while firing your position is fixed", + description: "1.8x fire rate
while firing your position is fixed", maxCount: 1, count: 0, frequency: 1, @@ -397,7 +397,7 @@ const tech = { }, { name: "Hilbert space", - description: "+300% damage
after a collision enter an alternate reality", + description: "4x damage
after a collision enter an alternate reality", maxCount: 1, count: 0, frequency: 1, @@ -408,7 +408,7 @@ const tech = { return !m.isAltSkin && !tech.isResearchReality && !tech.isSwitchReality }, requires: "not skinned, Ψ(t) collapse, many-worlds", - damage: 4, //1+300% + damage: 4, effect() { m.skin.anodize(); tech.damage *= this.damage @@ -421,7 +421,7 @@ const tech = { }, { name: "aperture", - description: "every 6 seconds your damage cycles
between -10% and +110% damage", + description: "every 6 seconds your damage cycles
between 1x and 2x damage", maxCount: 1, count: 0, frequency: 1, @@ -442,7 +442,7 @@ const tech = { }, { name: "diaphragm", - description: "every 6 seconds your defense cycles
between +8% and +80% defense", + description: "every 6 seconds your damage taken cycles
between 0.9x and 0.2x damage taken", maxCount: 1, count: 0, frequency: 2, @@ -464,8 +464,7 @@ const tech = { }, { name: "mass-energy equivalence", - // description: "energy protects you instead of health
√ of defense reduction reduces max energy", - description: `energy protects you instead of health
defensive upgrades reduced by about 50%`, + description: `energy protects you instead of health
damage taken effects 50% less effective`, maxCount: 1, count: 0, frequency: 1, @@ -536,10 +535,7 @@ const tech = { { name: "depolarization", descriptionFunction() { - // return `+300% damage or -50% damage
if a mob has died in the last 5 seconds` - // return `+333% damage if no mobs died in the last ${(tech.isDamageCooldownTime / 60).toFixed(1)} seconds
-55% damage if a mob died in the last ${(tech.isDamageCooldownTime / 60).toFixed(0)} seconds
` - // return `-55% damage if a mob died in the last ${(tech.isDamageCooldownTime / 60).toFixed(1)} seconds
otherwise do +333% damage
` - return `-55% damage for ${(tech.isDamageCooldownTime / 60).toFixed(1)} seconds after a mob dies
+333% damage otherwise
` + return `0.5x damage for ${(tech.isDamageCooldownTime / 60).toFixed(1)} seconds after a mob dies
4x damage otherwise
` }, maxCount: 1, count: 0, @@ -581,8 +577,6 @@ const tech = { }, { name: "CPT symmetry", - // description: "charge, parity, and time invert to undo defense
rewind (1.5—5) seconds for (66—220) energy", - // description: "after losing health, if you have full energy
rewind time for 44 energy per second", descriptionFunction() { return `after losing health, if you have above ${(85 * Math.min(100, m.maxEnergy)).toFixed(0)} energy
rewind time for 20 energy per second` }, @@ -646,7 +640,7 @@ const tech = { { name: "ternary", //"divisor", descriptionFunction() { - return `+77% damage while your current gun
has ammo divisible by 3` + return `1.8x damage while your current gun
has ammo divisible by 3` }, maxCount: 1, count: 0, @@ -664,7 +658,7 @@ const tech = { }, { name: "ordnance", - description: "double the frequency of finding guntech
spawn a gun and +6% JUNK to tech pool", + description: "double the frequency of finding guntech
spawn a gun and +6% JUNKtech chance", maxCount: 1, count: 0, frequency: 1, @@ -806,7 +800,7 @@ const tech = { { name: "arsenal", descriptionFunction() { - return `+22% damage per unequipped gun (${(22 * Math.max(0, b.inventory.length - 1)).toFixed(0)}%)` + return `1.22x damage per unequipped gun (${(22 * Math.max(0, b.inventory.length - 1)).toFixed(0)}%)` }, maxCount: 1, count: 0, @@ -824,7 +818,7 @@ const tech = { { name: "active cooling", descriptionFunction() { - return `+28% fire rate per unequipped gun (${(28 * Math.max(0, b.inventory.length - 1)).toFixed(0)}%)` + return `1.3x fire rate per unequipped gun` }, //
but not including your equipped gun` }, maxCount: 1, count: 0, @@ -847,11 +841,9 @@ const tech = { let info = "" if (this.count > 0 && Number.isInteger(tech.buffedGun) && b.inventory.length) { let gun = b.guns[b.inventory[tech.buffedGun]].name - info = `
this level: +${(31 * Math.max(0, b.inventory.length)).toFixed(0)}% damage for ${gun}` + info = `
this level: ${(1.3 * Math.max(0, b.inventory.length)).toFixed(2)}x damage for ${gun}` } - return ` - a new gun is chosen to be improved each level -
+31% damage per gun for the chosen gun${info}` + return `a new gun is chosen to be improved each level
1.3x damage per gun for the chosen gun${info}` }, maxCount: 1, count: 0, @@ -900,7 +892,7 @@ const tech = { }, { name: "logistics", - description: `${powerUps.orb.ammo()} give 80% more ammo, but
it's only added to your current gun`, + description: `${powerUps.orb.ammo()} give 1.8x ammo, but
it's only added to your current gun`, maxCount: 1, count: 0, frequency: 1, @@ -919,7 +911,7 @@ const tech = { { name: "cache", link: `cache`, - description: `${powerUps.orb.ammo()} give 1500% more ammo, but
you can't store any more ammo than that`, + description: `${powerUps.orb.ammo()} give 15x ammo, but
you can't store any more ammo than that`, // ammo powerups always max out your gun, // but the maximum ammo ti limited // description: `${powerUps.orb.ammo()} give 13x more ammo, but
you can't store any more ammo than that`, @@ -961,7 +953,7 @@ const tech = { }, { name: "non-renewables", - description: `+97% damage
${powerUps.orb.ammo()} can't spawn`, + description: `2x damage
${powerUps.orb.ammo()} can't spawn`, maxCount: 1, count: 0, frequency: 1, @@ -970,7 +962,7 @@ const tech = { return !tech.isAmmoFromHealth && !tech.isBoostReplaceAmmo }, requires: "not catabolism, quasiparticles", - damage: 1.97, + damage: 2, effect() { tech.damage *= this.damage tech.isEnergyNoAmmo = true; @@ -998,7 +990,7 @@ const tech = { }, { name: "gun turret", - description: "if crouching
+66% defense ", + description: "if crouching
0.3x damage taken", maxCount: 1, count: 0, frequency: 1, @@ -1016,7 +1008,7 @@ const tech = { }, { name: "dead reckoning", - description: "if your speed is 0
+50% damage", + description: "if your speed is 0
1.5x damage", maxCount: 9, count: 0, frequency: 1, @@ -1034,7 +1026,7 @@ const tech = { }, { name: "kinetic bombardment", - description: "far away mobs take more damage
up to +33% damage at 3000 displacement", + description: "far away mobs take more damage
up to 1.3x damage at 3000 displacement", maxCount: 1, count: 0, frequency: 1, @@ -1053,7 +1045,7 @@ const tech = { { name: "integrated armament", link: `integrated armament`, - description: `+25% damage, but new guns replace
your current gun and convert guntech
`, + description: `1.3x damage, but new guns replace
your current gun and convert guntech
`, maxCount: 1, count: 0, frequency: 1, @@ -1075,8 +1067,8 @@ const tech = { 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 + if (this.count) currentDamage = `
(${(damageTotal).toFixed(2)}x)` + return `randomly gain between 1x and 1.3x damage` + currentDamage }, maxCount: 9, count: 0, @@ -1087,7 +1079,7 @@ const tech = { 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 + const damage = (Math.floor((Math.random() * 0.3 + 1) * 100)) / 100 tech.damage *= damage this.damageSoFar.push(damage) }, @@ -1126,7 +1118,7 @@ const tech = { // }, { name: "Newtons 1st law", - description: "defense is proportional to your speed
up to +88% defense at 55 speed", + description: "damage taken is proportional to your speed
up to 0.2x damage taken at 55 speed", maxCount: 1, count: 0, frequency: 1, @@ -1144,7 +1136,7 @@ const tech = { }, { name: "Newtons 2nd law", - description: "damage is proportional to your speed
up to +88% damage at 55 speed", + description: "damage is proportional to your speed
up to 2x damage at 55 speed", maxCount: 1, count: 0, frequency: 1, @@ -1163,25 +1155,33 @@ const tech = { { name: "microstates", link: `microstates`, - description: "for each active bullet or bot
+0.7% damage", + descriptionFunction() { + return `use ${powerUps.orb.research(3)}
1.01x damage per bullet or bot` + }, maxCount: 1, count: 0, frequency: 1, frequencyDefault: 1, allowed() { - return true + return powerUps.research.count > 2 || build.isExperimentSelection }, requires: "", effect() { tech.isDamageFromBulletCount = true + for (let i = 0; i < 3; i++) { + if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) + } }, remove() { tech.isDamageFromBulletCount = false + if (this.count > 0) { + powerUps.research.changeRerolls(3) + } } }, { name: "regression", - description: "bullet collisions increase vulnerability to
damage by +5% for mobs (+0.25% for bosses)", + description: "bullet collisions increase vulnerability to
damage by 1.05x for mobs (+1.025x for bosses)", maxCount: 1, count: 0, frequency: 1, @@ -1199,7 +1199,7 @@ const tech = { }, { name: "simulated annealing", - description: "+20% damage
–20% fire rate", + description: "1.2x damage
0.8x fire rate", maxCount: 1, count: 0, frequency: 1, @@ -1221,7 +1221,7 @@ const tech = { }, { name: "dynamical systems", - description: `use ${powerUps.orb.research(2)}
+30% damage`, + description: `use ${powerUps.orb.research(2)}
1.3x damage`, // isFieldTech: true, maxCount: 1, count: 0, @@ -1253,7 +1253,7 @@ const tech = { }, { name: "heuristics", - description: "+22% fire rate
spawn a gun", + description: "1.2x fire rate
spawn a gun", maxCount: 9, count: 0, frequency: 1, @@ -1263,7 +1263,7 @@ const tech = { }, requires: "", effect() { - tech.fireRate *= 0.78 + tech.fireRate *= 0.8 b.setFireCD(); powerUps.spawn(m.pos.x, m.pos.y, "gun"); }, @@ -1275,7 +1275,7 @@ const tech = { { name: "anti-shear topology", link: `anti-shear topology`, - description: "your bullets last +30% longer", //
drone spore worm flea missile foam wave neutron ice", + description: "your bullets last 1.3x longer", //
drone spore worm flea missile foam wave neutron ice", maxCount: 3, count: 0, frequency: 1, @@ -1291,7 +1291,7 @@ const tech = { }, { name: "fracture analysis", - description: "if a mob is stunned it takes
+400% damage from bullet impacts", + description: "if a mob is stunned it takes
5x damage from bullet impacts", maxCount: 1, count: 0, frequency: 2, @@ -1347,7 +1347,7 @@ const tech = { name: "zoospore vector", link: `zoospore vector`, descriptionFunction() { - return `after mobs die there is a +10% chance
they grow ${b.guns[6].nameString('s')}` + return `after mobs die there is a 10% chance
they grow ${b.guns[6].nameString('s')}` }, // description: "after mobs die
they have a +10% chance to grow spores", maxCount: 9, @@ -1372,7 +1372,7 @@ const tech = { }, { name: "propagator", - description: "after mobs die advance time 0.5 seconds
+60% damage", + description: "after mobs die advance time 0.5 seconds
1.6x damage", maxCount: 3, count: 0, frequency: 1, @@ -1389,7 +1389,7 @@ const tech = { { name: "collider", descriptionFunction() { - return `after mobs die power ups
randomly collide to form different power ups` + return `after mobs die random power ups
collide to form different 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` }, @@ -1430,7 +1430,7 @@ const tech = { { name: "enthalpy", descriptionFunction() { - return `after mobs die
they have a +8% chance to spawn ${powerUps.orb.heal(1)}` + return `after mobs die
they have an 8% chance to spawn ${powerUps.orb.heal(1)}` }, maxCount: 9, count: 0, @@ -1448,27 +1448,9 @@ const tech = { tech.healSpawn = 0; } }, - // { - // name: "yield stress", - // description: "+55% damage
to mobs at maximum health", - // maxCount: 1, - // count: 0, - // frequency: 1, - // frequencyDefault: 1, - // allowed() { - // return m.fieldMode !== 7 && tech.mobSpawnWithHealth === 0 - // }, - // requires: "not cloaking, reaction inhibitor", - // effect() { - // tech.isMobFullHealth = true - // }, - // remove() { - // tech.isMobFullHealth = false - // } - // }, { name: "cascading failure", - description: "+222% damage
to mobs below 25% health", + description: "3x damage to mobs below 25% durability", maxCount: 1, count: 0, frequency: 3, @@ -1486,7 +1468,7 @@ const tech = { }, { name: "reaction inhibitor", - description: "mobs spawn with -12% initial health", + description: "mobs spawn with 0.88x initial durability", maxCount: 3, count: 0, frequency: 1, @@ -1498,7 +1480,6 @@ const tech = { effect() { tech.mobSpawnWithHealth++ mobs.setMobSpawnHealth() - //set all mobs at full health to 0.85 for (let i = 0; i < mob.length; i++) { if (mob.health > mobs.mobSpawnWithHealth) mob.health = mobs.mobSpawnWithHealth } @@ -1511,7 +1492,7 @@ const tech = { { name: "scrap bots", link: `scrap bots`, - description: "after mobs die you have a +33% chance
to build scrap bots that operate for 15 seconds", + description: "after mobs die you have a 33% chance
to build scrap bots that operate for 15 seconds", maxCount: 3, count: 0, frequency: 1, @@ -1577,7 +1558,7 @@ const tech = { { name: "nail-bot upgrade", link: `nail-bot upgrade`, - description: "convert your bots to nail-bots
+500% fire rate and +40% nail velocity", + description: "convert your bots to nail-bots
5x fire rate and 1.4x nail velocity", maxCount: 1, count: 0, frequency: 3, @@ -1635,7 +1616,7 @@ const tech = { { name: "foam-bot upgrade", link: `foam-bot upgrade`, - description: "convert your bots to foam-bots
+300% foam size and fire rate", + description: "convert your bots to foam-bots
3x foam size and fire rate", maxCount: 1, count: 0, frequency: 3, @@ -1691,7 +1672,7 @@ const tech = { { name: "sound-bot upgrade", link: `sound-bot upgrade`, - description: "convert your bots to sound-bots
+150% wave fire rate and +150% damage", + description: "convert your bots to sound-bots
2.5x wave fire rate and 2.5x damage", maxCount: 1, count: 0, frequency: 3, @@ -1749,7 +1730,7 @@ const tech = { { name: "boom-bot upgrade", link: `boom-bot upgrade`, - description: "convert your bots to boom-bots
+300% explosion damage and size", + description: "convert your bots to boom-bots
4x explosion damage and size", maxCount: 1, count: 0, frequency: 3, @@ -1807,7 +1788,7 @@ const tech = { { name: "laser-bot upgrade", link: `laser-bot upgrade`, - description: "convert your bots to laser-bots
+100% damage, efficiency, and range", + description: "convert your bots to laser-bots
2.00x damage, efficiency, and range", maxCount: 1, count: 0, frequency: 3, @@ -1865,7 +1846,7 @@ const tech = { { name: "orbital-bot upgrade", link: `orbital-bot upgrade`, - description: "convert your bots to orbital-bots
+300% orbital damage and +50% radius", + description: "convert your bots to orbital-bots
4x orbital damage and 1.5x radius", maxCount: 1, count: 0, frequency: 3, @@ -1906,7 +1887,7 @@ const tech = { { name: "dynamo-bot", link: `dynamo-bot`, - description: "a bot damages mobs while it traces your path
when it's near generate +8 energy per second", + description: "a bot damages mobs while it traces your path
+8 energy per second when nearby", maxCount: 9, count: 0, frequency: 1, @@ -1932,7 +1913,7 @@ const tech = { { name: "dynamo-bot upgrade", link: `dynamo-bot upgrade`, - description: "convert your bots to dynamo-bots
when it's near generate +24 energy per second", + description: "convert your bots to dynamo-bots
+24 energy per second when nearby", maxCount: 1, count: 0, frequency: 3, @@ -1963,7 +1944,7 @@ const tech = { }, { name: "perimeter defense", - description: "for each permanent bot
+6% defense", + description: "for each permanent bot
0.95x damage taken", maxCount: 1, count: 0, frequency: 2, @@ -1982,7 +1963,7 @@ const tech = { }, { name: "network effect", - description: "for each permanent bot
+6% damage", + description: "for each permanent bot
1.05x damage", maxCount: 1, count: 0, frequency: 2, @@ -2173,7 +2154,7 @@ const tech = { }, { name: "decorrelation", - description: "if your gun or field are unused for 2 seconds
+77% defense", + description: "if your gun or field are unused for 2 seconds
0.3x damage taken", maxCount: 1, count: 0, frequency: 1, @@ -2191,7 +2172,7 @@ const tech = { }, { name: "anticorrelation", - description: "if your gun or field are unused for 2 seconds
+111% damage", + description: "if your gun or field are unused for 2 seconds
2x damage", maxCount: 1, count: 0, frequency: 1, @@ -2209,7 +2190,7 @@ const tech = { }, { name: "mass driver", - description: "+300% block collision damage", + description: "4x block collision damage", maxCount: 1, count: 0, frequency: 1, @@ -2228,7 +2209,7 @@ const tech = { { name: "inflation", link: `inflation`, - description: "if holding a block +90% defense
after throwing a block it expands 200%", + description: "if holding a block 0.1x damage taken
after throwing a block it expands 3x", maxCount: 1, count: 0, frequency: 3, @@ -2246,7 +2227,7 @@ const tech = { }, { name: "restitution", - description: "+150% block collision damage
after throwing a block it becomes very bouncy", + description: "2.5x block collision damage
after throwing a block it becomes very bouncy", maxCount: 1, count: 0, frequency: 3, @@ -2264,7 +2245,7 @@ const tech = { }, { name: "flywheel", - description: "+150% block collision damage
after a mob dies its block is flung at mobs", + description: "2.5x block collision damage
after a mob dies its block is flung at mobs", maxCount: 1, count: 0, frequency: 3, @@ -2280,24 +2261,6 @@ const tech = { tech.isMobBlockFling = false } }, - // { - // name: "fermions", - // description: "blocks thrown by you or pilot wave will
collide with intangible mobs, but not you", - // maxCount: 1, - // count: 0, - // frequency: 2, - // frequencyDefault: 2, - // allowed() { - // return (tech.blockDamage > 0.075 || m.fieldMode === 8) && !tech.isTokamak - // }, - // requires: "mass driver or pilot wave, not tokamak", - // effect() { - // tech.isBlockBullets = true - // }, - // remove() { - // tech.isBlockBullets = false - // } - // }, { name: "buckling", descriptionFunction() { @@ -2420,7 +2383,7 @@ const tech = { }, { name: "NAND gate", - description: "if ON
+55.5% damage", + description: "if ON
1.555x damage", maxCount: 1, count: 0, frequency: 3, @@ -2600,7 +2563,7 @@ const tech = { { name: "first derivative", descriptionFunction() { - return `while your first gun is equipped
+15% defense per gun (${(100 * (1 - 0.85 ** b.inventory.length)).toFixed(0)}%)` + return `while your first gun is equipped
0.85x damage taken per gun (${(100 * (1 - 0.85 ** b.inventory.length)).toFixed(0)}%)` }, maxCount: 1, count: 0, @@ -2619,7 +2582,7 @@ const tech = { }, { name: "MACHO", - description: "a massive compact halo object follows you
+60% defense while you are inside the MACHO", + description: "a massive compact halo object follows you
0.4x damage taken inside the MACHO", maxCount: 1, count: 0, frequency: 1, @@ -2642,7 +2605,7 @@ const tech = { }, { name: "axion", - description: "while inside the MACHO
defense increases damage", + description: "while inside the MACHO
2x damage", maxCount: 1, count: 0, frequency: 2, @@ -2660,7 +2623,7 @@ const tech = { }, { name: "dark star", - description: "mobs inside the MACHO are damaged
increase MACHO radius by 15%", + description: "mobs inside the MACHO are damaged
1.2x MACHO radius", maxCount: 1, count: 0, frequency: 2, @@ -2696,7 +2659,7 @@ const tech = { { name: "non-Newtonian armor", link: `non-Newtonian armor`, - description: "after mob collisions
+66% defense for 10 seconds", + description: "after mob collisions
0.3x damage taken for 10 seconds", maxCount: 1, count: 0, frequency: 1, @@ -2714,9 +2677,7 @@ const tech = { }, { name: "tessellation", - description: `use ${powerUps.orb.research(2)}
+35% defense`, - // description: "use 4 research
reduce defense by 50%", - // isFieldTech: true, + description: `use ${powerUps.orb.research(2)}
0.6x damage taken`, maxCount: 1, count: 0, frequency: 1, @@ -2797,28 +2758,9 @@ const tech = { tech.isHarmFreeze = false; } }, - // { - // name: "clock gating", - // description: `after losing health slow time by 50%
+20% defense`, - // maxCount: 1, - // count: 0, - // frequency: 1, - // frequencyDefault: 1, - // allowed() { - // return simulation.fpsCapDefault > 45 - // }, - // requires: "FPS above 45", - // effect() { - // tech.isSlowFPS = true; - // }, - // remove() { - // tech.isSlowFPS = false; - // } - // }, - { name: "piezoelectricity", - description: "if you collide with a mob
generate +2048 energy", //
reduce defense by 15% + description: "if you collide with a mob
generate +2048 energy", maxCount: 1, count: 0, frequency: 1, @@ -2837,8 +2779,7 @@ const tech = { }, { name: "ground state", - description: "+266 maximum energy
–33% passive energy generation", - // description: "reduce defense by 66%
you no longer passively regenerate energy", + description: "+266 maximum energy
0.66x passive energy generation", maxCount: 1, count: 0, frequency: 1, @@ -2860,7 +2801,7 @@ const tech = { }, { name: "heat engine", - description: `+40% damage
–50 maximum energy`, + description: `1.4x damage
–50 maximum energy`, maxCount: 1, count: 0, frequency: 1, @@ -2881,7 +2822,7 @@ const tech = { }, { name: "exothermic process", - description: "+50% damage
after mobs die –20% energy", + description: "1.6x damage
after mobs die –20% energy", maxCount: 1, count: 0, frequency: 1, @@ -2890,7 +2831,7 @@ const tech = { return true }, requires: "", - damage: 1.55, + damage: 1.6, effect() { tech.damage *= this.damage tech.isEnergyLoss = true; @@ -2902,23 +2843,33 @@ const tech = { }, { name: "Gibbs free energy", - description: `for each energy below 100
+0.7% damage`, + descriptionFunction() { + return `use ${powerUps.orb.research(2)}
1.01x damage per energy below 100 (${(1 + Math.max(0, 1 - m.energy)).toFixed(2)}x)` + }, maxCount: 1, count: 0, frequency: 1, frequencyDefault: 1, - allowed: () => true, + allowed() { + return powerUps.research.count > 1 || build.isExperimentSelection + }, requires: "", effect() { tech.isLowEnergyDamage = true; + for (let i = 0; i < 2; i++) { + if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) + } }, remove() { tech.isLowEnergyDamage = false; + if (this.count > 0) { + powerUps.research.changeRerolls(2) + } } }, { name: "overcharge", - description: "+88 maximum energy
+5% JUNK to tech pool", + description: "+88 maximum energy
+5% JUNKtech chance", maxCount: 9, count: 0, frequency: 1, @@ -2944,7 +2895,7 @@ const tech = { }, { name: "Maxwells demon", - description: "energy above max decays by 30% 1% per second
+5% JUNK to tech pool", + description: "energy above max decays 30x slower
+5% JUNKtech chance", maxCount: 1, count: 0, frequency: 2, @@ -2968,7 +2919,7 @@ const tech = { }, { name: "inductive charging", - description: "if crouched +600% passive energy generation
if not crouched energy generation is disabled", + description: "if crouched 7x passive energy generation
if not crouched energy generation is disabled", maxCount: 1, count: 0, frequency: 1, @@ -2991,7 +2942,7 @@ const tech = { }, { name: "energy conservation", - description: "4% of damage done recovered as energy", + description: "1.04x of damage done recovered as energy", maxCount: 9, count: 0, frequency: 1, @@ -3009,7 +2960,7 @@ const tech = { }, { name: "parasitism", - description: "if a mob has died in the last 5 seconds
+93% damage, no passive energy generation", + description: "if a mob has died in the last 5 seconds
2x damage, no passive energy generation", maxCount: 1, count: 0, frequency: 1, @@ -3032,7 +2983,7 @@ const tech = { }, { name: "waste heat recovery", - description: "if a mob has died in the last 5 seconds
generate 5% of max energy per second", + description: "if a mob has died in the last 5 seconds
generate 0.05x max energy per second", maxCount: 1, count: 0, frequency: 1, @@ -3051,7 +3002,7 @@ const tech = { { name: "recycling", descriptionFunction() { - return `if a mob has died in the last 5 seconds
recover 0.5% of max ${tech.isEnergyHealth ? "energy" : "health"} per second` + return `if a mob has died in the last 5 seconds
recover 0.005x max ${tech.isEnergyHealth ? "energy" : "health"} per second` }, description: "", maxCount: 1, @@ -3072,7 +3023,7 @@ const tech = { }, { name: "torpor", - description: "if a mob has not died in the last 5 seconds
+74% defense", + description: "if a mob has not died in the last 5 seconds
0.3x damage taken", maxCount: 1, count: 0, frequency: 1, @@ -3091,7 +3042,7 @@ const tech = { { name: "homeostasis", descriptionFunction() { - return `for each health below 100
+0.8% defense (${(100 * (Math.max(0, 1 - m.health) * 0.8)).toFixed(0)}%)` + return `0.8x damage taken per health below 100
(${(1 - Math.max(0, 1 - m.health) * 0.8).toFixed(2)}x)` }, maxCount: 1, count: 0, @@ -3111,7 +3062,7 @@ const tech = { { name: "negative feedback", descriptionFunction() { - return `for each ${tech.isEnergyHealth ? "energy" : "health"} below 100
+0.7% damage (${(70 * Math.max(0, 1 - (tech.isEnergyHealth ? m.energy : m.health))).toFixed(0)}%)` + return `1.007x damage per ${tech.isEnergyHealth ? "energy" : "health"} below 100
(${(1 + 0.7 * Math.max(0, 1 - (tech.isEnergyHealth ? m.energy : m.health))).toFixed(2)}x)` }, maxCount: 1, count: 0, @@ -3131,10 +3082,8 @@ const tech = { { name: "Zenos paradox", descriptionFunction() { - return `+85% defense
–5% of current ${tech.isEnergyHealth ? "energy" : "health"} every 5 seconds` + return `0.15x damage taken
–5% of current ${tech.isEnergyHealth ? "energy" : "health"} every 5 seconds` }, - // description: "+85% defense
–5% of current health every 5 seconds", - // description: "every 5 seconds remove 1/10 of your health
reduce defense by 90%", maxCount: 1, count: 0, frequency: 1, @@ -3153,9 +3102,8 @@ const tech = { { name: "antiscience", descriptionFunction() { - return `–10 ${tech.isEnergyHealth ? "energy" : "health"} after picking up a tech
+66% damage` + return `–10 ${tech.isEnergyHealth ? "energy" : "health"} after picking up a tech
1.7x damage` }, - // description: "+66% damage
–10 health after picking up a tech", maxCount: 1, count: 0, frequency: 1, @@ -3164,7 +3112,7 @@ const tech = { return true }, requires: "", - damage: 1.66, + damage: 1.7, effect() { tech.damage *= this.damage tech.isTechDamage = true; @@ -3177,7 +3125,7 @@ const tech = { { name: "ergodicity", descriptionFunction() { - return `${powerUps.orb.heal()} have -50% effect
+66% damage` + return `0.50x healing from ${powerUps.orb.heal()}
1.7x damage` }, maxCount: 1, count: 0, @@ -3187,7 +3135,7 @@ const tech = { return true }, requires: "", - damage: 1.66, + damage: 1.7, effect() { tech.damage *= this.damage tech.isHalfHeals = true; @@ -3215,7 +3163,7 @@ const tech = { }, { name: "fluoroantimonic acid", - description: "if your health is above 100
+35% damage", + description: "if your health is above 100
1.35x damage", maxCount: 1, count: 0, frequency: 2, @@ -3256,7 +3204,7 @@ const tech = { { name: "adiabatic healing", descriptionFunction() { - return `${powerUps.orb.heal()} have +100% effect
+4% JUNK to tech pool` + return `2x healing from ${powerUps.orb.heal()}
+4% JUNKtech chance` }, maxCount: 3, count: 0, @@ -3299,7 +3247,7 @@ const tech = { { name: "quenching", descriptionFunction() { - return `${powerUps.orb.heal()} over healing results in 200% health loss
and 200% max health increase` + return `${powerUps.orb.heal()} overhealing results in 2x health loss
and 2x max health increase` }, maxCount: 1, count: 0, @@ -3345,7 +3293,7 @@ const tech = { { name: "accretion disk", descriptionFunction() { - return `+5% damage (${5 * powerUp.length}%)
for each power up that exists on this level` + return `1.05x damage (${(1 + 0.05 * powerUp.length).toFixed(2)}x)
for each power up that exists on this level` }, maxCount: 1, count: 0, @@ -3366,7 +3314,7 @@ const tech = { { name: "self-assembly", descriptionFunction() { - return `at the start of each level
for every 25% missing ${tech.isEnergyHealth ? "energy" : "health"} spawn ${powerUps.orb.heal()}` + return `at the start of each level
for every 25 missing ${tech.isEnergyHealth ? "energy" : "health"} spawn ${powerUps.orb.heal()}` }, maxCount: 1, count: 0, @@ -3460,7 +3408,7 @@ const tech = { }, { name: "strong anthropic principle", - description: "after anthropic principle prevents your death
+137.03599% damage for that level", + description: "after anthropic principle prevents your death
2.71828x damage for that level", maxCount: 1, count: 0, frequency: 3, @@ -3478,7 +3426,7 @@ const tech = { }, { name: "quantum immortality", - description: "+30% defense
after dying, continue in an alternate reality", + description: "0.7x damage taken
after dying, continue in an alternate reality", maxCount: 1, count: 0, frequency: 1, @@ -3537,6 +3485,30 @@ const tech = { if (this.count > 0) powerUps.research.changeRerolls(-this.bonusResearch) } }, + { + name: "peer review", + description: `+3% JUNKtech chance
after you research gain 1.04x damage`, + maxCount: 1, + count: 0, + frequency: 1, + frequencyDefault: 1, + allowed() { + return (powerUps.research.count > 1 || build.isExperimentSelection) && !tech.isSuperDeterminism + }, + 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 + } + } + }, { name: "decoherence", description: `tech options you don't choose won't reoccur
spawn ${powerUps.orb.research(7)}`, @@ -3567,7 +3539,7 @@ const tech = { }, { name: "renormalization", - description: `47% chance to spawn ${powerUps.orb.research(1)} after consuming ${powerUps.orb.research(1)}
+5% JUNK to tech pool`, + description: `47% chance to spawn ${powerUps.orb.research(1)} after consuming ${powerUps.orb.research(1)}
+5% JUNKtech chance`, maxCount: 1, count: 0, frequency: 2, @@ -3592,10 +3564,7 @@ const tech = { }, { name: "perturbation theory", - description: `if you have no ${powerUps.orb.research(1)} in your inventory
+60% fire rate`, - // descriptionFunction() { - // return `+40% damage, but -10% damage
for each ${powerUps.orb.research(1)} in your inventory (${40 - 10 * powerUps.research.count}% damage)` - // }, + description: `if you have no ${powerUps.orb.research(1)} in your inventory
1.6x fire rate`, maxCount: 1, count: 0, frequency: 1, @@ -3635,9 +3604,8 @@ const tech = { }, { name: "Bayesian statistics", - // description: `for each ${powerUps.orb.research(1)} in your inventory
+3.8% damage`, descriptionFunction() { - return `spawn ${powerUps.orb.research(this.bonusResearch)}
+3% damage per ${powerUps.orb.research(1)} in your inventory (${(3 * powerUps.research.count).toFixed(0)}%)` + return `spawn ${powerUps.orb.research(this.bonusResearch)}
1.03x damage per ${powerUps.orb.research(1)} in your inventory (${(1.03 * powerUps.research.count).toFixed(2)}x)` }, maxCount: 1, count: 0, @@ -3743,15 +3711,15 @@ const tech = { }, { name: "pseudoscience", - description: "when selecting a power up, research 3 times
for free, but add 1-3% JUNK to the tech pool", + description: "research 3 times
for free, but
add 1% JUNKtech chance each time", maxCount: 1, count: 0, frequency: 1, frequencyDefault: 1, allowed() { - return !tech.isResearchReality && !tech.isSuperDeterminism //tech.isResearchBoss || tech.isMetaAnalysis || tech.isRerollBots || tech.isDeathAvoid || tech.isRerollDamage || build.isExperimentSelection + return !tech.isResearchReality && !tech.isSuperDeterminism }, - requires: "not Ψ(t) collapse, superdeterminism", //"abiogenesis, meta-analysis, bot fabrication, anthropic principle, or Bayesian statistics, not Ψ(t) collapse", + requires: "not Ψ(t) collapse, superdeterminism", effect() { tech.isJunkResearch = true; }, @@ -3800,8 +3768,7 @@ const tech = { }, { name: "emergence", - description: "tech, fields, and guns have +1 choice
+8% damage", - // description: "tech, fields, and guns have +2 choices
+3% JUNK to tech pool", + description: "tech, fields, and guns have +1 choice
1.08x damage", maxCount: 9, count: 0, frequency: 1, @@ -3828,7 +3795,7 @@ const tech = { { name: "path integral", link: `path integral`, - description: "your next tech choice has all possible options
+5% JUNK to tech pool", + description: "your next tech choice has all possible options
+5% JUNKtech chance", maxCount: 1, count: 0, frequency: 1, @@ -3900,8 +3867,7 @@ const tech = { { name: "technical debt", descriptionFunction() { - // return `+300% damage –15% damage
for each tech you have learned (+${(Math.floor(100 * (Math.min(Math.pow(0.85, tech.totalCount - 20), 4 - 0.15 * tech.totalCount))) - 100)}%)` - return `+300% damage –15% damage
for each tech you have learned (${(tech.totalCount > 20 ? 100 * (Math.pow(0.85, tech.totalCount - 20) - 1) : 100 * (3 - 0.15 * tech.totalCount)).toFixed(0)}%)` + return `4x damage but lose 0.15x damage
for each tech you have learned (${(tech.totalCount > 20 ? (Math.pow(0.85, tech.totalCount - 20)) : (4 - 0.15 * tech.totalCount)).toFixed(2)}x)` }, maxCount: 1, count: 0, @@ -3918,25 +3884,6 @@ const tech = { tech.isTechDebt = false; } }, - // { - // name: "abiogenesis", - // // description: `use ${powerUps.orb.research(4)}(or 49% JUNK to the tech pool if you can't) to add a 2nd boss to each level`, - // description: `as a level begins spawn a 2nd boss using ${powerUps.orb.research(3)}
(+49% JUNK to the tech pool if you can't pay)
`, - // maxCount: 1, - // count: 0, - // frequency: 2, - // frequencyDefault: 2, - // allowed() { - // return (build.isExperimentSelection || powerUps.research.count > 2) && !tech.isDuplicateMobs - // }, - // requires: "at least 3 research, not parthenogenesis", - // effect() { - // tech.isResearchBoss = true; - // }, - // remove() { - // tech.isResearchBoss = false; - // } - // }, { name: "meta-analysis", description: `if you choose a JUNKtech you instead get a
random normal tech and spawn ${powerUps.orb.research(2)}`, @@ -3957,7 +3904,7 @@ const tech = { }, { name: "dark patterns", - description: "+22% damage
+11% JUNK to tech pool", + description: "1.3x damage
+17% JUNKtech chance", maxCount: 9, count: 0, frequency: 1, @@ -3966,10 +3913,10 @@ const tech = { return true }, requires: "", - damage: 1.22, + damage: 1.3, effect() { tech.damage *= this.damage - this.refundAmount += tech.addJunkTechToPool(0.11) + this.refundAmount += tech.addJunkTechToPool(0.17) }, refundAmount: 0, remove() { @@ -3982,7 +3929,7 @@ const tech = { { name: "junk DNA", descriptionFunction() { - return `increase damage by twice the
JUNK tech pool percent (${(200 * tech.junkChance).toFixed(0)}%)` + return `increase damage by twice the
JUNKtech chance (${(1 + 2 * tech.junkChance).toFixed(2)}x)` }, maxCount: 1, count: 0, @@ -4002,7 +3949,7 @@ const tech = { { name: "exciton", descriptionFunction() { - return `after mobs die they have a 14% chance to
spawn ${powerUps.orb.boost(1)} that give +${(powerUps.boost.damage * 100).toFixed(0)}% damage for ${(powerUps.boost.duration / 60).toFixed(0)} seconds
` + return `after mobs die they have a 14% chance to
spawn ${powerUps.orb.boost(1)} that give ${(1 + powerUps.boost.damage).toFixed(2)}x damage for ${(powerUps.boost.duration / 60).toFixed(0)} seconds
` }, maxCount: 1, count: 0, @@ -4020,7 +3967,7 @@ const tech = { { name: "band gap", descriptionFunction() { - return `${powerUps.orb.boost(1)} give +77% damage
but their duration is reduced by 1 second` + return `${powerUps.orb.boost(1)} give 1.77x damage
but their duration is reduced by 1 second` }, maxCount: 9, count: 1, @@ -4041,7 +3988,7 @@ const tech = { }, { name: "eternalism", - description: "+24% damage
time can't be paused (time can be dilated)", + description: "1.25x damage
time can't be paused (time can be dilated)", maxCount: 1, count: 0, frequency: 1, @@ -4050,7 +3997,7 @@ const tech = { return !tech.isPauseSwitchField && !tech.isPauseEjectTech && !tech.isWormHolePause }, requires: "not unified field theory, paradigm shift, invariant", - damage: 1.24, + damage: 1.25, effect() { tech.damage *= this.damage tech.isNoDraftPause = true @@ -4322,7 +4269,7 @@ const tech = { }, { name: "replication", - description: "+10% chance to duplicate spawned power ups
+22% JUNK to tech pool", + description: "+10% chance to duplicate spawned power ups
+22% JUNKtech chance", maxCount: 9, count: 0, frequency: 1, @@ -4391,7 +4338,7 @@ const tech = { }, { name: "correlated damage", - description: "duplication increases damage", + description: "duplication increases damage by the same percent", maxCount: 1, count: 0, frequency: 1, @@ -4449,7 +4396,7 @@ const tech = { { name: "strange attractor", descriptionFunction() { - return `+7% damage
removing this increases duplication by +11%` + return `1.1x damage
removing this increases duplication by +11%` }, maxCount: 1, count: 0, @@ -4460,7 +4407,7 @@ const tech = { return true }, requires: "", - damage: 1.07, + damage: 1.1, effect() { tech.damage *= this.damage }, @@ -4476,7 +4423,7 @@ const tech = { { name: "strange loop", // description: `+11% damage
removing this doubles it's damage if you take it again`, - description: `+9% damage
removing this gives strange attractor and null hypothesis`, + description: `1.1x damage
removing this gives strange attractor and null hypothesis`, maxCount: 1, count: 0, frequency: 1, @@ -4486,7 +4433,7 @@ const tech = { return true }, requires: "", - damage: 1.09, + damage: 1.1, effect() { tech.damage *= this.damage }, @@ -4503,7 +4450,7 @@ const tech = { }, { name: "null hypothesis", - description: `+8% damage
removing this spawns ${powerUps.orb.research(15)}`, + description: `1.1x damage
removing this spawns ${powerUps.orb.research(15)}`, maxCount: 1, count: 0, frequency: 1, @@ -4513,7 +4460,7 @@ const tech = { return true }, requires: "", - damage: 1.08, + damage: 1.1, effect() { tech.damage *= this.damage }, @@ -4528,7 +4475,7 @@ const tech = { { name: "martingale", descriptionFunction() { - return `+${(100 * this.damage).toFixed(0)}% damage. After removing this there is a 50%
chance to get it back with double its damage
` + return `${(1 + this.damage).toFixed(2)}x damage. After removing this there is a 50%
chance to get it back with double its damage
` }, maxCount: 1, count: 0, @@ -4591,7 +4538,7 @@ const tech = { { name: "Occams razor", descriptionFunction() { - return `randomly remove half your tech
for each removed +${this.damagePerRemoved * 100}% damage (~${(this.count === 0) ? this.damagePerRemoved * 50 * tech.totalCount : this.damage * 100}%)` + return `randomly remove half your tech
for each removed ${(1 + this.damagePerRemoved).toFixed(2)}x damage (~${((this.count === 0) ? 1 + this.damagePerRemoved * 0.5 * tech.totalCount : this.damage).toFixed(2)}x)` }, maxCount: 1, count: 0, @@ -4741,7 +4688,7 @@ const tech = { }, { name: "nanowires", - description: `needles tunnel through blocks and map
+20% needle damage`, + description: `needles tunnel through blocks and map
1.2x needle damage`, isGunTech: true, maxCount: 1, count: 0, @@ -4871,7 +4818,7 @@ const tech = { }, { name: "pneumatic actuator", - description: "nail gun takes no time to ramp up
to its fastest fire rate", + description: "nail gun takes no time to ramp up
to its fastest fire rate", isGunTech: true, maxCount: 1, count: 0, @@ -4931,7 +4878,7 @@ const tech = { }, { name: "rotary cannon", - description: "nail gun has increased muzzle speed,
maximum fire rate, accuracy, and recoil", + description: "nail gun has increased muzzle speed,
maximum fire rate, accuracy, and recoil", isGunTech: true, maxCount: 1, count: 0, @@ -4958,7 +4905,7 @@ const tech = { }, { name: "gauge", - description: `rivets, needles, super balls, and nails
have +30% mass and physical damage`, + description: `rivets, needles, super balls, and nails
have 1.3x mass and physical damage`, isGunTech: true, maxCount: 9, count: 0, @@ -4997,7 +4944,7 @@ const tech = { { name: "irradiated nails", link: `irradiated nails`, - description: "nails, needles, and rivets are radioactive
+90% radioactive damage over 3 seconds", + description: "nails, needles, and rivets are radioactive
1.9x radioactive damage over 3 seconds", isGunTech: true, maxCount: 1, count: 0, @@ -5037,7 +4984,7 @@ const tech = { { name: "1s half-life", link: `1s half-life`, - description: "nails, needles, rivets are made of lithium-8
+300% radioactive damage for 1 second
", + description: "nails, needles, rivets are made of lithium-8
4x radioactive damage for 1 second
", isGunTech: true, maxCount: 1, count: 0, @@ -5096,7 +5043,7 @@ const tech = { }, { name: "Newtons 3rd law", - description: "+66% shotgun fire rate and recoil", + description: "1.7x shotgun fire rate and recoil", isGunTech: true, maxCount: 1, count: 0, @@ -5116,7 +5063,7 @@ const tech = { { name: "Noether violation", link: `Noether violation`, - description: "+50% shotgun damage
shotgun recoil is reversed", + description: "1.5x shotgun damage
shotgun recoil is reversed", isGunTech: true, maxCount: 1, count: 0, @@ -5135,7 +5082,7 @@ const tech = { }, { name: "repeater", - description: "shotgun immediately fires again for no ammo
-50% shotgun fire rate", + description: "shotgun immediately fires again for no ammo
reduced 0.5x shotgun fire rate", isGunTech: true, maxCount: 9, count: 0, @@ -5328,7 +5275,7 @@ const tech = { }, { name: "rebound", - description: `after they collide with a mob, super balls
gain speed, duration, and +33% damage`, + description: `after they collide with a mob, super balls
gain speed, duration, and 1.3x damage`, isGunTech: true, maxCount: 1, count: 0, @@ -5347,7 +5294,7 @@ const tech = { }, { name: "Zectron", - description: `+90% super ball density and damage, but
after colliding with super balls -25% energy`, + description: `1.9x super ball density and damage, but
after colliding with super balls -25% energy`, isGunTech: true, maxCount: 1, count: 0, @@ -5458,7 +5405,7 @@ const tech = { }, { name: "phase velocity", - description: "wave particles propagate faster as solids
+40% wave damage", + description: "wave particles propagate faster as solids
1.4x wave damage", isGunTech: true, maxCount: 1, count: 0, @@ -5477,7 +5424,7 @@ const tech = { }, { name: "amplitude", - description: "+37% wave damage
+37% wave particle amplitude", + description: "1.4x wave damage
1.4x wave bullet amplitude", isGunTech: true, maxCount: 3, count: 0, @@ -5489,7 +5436,7 @@ const tech = { requires: "wave", effect() { tech.waveFrequency *= 0.66 - tech.wavePacketDamage *= 1.37 + tech.wavePacketDamage *= 1.4 }, remove() { tech.waveFrequency = 0.2 @@ -5498,7 +5445,7 @@ const tech = { }, { name: "propagation", - description: "–25% wave packet propagation speed
+41% wave damage", + description: "0.75x wave propagation speed
1.4x wave damage", isGunTech: true, maxCount: 9, count: 0, @@ -5510,7 +5457,7 @@ const tech = { requires: "wave", effect() { tech.waveBeamSpeed *= 0.75; - tech.waveBeamDamage += 0.27 * 0.41 //this sets base wave damage + tech.waveBeamDamage += 0.27 * 0.4 //this sets base wave damage }, remove() { tech.waveBeamSpeed = 11; @@ -5519,7 +5466,7 @@ const tech = { }, { name: "bound state", - description: "wave packets reflect backwards 2 times
–33% range", + description: "wave packets reflect backwards 2 times
0.66x wave range", isGunTech: true, maxCount: 9, count: 0, @@ -5538,7 +5485,7 @@ const tech = { }, { name: "frequency", - description: `wave has unlimited ammo
-25% wave damage`, + description: `wave has unlimited ammo
0.75x wave damage`, isGunTech: true, maxCount: 1, count: 0, @@ -5604,7 +5551,7 @@ const tech = { }, { name: "isotropic", - description: "waves expand in all directions
–40% range and +50% damage", + description: "waves expand in all directions
0.6x range and 1.5x damage", isGunTech: true, maxCount: 1, count: 0, @@ -5663,7 +5610,7 @@ const tech = { }, { name: "cruise missile", - description: "+100% missile explosive damage, radius
–50% missile speed", + description: "2x missile explosive damage, radius
0.5x missile speed", isGunTech: true, maxCount: 1, count: 0, @@ -5682,7 +5629,7 @@ const tech = { }, { name: "ICBM", - description: "+75% missile explosive damage, radius
–50% missile speed", + description: "1.75x missile explosive damage, radius
0.5x missile speed", isGunTech: true, maxCount: 1, count: 0, @@ -5701,7 +5648,7 @@ const tech = { }, { name: "launch system", - description: `+500% missile gun fire rate
+20% missile ammo per ${powerUps.orb.ammo(1)}`, + description: `5x missile gun fire rate
1.2x missile ammo per ${powerUps.orb.ammo(1)}`, isGunTech: true, maxCount: 1, count: 0, @@ -5773,7 +5720,7 @@ const tech = { }, { name: "iridium-192", - description: "explosions release gamma radiation
+100% explosion damage over 4 seconds", + description: "explosions release gamma radiation
2x explosion damage over 4 seconds", isGunTech: true, maxCount: 1, count: 0, @@ -5811,7 +5758,7 @@ const tech = { }, { name: "ammonium nitrate", - description: "+24% explosive damage, radius", + description: "1.25x explosive damage, radius", isGunTech: true, maxCount: 9, count: 0, @@ -5822,7 +5769,7 @@ const tech = { }, requires: "an explosive damage source, not iridium-192", effect() { - tech.explosiveRadius += 0.24; + tech.explosiveRadius += 0.25; }, remove() { tech.explosiveRadius = 1; @@ -5830,7 +5777,7 @@ const tech = { }, { name: "nitroglycerin", - description: "+66% explosive damage
–33% explosive radius", + description: "1.66x explosive damage
0.66x smaller explosive radius", isGunTech: true, maxCount: 1, count: 0, @@ -5849,7 +5796,7 @@ const tech = { }, { name: "acetone peroxide", - description: "+70% explosive radius
–33% explosive defense", + description: "1.7x explosive radius
1.4x explosive damage taken", isGunTech: true, maxCount: 1, count: 0, @@ -5909,29 +5856,9 @@ const tech = { if (this.count > 0) powerUps.research.changeRerolls(3) } }, - // { - // name: "electric armor", - // // description: "explosions do no defense
while your energy is above 98%", - // description: "instead of causing health loss, explosions
drain 12 energy and have more knockback", - // isGunTech: true, - // maxCount: 1, - // count: 0, - // frequency: 2, - // frequencyDefault: 2, - // allowed() { - // return !tech.isSmartRadius && !tech.isExplodeRadio && tech.hasExplosiveDamageCheck() - // }, - // requires: "an explosive damage source, not iridium-192", - // effect() { - // tech.isImmuneExplosion = true; - // }, - // remove() { - // tech.isImmuneExplosion = false; - // } - // }, { name: "MIRV", - description: "fire +1 missile or grenade per shot
–12% explosion damage and radius", + description: "fire +1 missile or grenade per shot
0.88x explosion damage and radius", isGunTech: true, maxCount: 9, count: 0, @@ -5994,7 +5921,7 @@ const tech = { }, { name: "chain reaction", - description: "+33% grenade radius and damage
blocks caught in explosions also explode", + description: "1.33x grenade radius and damage
blocks caught in explosions also explode", isGunTech: true, maxCount: 1, count: 0, @@ -6091,7 +6018,7 @@ const tech = { }, { name: "vacuum permittivity", - description: "+20% radioactive range
objects in range of the bomb are slowed", + description: "1.2x radioactive range
objects in range of the bomb are slowed", isGunTech: true, maxCount: 1, count: 0, @@ -6129,7 +6056,7 @@ const tech = { }, { name: "nuclear transmutation", - description: "+47% radiation damage
nail, drone, neutron bomb, iridium, cosmic string, deflect", + description: "1.5x radiation damage
nail, drone, neutron bomb, iridium, cosmic string, deflect", isGunTech: true, maxCount: 9, count: 0, @@ -6140,7 +6067,7 @@ const tech = { }, requires: "radiation damage source", effect() { - tech.radioactiveDamage += 1.47 + tech.radioactiveDamage += 1.5 }, remove() { tech.radioactiveDamage = 1 @@ -6149,7 +6076,7 @@ const tech = { { name: "water shielding", link: `water shielding`, - description: "radioactive effects on you are reduced by 75%
neutron bomb, drones, explosions, slime", + description: "you are protected from 75% of radioactivity
neutron bomb, drones, explosions, slime", isGunTech: true, maxCount: 1, count: 0, @@ -6168,7 +6095,7 @@ const tech = { }, { name: "ricochet", - description: "after nails hit a mob they rebound towards
a new mob with +180% damage per bounce", + description: "after nails hit a mob they rebound towards
a new mob with 2.8x damage per bounce", isGunTech: true, maxCount: 1, count: 0, @@ -6189,7 +6116,7 @@ const tech = { }, { name: "booby trap", - description: "50% chance to drop a mine from power ups
+30% JUNK to tech pool", + description: "50% chance to drop a mine from power ups
+30% JUNKtech chance", isGunTech: true, maxCount: 1, count: 0, @@ -6276,7 +6203,7 @@ const tech = { { name: "sentry", descriptionFunction() { - return `mines fire one ${b.guns[10].nameString()} at a time
mines fire 50% more ${b.guns[10].nameString('s')}` + return `mines fire one ${b.guns[10].nameString()} at a time
mines fire 1.5x more ${b.guns[10].nameString('s')}` }, isGunTech: true, maxCount: 1, @@ -6297,7 +6224,7 @@ const tech = { { name: "extended magazine", descriptionFunction() { - return `sentry mines fire 50% more ${b.guns[10].nameString('s')}` + return `sentry mines fire 1.5x more ${b.guns[10].nameString('s')}` }, isGunTech: true, maxCount: 9, @@ -6318,7 +6245,7 @@ const tech = { { name: "mycelial fragmentation", link: `mycelial fragmentation`, - description: "during their growth phase
+70% sporangium discharge", + description: "during their growth phase
1.7x sporangium discharge", isGunTech: true, maxCount: 1, count: 0, @@ -6359,7 +6286,7 @@ const tech = { }, { name: "colony", - description: "+50% sporangium discharge
40% chance to discharge something different", + description: "1.5x sporangium discharge
40% chance to discharge something different", link: `colony`, isGunTech: true, maxCount: 1, @@ -6380,7 +6307,7 @@ const tech = { { name: "cryodesiccation", descriptionFunction() { - return `+25% sporangium discharge
${b.guns[6].nameString('s')} freeze mobs for 1.5 second` + return `1.25x sporangium discharge
${b.guns[6].nameString('s')} freeze mobs for 1.5 second` }, // description: "+25% sporangium discharge
spores freeze mobs for 1.5 second", isGunTech: true, @@ -6402,9 +6329,8 @@ const tech = { { name: "flagella", descriptionFunction() { - return `+50% ${b.guns[6].nameString()} acceleration
if they can't find a target ${b.guns[6].nameString('s')} follow you` + return `2x ${b.guns[6].nameString()} acceleration
if they can't find a target ${b.guns[6].nameString('s')} follow you` }, - // description: "+50% spore acceleration
if they can't find a target spores follow you", isGunTech: true, maxCount: 1, count: 0, @@ -6421,38 +6347,11 @@ const tech = { tech.isSporeFollow = false } }, - // { - // name: "junk DNA", - // //increase damage by 10% for each JUNK tech percent in the tech pool, remove all JUNK tech, - // descriptionFunction() { return `+50% ${b.guns[6].nameString()} damage
+15% JUNK to tech pool` }, - // isGunTech: true, - // maxCount: 1, - // count: 0, - // frequency: 3, - // frequencyDefault: 3, - // allowed() { - // return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || (m.fieldMode === 4 && simulation.molecularMode === 0) || tech.isSporeWorm || tech.isSporeFlea - // }, - // requires: "spores", - // effect() { - // tech.isSporeWorm = true - // this.refundAmount += tech.addJunkTechToPool(0.15) - // }, - // refundAmount: 0, - // remove() { - // tech.isSporeWorm = false - // if (this.count > 0 && this.refundAmount > 0) { - // tech.removeJunkTechFromPool(this.refundAmount) - // this.refundAmount = 0 - // } - // } - // }, { name: "mutualism", descriptionFunction() { - return `+200% ${b.guns[6].nameString()} damage
${b.guns[6].nameString('s')} borrow 1 health until they die` + return `3x ${b.guns[6].nameString()} damage
${b.guns[6].nameString('s')} borrow 1 health until they die` }, - // description: `+150% ${b.guns[6].name()} damage
spores borrow 0.5 health until they die`, isGunTech: true, maxCount: 1, count: 0, @@ -6529,7 +6428,7 @@ const tech = { }, { name: "K-selection", - description: "+37% worm and flea damage", + description: "1.37x worm and flea damage", isGunTech: true, maxCount: 3, count: 0, @@ -6570,7 +6469,7 @@ const tech = { { name: "reduced tolerances", link: `reduced tolerances`, - description: `+66% drones per ${powerUps.orb.ammo()} and energy
–40% drone duration`, + description: `1.7x drones per ${powerUps.orb.ammo()} and energy
0.6x drone duration`, isGunTech: true, maxCount: 3, count: 0, @@ -6582,7 +6481,7 @@ const tech = { requires: "drones, not irradiated drones", effect() { tech.droneCycleReduction = Math.pow(0.6, 1 + this.count) - tech.droneEnergyReduction = Math.pow(0.333, 1 + this.count) + tech.droneEnergyReduction = Math.pow(0.3, 1 + this.count) for (i = 0, len = b.guns.length; i < len; i++) { //find which gun if (b.guns[i].name === "drones") { const scale = Math.pow(3, this.count + 1) @@ -6639,7 +6538,7 @@ const tech = { }, { name: "brushless motor", - description: "drones rapidly rush towards their target
+33% drone collision damage", + description: "drones rapidly rush towards their target
1.33x drone collision damage", isGunTech: true, maxCount: 1, count: 0, @@ -6658,7 +6557,7 @@ const tech = { }, { name: "axial flux motor", - description: "+66% drones rush frequency
+44% drone collision damage", + description: "1.66x drones rush frequency
1.44x drone collision damage", isGunTech: true, maxCount: 1, count: 0, @@ -6678,7 +6577,7 @@ const tech = { { name: "irradiated drones", link: `irradiated drones`, - description: `the space around drones is irradiated
–75% drones per ${powerUps.orb.ammo()} and energy`, + description: `the space around drones is irradiated
0.25x drones per ${powerUps.orb.ammo()} and energy`, isGunTech: true, maxCount: 1, count: 0, @@ -6713,7 +6612,7 @@ const tech = { }, { name: "beta radiation", //"control rod ejection", - description: "–50% drone duration
+100% drone radiation damage", + description: "0.5x drone duration
2x drone radiation damage", isGunTech: true, maxCount: 1, count: 0, @@ -6733,7 +6632,7 @@ const tech = { { name: "orthocyclic winding", link: `orthocyclic winding`, - description: "+66% drone acceleration
+33% radiation damage", + description: "1.66x drone acceleration
1.33x radiation damage", isGunTech: true, maxCount: 1, count: 0, @@ -6853,7 +6752,7 @@ const tech = { }, { name: "uncertainty principle", - description: "foam, wave, and super ball positions are erratic
+53% foam, wave, and super ball damage", + description: "foam, wave, and super ball positions are erratic
1.5x foam, wave, and super ball damage", isGunTech: true, maxCount: 1, count: 0, @@ -6872,7 +6771,7 @@ const tech = { }, { name: "aerogel", - description: "–50% foam duration and foam bubbles float
+180% foam damage", + description: "foam bubbles float with 0.5x foam duration
2.8x foam damage", isGunTech: true, maxCount: 1, count: 0, @@ -6893,7 +6792,7 @@ const tech = { }, { name: "surface tension", - description: "+43% foam damage", + description: "1.4x foam damage", isGunTech: true, maxCount: 9, count: 0, @@ -6904,7 +6803,7 @@ const tech = { }, requires: "foam", effect() { - tech.foamDamage += 0.01 * 0.43 + tech.foamDamage += 0.01 * 0.4 }, remove() { tech.foamDamage = 0.01; @@ -6912,7 +6811,7 @@ const tech = { }, { name: "cavitation", - description: "25% chance to discharge a huge foam bubble
increase foam recoil by 100%", + description: "25% chance to discharge a huge foam bubble
2x foam gun recoil", isGunTech: true, maxCount: 1, count: 0, @@ -6933,7 +6832,7 @@ const tech = { }, { name: "foam fractionation", - description: "if you have below 300 ammo
+100% foam gun bubble size", + description: "if you have below 300 ammo
2x foam gun bubble size", isGunTech: true, maxCount: 1, count: 0, @@ -6952,7 +6851,7 @@ const tech = { }, { name: "ideal gas law", - description: `remove all current foam ammo
+1200% foam ammo per ${powerUps.orb.ammo(1)}`, + description: `remove all current foam ammo
12x foam ammo per ${powerUps.orb.ammo(1)}`, isGunTech: true, maxCount: 1, count: 0, @@ -7023,7 +6922,7 @@ const tech = { { name: "Bitter electromagnet", descriptionFunction() { - return `railgun charges +33% slower
+100% harpoon density and damage` + return `0.66x railgun charge rate
2x harpoon density and damage` }, isGunTech: true, maxCount: 3, @@ -7076,52 +6975,6 @@ const tech = { } } }, - // { - // name: "grappling hook", - // description: `harpoons attach to the map and pull you
your rope extends while holding fire`, - // isGunTech: true, - // maxCount: 1, - // count: 0, - // frequency: 2, - // frequencyDefault: 2, - // allowed() { - // return tech.haveGunCheck("harpoon") && !tech.isFilament && !tech.isHarpoonPowerUp && !tech.isRailGun && !tech.isFireMoveLock - // }, - // requires: "harpoon, not railgun, UHMWPE, induction furnace, Higgs mechanism", - // effect() { - // tech.isGrapple = true; - // for (i = 0, len = b.guns.length; i < len; i++) { //find which gun - // if (b.guns[i].name === "harpoon") b.guns[i].chooseFireMethod() - // } - // }, - // remove() { - // if (tech.isGrapple) { - // tech.isGrapple = false; - // for (i = 0, len = b.guns.length; i < len; i++) { //find which gun - // if (b.guns[i].name === "harpoon") b.guns[i].chooseFireMethod() - // } - // } - // } - // }, - // { - // name: "bulk modulus", - // description: `while grappling become invulnerable
drain energy`, - // isGunTech: true, - // maxCount: 1, - // count: 0, - // frequency: 2, - // frequencyDefault: 2, - // allowed() { - // return tech.haveGunCheck("harpoon") && !tech.isRailEnergy - // }, - // requires: "not alternator", - // effect() { - // tech.isImmuneGrapple = true; - // }, - // remove() { - // tech.isImmuneGrapple = false - // } - // }, { name: "alternator", description: "harpoon no longer uses any energy", @@ -7163,7 +7016,7 @@ const tech = { { name: "Bessemer process", descriptionFunction() { - return `+${(10 * Math.sqrt(b.guns[9].ammo)).toFixed(0)}% harpoon size and damage
(effect scales by 1/10 √ harpoon ammo)` + return `${(1 + 0.1 * Math.sqrt(b.guns[9].ammo)).toFixed(2)}x harpoon size and damage
(effect scales by 1/10 √ harpoon ammo)` }, isGunTech: true, maxCount: 1, @@ -7229,7 +7082,7 @@ const tech = { { name: "UHMWPE", descriptionFunction() { - return `+${(b.guns[9].ammo * 1.25).toFixed(0)}% harpoon rope length
(effect scales by 1/80 of harpoon ammo)` + return `${(1 + b.guns[9].ammo * 0.0125).toFixed(2)}x harpoon rope length
(effect scales by 1/80 of harpoon ammo)` }, isGunTech: true, maxCount: 1, @@ -7249,7 +7102,7 @@ const tech = { }, { name: "induction furnace", - description: "after using harpoon/grapple to collect power ups
+77% harpoon or grapple damage for 8 seconds", + description: "after using harpoon/grapple to collect power ups
1.8x harpoon or grapple damage for 8 seconds", isGunTech: true, maxCount: 1, count: 0, @@ -7269,7 +7122,7 @@ const tech = { }, { name: "brittle", - description: "+111% harpoon/grapple damage
to mobs at maximum health", + description: "2.2x harpoon/grapple damage
to mobs at maximum durability", isGunTech: true, maxCount: 1, count: 0, @@ -7289,7 +7142,7 @@ const tech = { { name: "quasiparticles", descriptionFunction() { - return `convert current and future ${powerUps.orb.ammo(1)} into ${powerUps.orb.boost(1)} which
give +${(powerUps.boost.damage * 100).toFixed(0)}% damage for ${(powerUps.boost.duration / 60).toFixed(0)} seconds` + return `convert current and future ${powerUps.orb.ammo(1)} into ${powerUps.orb.boost(1)}
that give ${(1 + powerUps.boost.damage).toFixed(2)}x damage for ${(powerUps.boost.duration / 60).toFixed(0)} seconds` }, isGunTech: true, maxCount: 1, @@ -7398,8 +7251,7 @@ const tech = { }, { name: "iridescence", - // description: "if a laser hits a mob at a low angle of illumination
+66% laser damage", - description: "if laser beams hit mobs near their center
+100% laser damage", + description: "if laser beams hit mobs near their center
2x laser damage", isGunTech: true, maxCount: 9, count: 0, @@ -7418,7 +7270,7 @@ const tech = { }, { name: "lens", - description: "+150% laser gun damage if it passes
through a revolving 90° arc circular lens", //π / 2
+ description: "2.5x laser gun damage if it passes
through a revolving 90° arc circular lens", //π / 2
isGunTech: true, maxCount: 1, count: 0, @@ -7443,7 +7295,7 @@ const tech = { }, { name: "compound lens", - description: "+40% laser lens damage
+25° lens arc", + description: "1.4x laser lens damage
+25° lens arc", isGunTech: true, maxCount: 9, count: 0, @@ -7507,7 +7359,7 @@ const tech = { { name: "diffuse beam", link: `diffuse beam`, - description: "laser gun beam is wider and doesn't reflect
+220% laser damage", + description: "laser gun beam is wider and doesn't reflect
3.2x laser damage", isGunTech: true, maxCount: 1, count: 0, @@ -7532,7 +7384,7 @@ const tech = { }, { name: "output coupler", - description: "+30% laser gun beam width
+30% laser damage", + description: "1.3x laser gun beam width
1.3x laser damage", isGunTech: true, maxCount: 9, count: 0, @@ -7557,7 +7409,7 @@ const tech = { }, { name: "slow light", - description: "laser gun beam is spread into your recent past
+300% total beam damage", + description: "laser gun beam is spread into your recent past
4x full beam damage", isGunTech: true, maxCount: 9, count: 0, @@ -7581,7 +7433,7 @@ const tech = { }, { name: "infrared diode", - description: "+60% laser energy efficiency
infrared light is outside visual perception", + description: "0.4x laser energy cost
infrared light is outside visual perception", isGunTech: true, maxCount: 1, count: 0, @@ -7604,7 +7456,7 @@ const tech = { }, { name: "dye laser", - description: "+25% laser energy efficiency
+25% laser damage", + description: "0.75x laser energy cost
1.25x laser damage", isGunTech: true, maxCount: 1, count: 0, @@ -7629,7 +7481,7 @@ const tech = { }, { name: "free-electron laser", - description: "–250% laser energy efficiency
+200% laser damage", + description: "3.5x laser energy cost
3x laser damage", isGunTech: true, maxCount: 1, count: 0, @@ -7640,8 +7492,8 @@ const tech = { }, requires: "laser, not pulse, infrared diode", effect() { - tech.laserDrain *= 1 + 2.5 //250% more drain - tech.laserDamage *= 1 + 2 //190% more damage + tech.laserDrain *= 1 + 2.5 + tech.laserDamage *= 1 + 2 tech.laserColor = "#83f" tech.laserColorAlpha = "rgba(136, 51, 255,0.5)" }, @@ -7681,7 +7533,7 @@ const tech = { //************************************************** { name: "spherical harmonics", - description: "+50% standing wave deflection efficiency
shield deflection radius holds it's max range", //standing wave oscillates in a 3rd dimension
+ description: "1.5x standing wave deflection energy efficiency
shield deflection radius holds it's max range", //standing wave oscillates in a 3rd dimension
isFieldTech: true, maxCount: 9, count: 0, @@ -7773,7 +7625,7 @@ const tech = { { name: "electronegativity", descriptionFunction() { - return `+0.23% damage per current stored energy
(+${(27 * m.maxEnergy).toFixed(0)}% damage at max energy)` + return `1.0023x damage per energy
(${(1 + 0.23 * m.maxEnergy).toFixed(2)}x damage at max energy)` }, // description: "+1% damage per 8 stored energy", isFieldTech: true, @@ -7813,7 +7665,7 @@ const tech = { }, { name: "cherenkov radiation", //deflecting and blocks - description: "bremsstrahlung's effects are radioactive
+250% damage over 3 seconds", + description: "bremsstrahlung's effects are radioactive
3.5x damage over 3 seconds", isFieldTech: true, maxCount: 1, count: 0, @@ -7893,7 +7745,7 @@ const tech = { }, { name: "Meissner effect", - description: "+55% perfect diamagnetism radius
+22° perfect diamagnetism circular arc", + description: "1.55x perfect diamagnetism radius
+22° perfect diamagnetism circular arc", isFieldTech: true, maxCount: 1, count: 0, @@ -7913,9 +7765,8 @@ const tech = { { name: "radiative equilibrium", descriptionFunction() { - return `after losing ${tech.isEnergyHealth ? "energy" : "health"}
+200% damage for 8 seconds` + return `after losing ${tech.isEnergyHealth ? "energy" : "health"}
3x damage for 8 seconds` }, - // description: `after losing ${tech.isEnergyHealth ? "energy" : "health"}
+200% damage for 8 seconds`, isFieldTech: true, maxCount: 1, count: 0, @@ -7935,10 +7786,8 @@ const tech = { { name: "dynamic equilibrium", descriptionFunction() { - // return `increase damage by your defense and
5% of your last ${tech.isEnergyHealth ? "energy" : "health"} loss   (+${(100 * Math.max(5, tech.lastHitDamage) * m.lastHit * (2 - m.defense())).toFixed(0)}% damage)` - return `increase damage by your last ${tech.isEnergyHealth ? "energy" : "health"} loss
scales with defense   (+${(100 * Math.max(5, tech.lastHitDamage) * m.lastHit * (2 - m.defense())).toFixed(0)}% damage)` - }, // = +${10*m.defense()}% - // descriptionFunction() { return `increase damage by your last ${tech.isEnergyHealth ? "energy" : "health"} loss
(${(tech.lastHitDamage).toFixed(0)}%)(${(100*m.lastHit).toFixed(0)} ${tech.isEnergyHealth ? "energy" : "health"})(${2 - m.defense()} defense) = ${(100*tech.lastHitDamage * m.lastHit * (2 - m.defense())).toFixed(0)}% damage ` }, // = +${10*m.defense()}% + return `increase damage by your last ${tech.isEnergyHealth ? "energy" : "health"} loss
(${(1 + tech.lastHitDamage * m.lastHit).toFixed(2)}x damage)` + }, isFieldTech: true, maxCount: 9, count: 0, @@ -7949,7 +7798,7 @@ const tech = { }, requires: "negative mass, pilot wave", effect() { - tech.lastHitDamage += 4; + tech.lastHitDamage += 5; }, remove() { tech.lastHitDamage = 0; @@ -7957,7 +7806,7 @@ const tech = { }, { name: "neutronium", - description: `move and jump 20% slower
if your field is active +95% defense`, + description: `move and jump 20% slower
if your field is active 0.05x damage taken`, isFieldTech: true, maxCount: 1, count: 0, @@ -7985,7 +7834,7 @@ const tech = { }, { name: "aerostat", - description: `+100% damage while off the ground
-15% damage while on the ground`, + description: `2x damage while off the ground
0.85x damage while on the ground`, isFieldTech: true, maxCount: 1, count: 0, @@ -8250,7 +8099,7 @@ const tech = { // }, { name: "additive manufacturing", - description: "hold crouch and use your field to print a block
with +80% density, damage, and launch speed", + description: "hold crouch and use your field to print a block
with 1.8x density, damage, and launch speed", // description: "simultaneously fire and activate your field to make
molecular assembler print a throwable block
+80% block throwing speed", isFieldTech: true, maxCount: 1, @@ -8310,7 +8159,7 @@ const tech = { }, { name: "combinatorial optimization", - description: "+35% damage
–35% fire rate", + description: "1.35x damage
0.65x fire rate", isFieldTech: true, maxCount: 1, count: 0, @@ -8353,7 +8202,7 @@ const tech = { }, { name: "degenerate matter", - description: "if your field is active
+88% defense", + description: "if your field is active
0.1x damage taken", isFieldTech: true, maxCount: 1, count: 0, @@ -8416,7 +8265,7 @@ const tech = { { name: "plasma jet", link: `plasma jet`, - description: `use ${powerUps.orb.research(2)}
+50% plasma torch range`, + description: `use ${powerUps.orb.research(2)}
1.5x plasma torch range`, isFieldTech: true, maxCount: 1, count: 0, @@ -8439,7 +8288,7 @@ const tech = { }, { name: "extruder", - description: "extrude a thin hot wire of plasma
increases damage and energy drain", + description: "extrude a thin hot wire of plasma
increases damage and energy cost", isFieldTech: true, maxCount: 1, count: 0, @@ -8479,7 +8328,7 @@ const tech = { }, { name: "plasma ball", - description: "grow an expanding ball of plasma
increases damage and energy drain", + description: "grow an expanding ball of plasma
increases damage and energy cost", isFieldTech: true, maxCount: 1, count: 0, @@ -8541,7 +8390,7 @@ const tech = { }, { name: "frame-dragging", //"non-inertial frame", - description: "when not moving time dilation stops time
+33% defense", + description: "when not moving time dilation stops time
0.6x damage taken", isFieldTech: true, maxCount: 1, count: 0, @@ -8562,7 +8411,7 @@ const tech = { }, { name: "Lorentz transformation", - description: `use ${powerUps.orb.research(3)}
+50% movement, jumping, and fire rate`, + description: `use ${powerUps.orb.research(3)}
1.5x movement, jumping, and fire rate`, isFieldTech: true, maxCount: 1, count: 0, @@ -8589,9 +8438,8 @@ const tech = { }, { name: "time crystals", - // description: "+150% passive energy generation
${}", descriptionFunction() { - return `+150% passive energy generation
(+${(150 * m.fieldRegen * 60).toFixed(1)} energy per second)` + return `2.5x passive energy generation
(+${(150 * m.fieldRegen * 60).toFixed(1)} energy per second)` }, isFieldTech: true, maxCount: 1, @@ -8606,20 +8454,19 @@ const tech = { tech.isTimeCrystals = true m.setFieldRegen() this.descriptionFunction = function () { - return `+150% passive energy generation
(+${(60 * m.fieldRegen * 60).toFixed(1)} energy per second)` + return `2.5x passive energy generation
(+${(60 * m.fieldRegen * 60).toFixed(1)} energy per second)` } }, remove() { tech.isTimeCrystals = false m.setFieldRegen() this.descriptionFunction = function () { - return `+150% passive energy generation
(+${(150 * m.fieldRegen * 60).toFixed(1)} energy per second)` + return `2.5x passive energy generation
(+${(150 * m.fieldRegen * 60).toFixed(1)} energy per second)` } } }, { name: "no-cloning theorem", - // descriptionFunction() { return `+45% chance to duplicate spawned power ups
after a mob dies –2% duplication (${tech.duplicationChance()})` }, description: `+40% chance to duplicate spawned power ups
after a mob dies –1% duplication`, isFieldTech: true, maxCount: 1, @@ -8645,9 +8492,6 @@ const tech = { descriptionFunction() { return `for each mob left alive after you exit a level
there is a 25% chance to spawn a random power up` }, - // descriptionFunction() { - // return `for each mob left alive after you exit a level
` - // }, isFieldTech: true, maxCount: 1, count: 0, @@ -8750,7 +8594,7 @@ const tech = { }, { name: "topological defect", - description: "+111% damage
to mobs at maximum health", + description: "2.1x damage
to mobs at maximum durability", isFieldTech: true, maxCount: 1, count: 0, @@ -8767,25 +8611,6 @@ const tech = { tech.isMobFullHealthCloak = false } }, - // { - // name: "ambush", - // description: "metamaterial cloaking field damage effect
is increased from 333% to 555%", - // isFieldTech: true, - // maxCount: 1, - // count: 0, - // frequency: 2, - // frequencyDefault: 2, - // allowed() { - // return m.fieldMode === 7 - // }, - // requires: "metamaterial cloaking", - // effect() { - // tech.sneakAttackDmg = 6.55 //555% + 100% - // }, - // remove() { - // tech.sneakAttackDmg = 4.33 //333% + 100% - // } - // }, { name: "WIMPs", description: `at the end of each level spawn ${powerUps.orb.research(4)}
and a dangerous particle that slowly chases you`, @@ -8939,7 +8764,7 @@ const tech = { }, { name: "charmed baryons", - description: `–33% movement and jumping
wormholes drain zero energy`, + description: `0.66x movement and jumping
wormholes cost zero energy`, isFieldTech: true, maxCount: 1, count: 0, @@ -8967,7 +8792,7 @@ const tech = { }, { name: "affine connection", - description: "wormholes can tunnel through anything
for +200% energy drain", + description: "wormholes can tunnel through anything
for 2x energy cost", isFieldTech: true, maxCount: 1, count: 0, @@ -9025,7 +8850,7 @@ const tech = { }, { name: "reel", - description: "+400% block collision damage
up to +100 energy after reeling in blocks", + description: "5x block collision damage
up to +100 energy after reeling in blocks", isFieldTech: true, maxCount: 1, count: 0, @@ -9306,7 +9131,7 @@ const tech = { const loop = () => { if ((simulation.isChoosing) && m.alive && !build.isExperimentSelection) { const dmg = Math.floor(27 * Math.random()) * 0.01 - this.text = `+${(dmg * 100).toFixed(0).padStart(2, '0')}% damage` + this.text = `+${(1 + dmg).toFixed(2).padStart(2, '0')}x damage` this.damage = 1 + dmg if (document.getElementById(`damage-JUNK-id${this.id}`)) document.getElementById(`damage-JUNK-id${this.id}`).innerHTML = this.text setTimeout(() => { @@ -9362,7 +9187,7 @@ const tech = { count += 4.5 const waves = 2 * Math.sin(count * 0.0133) + Math.sin(count * 0.013) + 0.5 * Math.sin(count * 0.031) + 0.33 * Math.sin(count * 0.03) this.spawnCount = Math.floor(100 * Math.abs(waves)) - this.text = `spawn ${this.spawnCount.toLocaleString(undefined, { minimumIntegerDigits: 3 })} ${powerUps.orb.boost(1)}
that give +${(powerUps.boost.damage * 100).toFixed(0)}% damage for ${(powerUps.boost.duration / 60).toFixed(0)} seconds` + this.text = `spawn ${this.spawnCount.toLocaleString(undefined, { minimumIntegerDigits: 3 })} ${powerUps.orb.boost(1)}
that give ${(1 + powerUps.boost.damage).toFixed(2)}% damage for ${(powerUps.boost.duration / 60).toFixed(0)} seconds` if (document.getElementById(`boost-JUNK-id${this.id}`)) document.getElementById(`boost-JUNK-id${this.id}`).innerHTML = this.text setTimeout(() => { loop() @@ -9378,7 +9203,7 @@ const tech = { }, { name: "placebo", - description: "+777% damage
+777% defense", + description: "7.77x damage", maxCount: 1, count: 0, frequency: 0, @@ -10865,7 +10690,7 @@ const tech = { }, { name: "expert system", - description: "spawn a tech power up
+64% JUNK to tech pool", + description: "spawn a tech power up
+64% JUNKtech chance", maxCount: 9, count: 0, frequency: 0, @@ -11177,7 +11002,7 @@ const tech = { }, { name: "circular symmetry", - description: "turning the ship rotates the universe instead
+200% damage", + description: "turning the ship rotates the universe instead
2x damage", maxCount: 1, count: 0, frequency: 0, @@ -11603,7 +11428,7 @@ const tech = { }, { name: "beforeunload", - description: "75% of the time when you attempt to exit n-gon
you are prompted to cancel or continue.
Each time you cancel gain +25% damage.", + description: "75% of the time when you attempt to exit n-gon
you are prompted to cancel or continue.
Each time you cancel gain 1.25x damage.", maxCount: 1, count: 0, frequency: 1, @@ -11914,7 +11739,6 @@ const tech = { isBlockStun: null, isStunField: null, isHarmDamage: null, - energyRegen: null, isVacuumBomb: null, renormalization: null, fragments: null, @@ -12096,7 +11920,6 @@ const tech = { isBulletTeleport: null, isResearchBoss: null, isJunkResearch: null, - junkResearchNumber: null, laserColor: null, laserColorAlpha: null, isLongitudinal: null, @@ -12219,4 +12042,5 @@ const tech = { isDamageCooldownTime: null, isPowerUpDamage: null, isExitPrompt: null, + isResearchDamage: null, } \ No newline at end of file diff --git a/todo.txt b/todo.txt index d852bbd..234d30a 100644 --- a/todo.txt +++ b/todo.txt @@ -1,9 +1,19 @@ ******************************************************** NEXT PATCH ************************************************** -bug fix for experiment mode +text rework + most numbers converted from "+50%" to "1.5x" + renamed defense -> damage taken + adjusted about 20 tech to round down or up their values to less decimals + for a few I added research cost or JUNK chance to balance rounding + +new community map soft by Richard0820 +tech: peer review - gain +damage each time you research +self-assembly scales with health not health percent +matter.js engine reverted back to 0.18 (to fix an issue with time dilation) *********************************************************** TODO ***************************************************** +tech - destroys a random tech each new level and gains +damage each time List of ways to break the game CPT + high energy regen @@ -1085,7 +1095,6 @@ possible names for tech holographic - 2-D surface can predict the 3-D space behind it? I think 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 - genetic algorithm metaheuristic - is a higher-level procedure or heuristic designed to find, generate, or select a heuristic (partial search algorithm) that may provide a sufficiently good solution to an optimization problem, especially with incomplete or imperfect information or limited computation capacity stochastic optimization electrostatic discharge