From d68ca6369508d753b311be0ad2ab208b0b0da25c Mon Sep 17 00:00:00 2001 From: landgreen Date: Sat, 20 Nov 2021 09:05:21 -0800 Subject: [PATCH] Occam's razor tech: Occam's razor - remove 50% of your tech and guns; `for each removed get 36% damage tech dormancy removed tech: predator - if you have killed a mob in the last 5 seconds increase damage by 50% and disable energy regen tech: torpor - gives the opposite of it's previous effect if you have NOT killed a mob in the last 5 seconds reduce harm by 72%, else increase it by 10% relativistic momentum - pushes blocks in addition to mobs not much benefit, but it's fun supply chain: still doubles ammo, but now also adds 5% JUNK (yay) it no longer has any tech requirements inductive coupling: 600% -> 700% regen while crouched JUNK tech: density - blocks are 100x times less dense tech descriptions can change their text dynamically now only a few tech are using this option so far --- .DS_Store | Bin 6148 -> 6148 bytes js/bullet.js | 208 +++++++++++++++-- js/index.js | 55 ++--- js/level.js | 43 +++- js/player.js | 8 +- js/powerup.js | 16 +- js/simulation.js | 24 +- js/spawn.js | 13 +- js/tech.js | 575 ++++++++++++++++++++++++----------------------- todo.txt | 68 +++--- 10 files changed, 594 insertions(+), 416 deletions(-) diff --git a/.DS_Store b/.DS_Store index 873fa016dfcd2108b29744a85672585f1205da44..09b7c6843964b6a8fe94277c7323c0ff4ec80a26 100644 GIT binary patch delta 23 ecmZoMXffEJ$;>QkpgCEG*_TP4VRJQerw9N@f(5() delta 23 ecmZoMXffEJ$;>SCMPsrKvoDkEht1W@ogx5Oum@}a diff --git a/js/bullet.js b/js/bullet.js index dfca46a..48a1160 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -741,7 +741,6 @@ const b = { bullet[me].endCycle = simulation.cycle + Math.floor(input.down ? 120 : 80); bullet[me].restitution = 0.4; bullet[me].do = function() { - // console.log(this.mass * 0.0025) this.force.y += this.mass * 0.0025; //extra gravity for harder arcs }; Composite.add(engine.world, bullet[me]); //add bullet to world @@ -1171,6 +1170,150 @@ const b = { } } }, + dart(where, angle = m.angle, size = 0.8) { + //find a target + const closest = { + score: 10000, + position: null + } + for (let i = 0, len = mob.length; i < len; ++i) { + if (mob[i].alive && !mob[i].isBadTarget && Matter.Query.ray(map, where, mob[i].position).length === 0) { + const dot = Vector.dot({ x: Math.cos(angle), y: Math.sin(angle) }, Vector.normalise(Vector.sub(mob[i].position, where))) //the dot product of diff and dir will return how much over lap between the vectors + const dist = Vector.magnitude(Vector.sub(where, mob[i].position)) + // if (dist < closest.score && ((dist > 500 && dot > 0) || (dot > 0.9))) { //target closest mob that player is looking at and isn't too close to target + if (dist < closest.score && dot > 0.9 - 0.0004 * dist) { //target closest mob that player is looking at and isn't too close to target + closest.score = dist + closest.position = mob[i].position + } + } + } + if (!closest.position) { + // const unit = Vector.mult(sub(simulation.mouseInGame, where), 10000) + closest.position = Vector.mult(Vector.sub(simulation.mouseInGame, where), 10000) + } + const me = bullet.length; + bullet[me] = Bodies.fromVertices(where.x, where.y, [{ x: -20 * size, y: 2 * size, index: 0, isInternal: false }, { x: -20 * size, y: -2 * size, index: 1, isInternal: false }, { x: 5 * size, y: -2 * size, index: 4, isInternal: false }, { x: 20 * size, y: 0, index: 3, isInternal: false }, { x: 5 * size, y: 2 * size, index: 4, isInternal: false }], { + cycle: 0, + angle: angle, + friction: 1, + frictionAir: 0.15, + thrustMag: 0.03, + turnRate: 0.15, //0.015 + drawStringControlMagnitude: 3000 + 5000 * Math.random(), + drawStringFlip: (Math.round(Math.random()) ? 1 : -1), + dmg: 7, //damage done in addition to the damage from momentum + classType: "bullet", + endCycle: simulation.cycle + 120, + collisionFilter: { + category: cat.bullet, + mask: tech.isShieldPierce ? cat.body | cat.mob | cat.mobBullet : cat.body | cat.mob | cat.mobBullet | cat.mobShield, + }, + minDmgSpeed: 0, + lookFrequency: Math.floor(7 + Math.random() * 3), + density: 0.001, //0.001 is normal for blocks, 0.005 is normal for harpoon, 0.035 when buffed + beforeDmg(who) { + if (tech.isShieldPierce && who.isShielded) { //disable shields + who.isShielded = false + requestAnimationFrame(() => { who.isShielded = true }); + } + if (tech.fragments) { + b.targetedNail(this.vertices[2], tech.fragments * 4) + this.endCycle = 0; + } + if (!who.isBadTarget) { + this.frictionAir = 0.01 + this.do = this.doNoTargeting + } + }, + onEnd() {}, + doNoTargeting: function() { + // this.force.y += this.mass * 0.001; + if (Matter.Query.collides(this, map).length) { //stick in walls + this.collisionFilter.mask = 0; + Matter.Body.setAngularVelocity(this, 0) + Matter.Body.setVelocity(this, { + x: 0, + y: 0 + }); + this.do = () => { + // if (!Matter.Query.collides(this, map).length) this.force.y += this.mass * 0.001; + } + } + }, + do() { + if (!m.isBodiesAsleep) { + this.cycle++ + // if (this.cycle > 40) { + // this.frictionAir = 0.003 + // this.do = this.doNoTargeting + // } + // if (closest.target) { //rotate towards the target + const face = { x: Math.cos(this.angle), y: Math.sin(this.angle) }; + const vectorGoal = Vector.normalise(Vector.sub(this.position, closest.position)); + const cross = Vector.cross(vectorGoal, face) + if (cross > 0.01) { + Matter.Body.rotate(this, this.turnRate * Math.sqrt(cross)); + } else if (cross < 0.01) { + Matter.Body.rotate(this, -this.turnRate * Math.sqrt(Math.abs(cross))); + } + this.force.x += this.thrustMag * this.mass * Math.cos(this.angle); + this.force.y += this.thrustMag * this.mass * Math.sin(this.angle); + // } + if (Matter.Query.collides(this, map).length) { //stick in walls + this.collisionFilter.mask = 0; + Matter.Body.setAngularVelocity(this, 0) + Matter.Body.setVelocity(this, { + x: 0, + y: 0 + }); + this.do = this.doNoTargeting + } + // else if (!(this.cycle % 2)) { //look for a target if you don't have one + // simulation.drawList.push({ //add dmg to draw queue + // x: this.position.x, + // y: this.position.y, + // radius: 10, + // color: simulation.mobDmgColor, + // time: simulation.drawTime + // }); + // let closest = { + // distance: 2000, + // target: null + // } + // const dir = Vector.normalise(this.velocity) //make a vector for direction of length 1 + // for (let i = 0, len = mob.length; i < len; ++i) { + // if ( + // mob[i].alive && !mob[i].isBadTarget && + // Matter.Query.ray(map, this.position, mob[i].position).length === 0 && //check for map in Line of sight + // Vector.dot(dir, Vector.normalise(Vector.sub(mob[i].position, this.position))) > 0.55 //the dot product of diff and dir will return how much over lap between the vectors + // ) { + // const dist = Vector.magnitude(Vector.sub(this.position, mob[i].position)) + // if (dist < closest.distance) { + // closest.distance = dist + // closest.target = mob[i] + // } + // } + // } + // if (closest.target) { + // target = closest.target + // this.turnRate = 0.05 + // this.frictionAir = 0.8 + // } + // } + } + }, + }); + Matter.Body.setVelocity(bullet[me], { + x: m.Vx / 2 + 40 * Math.cos(bullet[me].angle), + y: m.Vy / 2 + 40 * Math.sin(bullet[me].angle) + }); + // if (!closest.target) { + // bullet[me].frictionAir = 0.002 + // bullet[me].do = bullet[me].doNoTargeting + // } + Composite.add(engine.world, bullet[me]); //add bullet to world + + }, harpoon(where, target, angle = m.angle, harpoonSize = 1, isReturn = false, totalCycles = 15) { const me = bullet.length; const returnRadius = 100 * Math.sqrt(harpoonSize) @@ -1188,13 +1331,13 @@ const b = { endCycle: simulation.cycle + totalCycles * 2.5 + 15, collisionFilter: { category: cat.bullet, - mask: tech.isNeedleShieldPierce ? cat.map | cat.body | cat.mob | cat.mobBullet : cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield, + mask: tech.isShieldPierce ? cat.map | cat.body | cat.mob | cat.mobBullet : cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield, }, minDmgSpeed: 0, lookFrequency: Math.floor(7 + Math.random() * 3), density: tech.harpoonDensity, //0.001 is normal for blocks, 0.005 is normal for harpoon, 0.035 when buffed beforeDmg(who) { - if (tech.isNeedleShieldPierce && who.isShielded) { //disable shields + if (tech.isShieldPierce && who.isShielded) { //disable shields who.isShielded = false requestAnimationFrame(() => { who.isShielded = true }); } @@ -1892,6 +2035,11 @@ const b = { const force = Vector.mult(Vector.normalise(Vector.sub(path[index], path[Math.max(0, index - 1)])), 0.006 * push * Math.min(6, best.who.mass)) Matter.Body.applyForce(best.who, path[index], force) } + } else if (tech.isLaserPush && best.who.classType === "body") { + const index = path.length - 1 + Matter.Body.setVelocity(best.who, { x: best.who.velocity.x * 0.94, y: best.who.velocity.y * 0.94 }); + const force = Vector.mult(Vector.normalise(Vector.sub(path[index], path[Math.max(0, index - 1)])), 0.006 * push * Math.min(6, best.who.mass)) + Matter.Body.applyForce(best.who, path[index], force) } }; const reflection = function() { // https://math.stackexchange.com/questions/13261/how-to-get-a-reflection-vector @@ -1923,7 +2071,7 @@ const b = { }; damage *= reflectivity laserHitMob(); - //I'm not clear on how this works, but it gets ride of a bug where the laser reflects inside a block, often vertically. + //I'm not clear on how this works, but it gets rid of a bug where the laser reflects inside a block, often vertically. //I think it checks to see if the laser is reflecting off a different part of the same block, if it is "inside" a block if (i % 2) { if (lastBestOdd === best.who) break @@ -2487,7 +2635,7 @@ const b = { //total 0.24 + 0.3 average dmg: 0.34 + 0.12 * tech.isDroneTeleport + 0.15 * tech.isDroneFastLook, //damage done in addition to the damage from momentum lookFrequency: (tech.isDroneFastLook ? 20 : 70) + Math.floor(17 * Math.random()), - endCycle: simulation.cycle + Math.floor((950 + 400 * Math.random()) * tech.isBulletsLastLonger * tech.droneCycleReduction) + 5 * RADIUS + Math.max(0, 150 - b.length), + endCycle: simulation.cycle + Math.floor((950 + 400 * Math.random()) * tech.isBulletsLastLonger * tech.droneCycleReduction) + 5 * RADIUS + Math.max(0, 150 - bullet.length), classType: "bullet", collisionFilter: { category: cat.bullet, @@ -2507,7 +2655,6 @@ const b = { b.drone({ x: m.pos.x + 30 * (Math.random() - 0.5), y: m.pos.y + 30 * (Math.random() - 0.5) }, 5) bullet[bullet.length - 1].endCycle = Infinity } else { - this.endCycle -= max } } else { @@ -2692,7 +2839,7 @@ const b = { restitution: 0.4 + 0.199 * Math.random(), dmg: 0, //0.24 damage done in addition to the damage from momentum and radiation lookFrequency: 120 + Math.floor(23 * Math.random()), - endCycle: simulation.cycle + Math.floor((900 + 110 * Math.random()) * tech.isBulletsLastLonger / tech.droneRadioDamage) + 5 * RADIUS + Math.max(0, 150 - 2 * b.length), + endCycle: simulation.cycle + Math.floor((900 + 110 * Math.random()) * tech.isBulletsLastLonger / tech.droneRadioDamage) + 5 * RADIUS + Math.max(0, 150 - 2 * bullet.length), classType: "bullet", collisionFilter: { category: cat.bullet, @@ -3123,7 +3270,7 @@ const b = { needle(angle = m.angle) { const me = bullet.length; bullet[me] = Bodies.rectangle(m.pos.x + 40 * Math.cos(m.angle), m.pos.y + 40 * Math.sin(m.angle), 75, 0.75, b.fireAttributes(angle)); - bullet[me].collisionFilter.mask = tech.isNeedleShieldPierce ? cat.body : cat.body | cat.mobShield + bullet[me].collisionFilter.mask = tech.isShieldPierce ? cat.body : cat.body | cat.mobShield Matter.Body.setDensity(bullet[me], 0.00001); //0.001 is normal bullet[me].endCycle = simulation.cycle + 100; bullet[me].immuneList = [] @@ -3151,7 +3298,7 @@ const b = { dmg *= 0.25 } if (tech.isCrit && who.isStunned) dmg *= 4 - who.damage(dmg, tech.isNeedleShieldPierce); + who.damage(dmg, tech.isShieldPierce); if (who.alive) who.foundPlayer(); simulation.drawList.push({ //add dmg to draw queue x: this.position.x, @@ -4115,6 +4262,8 @@ const b = { } } else if (tech.isRivets) { this.fire = this.fireRivets + } else if (tech.isDarts) { + this.fire = this.fireDarts } else if (tech.isNeedles) { this.fire = this.fireNeedles } else if (tech.nailInstantFireRate) { @@ -4127,6 +4276,22 @@ const b = { }, do() {}, fire() {}, + // for (let i = 0; i < 5; i++) { + // b.dart(where, m.angle + 0.1 * i) + // b.dart(where, m.angle - 0.1 * i) + // } + fireDarts() { + const where = { + x: m.pos.x + 30 * Math.cos(m.angle), + y: m.pos.y + 30 * Math.sin(m.angle) + } + m.fireCDcycle = m.cycle + 10 * b.fireCDscale; // cool down + b.dart(where, m.angle) //+ 0.6 * (Math.random() - 0.5) + // const spread = 0.5 + // b.dart(where, m.angle + spread) + // b.dart(where, m.angle) + // b.dart(where, m.angle - spread) + }, fireRecoilNails() { if (this.nextFireCycle + 1 < m.cycle) this.startingHoldCycle = m.cycle //reset if not constantly firing const CD = Math.max(11 - 0.08 * (m.cycle - this.startingHoldCycle), 1) //CD scales with cycles fire is held down @@ -5172,7 +5337,7 @@ const b = { bullet[me] = Bodies.polygon(m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle), 20, 4.5, b.fireAttributes(dir, false)); b.fireProps(input.down ? 45 : 25, input.down ? 30 : 16, dir, me); //cd , speed Matter.Body.setDensity(bullet[me], 0.000001); - bullet[me].endCycle = simulation.cycle + 480 + Math.max(0, 120 - 2 * b.length); + bullet[me].endCycle = simulation.cycle + 480 + Math.max(0, 120 - 2 * bullet.length); bullet[me].frictionAir = 0; bullet[me].friction = 0.5; bullet[me].radius = 4.5; @@ -5415,6 +5580,7 @@ const b = { const harpoonSize = tech.isLargeHarpoon ? 1 + 0.1 * Math.sqrt(this.ammo) : 1 const totalCycles = 7 * (tech.isFilament ? 1 + 0.01 * Math.min(110, this.ammo) : 1) * Math.sqrt(harpoonSize) if (input.down) { + if (tech.isRailGun) { function pushAway(range) { //push away blocks when firing for (let i = 0, len = mob.length; i < len; ++i) { @@ -5443,7 +5609,7 @@ const b = { const size = 3 + tech.isLargeHarpoon * 0.1 * Math.sqrt(this.ammo) bullet[me] = Bodies.rectangle(0, 0, 0.015, 0.0015, { //start as a small shape that can't even be seen vertexGoal: [{ x: -40 * size, y: 2 * size, index: 0, isInternal: false }, { x: -40 * size, y: -2 * size, index: 1, isInternal: false }, { x: 50 * size, y: -3 * size, index: 3, isInternal: false }, { x: 30 * size, y: 2 * size, index: 4, isInternal: false }], - density: 0.008, //0.001 is normal + density: 0.015, //0.001 is normal restitution: 0, frictionAir: 0, dmg: 0, //damage done in addition to the damage from momentum @@ -5454,17 +5620,18 @@ const b = { }, minDmgSpeed: 5, beforeDmg(who) { - if (who.shield) { + if (tech.isShieldPierce && who.isShielded) { //disable shields + who.isShielded = false + requestAnimationFrame(() => { who.isShielded = true }); + } + if (who.shield && !tech.isShieldPierce) { for (let i = 0, len = mob.length; i < len; i++) { if (mob[i].id === who.shieldTargetID) { //apply some knock back to shield mob before shield breaks Matter.Body.setVelocity(mob[i], Vector.mult(Vector.normalise(this.velocity), 10)); break } } - Matter.Body.setVelocity(this, { - x: -0.4 * this.velocity.x, - y: -0.4 * this.velocity.y - }); + Matter.Body.setVelocity(this, { x: -0.4 * this.velocity.x, y: -0.4 * this.velocity.y }); } else { if (tech.fragments && this.speed > 10) { b.targetedNail(this.position, tech.fragments * 17) @@ -5488,6 +5655,12 @@ const b = { } if ((!input.fire && this.charge > 0.6)) { //fire on mouse release or on low energy + // if (tech.isDarts) { + // for (let i = 0; i < 5; i++) { + // b.dart(where, m.angle + 0.1 * i) + // b.dart(where, m.angle - 0.1 * i) + // } + // } Matter.Body.setVertices(this, this.vertexGoal) //take on harpoon shape m.fireCDcycle = m.cycle + 2; // set fire cool down //normal bullet behavior occurs after firing, overwrites this function @@ -5623,7 +5796,7 @@ const b = { } } else { - // if (true) { + // if (true) { //grappling hook, not working really // if (m.immuneCycle < m.cycle + 60) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage for 30 cycles // b.harpoon(where, closest.target, m.angle, harpoonSize, false, 15) // m.fireCDcycle = m.cycle + 50 * b.fireCDscale; // cool down @@ -5645,7 +5818,6 @@ const b = { } b.harpoon(where, closest.target, m.angle, harpoonSize, false, 15) m.fireCDcycle = m.cycle + 50 * b.fireCDscale; // cool down - // } } } else if (tech.extraHarpoons) { const range = 450 * (tech.isFilament ? 1 + 0.005 * Math.min(110, this.ammo) : 1) diff --git a/js/index.js b/js/index.js index 1062e1e..f89ab9d 100644 --- a/js/index.js +++ b/js/index.js @@ -261,23 +261,21 @@ const build = {
-         ${tech.tech[i].link} ${isCount}${tech.tech[i].description}` +         ${tech.tech[i].link} ${isCount}${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}` } else if (tech.tech[i].isGunTech) { text += `
-         ${tech.tech[i].link} ${isCount}
${tech.tech[i].description}
` +         ${tech.tech[i].link} ${isCount}${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}` } else if (tech.tech[i].isLore) { - text += `
  ${tech.tech[i].name} ${isCount}
${tech.tech[i].description}
` - // } else if (tech.tech[i].isJunk) { - // text += `
  ${tech.tech[i].name} ${isCount}
${tech.tech[i].description}
` + text += `
  ${tech.tech[i].name} ${isCount}
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}
` } else { - text += `
  ${tech.tech[i].link} ${isCount}
