From b217a50f758a06cc35cf5ebd47aae358d90f7414 Mon Sep 17 00:00:00 2001 From: landgreen Date: Thu, 8 Apr 2021 12:26:06 -0700 Subject: [PATCH] refit experiment and junk: panopticon - mobs can see you all the time scrap bots now have a 33% chance to spawn for 10 seconds after killing a mob (was 20% chance for 20 seconds) tech: scrap refit - killing a mob resets your functional scrap bots back to 10 seconds of operation several damage tech have reduced damage by about 10% spores do 20% more damage, but last 1 second shorter --- .DS_Store | Bin 6148 -> 6148 bytes js/bullet.js | 90 +++++++-------------- js/index.js | 2 +- js/level.js | 42 +++++++--- js/mob.js | 9 ++- js/player.js | 23 ++++-- js/simulation.js | 2 +- js/spawn.js | 4 + js/tech.js | 204 ++++++++++++++++++++++++++++++++++------------- todo.txt | 26 +++--- 10 files changed, 254 insertions(+), 148 deletions(-) diff --git a/.DS_Store b/.DS_Store index f347eb73173b44763dc06e8c288a9560052ca475..d3548a0903c36c476bb4d6332b7a34c8d71617f3 100644 GIT binary patch delta 21 ccmZoMXffEJ#muxtc(M+&AEU$OYUWN607okZE&u=k delta 21 ccmZoMXffEJ#muz))npxJKgJ82tC>4R08{n{hyVZp diff --git a/js/bullet.js b/js/bullet.js index fbb9097..7a43b1d 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -1814,14 +1814,14 @@ const b = { friction: 0, frictionAir: 0.025, thrust: (tech.isFastSpores ? 0.001 : 0.0004) * (1 + 0.3 * (Math.random() - 0.5)), - dmg: tech.isMutualism ? 12 : 5, //bonus damage from tech.isMutualism + dmg: tech.isMutualism ? 16.8 : 7, //bonus damage from tech.isMutualism lookFrequency: 100 + Math.floor(117 * Math.random()), classType: "bullet", collisionFilter: { category: cat.bullet, mask: cat.map | cat.mob | cat.mobBullet | cat.mobShield //no collide with body }, - endCycle: simulation.cycle + Math.floor((600 + Math.floor(Math.random() * 420)) * tech.isBulletsLastLonger), + endCycle: simulation.cycle + Math.floor((540 + Math.floor(Math.random() * 420)) * tech.isBulletsLastLonger), minDmgSpeed: 0, playerOffPosition: { //used when moving towards player to keep spores separate x: 100 * (Math.random() - 0.5), @@ -2301,7 +2301,7 @@ const b = { World.add(engine.world, bullet[me]); //add bullet to world Matter.Body.setVelocity(bullet[me], velocity); }, - targetedNail(position, num = 1, speed = 50 + 10 * Math.random(), range = 1200, isRandomAim = true) { + targetedNail(position, num = 1, speed = 40 + 10 * Math.random(), range = 1200, isRandomAim = true) { const targets = [] //target nearby mobs for (let i = 0, len = mob.length; i < len; i++) { if (mob[i].dropPowerUp) { @@ -2321,7 +2321,7 @@ const b = { x: targets[index].x + SPREAD * (Math.random() - 0.5), y: targets[index].y + SPREAD * (Math.random() - 0.5) } - b.nail(position, Vector.mult(Vector.normalise(Vector.sub(WHERE, position)), speed), 1.1) + b.nail(position, Vector.mult(Vector.normalise(Vector.sub(WHERE, position)), speed)) } else if (isRandomAim) { // aim in random direction const ANGLE = 2 * Math.PI * Math.random() b.nail(position, { @@ -2331,7 +2331,7 @@ const b = { } } }, - nail(pos, velocity, dmg = 0) { + nail(pos, velocity, dmg = 1) { const me = bullet.length; bullet[me] = Bodies.rectangle(pos.x, pos.y, 25, 2, b.fireAttributes(Math.atan2(velocity.y, velocity.x))); Matter.Body.setVelocity(bullet[me], velocity); @@ -2492,7 +2492,7 @@ const b = { if (Vector.magnitude(Vector.sub(this.position, player.position)) < 250) { //give energy Matter.Body.setAngularVelocity(this, this.spin) if (this.isUpgraded) { - m.energy += 0.12 + m.energy += 0.11 simulation.drawList.push({ //add dmg to draw queue x: this.position.x, y: this.position.y, @@ -2583,16 +2583,16 @@ const b = { } else { //close to player Matter.Body.setVelocity(this, Vector.add(Vector.mult(this.velocity, 0.90), Vector.mult(player.velocity, 0.17))); //add player's velocity if (this.lastLookCycle < simulation.cycle && !m.isCloak) { - this.lastLookCycle = simulation.cycle + (this.isUpgraded ? 15 : 80) + this.lastLookCycle = simulation.cycle + (this.isUpgraded ? 21 : 110) for (let i = 0, len = mob.length; i < len; i++) { const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)); if (dist < 3000000 && //1400*1400 Matter.Query.ray(map, this.position, mob[i].position).length === 0 && Matter.Query.ray(body, this.position, mob[i].position).length === 0 && !mob[i].isShielded) { - const SPEED = 40 + const SPEED = 35 const unit = Vector.normalise(Vector.sub(Vector.add(mob[i].position, Vector.mult(mob[i].velocity, Math.sqrt(dist) / 60)), this.position)) - b.nail(this.position, Vector.mult(unit, SPEED), 0.4) + b.nail(this.position, Vector.mult(unit, SPEED)) this.force = Vector.mult(unit, -0.01 * this.mass) break; } @@ -3343,14 +3343,13 @@ const b = { }, baseFire(angle) { const speed = 30 + 6 * Math.random() + 9 * tech.nailInstantFireRate - const dmg = 0.9 b.nail({ x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }, { x: m.Vx / 2 + speed * Math.cos(angle), y: m.Vy / 2 + speed * Math.sin(angle) - }, dmg) //position, velocity, damage + }) //position, velocity, damage if (tech.isIceCrystals) { bullet[bullet.length - 1].beforeDmg = function(who) { mobs.statusSlow(who, 60) @@ -3374,35 +3373,9 @@ const b = { defaultAmmoPack: 5.5, have: false, fire() { - - // if (true) { - // const direction = { - // x: Math.cos(m.angle), - // y: Math.sin(m.angle) - // } - // for (let i = 0; i < 2; i++) { - // const push = Vector.mult(Vector.perp(direction), 0.08) - // const where = { - // x: m.pos.x + 40 * direction.x, - // y: m.pos.y + 40 * direction.y - // } - // b.missile(where, m.angle, 0, 0.5) //where, angle, speed, size = 1) - // // bullet[bullet.length - 1].force.x += push.x; - // // bullet[bullet.length - 1].force.y += push.y; - // } - // } - - // setTimeout(() => { - // if (!simulation.paused) { - // b.foam(position, velocity, radius) - // bullet[bullet.length - 1].damage = (1 + 1.53 * tech.foamFutureFire) * (tech.isFastFoam ? 0.048 : 0.012) //double damage - // } - // }, 350 * tech.foamFutureFire); - - let knock, spread if (m.crouch) { - spread = 0.75 + spread = 0.65 m.fireCDcycle = m.cycle + Math.floor(55 * b.fireCD); // cool down if (tech.isShotgunImmune && m.immuneCycle < m.cycle + Math.floor(58 * b.fireCD)) m.immuneCycle = m.cycle + Math.floor(58 * b.fireCD); //player is immune to damage for 30 cycles knock = 0.01 @@ -3476,25 +3449,25 @@ const b = { } } } else if (tech.isIncendiary) { - const SPEED = m.crouch ? 35 : 25 - const END = Math.floor(m.crouch ? 9 : 6); - const totalBullets = 8 - const angleStep = (m.crouch ? 0.15 : 0.4) / totalBullets + spread *= 0.15 + const END = Math.floor(m.crouch ? 10 : 7); + const totalBullets = 10 + const angleStep = (m.crouch ? 0.4 : 1.3) / totalBullets let dir = m.angle - angleStep * totalBullets / 2; for (let i = 0; i < totalBullets; i++) { //5 -> 7 dir += angleStep const me = bullet.length; bullet[me] = Bodies.rectangle(m.pos.x + 50 * Math.cos(m.angle), m.pos.y + 50 * Math.sin(m.angle), 17, 4, b.fireAttributes(dir)); - const end = END + Math.random() * 3 + const end = END + Math.random() * 4 bullet[me].endCycle = 2 * end + simulation.cycle - const speed = SPEED * end / END - const dirOff = dir + 0.15 * (Math.random() - 0.5) + const speed = 25 * end / END + const dirOff = dir + (Math.random() - 0.5) * spread Matter.Body.setVelocity(bullet[me], { x: speed * Math.cos(dirOff), y: speed * Math.sin(dirOff) }); bullet[me].onEnd = function() { - b.explosion(this.position, 100 + (Math.random() - 0.5) * 30); //makes bullet do explosive damage at end + b.explosion(this.position, 135 + (Math.random() - 0.5) * 40); //makes bullet do explosive damage at end } bullet[me].beforeDmg = function() { this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion @@ -3503,33 +3476,32 @@ const b = { World.add(engine.world, bullet[me]); //add bullet to world } } else if (tech.isNailShot) { + spread *= 0.4 if (m.crouch) { - for (let i = 0; i < 11; i++) { - const dir = m.angle + (Math.random() - 0.5) * 0.015 + for (let i = 0; i < 17; i++) { + const dir = m.angle + (Math.random() - 0.5) * spread const pos = { x: m.pos.x + 35 * Math.cos(m.angle) + 15 * (Math.random() - 0.5), y: m.pos.y + 35 * Math.sin(m.angle) + 15 * (Math.random() - 0.5) } - speed = 39 + 7 * Math.random() - const velocity = { + speed = 48 + 8 * Math.random() + b.nail(pos, { x: speed * Math.cos(dir), y: speed * Math.sin(dir) - } - b.nail(pos, velocity, 1.2) + }) } } else { - for (let i = 0; i < 15; i++) { - const dir = m.angle + (Math.random() - 0.5) * 0.42 + for (let i = 0; i < 17; i++) { + const dir = m.angle + (Math.random() - 0.5) * spread const pos = { x: m.pos.x + 35 * Math.cos(m.angle) + 15 * (Math.random() - 0.5), y: m.pos.y + 35 * Math.sin(m.angle) + 15 * (Math.random() - 0.5) } - speed = 34 + 6 * Math.random() - const velocity = { + speed = 48 + 8 * Math.random() + b.nail(pos, { x: speed * Math.cos(dir), y: speed * Math.sin(dir) - } - b.nail(pos, velocity, 1.2) + }) } } } else { @@ -3888,7 +3860,7 @@ const b = { name: "spores", description: "fire a sporangium that discharges spores
spores seek out nearby mobs", ammo: 0, - ammoPack: 3.5, + ammoPack: 3, have: false, fire() { const me = bullet.length; diff --git a/js/index.js b/js/index.js index e5972a2..234ca92 100644 --- a/js/index.js +++ b/js/index.js @@ -400,7 +400,7 @@ const build = { if (!tech.tech[i].isExperimentHide) { if (tech.tech[i].allowed()) { // || tech.tech[i].name === "+1 cardinality") { //|| tech.tech[i].name === "leveraged investment" if (tech.tech[i].isExperimentalMode) { - text += `
${tech.tech[i].description}
` + text += `
${tech.tech[i].name}
${tech.tech[i].description}
` } else { text += `
  ${tech.tech[i].name}