${tech.tech[i].description}
` + text += `
  ${tech.tech[i].link} ${isCount}
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}
` } } else if (tech.tech[i].isLost) { - text += `
${tech.tech[i].link}
${tech.tech[i].description}
` + text += `
${tech.tech[i].link}
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}
` } } el = document.getElementById("pause-grid-right") @@ -371,7 +369,7 @@ const build = {
-         ${tech.tech[i].link} ${isCount}${tech.tech[i].description} +         ${tech.tech[i].link} ${isCount}${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description} ` //
//
@@ -384,18 +382,15 @@ const build = {
-         ${tech.tech[i].link} ${isCount}${tech.tech[i].description} +         ${tech.tech[i].link} ${isCount}${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description} ` } else if (tech.tech[i].isJunk) { - // text += `
  ${tech.tech[i].name} ${isCount}
${tech.tech[i].description}
` - techID.innerHTML = `
  ${tech.tech[i].link} ${isCount}
${tech.tech[i].description}` + techID.innerHTML = `
  ${tech.tech[i].link} ${isCount}
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}` } else if (tech.tech[i].isExperimentalMode) { - // techID.innerHTML = `${tech.tech[i].description}` - techID.innerHTML = `
${tech.tech[i].name}
${tech.tech[i].description}` - // text += `
${tech.tech[i].name}
${tech.tech[i].description}` + techID.innerHTML = `
${tech.tech[i].name}
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}` } else { - techID.innerHTML = `
  ${tech.tech[i].link} ${isCount}
${tech.tech[i].description}` + techID.innerHTML = `
  ${tech.tech[i].link} ${isCount}
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}` } //deselect selected tech options if you don't have the tech any more // for example: when bot techs are converted after a bot upgrade tech is taken if (tech.tech[i].count === 0 && techID.classList.contains("build-tech-selected")) techID.classList.remove("build-tech-selected"); @@ -409,7 +404,7 @@ const build = { } else { //disabled color // techID.innerHTML = `
${tech.tech[i].name}
requires: ${tech.tech[i].requires}` // techID.innerHTML = `
${tech.tech[i].name}
requires: ${tech.tech[i].requires}` - techID.innerHTML = `
${tech.tech[i].name}
${tech.tech[i].description}` + techID.innerHTML = `
${tech.tech[i].name}
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}` // console.log(techID) if (!techID.classList.contains("experiment-grid-disabled")) { techID.classList.add("experiment-grid-disabled"); @@ -466,20 +461,12 @@ const build = { if (!tech.tech[i].isExperimentHide) { //&& (!tech.tech[i].isNonRefundable || tech.tech[i].isExperimentalMode)) { if (tech.tech[i].allowed() && (!tech.tech[i].isNonRefundable || tech.tech[i].isExperimentalMode)) { // || tech.tech[i].name === "+1 cardinality") { //|| tech.tech[i].name === "leveraged investment" if (tech.tech[i].isExperimentalMode) { - text += `
${tech.tech[i].name}
${tech.tech[i].description}
` + text += `
${tech.tech[i].name}
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}
` } else { - text += `
  ${tech.tech[i].link}