${tech.tech[i].description}
` } diff --git a/js/level.js b/js/level.js index 161adc7..32d9bc0 100644 --- a/js/level.js +++ b/js/level.js @@ -12,15 +12,15 @@ const level = { start() { if (level.levelsCleared === 0) { //this code only runs on the first level // simulation.enableConstructMode() //used to build maps in testing mode - // level.difficultyIncrease(125) + // level.difficultyIncrease(50) // simulation.zoomScale = 1000; // simulation.setZoom(); // m.setField("nano-scale manufacturing") - // b.giveGuns("spores") + // b.giveGuns("shotgun") // tech.isExplodeRadio = true // for (let i = 0; i < 1; i++) tech.giveTech("dynamo-bot") - // tech.giveTech("needle gun") - // tech.giveTech("ceramic needles") + // tech.giveTech("incendiary ammunition") + // tech.giveTech("flip-flop") // tech.giveTech("causality bombs") // tech.giveTech("cardinality") // tech.giveTech("Bayesian statistics") @@ -1077,7 +1077,6 @@ const level = { spawn.mapRect(6400, -200, 400, 300); //right wall spawn.mapRect(6700, -1800, 800, 2600); //right wall spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump - // spawn.boost(1500, 0, 900); // simulation.difficulty = 30 // spawn.starter(1900, -500, 200) //big boy @@ -1098,7 +1097,7 @@ const level = { // spawn.beamer(1200, -500) // spawn.shield(mob[mob.length - 1], 1800, -120, 1); - spawn.nodeGroup(1200, -500, "sniper") + spawn.nodeGroup(1200, -500, "pulsar") // spawn.snakeBoss(1200, -500) // spawn.powerUpBoss(2900, -500) // spawn.randomMob(1600, -500) @@ -1715,7 +1714,30 @@ const level = { const balance3 = level.spinner(2608, 1900, 584, 25, 0.001) //falling const balance4 = level.spinner(9300, 2205, 25, 380, 0.001) //exit + const drip = { + x: 7150, + y: 0, + speed: 0 + } level.custom = () => { + const dripCycle = (simulation.cycle % 200) //drips + if (dripCycle < 70) { + if (!m.isBodiesAsleep) { + if (dripCycle === 0) { + drip.y = 1900 + drip.x = 4600 + 4400 * Math.random() + drip.speed = 1 + } + drip.speed += 0.35 //acceleration from gravity + drip.y += drip.speed + } + // if (drip.y > 2900) console.log(dripCycle) + ctx.fillStyle = "hsla(160, 100%, 35%, 0.5)" //"hsla(160, 100%, 35%,0.75)" + ctx.beginPath(); + ctx.arc(drip.x, drip.y, 8, 0, 2 * Math.PI); + ctx.fill(); + } + button.query(); button.draw(); hazard.query(); @@ -2579,7 +2601,7 @@ const level = { spawn.mapRect(-4450, -3075, 450, 25); spawn.mapRect(-4025, -3075, 25, 100); spawn.mapRect(-4275, -2785, 100, 25); - spawn.bodyRect(-3830, -2400, 50, 50); + spawn.bodyRect(-3900, -2400, 50, 50); //mobs spawn.randomMob(-2500, -2700, 1); @@ -2942,9 +2964,7 @@ const level = { spawn.mapRect(3650, -1300, 50, 700); //exit wall spawn.mapRect(3650, -1300, 1350, 50); //exit wall spawn.bodyRect(3665, -600, 20, 100); //door - spawn.mapRect(3000, -550, 375, 75); - spawn.mapRect(3000, -600, 225, 75); - + spawn.mapVertex(3160, -525, "625 0 300 0 300 -140 500 -140"); //entrance/exit ramp spawn.mapRect(3000, -2000 * 0.5, 700, 50); //exit roof spawn.mapRect(3000, -2000 * 0.25, 2000 - 300, 50); //1st floor spawn.spawnStairs(3000 + 2000 - 50, 0, 4, 250, 350, true); //stairs ground @@ -3928,7 +3948,7 @@ const level = { }; level.customTopLayer = () => { ctx.fillStyle = "rgba(64,64,64,0.97)"; - ctx.fillRect(1175, -400, 275, 175); + ctx.fillRect(2800, -400, 275, 175); hazard.draw(); doorBedroom.draw(); diff --git a/js/mob.js b/js/mob.js index 90e0d50..5902131 100644 --- a/js/mob.js +++ b/js/mob.js @@ -1053,9 +1053,14 @@ const mobs = { } else if (tech.nailsDeathMob) { b.targetedNail(this.position, tech.nailsDeathMob, 39 + 6 * Math.random()) } - if (Math.random() < tech.isBotSpawner) { + if (tech.isBotSpawnerReset) { + for (let i = 0, len = bullet.length; i < len; i++) { + if (bullet[i].botType && !bullet[i].isKeep) bullet[i].endCycle = simulation.cycle + 660 //10 seconds and 1 extra second for fun + } + } + if (Math.random() < tech.botSpawner) { b.randomBot(this.position, false) - bullet[bullet.length - 1].endCycle = simulation.cycle + 1000 + Math.floor(400 * Math.random()) + bullet[bullet.length - 1].endCycle = simulation.cycle + 660 //10 seconds and 1 extra second for fun this.leaveBody = false; // no body since it turned into the bot } } else if (tech.isShieldAmmo && this.shield && !this.isBonusShield) { diff --git a/js/player.js b/js/player.js index 3972933..52dc45b 100644 --- a/js/player.js +++ b/js/player.js @@ -1600,16 +1600,23 @@ const m = { name: "nano-scale manufacturing", description: "use energy to block mobs
excess energy used to build drones
double your default energy regeneration", effect: () => { + // m.fieldMeterColor = "#0c5" + // m.eyeFillColor = m.fieldMeterColor m.hold = function() { if (m.energy > m.maxEnergy - 0.02 && m.fieldCDcycle < m.cycle && !input.field && bullet.length < 200 && (m.cycle % 2)) { if (tech.isSporeField) { - // const len = Math.floor(5 + 4 * Math.random()) - const len = Math.ceil(m.energy * 10) - m.energy = 0; - for (let i = 0; i < len; i++) b.spore(m.pos) + for (let i = 0; i < 30; i++) { + m.energy -= 0.11 + if (m.energy > 0) { + b.spore(m.pos) + } else { + m.energy = 0.01 + break; + } + } } else if (tech.isMissileField) { - m.energy -= 0.5; - b.missile({ x: m.pos.x, y: m.pos.y - 40 }, -Math.PI / 2, 0, 1) + m.energy -= 0.4; + b.missile({ x: m.pos.x, y: m.pos.y - 40 }, -Math.PI / 2 + 0.5 * (Math.random() - 0.5), 0, 1) } else if (tech.isIceField) { m.energy -= 0.057; b.iceIX(1) @@ -1907,7 +1914,7 @@ const m = { }, { name: "metamaterial cloaking", //"weak photonic coupling" "electromagnetically induced transparency" "optical non-coupling" "slow light field" "electro-optic transparency" - description: "cloak after not using your gun or field
while cloaked mobs can't see you
increase damage by 133%", + description: "cloak after not using your gun or field
while cloaked mobs can't see you
increase damage by 121%", effect: () => { m.fieldFire = true; m.fieldMeterColor = "#333"; @@ -1915,7 +1922,7 @@ const m = { // m.eyeFillColor = '#333' m.fieldPhase = 0; m.isCloak = false - m.fieldDamage = 2.33 // 1 + 111/100 + m.fieldDamage = 2.21 // 1 + 111/100 m.fieldDrawRadius = 0 const drawRadius = 1000 diff --git a/js/simulation.js b/js/simulation.js index 5788659..a3dfd59 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -793,7 +793,7 @@ const simulation = { if (tech.isFlipFlopOn) { m.energy += 0.22; } else { - m.energy -= 0.031; + m.energy -= 0.041; if (m.energy < 0) m.energy = 0 } } diff --git a/js/spawn.js b/js/spawn.js index 733c092..5d06edd 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -1580,6 +1580,8 @@ const spawn = { const sub = Vector.sub(this.homePosition, this.position) const dist = Vector.magnitude(sub) if (dist > 250) this.force = Vector.mult(Vector.normalise(sub), this.mass * 0.0002) + } else { + this.isFiring = false } }; }, @@ -1700,6 +1702,8 @@ const spawn = { const sub = Vector.sub(this.homePosition, this.position) const dist = Vector.magnitude(sub) if (dist > 350) this.force = Vector.mult(Vector.normalise(sub), this.mass * 0.0002) + } else { + this.isFiring = false } }; }, diff --git a/js/tech.js b/js/tech.js index ba3b1f1..df49cc6 100644 --- a/js/tech.js +++ b/js/tech.js @@ -124,31 +124,31 @@ damageFromTech() { let dmg = m.fieldDamage if (tech.isOneBullet && bullet.length - b.totalBots() === 1) dmg *= 2 //3 / Math.sqrt(bullet.length + 1) //testing this tech out, seems to have too many negatives though ... - if (tech.isFlipFlopDamage && tech.isFlipFlopOn) dmg *= 1.555 + if (tech.isFlipFlopDamage && tech.isFlipFlopOn) dmg *= 1.45 if (tech.isAnthropicDamage && tech.isDeathAvoidedThisLevel) dmg *= 2.3703599 - if (tech.isDamageAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 1.5 : 0.75 - if (tech.isTechDamage) dmg *= 2 + if (tech.isDamageAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 1.4 : 0.85 + if (tech.isTechDamage) dmg *= 1.9 if (tech.isDupDamage) dmg *= 1 + Math.min(1, tech.duplicationChance()) if (tech.isLowEnergyDamage) dmg *= 1 + Math.max(0, 1 - m.energy) * 0.5 if (tech.isMaxEnergyTech) dmg *= 1.4 if (tech.isEnergyNoAmmo) dmg *= 1.5 - if (tech.isDamageForGuns) dmg *= 1 + 0.17 * b.inventory.length - if (tech.isLowHealthDmg) dmg *= 1 + 0.6 * Math.max(0, 1 - m.health) + if (tech.isDamageForGuns) dmg *= 1 + 0.14 * b.inventory.length + if (tech.isLowHealthDmg) dmg *= 1 + 0.5 * Math.max(0, 1 - m.health) if (tech.isHarmDamage && m.lastHarmCycle + 600 > m.cycle) dmg *= 3; - if (tech.isEnergyLoss) dmg *= 1.5; - if (tech.isAcidDmg && m.health > 1) dmg *= 1.4; + if (tech.isEnergyLoss) dmg *= 1.45; + if (tech.isAcidDmg && m.health > 1) dmg *= 1.35; if (tech.restDamage > 1 && player.speed < 1) dmg *= tech.restDamage if (tech.isEnergyDamage) dmg *= 1 + m.energy / 9; if (tech.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.0038 if (tech.isRerollDamage) dmg *= 1 + 0.039 * powerUps.research.count - if (tech.isOneGun && b.inventory.length < 2) dmg *= 1.25 - if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 2 + if (tech.isOneGun && b.inventory.length < 2) dmg *= 1.22 + if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 1.9 if (tech.isSpeedDamage) dmg *= 1 + Math.min(0.43, player.speed * 0.015) - if (tech.isBotDamage) dmg *= 1 + 0.06 * b.totalBots() + if (tech.isBotDamage) dmg *= 1 + 0.05 * b.totalBots() return dmg * tech.slowFire * tech.aimDamage }, duplicationChance() { - return (tech.isBayesian ? 0.2 : 0) + tech.cancelCount * 0.045 + tech.duplicateChance + m.duplicateChance + return (tech.isBayesian ? 0.2 : 0) + tech.cancelCount * 0.043 + tech.duplicateChance + m.duplicateChance }, maxDuplicationEvent() { if (tech.is100Duplicate && tech.duplicationChance() > 0.99) { @@ -163,7 +163,7 @@ }, tech: [{ name: "integrated armament", - description: `increase damage by 25%
your inventory can only hold 1 gun`, + description: `increase damage by 22%
your inventory can only hold 1 gun`, maxCount: 1, count: 0, frequency: 2, @@ -213,7 +213,7 @@ }, { name: "arsenal", - description: "increase damage by 17%
for each gun in your inventory", + description: "increase damage by 14%
for each gun in your inventory", maxCount: 1, count: 0, frequency: 2, @@ -473,7 +473,7 @@ }, { name: "dead reckoning", - description: "increase damage by 33% when at rest", + description: "increase damage by 30% when at rest", maxCount: 9, count: 0, frequency: 4, @@ -483,7 +483,7 @@ }, requires: "inertial frame", effect: () => { - tech.restDamage += 0.33 + tech.restDamage += 0.3 }, remove() { tech.restDamage = 1; @@ -833,7 +833,7 @@ count: 0, frequency: 2, allowed() { - return (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1) && !tech.sporesOnDeath && !tech.nailsDeathMob && !tech.isBotSpawner + return (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1) && !tech.sporesOnDeath && !tech.nailsDeathMob && !tech.botSpawner }, requires: "an explosive damage source, no other mob death tech", effect: () => { @@ -850,7 +850,7 @@ count: 0, frequency: 2, allowed() { - return !tech.sporesOnDeath && !tech.isExplodeMob && !tech.isBotSpawner + return !tech.sporesOnDeath && !tech.isExplodeMob && !tech.botSpawner }, requires: "no other mob death tech", effect: () => { @@ -867,7 +867,7 @@ count: 0, frequency: 2, allowed() { - return !tech.nailsDeathMob && !tech.isExplodeMob && !tech.isBotSpawner + return !tech.nailsDeathMob && !tech.isExplodeMob && !tech.botSpawner }, requires: "no other mob death tech", effect() { @@ -887,7 +887,7 @@ count: 0, frequency: 2, allowed() { - return tech.nailsDeathMob || tech.sporesOnDeath || tech.isExplodeMob || tech.isBotSpawner + return tech.nailsDeathMob || tech.sporesOnDeath || tech.isExplodeMob || tech.botSpawner }, requires: "any mob death tech", effect: () => { @@ -921,7 +921,7 @@ }, { name: "anticorrelation", - description: "increase damage by 100%
after not using your gun or field for 2 seconds", + description: "increase damage by 90%
after not using your gun or field for 2 seconds", maxCount: 1, count: 0, frequency: 2, @@ -938,20 +938,38 @@ }, { name: "scrap bots", - description: "20% chance to build a bot after killing a mob
the bot lasts for about 20 seconds", + description: "33% chance after killing a mob to build
a scrap bot that operates for 10 seconds", maxCount: 3, count: 0, frequency: 1, isBotTech: true, allowed() { - return b.totalBots() > 0 && !tech.sporesOnDeath && !tech.nailsDeathMob && !tech.isExplodeMob + return !tech.sporesOnDeath && !tech.nailsDeathMob && !tech.isExplodeMob //b.totalBots() > 0 && }, - requires: "a bot and no other mob death tech", + requires: "no other mob death tech", effect() { - tech.isBotSpawner += 0.20; + tech.botSpawner += 0.33; }, remove() { - tech.isBotSpawner = 0; + tech.botSpawner = 0; + } + }, + { + name: "scrap refit", + description: "killing a mob resets your functional scrap bots
to 10 seconds of operation", + maxCount: 1, + count: 0, + frequency: 1, + isBotTech: true, + allowed() { + return tech.botSpawner + }, + requires: "scrap bots", + effect() { + tech.isBotSpawnerReset = true; + }, + remove() { + tech.isBotSpawnerReset = false; } }, { @@ -1211,7 +1229,7 @@ }, { name: "dynamo-bot upgrade", - description: "convert your bots to dynamo-bots
dynamo-bots regen 24 energy per second", + description: "convert your bots to dynamo-bots
increase regen to 22 energy per second", maxCount: 1, count: 0, frequency: 2, @@ -1302,7 +1320,7 @@ }, { name: "network effect", - description: "increase damage by 6%
for each of your permanent bots", + description: "increase damage by 5%
for each of your permanent bots", maxCount: 1, count: 0, frequency: 2, @@ -1554,7 +1572,7 @@ }, { name: "NAND gate", - description: "if in the ON state
do 55.5% more damage", + description: "if in the ON state
do 45% more damage", maxCount: 1, count: 0, frequency: 4, @@ -1572,7 +1590,7 @@ }, { name: "transistor", - description: "if ON regen 22 energy per second
if OFF drain 3.1 energy per second", + description: "if ON regen 22 energy per second
if OFF drain 4.1 energy per second", maxCount: 1, count: 0, frequency: 4, @@ -1910,7 +1928,7 @@ }, { name: "exothermic process", - description: "increase damage by 50%
if a mob dies drain energy by 25%", + description: "increase damage by 45%
if a mob dies drain energy by 25%", maxCount: 1, count: 0, frequency: 2, @@ -1933,9 +1951,9 @@ frequency: 4, frequencyDefault: 4, allowed() { - return tech.isEnergyLoss && m.maxEnergy < 1.1 && !tech.isSporeField && !tech.isRewindAvoidDeath + return tech.isEnergyLoss && !tech.isRewindAvoidDeath }, - requires: "exothermic process, not max energy increase, CPT, or spore nano-scale", + requires: "exothermic process, CPT", effect() { tech.isMaxEnergyTech = true; m.setMaxEnergy() @@ -1970,12 +1988,10 @@ count: 0, frequency: 1, allowed() { - return m.maxEnergy > 0.99 + return true }, - requires: "max energy >= 1", + requires: "", effect() { - // m.maxEnergy += 0.5 - // m.energy += 0.5 tech.bonusEnergy += 0.5 m.setMaxEnergy() }, @@ -2057,7 +2073,7 @@ }, { name: "dormancy", - description: "if a mob has died in the last 5 seconds
increase damage by 50% else decrease it by 25%", + description: "if a mob has died in the last 5 seconds
increase damage by 40% else decrease it by 15%", maxCount: 1, count: 0, frequency: 2, @@ -2092,7 +2108,7 @@ }, { name: "negative feedback", - description: "increase damage by 6%
for every 10 health below 100", + description: "increase damage by 5%
for every 10 health below 100", maxCount: 1, count: 0, frequency: 2, @@ -2109,7 +2125,7 @@ }, { name: "antiscience", - description: "increase damage by 100%
lose 11 health when you pick up a tech", + description: "increase damage by 90%
lose 11 health when you pick up a tech", maxCount: 1, count: 0, frequency: 2, @@ -2144,7 +2160,7 @@ }, { name: "fluoroantimonic acid", - description: "increase damage by 40%
when your health is above 100", + description: "increase damage by 35%
when your health is above 100", maxCount: 1, count: 0, frequency: 2, @@ -2615,7 +2631,7 @@ }, { name: "futures exchange", - description: "clicking × to cancel a field, tech, or gun
adds 4.5% power up duplication chance", + description: "clicking × to cancel a field, tech, or gun
adds 4.3% power up duplication chance", maxCount: 1, count: 0, frequency: 1, @@ -3889,7 +3905,7 @@ }, { name: "drone repair", - description: "broken drones repair if the drone gun is active
repairing has a 33% chance to use an ammo", + description: "broken drones repair if the drone gun is active
repairing has a 33% chance to use 1 ammo", isGunTech: true, maxCount: 1, count: 0, @@ -4399,7 +4415,7 @@ }, { name: "eddy current brake", - description: "your stored energy projects a field that
limits the top speed of mobs", + description: "project a field that limits the top speed of mobs
field radius scales with stored energy", isFieldTech: true, maxCount: 1, count: 0, @@ -4553,7 +4569,7 @@ count: 0, frequency: 2, allowed() { - return m.maxEnergy > 0.99 && m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isMissileField || tech.isIceField || tech.isFastDrones || tech.isDroneGrab) + return m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" && !(tech.isMissileField || tech.isIceField || tech.isFastDrones || tech.isDroneGrab) }, requires: "nano-scale manufacturing", effect() { @@ -4848,7 +4864,7 @@ }, { name: "discrete optimization", - description: "increase damage by 66%
50% increased delay after firing", + description: "increase damage by 50%
50% increased delay after firing", isFieldTech: true, maxCount: 1, count: 0, @@ -4858,7 +4874,7 @@ }, requires: "metamaterial cloaking", effect() { - tech.aimDamage = 1.66 + tech.aimDamage = 1.5 b.setFireCD(); }, remove() { @@ -4946,7 +4962,7 @@ //************************************************** { name: "ship", - description: "experiment: fly around with no legs
aim with the keyboard", + description: "experiment: fly around with no legs
aim with the keyboard", maxCount: 1, count: 0, frequency: 0, @@ -4964,7 +4980,7 @@ }, { name: "quantum leap", - description: "experiment: every 20 seconds
become an alternate version of yourself", + description: "experiment: every 20 seconds
become an alternate version of yourself", maxCount: 1, count: 0, frequency: 0, @@ -4979,13 +4995,13 @@ setInterval(() => { m.switchWorlds() simulation.trails() - }, 20000); //every 20 sections + }, 20000); //every 20 seconds }, remove() {} }, { name: "shields", - description: "experiment: every 5 seconds
all mobs gain a shield", + description: "experiment: every 5 seconds
all mobs gain a shield", maxCount: 1, count: 0, frequency: 0, @@ -5001,13 +5017,13 @@ for (let i = 0; i < mob.length; i++) { if (!mob[i].isShielded && !mob[i].shield && mob[i].dropPowerUp) spawn.shield(mob[i], mob[i].position.x, mob[i].position.y, 1, true); } - }, 5000); //every 5 sections + }, 5000); //every 5 seconds }, remove() {} }, { - name: "aim", - description: "experiment: your aiming is random", + name: "Fourier analysis", + description: "experiment: your aiming is random", maxCount: 1, count: 0, frequency: 0, @@ -5030,6 +5046,31 @@ }, remove() {} }, + { + name: "panopticon", + description: "experiment: mobs can see you all the time", + maxCount: 1, + count: 0, + frequency: 0, + isNonRefundable: true, + isBadRandomOption: true, + isExperimentalMode: true, + allowed() { + return build.isExperimentSelection + }, + requires: "", + effect() { + setInterval(() => { + for (let i = 0; i < mob.length; i++) { + if (!mob[i].shield && mob[i].dropPowerUp) { + mob[i].locatePlayer() + mob[i].seePlayer.yes = true; + } + } + }, 1000); //every 1 seconds + }, + remove() {} + }, //************************************************** //************************************************** JUNK //************************************************** tech @@ -5052,6 +5093,55 @@ // }, // remove() {} // }, + { + name: "panopticon", + description: "experiment: mobs can see you all the time", + maxCount: 1, + count: 0, + frequency: 0, + isExperimentHide: true, + isNonRefundable: true, + isJunk: true, + allowed() { + return build.isExperimentSelection + }, + requires: "", + effect() { + setInterval(() => { + for (let i = 0; i < mob.length; i++) { + if (!mob[i].shield && mob[i].dropPowerUp) { + mob[i].locatePlayer() + mob[i].seePlayer.yes = true; + } + } + }, 1000); //every 1 seconds + }, + remove() {} + }, + { + name: "inverted mouse", + description: "your mouse is scrambled
it's fine, just rotate it 90 degrees", + maxCount: 1, + count: 0, + frequency: 0, + isExperimentHide: true, + isNonRefundable: true, + isJunk: true, + allowed() { + return !m.isShipMode + }, + requires: "not ship", + effect() { + document.body.addEventListener("mousemove", (e) => { + const ratio = window.innerWidth / window.innerHeight + simulation.mouse.x = e.clientY * ratio + simulation.mouse.y = e.clientX / ratio; + }); + }, + remove() { + // m.look = m.lookDefault + } + }, { name: "Fourier analysis", description: "your aiming is now controlled by this equation:
2sin(0.0133t) + sin(0.013t) + 0.5sin(0.031t)+ 0.33sin(0.03t)", @@ -5068,6 +5158,7 @@ m.look = () => { m.angle = 2 * Math.sin(m.cycle * 0.0133) + Math.sin(m.cycle * 0.013) + 0.5 * Math.sin(m.cycle * 0.031) + 0.33 * Math.sin(m.cycle * 0.03) const scale = 0.8; + simulation.mouse.y m.transSmoothX = canvas.width2 - m.pos.x - (simulation.mouse.x - canvas.width2) * scale; m.transSmoothY = canvas.height2 - m.pos.y - (simulation.mouse.y - canvas.height2) * scale; m.transX += (m.transSmoothX - m.transX) * 0.07; @@ -5193,7 +5284,7 @@ setInterval(() => { m.switchWorlds() simulation.trails() - }, 20000); //every 30 sections + }, 20000); //every 30 seconds }, remove() {} }, @@ -5213,7 +5304,7 @@ effect() { setInterval(() => { alert(`The best combo is ${tech.tech[Math.floor(Math.random() * tech.tech.length)].name} with ${tech.tech[Math.floor(Math.random() * tech.tech.length)].name}!`); - }, 30000); //every 30 sections + }, 30000); //every 30 seconds }, remove() {} }, @@ -6119,7 +6210,8 @@ renormalization: null, fragments: null, isEnergyDamage: null, - isBotSpawner: null, + botSpawner: null, + isBotSpawnerReset: null, waveHelix: null, isSporeFollow: null, isNailRadiation: null, diff --git a/todo.txt b/todo.txt index c31fcd5..a20f323 100644 --- a/todo.txt +++ b/todo.txt @@ -1,9 +1,13 @@ ******************************************************** NEXT PATCH ******************************************************** -tech: automatic - always fire, but get 2.5x ammo - requires inertial frame +experiment and junk: panopticon - mobs can see you all the time -tech: drone repair - while drones are your active gun, drones respawn with a 50% chance to consume ammo +scrap bots now have a 33% chance to spawn for 10 seconds after killing a mob + (was 20% chance for 20 seconds) +tech: scrap refit - killing a mob resets your functional scrap bots back to 10 seconds of operation + +several damage tech have reduced damage by about 10% +spores do 20% more damage, but last 1 second shorter ******************************************************** BUGS ******************************************************** @@ -33,17 +37,19 @@ fix door.isOpen actually meaning isClosed? (repeatable almost every time) bug - mines spawn extra mines when fired at thin map wall while jumping - ******************************************************** TODO ******************************************************** +quantum foam: hold fire to charge up foam, release fire to let go an amount relative to hold long you held fire + foam gun fires a bullet that tracks how long mouse is down + when mouse is up it streams out a hose of foam based on how long foam was down + bullet is small and hidden + +make some bullets move super fast, but do collisions checks in .do() + check for hitting mobs or map with fractional velocity + if velocity is above 40ish + flipflop, but toggles after a kill -tech shotgun - crouching makes your spread very small - remove spread reduction on nail shot - doesn't apply to slug - -add water drops to sewers - new level: procedural generation several small rooms are linked by portals the portals have a randomized pattern