${tech.tech[i].description}
` + text += `
  ${tech.tech[i].link}
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}
` } } else { - text += `
${tech.tech[i].name}
${tech.tech[i].description}
` - // if (tech.tech[i].isGunTech || tech.tech[i].isFieldTech) { - // text += `
` //built but hidden - // } else { - // text += `
${tech.tech[i].name}
${tech.tech[i].description}
` - // } - // } else if (!tech.tech[i].isGunTech && !tech.tech[i].isFieldTech) { - // text += `
${tech.tech[i].name}
requires: ${tech.tech[i].requires}
` - + text += `
${tech.tech[i].name}
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}
` } } } @@ -570,6 +557,7 @@ const build = { }); }, + hasExperimentalMode: false, startExperiment() { //start playing the game after exiting the experiment menu build.isExperimentSelection = false; spawn.setSpawnList(); //gives random mobs, not starter mobs @@ -597,12 +585,12 @@ const build = { } removeOne(); } - let hasExperimentalMode = false + build.hasExperimentalMode = false if (!simulation.isCheating) { for (let i = 0, len = tech.tech.length; i < len; i++) { if (tech.tech[i].count > 0) { if (tech.tech[i].isExperimentalMode) { - hasExperimentalMode = true + build.hasExperimentalMode = true } else if (!tech.tech[i].isLore) { simulation.isCheating = true; } @@ -610,7 +598,6 @@ const build = { } if (b.inventory.length !== 0 || m.fieldMode !== 0) simulation.isCheating = true; } - if (simulation.isCheating) { //if you are cheating remove any lore you might have gotten lore.techCount = 0; for (let i = 0, len = tech.tech.length; i < len; i++) { @@ -623,9 +610,9 @@ const build = { } else { //if you have no tech (not cheating) remove all power ups that might have spawned from tech for (let i = 0; i < powerUp.length; ++i) Matter.Composite.remove(engine.world, powerUp[i]); powerUp = []; - if (hasExperimentalMode) { - for (let i = 0; i < 7; i++) tech.giveTech("undefined") - } + // if (build.hasExperimentalMode) { + // for (let i = 0; i < 7; i++) tech.giveTech("undefined") + // } } document.body.style.cursor = "none"; document.body.style.overflow = "hidden" @@ -1028,7 +1015,7 @@ window.addEventListener("keydown", function(event) { break case "h": // m.health = Infinity - m.immuneCycle = Infinity + m.immuneCycle = Infinity //you can't take damage // m.energy = Infinity // document.getElementById("health").style.display = "none" // document.getElementById("health-bg").style.display = "none" diff --git a/js/level.js b/js/level.js index 3205728..e2485e0 100644 --- a/js/level.js +++ b/js/level.js @@ -12,14 +12,17 @@ const level = { start() { if (level.levelsCleared === 0) { //this code only runs on the first level // simulation.enableConstructMode() //used to build maps in testing mode + // m.immuneCycle = Infinity //you can't take damage // localSettings.levelsClearedLastGame = 10 // level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why // simulation.isHorizontalFlipped = true // m.setField("molecular assembler") + // b.giveGuns("laser") + // b.giveGuns("nail gun") // b.giveGuns("harpoon") - // tech.giveTech("railgun") - // tech.giveTech("capacitor bank") - // tech.giveTech("half-wave rectifier") + // tech.giveTech("darts") + // tech.giveTech("incendiary ammunition") + // tech.giveTech("relativistic momentum") // for (let i = 0; i < 2; i++) tech.giveTech("refractory metal") // tech.giveTech("antiscience") // for (let i = 0; i < 1; i++) tech.giveTech("reticulum") @@ -211,6 +214,30 @@ const level = { simulation.updateTechHUD(); simulation.clearNow = true; //triggers in simulation.clearMap to remove all physics bodies and setup for new map }, + populateLevels() { + simulation.isHorizontalFlipped = (Math.random() < 0.5) ? true : false //if true, some maps are flipped horizontally + level.levels = level.playableLevels.slice(0) //copy array, not by just by assignment + if (simulation.isCommunityMaps) { + level.levels.push("stronghold"); + level.levels.push("basement"); + level.levels.push("crossfire"); + level.levels.push("vats") + level.levels.push("n-gon") + level.levels.push("house"); + level.levels.push("perplex"); + level.levels.push("coliseum"); + level.levels.push("tunnel"); + level.levels = shuffle(level.levels); //shuffles order of maps + level.levels.splice(0, 9); //remove some random levels to make up for adding the community levels + } else { + level.levels = shuffle(level.levels); //shuffles order of maps + } + if (!build.isExperimentSelection || (build.hasExperimentalMode && !simulation.isCheating)) { //experimental mode is endless, unless you only have an experiment Tech + level.levels.unshift("intro"); //add level to the start of the randomized levels list + level.levels.push("gauntlet"); //add level to the end of the randomized levels list + level.levels.push("final"); //add level to the end of the randomized levels list + } + }, flipHorizontal() { const flipX = (who) => { for (let i = 0, len = who.length; i < len; i++) { @@ -2309,8 +2336,10 @@ const level = { spawn.mapRect(5300, -275, 50, 175); spawn.mapRect(5050, -100, 50, 150); spawn.mapRect(4850, -275, 50, 175); + + //??? level.difficultyIncrease(40) //30 is near max on hard //60 is near max on why - spawn.starter(1900, -500, 200) //big boy + // spawn.starter(1900, -500, 200) //big boy // spawn.spiderBoss(1700, -500) // spawn.launcherBoss(3200, -500) @@ -2324,11 +2353,13 @@ const level = { // spawn.growBossCulture(3200, -500) // spawn.blinkBoss(1700, -500) // spawn.snakeSpitBoss(3200, -500) - // spawn.laserBombingBoss(1700, -500) // spawn.launcherBoss(3200, -500) // spawn.blockBoss(1700, -500) // spawn.slashBoss(3200, -500) + // spawn.spiderBoss(3200, -500) + // spawn.tetherBoss(1700, -500) //go to actual level? + // for (let i = 0; i < 10; ++i) spawn.bodyRect(1600 + 5, -500, 30, 40); // for (let i = 0; i < 5; i++) spawn.focuser(1900, -500) // spawn.slashBoss(1900, -500) @@ -2340,7 +2371,7 @@ const level = { // spawn.blinkBoss(1600, -500) // spawn.laserTargetingBoss(1700, -120) // spawn.bomberBoss(1400, -500) - // spawn.laser(1800, -120) + spawn.laser(1800, -320) // spawn.laserBombingBoss(1600, -500) // spawn.laserTargetingBoss(1600, -500) // spawn.laserBoss(1600, -500) diff --git a/js/player.js b/js/player.js index 91eaca3..1ae9455 100644 --- a/js/player.js +++ b/js/player.js @@ -325,7 +325,9 @@ const m = { !tech.tech[i].isNonRefundable && tech.tech[i].name !== "many-worlds" && tech.tech[i].name !== "Ψ(t) collapse" && - tech.tech[i].name !== "non-unitary operator" + tech.tech[i].name !== "non-unitary operator" && + tech.tech[i].name !== "-quantum leap-" + ) { totalTech += tech.tech[i].count tech.tech[i].remove(); @@ -504,7 +506,7 @@ const m = { if (tech.isFieldHarmReduction) dmg *= 0.5 if (tech.isHarmMACHO) dmg *= 0.33 if (tech.isImmortal) dmg *= 0.66 - if (tech.isHarmReduceAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 0.33 : 1.15 + if (tech.isHarmReduceNoKill) dmg *= (m.lastKillCycle + 300 < m.cycle) ? 0.28 : 1.1 if (tech.healthDrain) dmg *= 1 + 3.33 * tech.healthDrain //tech.healthDrain = 0.03 at one stack //cause more damage if (tech.squirrelFx !== 1) dmg *= 1 + (tech.squirrelFx - 1) / 5 //cause more damage if (tech.isAddBlockMass && m.isHolding) dmg *= 0.15 @@ -2819,7 +2821,7 @@ const m = { // body[i].force.y -= body[i].mass * simulation.g; //remove gravity effects //blocks drift towards center of pilot wave const sub = Vector.sub(m.fieldPosition, body[i].position) - const push = Vector.mult(Vector.normalise(sub), 0.0007 * body[i].mass * Vector.magnitude(sub)) + const push = Vector.mult(Vector.normalise(sub), 0.0001 * body[i].mass * Vector.magnitude(sub)) body[i].force.x += push.x body[i].force.y += push.y - body[i].mass * simulation.g //remove gravity effects // if (body[i].collisionFilter.category !== cat.bullet) { diff --git a/js/powerup.js b/js/powerup.js index e8b91c1..1f5c936 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -335,9 +335,9 @@ const powerUps = { } }, delay); } - for (let i = 0, len = tech.tech.length; i < len; i++) { - if (tech.tech[i].name === "bot fabrication") tech.tech[i].description = `if you collect ${powerUps.orb.research(2 + Math.floor(0.2 * b.totalBots()))}use them to build a
random bot (+1 cost every 5 bots)` - } + // for (let i = 0, len = tech.tech.length; i < len; i++) { + // if (tech.tech[i].name === "bot fabrication") tech.tech[i].description = `if you collect ${powerUps.orb.research(2 + Math.floor(0.2 * b.totalBots()))}use them to build a
random bot (+1 cost every 5 bots)` + // } } if (tech.isDeathAvoid && document.getElementById("tech-anthropic")) { document.getElementById("tech-anthropic").innerHTML = `-${powerUps.research.count}` @@ -643,20 +643,20 @@ const powerUps = {
-         ${tech.tech[choose].name} ${isCount}${tech.tech[choose].description}` +         ${tech.tech[choose].name} ${isCount}${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() :tech.tech[choose].description}` } else if (tech.tech[choose].isGunTech) { text += `
-         ${tech.tech[choose].name} ${isCount}
${tech.tech[choose].description}
` +         ${tech.tech[choose].name} ${isCount}${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() :tech.tech[choose].description}` } else if (tech.tech[choose].isLore) { - text += `
  ${tech.tech[choose].name} ${isCount}
${tech.tech[choose].description}
` + text += `
  ${tech.tech[choose].name} ${isCount}
${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}
` } else if (tech.tech[choose].isJunk) { - text += `
  ${tech.tech[choose].name} ${isCount}
${tech.tech[choose].description}
` + text += `
  ${tech.tech[choose].name} ${isCount}
${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}
` } else { - text += `
  ${tech.tech[choose].name} ${isCount}
${tech.tech[choose].description}
` + text += `
  ${tech.tech[choose].name} ${isCount}
${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}
` } // text += `
  ${tech.tech[choose].name}
${tech.tech[choose].description}
` diff --git a/js/simulation.js b/js/simulation.js index 672aec1..56b5269 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -616,28 +616,7 @@ const simulation = { Composite.add(engine.world, [player]) } - simulation.isHorizontalFlipped = (Math.random() < 0.5) ? true : false //if true, some maps are flipped horizontally - level.levels = level.playableLevels.slice(0) //copy array, not by just by assignment - if (simulation.isCommunityMaps) { - level.levels.push("stronghold"); - level.levels.push("basement"); - level.levels.push("crossfire"); - level.levels.push("vats") - level.levels.push("n-gon") - level.levels.push("house"); - level.levels.push("perplex"); - level.levels.push("coliseum"); - level.levels.push("tunnel"); - level.levels = shuffle(level.levels); //shuffles order of maps - level.levels.splice(0, 9); //remove some random levels to make up for adding the community levels - } else { - level.levels = shuffle(level.levels); //shuffles order of maps - } - if (!build.isExperimentSelection) { //experimental mode is endless - level.levels.unshift("intro"); //add level to the start of the randomized levels list - level.levels.push("gauntlet"); //add level to the end of the randomized levels list - level.levels.push("final"); //add level to the end of the randomized levels list - } + level.populateLevels() input.endKeySensing(); b.removeAllGuns(); @@ -736,6 +715,7 @@ const simulation = { } simulation.isCheating = false simulation.firstRun = false; + build.hasExperimentalMode = false build.isExperimentSelection = false; build.isExperimentRun = false; diff --git a/js/spawn.js b/js/spawn.js index c6aca3c..8471eb1 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -1710,7 +1710,7 @@ const spawn = { Composite.add(engine.world, cons[cons.length - 1]); cons[len2].length = 100 + 1.5 * radius; me.cons2 = cons[len2]; - me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) //normal is 1, most bosses have 0.25 + me.damageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) //normal is 1, most bosses have 0.25 me.do = function() { // this.armor(); this.gravity(); @@ -1733,11 +1733,12 @@ const spawn = { for (let i = 0; i < nodes; ++i) { spawn.stabber(x + sideLength * Math.sin(i * angle), y + sideLength * Math.cos(i * angle), radius, 12); - Matter.Body.setDensity(mob[mob.length - 1], 0.004); //extra dense //normal is 0.001 //makes effective life much larger + Matter.Body.setDensity(mob[mob.length - 1], 0.003); //extra dense //normal is 0.001 //makes effective life much larger + mob[mob.length - 1].damageReduction = 0.5 targets.push(mob[mob.length - 1].id) //track who is in the node boss, for shields } - const attachmentStiffness = 0.05 + const attachmentStiffness = 0.02 spawn.constrain2AdjacentMobs(nodes, attachmentStiffness, true); //loop mobs together for (let i = 0; i < nodes; ++i) { //attach to center mob @@ -1745,7 +1746,7 @@ const spawn = { bodyA: me, bodyB: mob[mob.length - i - 1], stiffness: attachmentStiffness, - damping: 0.01 + damping: 0.03 }); Composite.add(engine.world, consBB[consBB.length - 1]); } @@ -2942,9 +2943,9 @@ const spawn = { Matter.Body.rotate(me, 2 * Math.PI * Math.random()); me.accelMag = 0.00038 * Math.sqrt(simulation.accelScale); me.frictionAir = 0.01; - me.swordRadiusMax = 450 + 7 * simulation.difficulty; + me.swordRadiusMax = 500 + 8 * simulation.difficulty; me.laserAngle = 0; - me.swordDamage = 0.0015 * simulation.dmgScale + me.swordDamage = 0.002 * simulation.dmgScale spawn.shield(me, x, y, 1); Matter.Body.setDensity(me, 0.005); //extra dense //normal is 0.001 //makes effective life much larger diff --git a/js/tech.js b/js/tech.js index 9d13143..9c8b1d8 100644 --- a/js/tech.js +++ b/js/tech.js @@ -51,6 +51,7 @@ } if (!found) return 0 //if name not found don't remove any tech } + if (tech.tech[index].count === 0) return 0 const totalRemoved = tech.tech[index].count simulation.makeTextLog(`tech.removeTech("${tech.tech[index].name}")`) tech.tech[index].remove(); @@ -156,14 +157,14 @@ simulation.updateTechHUD(); } }, - setTechoNonRefundable(name) { - for (let i = 0; i < tech.tech.length; i++) { - if (tech.tech.name === name) { - tech.tech[i].isNonRefundable = true; - return - } - } - }, + // setTechoNonRefundable(name) { + // for (let i = 0; i < tech.tech.length; i++) { + // if (tech.tech.name === name) { + // tech.tech[i].isNonRefundable = true; + // return + // } + // } + // }, setCheating() { if (!simulation.isCheating) { simulation.isCheating = true; @@ -208,10 +209,10 @@ }, damageFromTech() { let dmg = 1 //m.fieldDamage + if (tech.OccamDamage) dmg *= tech.OccamDamage if (tech.isCloakingDamage) dmg *= 1.35 if (tech.isFlipFlopDamage && tech.isFlipFlopOn) dmg *= 1.5 if (tech.isAnthropicDamage && tech.isDeathAvoidedThisLevel) dmg *= 2.3703599 - if (tech.isDamageAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 2 : 0.72 if (m.isSneakAttack && m.cycle > m.lastKillCycle + 240) dmg *= tech.sneakAttackDmg if (tech.isTechDamage) dmg *= 1.9 if (tech.isDupDamage) dmg *= 1 + Math.min(1, tech.duplicationChance()) @@ -231,6 +232,7 @@ if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 2 if (tech.isSpeedDamage) dmg *= 1 + Math.min(0.66, player.speed * 0.0165) if (tech.isBotDamage) dmg *= 1 + 0.07 * b.totalBots() + if (tech.isDamageAfterKillNoRegen && m.lastKillCycle + 300 > m.cycle) dmg *= 1.5 return dmg * tech.slowFire * tech.aimDamage }, duplicationChance() { @@ -338,6 +340,9 @@ }, { name: "arsenal", + // descriptionFunction() { + // return `increase damage by ${14 * b.inventory.length}%
14% for each gun in your inventory` + // }, description: "increase damage by 14%
for each gun in your inventory", maxCount: 1, count: 0, @@ -463,22 +468,33 @@ }, requires: "NOT EXPERIMENT MODE, at least 2 guns", effect() { - for (let i = 0; i < b.inventory.length; i++) { + for (let i = b.inventory.length - 1; i > -1; i--) { //spawn a research for each gun powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false); //find a gun tech for this gun const gunTechPool = [] - for (let j = 0; j < tech.tech.length; j++) { + for (let j = 0, len = tech.tech.length; j < len; j++) { + // console.log(j, tech.tech[j].isGunTech, tech.tech[j].allowed(), !tech.tech[j].isJunk, !tech.tech[j].isBadRandomOption, tech.tech[j].count < tech.tech[j].maxCount) + //set current gun to active so allowed works + const originalActiveGunIndex = b.activeGun + b.activeGun = b.inventory[i] //to make the .allowed work for guns that aren't active if (tech.tech[j].isGunTech && tech.tech[j].allowed() && !tech.tech[j].isJunk && !tech.tech[j].isBadRandomOption && tech.tech[j].count < tech.tech[j].maxCount) { const regex = tech.tech[j].requires.search(b.guns[b.inventory[i]].name) //get string index of gun name const not = tech.tech[j].requires.search(' not ') //get string index of ' not ' //look for the gun name in the requirements, but the gun name needs to show up before the word ' not ' - if (regex !== -1 && (not === -1 || not > regex)) gunTechPool.push(j) - // console.log(gunName, regex, not, tech.tech[j].name) + if (regex !== -1 && (not === -1 || not > regex)) { + gunTechPool.push(j) + } } + b.activeGun = originalActiveGunIndex + } + if (gunTechPool.length) { + const index = Math.floor(Math.random() * gunTechPool.length) + tech.giveTech(gunTechPool[index]) // choose from the gun pool + simulation.makeTextLog(`tech.giveTech("${tech.tech[gunTechPool[index]].name}")`) } - if (gunTechPool.length) tech.giveTech(gunTechPool[Math.floor(Math.random() * gunTechPool.length)]) // choose from the gun pool } + simulation.boldActiveGunHUD(); }, remove() {} }, @@ -502,21 +518,22 @@ }, { name: "supply chain", - description: "double your current ammo for all guns", + junk: 0.05, + descriptionFunction() { return `double your current ammo for all guns
+${this.junk*100}% JUNK to the potential tech pool` }, maxCount: 9, count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return tech.isAmmoForGun - }, - requires: "logistics", + frequency: 1, + frequencyDefault: 1, + allowed() { return true }, + requires: "", effect() { for (let i = 0; i < b.guns.length; i++) { if (b.guns[i].have) b.guns[i].ammo = Math.floor(2 * b.guns[i].ammo) } simulation.makeGunHUD(); + this.refundAmount += tech.addJunkTechToPool(this.junk) }, + refundAmount: 0, remove() { for (let j = 0; j < this.count; j++) { for (let i = 0; i < b.guns.length; i++) { @@ -524,6 +541,10 @@ } } simulation.makeGunHUD(); + if (this.count > 0 && this.refundAmount > 0) { + tech.removeJunkTechFromPool(this.refundAmount) + this.refundAmount = 0 + } } }, { @@ -567,30 +588,20 @@ { name: "desublimated ammunition", link: `desublimated ammunition`, - description: `use ${powerUps.orb.research(1)} to produce bullets from air molecules
every other crouched shot uses no ammo`, + description: `produce bullets from air molecules
every other crouched shot uses no ammo`, maxCount: 1, count: 0, frequency: 1, frequencyDefault: 1, allowed() { - return build.isExperimentSelection || powerUps.research.count > 0 + return build.isExperimentSelection }, requires: "", effect() { tech.isCrouchAmmo = true - for (let i = 0; i < 1; i++) { - if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) - } - // this.refundAmount += tech.addJunkTechToPool(0.06) }, - // refundAmount: 0, remove() { tech.isExtraChoice = false; - if (this.count > 0) powerUps.research.changeRerolls(1) - // if (this.count > 0 && this.refundAmount > 0) { - // tech.removeJunkTechFromPool(this.refundAmount) - // this.refundAmount = 0 - // } } }, { @@ -618,9 +629,7 @@ count: 0, frequency: 1, frequencyDefault: 1, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect: () => { tech.restDamage += 0.36 @@ -660,9 +669,7 @@ count: 0, frequency: 1, frequencyDefault: 1, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { // good with melee builds, content skipping builds tech.squirrelFx += 0.25; @@ -700,9 +707,7 @@ count: 0, frequency: 1, frequencyDefault: 1, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { tech.isSpeedDamage = true //max at speed = 40 @@ -718,9 +723,7 @@ count: 0, frequency: 1, frequencyDefault: 1, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { tech.isFarAwayDmg = true; //used in mob.damage() @@ -736,9 +739,7 @@ count: 0, frequency: 1, frequencyDefault: 1, - allowed() { - return true - }, + allowed() { return true }, effect() { tech.slowFire = 1.2 b.setFireCD(); @@ -755,9 +756,7 @@ count: 0, frequency: 1, frequencyDefault: 1, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { tech.fireRate *= 0.7 @@ -795,9 +794,7 @@ count: 0, frequency: 1, frequencyDefault: 1, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { tech.isDamageFromBulletCount = true @@ -809,7 +806,8 @@ { name: "anti-shear topology", link: `anti-shear topology`, - description: "some projectiles last 30% longer
drones, spores, missiles, foam, wave, neutron", + description: "some projectiles last 30% longer
drone, spore, missile, foam, wave, neutron, ice", + // isGunTech: true, maxCount: 3, count: 0, @@ -1081,12 +1079,11 @@ requires: "no other mob death tech", effect() { tech.sporesOnDeath += 0.11; - if (tech.isSporeWorm) { - for (let i = 0; i < 4; i++) b.worm(m.pos) - - } else { - for (let i = 0; i < 8; i++) b.spore(m.pos) - } + // if (tech.isSporeWorm) { + // for (let i = 0; i < 4; i++) b.worm(m.pos) + // } else { + // for (let i = 0; i < 8; i++) b.spore(m.pos) + // } }, remove() { tech.sporesOnDeath = 0; @@ -1201,9 +1198,7 @@ frequencyDefault: 1, isBot: true, isBotTech: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { tech.nailBotCount++; @@ -1259,9 +1254,7 @@ frequencyDefault: 1, isBot: true, isBotTech: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { tech.foamBotCount++; @@ -1317,9 +1310,7 @@ frequencyDefault: 1, isBot: true, isBotTech: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { tech.boomBotCount++; @@ -1433,9 +1424,7 @@ frequencyDefault: 1, isBot: true, isBotTech: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { b.orbitBot(); @@ -1500,9 +1489,7 @@ frequencyDefault: 1, isBot: true, isBotTech: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { tech.dynamoBotCount++; @@ -1551,8 +1538,10 @@ { name: "bot fabrication", link: `bot fabrication`, - //-----------description is overwritten in powerUps.research.changeRerolls------------ - description: `if you collect ${powerUps.orb.research(2)}use them to build a
random bot (+1 cost every 5 bots)`, + descriptionFunction() { + return `if you collect ${powerUps.orb.research(2 + Math.floor(0.2 * b.totalBots()))}use them to build a
random bot (+1 cost every 5 bots)` + }, + // description: `if you collect ${powerUps.orb.research(2)}use them to build a
random bot (+1 cost every 5 bots)`, maxCount: 1, count: 0, frequency: 2, @@ -1569,7 +1558,7 @@ }, remove() { tech.isRerollBots = false; - this.description = `if you collect ${powerUps.orb.research(2 + Math.floor(0.2 * b.totalBots()))}use them to build a
random bot (+1 cost every 5 bots)` + // this.description = `if you collect ${powerUps.orb.research(2 + Math.floor(0.2 * b.totalBots()))}use them to build a
random bot (+1 cost every 5 bots)` } }, { @@ -1701,7 +1690,8 @@ }, { name: "capacitor bank", - description: "charge effects build up almost instantly
throwing blocks, foam, railgun, pulse, tokamak", + // description: "charge effects build up almost instantly
throwing blocks, foam, railgun, pulse, tokamak", + descriptionFunction() { return `charge effects build up almost instantly
throwing blocks, ${tech.haveGunCheck("foam", false)?"foam" :"foam"}, ${tech.isRailGun?"railgun" :"railgun"}, ${tech.isPulseLaser?"pulse" :"pulse"}, ${tech.isTokamak?"tokamak" :"tokamak"}` }, maxCount: 1, count: 0, frequency: 2, @@ -1851,9 +1841,7 @@ count: 0, frequency: 1, frequencyDefault: 1, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { tech.collisionImmuneCycles += 60; @@ -2163,9 +2151,7 @@ count: 0, frequency: 1, frequencyDefault: 1, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { tech.isImmortal = true; @@ -2380,6 +2366,7 @@ simulation.mobDmgColor = "rgba(255,0,0,0.7)" m.displayHealth(); } + tech.isEnergyHealth = false; } }, { @@ -2453,9 +2440,7 @@ count: 0, frequency: 1, frequencyDefault: 1, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect: () => { tech.isEnergyDamage = true @@ -2471,9 +2456,7 @@ count: 0, frequency: 1, frequencyDefault: 1, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { tech.isEnergyNoAmmo = true; @@ -2489,9 +2472,7 @@ count: 0, frequency: 1, frequencyDefault: 1, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { tech.isEnergyLoss = true; @@ -2545,9 +2526,7 @@ count: 0, frequency: 1, frequencyDefault: 1, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { tech.bonusEnergy += 0.6 @@ -2590,19 +2569,19 @@ }, { name: "inductive coupling", - description: "passive energy regen is increased by 600%
but you only regen when crouched", + description: "passive energy regen is increased by 700%
but you only regen when crouched", maxCount: 1, count: 0, frequency: 1, frequencyDefault: 1, allowed() { - return tech.energyRegen !== 0 + return tech.energyRegen !== 0 && !tech.isDamageAfterKillNoRegen }, - requires: "not ground state", + requires: "not ground state, apex predator", effect() { tech.isCrouchRegen = true; //only used to check for requirements m.regenEnergy = function() { - if (m.immuneCycle < m.cycle && m.crouch) m.energy += 6 * m.fieldRegen; //m.fieldRegen = 0.001 + if (m.immuneCycle < m.cycle && m.crouch) m.energy += 7 * m.fieldRegen; //m.fieldRegen = 0.001 if (m.energy < 0) m.energy = 0 } }, @@ -2618,9 +2597,7 @@ count: 0, frequency: 1, frequencyDefault: 1, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { tech.energySiphon += 0.05; @@ -2636,9 +2613,7 @@ count: 0, frequency: 1, frequencyDefault: 1, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { tech.isEnergyRecovery = true; @@ -2667,39 +2642,42 @@ } }, { - name: "dormancy", - description: "if a mob has died in the last 5 seconds
increase damage by 100% else decrease it by 28%", + name: "predator", + description: "if a mob has died in the last 5 seconds
increase damage 50% and inhibit energy regen", + maxCount: 1, + count: 0, + frequency: 1, + frequencyDefault: 1, + allowed() { return !tech.isCrouchRegen }, + requires: "not inductive coupling", + effect() { + tech.isDamageAfterKillNoRegen = true; + m.regenEnergy = function() { + if (m.immuneCycle < m.cycle && (m.lastKillCycle + 300 < m.cycle)) m.energy += m.fieldRegen; //m.fieldRegen = 0.001 + if (m.energy < 0) m.energy = 0 + } + }, + remove() { + if (this.count) m.regenEnergy = m.regenEnergyDefault + tech.isDamageAfterKillNoRegen = false; + } + }, + { + name: "torpor", + description: "if a mob has not died in the last 5 seconds
reduce harm by 72% else increase it by 10%", maxCount: 1, count: 0, frequency: 1, frequencyDefault: 1, allowed() { - return true + return !tech.isEnergyHealth }, - requires: "", + requires: "not mass-energy", effect() { - tech.isDamageAfterKill = true; + tech.isHarmReduceNoKill = true; }, remove() { - tech.isDamageAfterKill = false; - } - }, - { - name: "torpor", - description: "if a mob has died in the last 5 seconds
reduce harm by 66% else increase it by 15%", - maxCount: 1, - count: 0, - frequency: 3, - frequencyDefault: 3, - allowed() { - return tech.isDamageAfterKill && !tech.isEnergyHealth - }, - requires: "dormancy, not mass-energy", - effect() { - tech.isHarmReduceAfterKill = true; - }, - remove() { - tech.isHarmReduceAfterKill = false; + tech.isHarmReduceNoKill = false; } }, { @@ -2710,9 +2688,7 @@ count: 0, frequency: 1, frequencyDefault: 1, - allowed() { - return !tech.isEnergyHealth - }, + allowed() { return !tech.isEnergyHealth }, requires: "not mass-energy", effect() { tech.isZeno = true; @@ -2886,9 +2862,7 @@ frequencyDefault: 1, isNonRefundable: true, isBadRandomOption: true, - allowed() { - return true - }, + allowed() { return true }, requires: "NOT EXPERIMENT MODE", effect() { for (let i = 0; i < 11; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "heal"); @@ -3092,7 +3066,7 @@ }, { name: "ansatz", - description: `after choosing a field, tech, or gun
spawn ${powerUps.orb.research(2)}if you have 0 ${powerUps.orb.research(1)} in your inventory`, + description: `after choosing a field, tech, or gun
spawn ${powerUps.orb.research(2)}if you have no ${powerUps.orb.research(1)} in your inventory`, maxCount: 1, count: 0, frequency: 1, @@ -3149,8 +3123,8 @@ description: "remove all current tech
spawn new tech to replace them", maxCount: 1, count: 0, - frequency: 2, - frequencyDefault: 2, + frequency: 1, + frequencyDefault: 1, isNonRefundable: true, isBadRandomOption: true, allowed() { @@ -3177,6 +3151,37 @@ }, remove() {} }, + { + name: "Occam's razor", + descriptionFunction() { + return `randomly remove ${this.removePercent*100}% of your tech
for each removed gain ${this.damagePerRemoved*100}% damage` + }, + maxCount: 1, + count: 0, + frequency: 1, + frequencyDefault: 1, + isNonRefundable: true, + isBadRandomOption: true, + allowed() { + return (tech.totalCount > 6) + }, + requires: "NOT EXPERIMENT MODE, more than 6 tech", + removePercent: 0.5, + damagePerRemoved: 0.36, + effect() { + let pool = [] + for (let i = 0, len = tech.tech.length; i < len; i++) { // spawn new tech power ups + if (tech.tech[i].count && !tech.tech[i].isNonRefundable) pool.push(i) + } + pool = shuffle(pool); //shuffles order of maps + let removeCount = 0 + for (let i = 0, len = pool.length * this.removePercent; i < len; i++) removeCount += tech.removeTech(pool[i]) + tech.OccamDamage = 1 + this.damagePerRemoved * removeCount + }, + remove() { + tech.OccamDamage = 0; + } + }, { name: "abiogenesis", description: `at the start of a level spawn a 2nd boss
use ${powerUps.orb.research(4)}or add 49% JUNK to the tech pool`, @@ -3202,9 +3207,7 @@ count: 0, frequency: 1, frequencyDefault: 1, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { tech.isShieldAmmo = true; @@ -3220,9 +3223,7 @@ count: 0, frequency: 1, frequencyDefault: 1, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { tech.isMetaAnalysis = true @@ -3412,7 +3413,7 @@ if (tech.tech[i].count > 0) have.push(i) } const choose = have[Math.floor(Math.random() * have.length)] - simulation.makeTextLog(`tech.remove("${tech.tech[choose].name}")`) + simulation.makeTextLog(`tech.removeTech("${tech.tech[choose].name}")`) for (let i = 0; i < tech.tech[choose].count; i++) { powerUps.spawn(m.pos.x, m.pos.y, "gun"); } @@ -3618,7 +3619,7 @@ frequency: 1, frequencyDefault: 1, isBadRandomOption: true, - // isNonRefundable: true, + isNonRefundable: true, allowed() { return !tech.isExtraChoice && !tech.isCancelDuplication && !tech.isCancelRerolls }, @@ -3630,20 +3631,21 @@ }, remove() { tech.isDeterminism = false; - if (this.count > 0) { - for (let i = 0; i < 5; i++) { - const numberRemoved = tech.removeTech() - if (numberRemoved === 0) { //if the player didn't remove a power up then remove 1 tech for the map - for (let j = 0; j < powerUp.length; j++) { - if (powerUp[j].name === "tech") { - Matter.Composite.remove(engine.world, powerUp[j]); - powerUp.splice(j, 1); - break; - } - } - } - } - } + // if (this.count > 0) { + // for (let i = 0; i < 5; i++) { + // const numberRemoved = tech.removeTech() + // console.log(numberRemoved) + // if (numberRemoved === 0) { //if the player didn't remove a power up then remove 1 tech for the map + // for (let j = powerUp.length - 1; j > -1; j--) { + // if (powerUp[j].name === "tech") { + // Matter.Composite.remove(engine.world, powerUp[j]); + // powerUp.splice(j, 1); + // break; + // } + // } + // } + // } + // } } }, { @@ -3651,9 +3653,10 @@ description: `spawn 5 tech
${powerUps.orb.research(1)}, guns, and fields no longer spawn`, maxCount: 1, count: 0, - frequency: 5, - frequencyDefault: 5, + frequency: 3, + frequencyDefault: 3, isBadRandomOption: true, + isNonRefundable: true, allowed() { return tech.isDeterminism && !tech.isAnsatz && !tech.isGunSwitchField }, @@ -3665,9 +3668,10 @@ }, remove() { tech.isSuperDeterminism = false; - if (this.count) { - for (let i = 0; i < 5; i++) tech.removeTech() - } + // tech.isSuperDeterminism = false; + // if (this.count) { + // for (let i = 0; i < 5; i++) tech.removeTech() + // } } }, { @@ -3808,10 +3812,10 @@ }, requires: "nail gun, needle gun, needle-shot, harpoon", effect() { - tech.isNeedleShieldPierce = true + tech.isShieldPierce = true }, remove() { - tech.isNeedleShieldPierce = false + tech.isShieldPierce = false } }, { @@ -3853,6 +3857,39 @@ } } }, + // { + // name: "darts", + // description: "nail gun fires firing several self-steering darts", + // isGunTech: true, + // maxCount: 1, + // count: 0, + // frequency: 2, + // frequencyDefault: 2, + // allowed() { + // return tech.haveGunCheck("nail gun") + // }, + // requires: "nail gun", + // effect() { + // tech.isDarts = true; + // for (i = 0, len = b.guns.length; i < len; i++) { //find which gun + // if (b.guns[i].name === "nail gun") { + // b.guns[i].chooseFireMethod() + // break + // } + // } + // }, + // remove() { + // if (tech.isDarts) { + // tech.isDarts = false; + // for (i = 0, len = b.guns.length; i < len; i++) { //find which gun + // if (b.guns[i].name === "nail gun") { + // b.guns[i].chooseFireMethod() + // break + // } + // } + // } + // } + // }, { name: "rivet gun", description: "nail gun slowly fires a heavy rivet", @@ -4027,7 +4064,7 @@ frequency: 2, frequencyDefault: 2, allowed() { - return tech.isMineDrop + tech.nailBotCount + tech.fragments + tech.nailsDeathMob / 2 + ((tech.haveGunCheck("mine") && !tech.isLaserMine) + (tech.haveGunCheck("nail gun") && !tech.isNeedleShieldPierce) + tech.isNeedleShot + tech.isNailShot) * 2 > 1 + return tech.isMineDrop + tech.nailBotCount + tech.fragments + tech.nailsDeathMob / 2 + ((tech.haveGunCheck("mine") && !tech.isLaserMine) + (tech.haveGunCheck("nail gun") && !tech.isShieldPierce) + tech.isNeedleShot + tech.isNailShot) * 2 > 1 }, requires: "nail gun, nails, rivets, not ceramic needles", effect() { @@ -5460,7 +5497,7 @@ }, { name: "relativistic momentum", - description: "all lasers push mobs away
affects laser-gun, laser-bot, and laser-mines", + description: "all lasers push mobs and blocks away
affects laser-gun, laser-bot, and laser-mines", isGunTech: true, maxCount: 1, count: 0, @@ -7010,17 +7047,50 @@ // remove() {} // }, { - name: "palantír", - description: `see far away lands`, + name: "density", + description: `block are 100 times less dense`, maxCount: 1, count: 0, frequency: 0, isNonRefundable: true, isExperimentHide: true, isJunk: true, - allowed() { - return true + allowed() { return true }, + requires: "", + effect() { + for (let i = 0; i < body.length; i++) Matter.Body.setDensity(body[i], 0.00001) //set current blocks to low density + level.addToWorld = () => { + for (let i = 0; i < body.length; i++) { + if (body[i] !== m.holdingTarget && !body[i].isNoSetCollision) { + body[i].collisionFilter.category = cat.body; + body[i].collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet + } + Matter.Body.setDensity(body[i], 0.00001) //THIS IS THE ONLY ADDED LINE OF CODE + body[i].classType = "body"; + Composite.add(engine.world, body[i]); //add to world + } + for (let i = 0; i < map.length; i++) { + map[i].collisionFilter.category = cat.map; + map[i].collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet; + Matter.Body.setStatic(map[i], true); //make static + Composite.add(engine.world, map[i]); //add to world + } + } }, + remove() { + if (this.count) m.look = m.lookDefault + } + }, + { + name: "palantír", + description: `see far away lands`, + maxCount: 1, + count: 0, + frequency: 0, + // isNonRefundable: true, + isExperimentHide: true, + isJunk: true, + allowed() { return true }, requires: "", effect() { m.look = () => { @@ -7047,12 +7117,10 @@ maxCount: 1, count: 0, frequency: 0, - isNonRefundable: true, + // isNonRefundable: true, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { m.look = () => { @@ -7084,9 +7152,7 @@ isNonRefundable: true, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { window.open('../../planetesimals/index.html', '_blank') @@ -7120,9 +7186,7 @@ isNonRefundable: true, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { level.levels.splice(level.onLevel, 0, level.levels[level.onLevel]); @@ -7137,9 +7201,7 @@ frequency: 0, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { player.friction = -0.4 @@ -7156,9 +7218,7 @@ frequency: 0, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { player.restitution = 0.9 @@ -7175,9 +7235,7 @@ frequency: 0, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { mobs.draw = () => { @@ -7222,9 +7280,7 @@ frequency: 0, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { mobs.draw = () => { @@ -7284,9 +7340,7 @@ frequency: 0, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { // const colors = shuffle(["#f7b", "#0eb", "#467", "#0cf", "hsl(246,100%,77%)", "#26a"]) @@ -7361,9 +7415,7 @@ isExperimentHide: true, isJunk: true, isNonRefundable: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect: () => { //setup audio context @@ -7501,9 +7553,7 @@ isNonRefundable: true, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { const savedfunction = simulation.drawCircle @@ -7618,9 +7668,7 @@ isExperimentHide: true, isNonRefundable: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { setInterval(() => { @@ -7714,9 +7762,7 @@ isNonRefundable: true, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { let options = []; //find what tech I could get @@ -7746,9 +7792,7 @@ isNonRefundable: true, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { String.prototype.shuffle = function() { @@ -7777,9 +7821,7 @@ isNonRefundable: true, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { m.draw = () => {} @@ -7795,9 +7837,7 @@ isNonRefundable: true, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { setInterval(() => { @@ -7816,9 +7856,7 @@ isNonRefundable: true, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { setInterval(() => { @@ -7837,9 +7875,7 @@ isNonRefundable: true, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { setInterval(() => { @@ -7857,9 +7893,7 @@ isNonRefundable: true, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { window.open('https://www.youtube.com/results?search_query=music', '_blank') @@ -7875,9 +7909,7 @@ isNonRefundable: true, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { (function() { @@ -7908,9 +7940,7 @@ isNonRefundable: true, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { for (let i = 0, len = tech.tech.length; i < len; i++) { @@ -7933,9 +7963,7 @@ isNonRefundable: true, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { for (let i = tech.tech.length - 1; i > 0; i--) { @@ -7993,9 +8021,7 @@ isNonRefundable: true, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { setInterval(() => { if (!simulation.paused) ctx.rotate(0.001 * Math.sin(simulation.cycle * 0.01)) }, 16); @@ -8011,9 +8037,7 @@ isNonRefundable: true, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { ctx.shadowColor = '#06f'; @@ -8048,9 +8072,7 @@ isNonRefundable: true, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { for (let i = 0; i < 24; i++) { @@ -8068,9 +8090,7 @@ isNonRefundable: true, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { for (let i = 0, len = 40; i < len; i++) { @@ -8098,9 +8118,7 @@ isNonRefundable: true, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { level.nextLevel(); @@ -8116,9 +8134,7 @@ isNonRefundable: true, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { powerUps.spawn(m.pos.x, m.pos.y, "tech"); @@ -8135,9 +8151,7 @@ isNonRefundable: true, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { for (let i = 0; i < 18; i++) { @@ -8161,9 +8175,7 @@ isNonRefundable: true, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { for (let i = 0; i < 60; i++) { @@ -8187,9 +8199,7 @@ isNonRefundable: true, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { for (let i = 0; i < 120; i++) { @@ -8394,9 +8404,7 @@ isNonRefundable: true, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { m.color = { @@ -8479,9 +8487,7 @@ isNonRefundable: true, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { level.difficultyIncrease(simulation.difficultyMode) @@ -8497,9 +8503,7 @@ isNonRefundable: true, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { for (let i = 0; i < mob.length; i++) mobs.statusStun(mob[i], 480) @@ -8583,9 +8587,7 @@ isNonRefundable: true, isExperimentHide: true, isJunk: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { const unit = { x: 1, y: 0 } @@ -8611,9 +8613,7 @@ isLore: true, // isNonRefundable: true, isExperimentHide: true, - allowed() { - return true - }, + allowed() { return true }, requires: "", effect() { setTimeout(() => { //a short delay, I can't remember why @@ -8857,14 +8857,14 @@ isNeedles: null, isExplodeRadio: null, isGunSwitchField: null, - isNeedleShieldPierce: null, + isShieldPierce: null, isDuplicateBoss: null, is111Duplicate: null, isDynamoBotUpgrade: null, isBlockPowerUps: null, foamFutureFire: null, - isDamageAfterKill: null, - isHarmReduceAfterKill: null, + isDamageAfterKillNoRegen: null, + isHarmReduceNoKill: null, isSwitchReality: null, isResearchReality: null, isAnthropicDamage: null, @@ -8946,7 +8946,6 @@ isSpawnExitTech: null, cloakDuplication: null, extruderRange: null, - // isRodAreaDamage: null, isForeverDrones: null, isMoreMobs: null, nailRecoil: null, @@ -8955,5 +8954,7 @@ isNeutronium: null, isFreeWormHole: null, isRewindField: null, - isCrouchRegen: null + isCrouchRegen: null, + isDarts: null, + OccamDamage: null, } \ No newline at end of file diff --git a/todo.txt b/todo.txt index 5d93696..2a84870 100644 --- a/todo.txt +++ b/todo.txt @@ -1,58 +1,61 @@ ******************************************************** NEXT PATCH ************************************************** -railgun is now a tech for harpoon - railgun tech: dielectric polarization has been removed -unaaq increases the size not length of harpoons +tech: Occam's razor - remove 50% of your tech and guns; `for each removed get 36% damage -capacitor bank applies charging effects: throwing blocks, foam, railgun, pulse, tokamak - fire cooldown reduction no longer effects these charging abilities, but it does reduce cooldown between discharges +tech dormancy removed +tech: predator - if you have killed a mob in the last 5 seconds increase damage by 50% and disable energy regen +tech: torpor - gives the opposite of it's previous effect + if you have NOT killed a mob in the last 5 seconds reduce harm by 72%, else increase it by 10% -foam now has a short delay between each discharge -foam charges ~10% faster -tokamak graphics indicate charging and max charge better -pulse laser can now regen energy passively while charging +relativistic momentum - pushes blocks in addition to mobs + not much benefit, but it's fun +supply chain: still doubles ammo, but now also adds 5% JUNK (yay) + it no longer has any tech requirements +inductive coupling: 600% -> 700% regen while crouched -tech: mass driver no longer gives improved block charge rate, - but it gives 200% -> 300% damage for blocks -tech: inflation no longer gives improved block charge rate - it gives harm reduction when holding a block and makes block expand when you throw them -tech: inelastic collision was removed it used to give harm reduction when holding a block +JUNK tech: density - blocks are 100x times less dense -pilot wave uses 66% less energy to fling blocks -pilot wave can fling block effectively at much higher speeds now (which happens to use much more energy) -tech potential well is removed, because it isn't really needed anymore - -inductive coupling: 500% -> 600% regen while crouched -molecular assembler now works with inductive coupling regen properly - -bug fixes (superdeterminism, wormhole, applied science) -I probably added several new bugs, let me know if you find any +tech descriptions can change their text dynamically now + only a few tech are using this option so far ******************************************************** TODO ******************************************************** -tech: instead of throwing a block, give bots that last for 20 seconds +if a mob has died in the last 5 seconds 100% damage and no energy regen -tech: Occam's razor - remove 66% of your tech and guns; for each removed get 20% damage - remove first half of guns and tech, it's not random - this is going to leave field and gun tech, but also remove the first gun, which is probably the main one - make 20% damage additive, so it's worse with more tech - remove upto 66% of guns and tech - and 10% harm reduction? +dart: a new bullet type for string-less harpoons + can turn harder + can get new targets? + +convert tech descriptions into a method() + this means the text would generate when you: press pause, or display options, or open experiment mode + this would allow the description to reference variables inside it, like this.count + who could use this: + Occam's razor + +tech: dart - alt fire several small harpoons, with guidance + requires not railgun tech: after bullets hit a mob, the mob takes 1% more damage this.damageReduction *= 1.01 only for drones? only for drones, spores, worms, ice-IX? + +make it easier to push blocks around with your body + part of negative mass? + link to other block tech + +tech: instead of throwing a block, give bots that last for 20 seconds + tech: open a new tab for n-gon, spawn things in the original game based on events in new game if you die in new die in original? new is n-gon classic? make a JUNK tech? if you die in original open a tab with a new n-gon that starts on a random level with a random load out. if you clear the level you come back to life in the original? -bug - death while paused crashes game? +tech or field aspect - Firing now doesn't alert any mob but the mob you hit -tech: aerodynamic heating - railgun rods super heat the air around it doing AoE damage +bug - death while paused crashes game? tech rocket jump - jumping produces an explosion at your feet that lets you jump extra high, but does some damage require electric reactive armor? @@ -457,6 +460,7 @@ level boss: fires a line intersection in a random direction every few seconds. possible names for tech astrophage strange loop + homeostasis holonomy - parallel transport of a vector leads to movement (applies to curved space) 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