From 4efc3d2d82ba75d3847fd2509886fb457ea193d1 Mon Sep 17 00:00:00 2001 From: landgreen Date: Sun, 6 Mar 2022 19:00:27 -0800 Subject: [PATCH] merged shotgun tech railgun and foam have a bit more ammo capacitor bank makes foam gun fire a stream of foam tech shift registers is now always on (set ON/OFF to ON at the start of a new level) tech from applied science doesn't count for various tech that convert tech into other things (pure science, many worlds) grappling hook now shows hooks on the grapple merged similar gun tech needle gun+needle shot rivet gun+shotgun slug shockwave+blast mines nematodes+worm-shot necrophoresis+necrophage the worm aspect now spawns 3 copies instead of just a lifespan reset --- .DS_Store | Bin 6148 -> 6148 bytes js/bullet.js | 166 ++++++++++++----- js/index.js | 9 +- js/level.js | 23 +-- js/player.js | 5 +- js/simulation.js | 5 +- js/tech.js | 453 ++++++++++++++++++++--------------------------- todo.txt | 62 +++++-- 8 files changed, 391 insertions(+), 332 deletions(-) diff --git a/.DS_Store b/.DS_Store index 5ca13c147c8653ba850077522c5f9526f4696d1a..72b112ce99827b6752070f7eb807991e7d0c7917 100644 GIT binary patch delta 21 ccmZoMXffEJ#mrP9GFgY&kMY9hYUWN607q8_e*gdg delta 21 ccmZoMXffEJ#mtoUd$JC*ALEA2)y$nD08q6DH~;_u diff --git a/js/bullet.js b/js/bullet.js index 6c833c4..e3d5b5e 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -82,12 +82,12 @@ const b = { }, fireWithAmmo() { //triggers after firing when you have ammo b.guns[b.activeGun].fire(); - if (tech.isCrouchAmmo && input.down) { - if (tech.isCrouchAmmo % 2) { + if (tech.crouchAmmoCount && input.down) { + if (tech.crouchAmmoCount % 2) { b.guns[b.activeGun].ammo--; simulation.updateGunHUD(); } - tech.isCrouchAmmo++ //makes the no ammo toggle off and on + tech.crouchAmmoCount++ //makes the no ammo toggle off and on } else { b.guns[b.activeGun].ammo--; simulation.updateGunHUD(); @@ -103,9 +103,9 @@ const b = { } }, refundAmmo() { //triggers after firing when you removed ammo for a gun, but didn't need to - if (tech.isCrouchAmmo && input.down) { - tech.isCrouchAmmo-- - if ((tech.isCrouchAmmo) % 2) { + if (tech.crouchAmmoCount && input.down) { + tech.crouchAmmoCount-- + if ((tech.crouchAmmoCount) % 2) { b.guns[b.activeGun].ammo++; simulation.updateGunHUD(); } @@ -1351,7 +1351,7 @@ const b = { grapple(where, angle = m.angle, harpoonSize = 1) { const me = bullet.length; const returnRadius = 100 * Math.sqrt(harpoonSize) - bullet[me] = Bodies.fromVertices(where.x, where.y, [{ x: -70 * harpoonSize, y: 3 * harpoonSize, index: 0, isInternal: false }, { x: -70 * harpoonSize, y: -3 * harpoonSize, index: 1, isInternal: false }, { x: 45 * harpoonSize, y: -2 * harpoonSize, index: 2, isInternal: false }, { x: 50 * harpoonSize, y: 0, index: 3, isInternal: false }, { x: 45 * harpoonSize, y: 2 * harpoonSize, index: 4, isInternal: false }], { + bullet[me] = Bodies.fromVertices(where.x, where.y, [{ x: -50 * harpoonSize, y: 2 * harpoonSize, index: 0, isInternal: false }, { x: -50 * harpoonSize, y: -2 * harpoonSize, index: 1, isInternal: false }, { x: 45 * harpoonSize, y: -3 * harpoonSize, index: 2, isInternal: false }, { x: 50 * harpoonSize, y: 0, index: 3, isInternal: false }, { x: 45 * harpoonSize, y: 3 * harpoonSize, index: 4, isInternal: false }], { angle: angle, friction: 1, frictionAir: 0.4, @@ -1420,8 +1420,20 @@ const b = { ctx.quadraticCurveTo(controlPoint.x, controlPoint.y, this.vertices[0].x, this.vertices[0].y) // ctx.lineTo(this.vertices[0].x, this.vertices[0].y); ctx.stroke(); - //draw hook - // ctx.beginPath(); + //draw harpoon spikes + const spikeLength = 2 + ctx.beginPath(); + const spike1 = Vector.add(this.vertices[1], Vector.mult(Vector.sub(this.vertices[1], this.vertices[2]), spikeLength)) + ctx.moveTo(this.vertices[2].x, this.vertices[2].y); + ctx.lineTo(spike1.x, spike1.y); + ctx.lineTo(this.vertices[3].x, this.vertices[3].y); + + const spike2 = Vector.add(this.vertices[3], Vector.mult(Vector.sub(this.vertices[3], this.vertices[2]), spikeLength)) + ctx.moveTo(this.vertices[2].x, this.vertices[2].y); + ctx.lineTo(spike2.x, spike2.y); + ctx.lineTo(this.vertices[1].x, this.vertices[1].y); + ctx.fillStyle = '#000' + ctx.fill(); }, returnToPlayer() { if (Vector.magnitude(Vector.sub(this.position, m.pos)) < returnRadius) { //near player @@ -2375,7 +2387,7 @@ const b = { ctx.globalAlpha = 1; } }, - AoEStunEffect(where, range, cycles = 150 + 120 * Math.random()) { + AoEStunEffect(where, range, cycles = 90 + 60 * Math.random()) { for (let i = 0, len = mob.length; i < len; ++i) { if (mob[i].alive && !mob[i].isShielded && !mob[i].shield && !mob[i].isBadTarget) { if (Vector.magnitude(Vector.sub(where, mob[i].position)) - mob[i].radius < range) mobs.statusStun(mob[i], cycles) @@ -2421,7 +2433,7 @@ const b = { Matter.Query.ray(map, this.position, mob[i].position).length === 0 && Matter.Query.ray(body, this.position, mob[i].position).length === 0 ) { - if (tech.isMineStun) b.AoEStunEffect(this.position, 1300); + if (tech.isExplosionStun) b.AoEStunEffect(this.position, 1300); this.do = this.laserSpin if (this.angularSpeed < 0.5) this.torque += this.inertia * this.torqueMagnitude * 200 //spin this.endCycle = simulation.cycle + 360 + 120 @@ -2555,7 +2567,7 @@ const b = { Matter.Query.ray(map, this.position, mob[i].position).length === 0 && Matter.Query.ray(body, this.position, mob[i].position).length === 0 ) { - if (tech.isMineStun) b.AoEStunEffect(this.position, 700 + mob[i].radius + random); + if (tech.isExplosionStun) b.AoEStunEffect(this.position, 700 + mob[i].radius + random); if (tech.isMineSentry) { this.lookFrequency = 8 + Math.floor(3 * Math.random()) this.endCycle = simulation.cycle + 1020 @@ -2619,13 +2631,15 @@ const b = { y: 100 * (Math.random() - 0.5) }, beforeDmg(who) { - if (tech.wormSurviveDmg && who.alive) { + if (tech.isSpawnBulletsOnDeath && who.alive && who.isDropPowerUp) { setTimeout(() => { if (!who.alive) { - this.endCycle = simulation.cycle + Math.floor((600 + Math.floor(Math.random() * 420)) * tech.isBulletsLastLonger); //bullet ends cycle resets - } else { - this.endCycle = 0; //bullet ends cycle after doing damage + for (let i = 0; i < 3; i++) { //spawn 3 more + b.worm(this.position) + bullet[bullet.length - 1].endCycle = Math.min(simulation.cycle + Math.floor(420 * tech.isBulletsLastLonger), this.endCycle + 180 + Math.floor(60 * Math.random())) //simulation.cycle + Math.floor(420 * tech.isBulletsLastLonger) + } } + this.endCycle = 0; //bullet ends cycle after doing damage }, 1); } else { this.endCycle = 0; //bullet ends cycle after doing damage @@ -2948,7 +2962,7 @@ const b = { const who = b.guns[b.activeGun] if (who.name === "drones" && who.ammo > 0 && mob.length) { b.drone({ x: this.position.x, y: this.position.y }, 0) - if (Math.random() < 0.25) { + if (Math.random() < 0.2) { b.guns[b.activeGun].ammo--; simulation.updateGunHUD(); } @@ -3143,7 +3157,7 @@ const b = { const who = b.guns[b.activeGun] if (who.name === "drones" && who.ammo > 0 && mob.length) { b.droneRadioactive({ x: this.position.x, y: this.position.y }, 0) - if (Math.random() < 0.25) { + if (Math.random() < 0.2) { b.guns[b.activeGun].ammo--; simulation.updateGunHUD(); } @@ -3409,7 +3423,7 @@ const b = { } else if (this.target !== null) { //look for a new target this.collisionFilter.category = cat.bullet; this.collisionFilter.mask = cat.mob //| cat.mobShield //cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield - if (tech.isFoamGrowOnDeath && bullet.length < 180 && !this.target.isMobBullet) { + if (tech.isSpawnBulletsOnDeath && bullet.length < 180 && !this.target.isMobBullet) { let targets = [] for (let i = 0, len = mob.length; i < len; i++) { const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)); @@ -4765,11 +4779,20 @@ const b = { y: SPEED * Math.sin(m.angle) }); bullet[me].endCycle = simulation.cycle + 180 + bullet[me].beforeDmg = function(who) { //beforeDmg is rewritten with ice crystal tech + if (tech.isIncendiary) { + this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion + b.explosion(this.position, 100 + (Math.random() - 0.5) * 20); //makes bullet do explosive damage at end + } if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.94) { b.explosion(this.position, 300 + 30 * Math.random()); //makes bullet do explosive damage at end } if (tech.isNailRadiation) mobs.statusDoT(who, 7 * (tech.isFastRadiation ? 0.7 : 0.24), tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles + if (this.speed > 4 && tech.fragments) { + b.targetedNail(this.position, 1.5 * tech.fragments * tech.nailSize) + this.endCycle = 0 //triggers despawn + } }; bullet[me].minDmgSpeed = 10 @@ -4829,10 +4852,18 @@ const b = { }); bullet[me].endCycle = simulation.cycle + 180 bullet[me].beforeDmg = function(who) { //beforeDmg is rewritten with ice crystal tech + if (tech.isIncendiary) { + this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion + b.explosion(this.position, 100 + (Math.random() - 0.5) * 20); //makes bullet do explosive damage at end + } if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.94) { b.explosion(this.position, 300 + 30 * Math.random()); //makes bullet do explosive damage at end } if (tech.isNailRadiation) mobs.statusDoT(who, 7 * (tech.isFastRadiation ? 0.7 : 0.24), tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles + if (this.speed > 4 && tech.fragments) { + b.targetedNail(this.position, 1.5 * tech.fragments * tech.nailSize) + this.endCycle = 0 //triggers despawn + } }; bullet[me].minDmgSpeed = 10 @@ -4913,8 +4944,8 @@ const b = { name: "shotgun", description: "fire a wide burst of short range bullets", ammo: 0, - ammoPack: 4, - defaultAmmoPack: 4, + ammoPack: 3.8, + defaultAmmoPack: 3.8, have: false, do() {}, fire() { @@ -4945,7 +4976,7 @@ const b = { b.muzzleFlash(35); - if (tech.isSlugShot) { + if (tech.isRivets) { const me = bullet.length; // const dir = m.angle + 0.02 * (Math.random() - 0.5) bullet[me] = Bodies.rectangle(m.pos.x + 35 * Math.cos(m.angle), m.pos.y + 35 * Math.sin(m.angle), 60 * tech.nailSize, 27 * tech.nailSize, b.fireAttributes(m.angle)); @@ -5048,20 +5079,17 @@ const b = { }, dmg) } } - } else if (tech.isWormShot) { - const where = { - x: m.pos.x + 35 * Math.cos(m.angle), - y: m.pos.y + 35 * Math.sin(m.angle) - } - const spread = (input.down ? 0.04 : 0.08) + } else if (tech.isSporeWorm) { + const where = { x: m.pos.x + 35 * Math.cos(m.angle), y: m.pos.y + 35 * Math.sin(m.angle) } + const spread = (input.down ? 0.02 : 0.07) const number = 3 * (tech.isShotgunReversed ? 1.6 : 1) + Math.random() let angle = m.angle - (number - 1) * spread * 0.5 for (let i = 0; i < number; i++) { b.worm(where) - const SPEED = (16 + 20 * input.down) * (1 + 0.15 * Math.random()) + const SPEED = (8 + 10 * input.down) * (1 + 0.15 * Math.random()) Matter.Body.setVelocity(bullet[bullet.length - 1], { - x: SPEED * Math.cos(angle), - y: SPEED * Math.sin(angle) + x: player.velocity.x * 0.5 + SPEED * Math.cos(angle), + y: player.velocity.y * 0.5 + SPEED * Math.sin(angle) }); angle += spread } @@ -5083,7 +5111,7 @@ const b = { const angle = m.angle + spread * (Math.random() - 0.5) b.foam(where, { x: SPEED * Math.cos(angle), y: SPEED * Math.sin(angle) }, 5 + 8 * Math.random()) } - } else if (tech.isNeedleShot) { + } else if (tech.isNeedles) { const number = 9 * (tech.isShotgunReversed ? 1.6 : 1) const spread = (input.down ? 0.03 : 0.05) let angle = m.angle - (number - 1) * spread * 0.5 @@ -5249,12 +5277,15 @@ const b = { propagationRate: 20, waves: [], //used in longitudinal mode chooseFireMethod() { //set in simulation.startGame - if (tech.is360Longitudinal) { - this.fire = this.fire360Longitudinal - this.do = this.do360Longitudinal - } else if (tech.isLongitudinal) { - this.fire = this.fireLongitudinal - this.do = this.doLongitudinal + this.waves = []; + if (tech.isLongitudinal) { + if (tech.is360Longitudinal) { + this.fire = this.fire360Longitudinal + this.do = this.do360Longitudinal + } else { + this.fire = this.fireLongitudinal + this.do = this.doLongitudinal + } } else { this.fire = this.fireTransverse this.do = this.doTransverse @@ -5567,7 +5598,7 @@ const b = { this.wavePacketCycle = 0; } }, - + fire() {} }, { name: "missiles", @@ -5817,11 +5848,53 @@ const b = { name: "foam", description: "spray bubbly foam that sticks to mobs
slows mobs and does damage over time", ammo: 0, - ammoPack: 22, + ammoPack: 24, have: false, charge: 0, isDischarge: false, - do() { + chooseFireMethod() { + if (tech.isCapacitor) { + this.do = this.doStream + this.fire = this.fireStream + } else { + this.do = this.doCharges // () => {} + this.fire = this.fireCharges + } + }, + doStream() {}, + fireStream() { + const spread = (input.down ? 0.04 : 0.3) * (Math.random() - 0.5) + const radius = 5 + 8 * Math.random() + (tech.isAmmoFoamSize && this.ammo < 300) * 12 + const SPEED = Math.max(2, 14 - radius * 0.25) + const dir = m.angle + 0.15 * (Math.random() - 0.5) + const velocity = { + x: SPEED * Math.cos(dir), + y: SPEED * Math.sin(dir) + } + const position = { + x: m.pos.x + 30 * Math.cos(m.angle), + y: m.pos.y + 30 * Math.sin(m.angle) + } + if (tech.foamFutureFire) { + simulation.drawList.push({ //add dmg to draw queue + x: position.x, + y: position.y, + radius: 5, + color: "rgba(0,50,50,0.3)", + time: 15 * tech.foamFutureFire + }); + setTimeout(() => { + if (!simulation.paused) { + b.foam(position, Vector.rotate(velocity, spread), radius) + bullet[bullet.length - 1].damage *= (1 + 0.7 * tech.foamFutureFire) + } + }, 210 * tech.foamFutureFire); + } else { + b.foam(position, Vector.rotate(velocity, spread), radius) + } + m.fireCDcycle = m.cycle + Math.floor(1.5 * b.fireCDscale); + }, + doCharges() { if (this.charge > 0) { //draw charge level ctx.fillStyle = "rgba(0,50,50,0.3)"; @@ -5833,7 +5906,7 @@ const b = { if (this.isDischarge) { this.charge-- - const spread = (input.down ? 0.05 : 0.6) * (Math.random() - 0.5) + const spread = (input.down ? 0.04 : 0.5) * (Math.random() - 0.5) const radius = 5 + 8 * Math.random() + (tech.isAmmoFoamSize && this.ammo < 300) * 12 const SPEED = 18 - radius * 0.4; const dir = m.angle + 0.15 * (Math.random() - 0.5) @@ -5874,7 +5947,7 @@ const b = { this.isDischarge = false } }, - fire() { + fireCharges() { const capacity = 20 if (tech.isCapacitor && this.charge === 0 && b.guns[b.activeGun].ammo > capacity) { this.charge = capacity @@ -5884,6 +5957,8 @@ const b = { this.charge++ m.fireCDcycle = m.cycle + Math.floor(1 + 0.3 * this.charge); }, + fire() {}, + do() {}, }, { name: "harpoon", @@ -6089,7 +6164,10 @@ const b = { this.ammo++ //make up for the ammo used up in fire() simulation.updateGunHUD(); m.fireCDcycle = m.cycle + Math.floor(75 * b.fireCDscale) // cool down + // } else if (input.down) { + // b.harpoon(where, null, m.angle, harpoonSize, false, 70) } else { + if (tech.crouchAmmoCount) tech.crouchAmmoCount = 1 b.grapple(where, m.angle, harpoonSize) } m.fireCDcycle = m.cycle + Math.floor(75 * b.fireCDscale) // cool down @@ -6974,7 +7052,7 @@ const b = { x: 7.5 * Math.cos(m.angle - Math.PI / 2), y: 7.5 * Math.sin(m.angle - Math.PI / 2) } - const dmg = 0.7 * tech.laserDamage // 3.5 * 0.55 = 200% more damage + const dmg = 0.66 * tech.laserDamage // 3.5 * 0.55 = 200% more damage const where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) } const eye = { x: m.pos.x + 15 * Math.cos(m.angle), diff --git a/js/index.js b/js/index.js index dacc841..ab77e25 100644 --- a/js/index.js +++ b/js/index.js @@ -7,7 +7,9 @@ Math.hash = s => { for (var i = 0, h = 9; i < s.length;) h = Math.imul(h ^ s.cha // console.log(date1.getUTCHours()) // document.getElementById("seed").placeholder = Math.initialSeed = String(date1.getUTCDate() * date1.getUTCFullYear()) // daily seed, day + year -document.getElementById("seed").placeholder = Math.initialSeed = Math.floor(Date.now() % 100000) //random every time: just the time in milliseconds UTC +// document.getElementById("seed").placeholder = Math.initialSeed = Math.floor(Date.now() % 100000) //random every time: just the time in milliseconds UTC + +document.getElementById("seed").placeholder = Math.initialSeed = String(Math.floor(Date.now() % 100000)) Math.seed = Math.abs(Math.hash(Math.initialSeed)) //update randomizer seed in case the player changed it Math.seededRandom = function(min = 0, max = 1) { // in order to work 'Math.seed' must NOT be undefined Math.seed = (Math.seed * 9301 + 49297) % 233280; @@ -1109,6 +1111,11 @@ window.addEventListener("keydown", function(event) { setTimeout(() => { for (let i = 0, len = mob.length; i < len; ++i) mob[i].damage(Infinity, true) }, 100); setTimeout(() => { for (let i = 0, len = mob.length; i < len; ++i) mob[i].damage(Infinity, true) }, 200); break + case "l": + document.getElementById("field").style.display = "none" + document.getElementById("guns").style.display = "none" + document.getElementById("tech").style.display = "none" + break } } }); diff --git a/js/level.js b/js/level.js index eacfe7b..26ee57b 100644 --- a/js/level.js +++ b/js/level.js @@ -16,10 +16,10 @@ const level = { if (level.levelsCleared === 0) { //this code only runs on the first level // simulation.isHorizontalFlipped = true // m.setField("time dilation") - // b.giveGuns("harpoon") - // for (let i = 0; i < 9; i++) tech.giveTech("smelting") - // tech.giveTech("exchange interaction") - // tech.giveTech("grappling hook") + b.giveGuns("harpoon") + tech.giveTech("railgun") + // tech.giveTech("necrophage") + // tech.giveTech("isotropic radiator") // for (let i = 0; i < 2; i++) powerUps.directSpawn(0, 0, "tech"); // for (let i = 0; i < 3; i++) tech.giveTech("undefined") // for (let i = 10; i < tech.tech.length; i++) { tech.tech[i].isBanished = true } @@ -32,7 +32,7 @@ const level = { // simulation.enableConstructMode() //used to build maps in testing mode // level.reactor(); // level.testing(); //not in rotation, used for testing - // level.pavilion() + // level.highrise() if (simulation.isTraining) { level.walk(); } else { level.intro(); } // powerUps.research.changeRerolls(3000) @@ -103,7 +103,8 @@ const level = { for (let j = 0, len = 5; j < len; j++) powerUps.spawn(level.exit.x + 100 * (Math.random() - 0.5), level.exit.y - 100 + 100 * (Math.random() - 0.5), "research", false) } for (let i = 0; i < tech.wimpExperiment; i++) spawn.WIMP() - if (tech.isFlipFlopLevelReset && !tech.isFlipFlopOn) { + // if (tech.isFlipFlopLevelReset && !tech.isFlipFlopOn) { + if ((tech.isRelay || tech.isFlipFlop) && !tech.isFlipFlopOn) { tech.isFlipFlopOn = true m.eyeFillColor = m.fieldMeterColor simulation.makeTextLog(`tech.isFlipFlopOn = true`); @@ -2538,16 +2539,16 @@ const level = { spawn.mapRect(4850, -275, 50, 175); //??? - level.difficultyIncrease(1) //30 is near max on hard //60 is near max on why + level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why m.addHealth(Infinity) // spawn.starter(1900, -500, 200) //big boy - // for (let i = 0; i < 10; ++i) spawn.hopper(1900, -500) + for (let i = 0; i < 10; ++i) spawn.hopper(1900, -500) // spawn.slashBoss(1900, -500) // spawn.launcherBoss(3200, -500) // spawn.laserTargetingBoss(1700, -500) // spawn.powerUpBoss(1900, -500) - spawn.powerUpBossBaby(3200, -500) + // spawn.powerUpBossBaby(3200, -500) // spawn.snakeBoss(1700, -500) // spawn.streamBoss(3200, -500) // spawn.pulsarBoss(1700, -500) @@ -4729,7 +4730,7 @@ const level = { const elevator1 = level.elevator(-790, -190, 180, 25, -1150, 0.0025, { up: 0.01, down: 0.2 }, true) //x, y, width, height, maxHeight, force = 0.003, friction = { up: 0.01, down: 0.2 }) { elevator1.addConstraint(); // const button1 = level.button(-500, -200) - const toggle1 = level.toggle(-500, -200) //(x,y,isOn,isLockOn = true/false) + const toggle1 = level.toggle(-300, -200) //(x,y,isOn,isLockOn = true/false) const elevator2 = level.elevator(-3630, -1000, 180, 25, -1740) //x, y, width, height, maxHeight, force = 0.003, friction = { up: 0.01, down: 0.2 }) { elevator2.addConstraint(); @@ -4843,7 +4844,7 @@ const level = { spawn.bodyRect(-75, -300, 50, 50); spawn.mapRect(-600, -200, 500, 250); //ledge for boarding elevator - spawn.bodyRect(-250, -300, 100, 100); //a nice block near the elevator + spawn.bodyRect(-500, -300, 100, 100, 0.6); //a nice block near the elevator spawn.bodyRect(-425, -1375, 400, 225); spawn.mapRect(-925, -1575, 50, 475); diff --git a/js/player.js b/js/player.js index 164af9e..62148a7 100644 --- a/js/player.js +++ b/js/player.js @@ -323,6 +323,7 @@ const m = { } if ( !tech.tech[i].isNonRefundable && + !tech.tech[i].isFromAppliedScience && tech.tech[i].name !== "many-worlds" && tech.tech[i].name !== "Ψ(t) collapse" && tech.tech[i].name !== "non-unitary operator" && @@ -891,7 +892,7 @@ const m = { isSneakAttack: false, duplicateChance: 0, energy: 0, - fieldRegen: 0, + fieldRegen: 0.001, fieldMode: 0, fieldFire: false, fieldHarmReduction: 1, @@ -923,7 +924,7 @@ const m = { if (removed) powerUps.directSpawn(m.pos.x, m.pos.y, "tech"); } if (m.energy < m.maxEnergy) m.energy = m.maxEnergy; - m.fieldRegen = 0.001 + // m.fieldRegen = 0.001 m.fieldMeterColor = "#0cf" m.eyeFillColor = m.fieldMeterColor m.fieldShieldingScale = 1; diff --git a/js/simulation.js b/js/simulation.js index 7e48d45..3e37190 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -399,7 +399,7 @@ const simulation = { } } } - if (tech.isCrouchAmmo) tech.isCrouchAmmo = 1 //this prevents hacking the tech by switching guns + if (tech.crouchAmmoCount) tech.crouchAmmoCount = 1 //this prevents hacking the tech by switching guns b.activeGun = b.inventory[b.inventoryGun]; if (b.guns[b.activeGun].charge) b.guns[b.activeGun].charge = 0; //if switching into foam set charge to 0 @@ -653,6 +653,7 @@ const simulation = { if (b.guns[i].name === "nail gun") b.guns[i].chooseFireMethod() if (b.guns[i].name === "super balls") b.guns[i].chooseFireMethod() if (b.guns[i].name === "harpoon") b.guns[i].chooseFireMethod() + if (b.guns[i].name === "foam") b.guns[i].chooseFireMethod() } tech.dynamoBotCount = 0; tech.nailBotCount = 0; @@ -778,7 +779,7 @@ const simulation = { } for (i = 0, len = b.guns.length; i < len; i++) { //find which gun is mine if (b.guns[i].name === "mine") { - if (tech.isCrouchAmmo) count = Math.ceil(count / 2) + if (tech.crouchAmmoCount) count = Math.ceil(count / 2) b.guns[i].ammo += count if (tech.ammoCap) b.guns[i].ammo = Math.min(tech.ammoCap, b.guns[i].ammo) simulation.updateGunHUD(); diff --git a/js/tech.js b/js/tech.js index e804f8a..b581cf6 100644 --- a/js/tech.js +++ b/js/tech.js @@ -610,10 +610,10 @@ const tech = { }, requires: "", effect() { - tech.isCrouchAmmo = true + tech.crouchAmmoCount = true }, remove() { - tech.isCrouchAmmo = false; + tech.crouchAmmoCount = false; } }, { @@ -624,7 +624,7 @@ const tech = { frequency: 1, frequencyDefault: 1, allowed() { - return !tech.isEnergyHealth //(tech.isCrouchAmmo || tech.isCrouchRegen) && + return !tech.isEnergyHealth //(tech.crouchAmmoCount || tech.isCrouchRegen) && }, requires: "not mass-energy", //inductive coupling, desublimated ammunition, effect() { @@ -821,7 +821,7 @@ const tech = { frequency: 2, frequencyDefault: 2, allowed() { - return tech.isStunField || tech.oneSuperBall || tech.isCloakStun || tech.orbitBotCount > 1 || tech.isExplosionStun || tech.isMineStun + return tech.isStunField || tech.oneSuperBall || tech.isCloakStun || tech.orbitBotCount > 1 || tech.isExplosionStun }, requires: "a stun effect", effect() { @@ -1619,7 +1619,7 @@ const tech = { }, { name: "Pauli exclusion", - description: `after receiving harm from a collision become
immune to harm for 1 extra second`, + description: `after receiving harm from a collision become
immune to harm for 1.5 extra seconds`, maxCount: 9, count: 0, frequency: 1, @@ -1627,8 +1627,8 @@ const tech = { allowed() { return true }, requires: "", effect() { - tech.collisionImmuneCycles += 60; - if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage for 30 cycles + tech.collisionImmuneCycles += 90; + if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage }, remove() { tech.collisionImmuneCycles = 30; @@ -1783,24 +1783,24 @@ const tech = { tech.isFlipFlopEnergy = false; } }, - { - name: "shift registers", - description: "set to the ON state
at the start of a level", - maxCount: 1, - count: 0, - frequency: 4, - frequencyDefault: 4, - allowed() { - return tech.isFlipFlopEnergy || tech.isFlipFlopDamage || tech.isFlipFlopHarm || tech.relayIce - }, - requires: "2 ON/OFF techs", - effect() { - tech.isFlipFlopLevelReset = true; - }, - remove() { - tech.isFlipFlopLevelReset = false; - } - }, + // { + // name: "shift registers", + // description: "set to the ON state
at the start of a level", + // maxCount: 1, + // count: 0, + // frequency: 4, + // frequencyDefault: 4, + // allowed() { + // return tech.isFlipFlopEnergy || tech.isFlipFlopDamage || tech.isFlipFlopHarm || tech.relayIce + // }, + // requires: "2 ON/OFF techs", + // effect() { + // tech.isFlipFlopLevelReset = true; + // }, + // remove() { + // tech.isFlipFlopLevelReset = false; + // } + // }, { name: "thermocouple", description: "if relay switch is in the ON state
condense 4-13 ice IX crystals every second", @@ -3341,7 +3341,7 @@ const tech = { frequencyDefault: 10, isNonRefundable: true, allowed() { - return tech.duplicationChance() > 0.7 + return tech.duplicationChance() > 0.6 }, requires: "duplication chance above 70%", effect() { @@ -3408,7 +3408,7 @@ const tech = { effect() { let pool = [] for (let i = 0, len = tech.tech.length; i < len; i++) { // spawn new tech power ups - if (tech.tech[i].count && !tech.tech[i].isNonRefundable) pool.push(i) + if (tech.tech[i].count && !tech.tech[i].isNonRefundable && !tech.tech[i].isFromAppliedScience) pool.push(i) } pool = shuffle(pool); //shuffles order of maps let removeCount = 0 @@ -3645,9 +3645,9 @@ const tech = { frequency: 2, frequencyDefault: 2, allowed() { - return (tech.isNeedles || tech.isNeedleShot) && !tech.needleTunnel + return (tech.isNeedles || tech.isNeedles) && !tech.needleTunnel }, - requires: "nail gun, needle gun, needle-shot, not nanowires", + requires: "nail gun, needle gun, not nanowires", effect() { tech.isNeedleIce = true }, @@ -3664,9 +3664,9 @@ const tech = { frequency: 2, frequencyDefault: 2, allowed() { - return ((tech.haveGunCheck("nail gun") && tech.isNeedles) || (tech.isNeedleShot && tech.haveGunCheck("shotgun"))) && !tech.isNeedleIce + return ((tech.haveGunCheck("nail gun") && tech.isNeedles) || (tech.isNeedles && tech.haveGunCheck("shotgun"))) && !tech.isNeedleIce }, - requires: "needle gun, needle-shot, not needle ice", + requires: "needle gun, not needle ice", effect() { tech.needleTunnel = true }, @@ -3676,16 +3676,16 @@ const tech = { }, { name: "needle gun", - description: "nail gun fires 3 mob piercing needles
requires 3 times more bullets", + description: "nail gun and shot gun fire mob piercing needles", isGunTech: true, maxCount: 1, count: 0, frequency: 2, frequencyDefault: 2, allowed() { - return tech.haveGunCheck("nail gun") && !tech.nailInstantFireRate && !tech.isIceCrystals && !tech.isRivets && !tech.nailRecoil + return ((tech.haveGunCheck("nail gun") && !tech.nailInstantFireRate && !tech.nailRecoil) || (tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isFoamShot && !tech.isSporeWorm)) && !tech.isRivets && !tech.isIncendiary && !tech.isIceCrystals }, - requires: "nail gun, not ice crystal, rivets, rotary cannon, or pneumatic actuator", + requires: "nail gun, shotgun, not ice crystal, rivets, rotary cannon, or pneumatic, incendiary, nail-shot, rivets, foam-shot, worm-shot, ice-shot", effect() { tech.isNeedles = true for (i = 0, len = b.guns.length; i < len; i++) { //find which gun @@ -3713,51 +3713,18 @@ const tech = { } } }, - // { - // 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", + description: "nail gun and shot gun slowly lob a heavy rivet", isGunTech: true, maxCount: 1, count: 0, frequency: 2, frequencyDefault: 2, allowed() { - return tech.haveGunCheck("nail gun") && !tech.nailInstantFireRate && !tech.isIceCrystals && !tech.isNeedles + return ((tech.haveGunCheck("nail gun") && !tech.nailInstantFireRate) || (tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isFoamShot && !tech.isSporeWorm)) && !tech.isNeedles && !tech.isIceCrystals }, - requires: "nail gun, not ice crystal, needles, or pneumatic actuator", + requires: "nail gun shot gun, not ice crystal, needles, or pneumatic actuator", effect() { tech.isRivets = true for (i = 0, len = b.guns.length; i < len; i++) { //find which gun @@ -3777,21 +3744,71 @@ const tech = { } } } + tech.isRivets = false } }, + // { + // name: "slug", + // description: "shotgun lobs 1 huge bullet", + // isGunTech: true, + // maxCount: 1, + // count: 0, + // frequency: 2, + // frequencyDefault: 2, + // allowed() { + // return tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIncendiary && !tech.isIceShot && !tech.isFoamShot && !tech.isSporeWorm && !tech.isNeedles + // }, + // requires: "shotgun, not nail-shot, foam-shot, worm-shot, ice-shot, needle-shot", + // effect() { + // tech.isSlugShot = true; + // for (i = 0, len = b.guns.length; i < len; i++) { //find which gun + // if (b.guns[i].name === "shotgun") { + // b.guns[i].do = function() { + // if (!input.field && input.down) { + // ctx.beginPath() + // const speed = input.down ? 212 : 160 + // const v = { x: speed * Math.cos(m.angle), y: speed * Math.sin(m.angle) } //m.Vy / 2 + removed to make the path less jerky + // const where = { x: m.pos.x, y: m.pos.y } + // for (let i = 0; i < 20; i++) { + // v.x *= 0.9712 + // v.y = v.y * 0.977 + 9.87 + // where.x += v.x + // where.y += v.y + // ctx.lineTo(where.x, where.y) + // } + // ctx.strokeStyle = "rgba(68, 68, 68, 0.2)" //color.map + // ctx.lineWidth = 2 + // ctx.stroke() + // } + // } + // break + // } + // } + // }, + // remove() { + // if (tech.isSlugShot) { + // for (i = 0, len = b.guns.length; i < len; i++) { //find which gun + // if (b.guns[i].name === "shotgun") { + // b.guns[i].do = function() {} + // break + // } + // } + // } + // tech.isSlugShot = false; + // } + // }, { name: "pneumatic hammer", - description: `rivets, slugs, needles, and nails are 18% larger
increases mass and physical damage`, + description: `rivets, needles, and nails are 18% larger
increases mass and physical damage`, isGunTech: true, maxCount: 9, count: 0, frequency: 2, frequencyDefault: 2, allowed() { - // return tech.haveGunCheck("nail gun") || tech.isSlugShot - return tech.isMineDrop + tech.nailBotCount + tech.fragments + tech.nailsDeathMob + ((tech.haveGunCheck("mine") && !tech.isLaserMine) + (tech.haveGunCheck("nail gun")) + tech.isNeedleShot + tech.isNailShot + tech.isSlugShot) * 2 > 1 + return tech.isMineDrop + tech.nailBotCount + tech.fragments + tech.nailsDeathMob + ((tech.haveGunCheck("mine") && !tech.isLaserMine) + (tech.haveGunCheck("nail gun")) + tech.isNeedles + tech.isNailShot + tech.isRivets) * 2 > 1 }, - requires: "nails, nail gun, rivets, shotgun, slug", + requires: "nails, nail gun, rivets, shotgun", effect() { tech.nailSize += 0.18 }, @@ -3901,9 +3918,9 @@ const tech = { frequency: 2, frequencyDefault: 2, allowed() { - return (tech.isNailShot || tech.isNeedleShot || tech.nailBotCount > 1 || tech.haveGunCheck("nail gun")) + return (tech.isNailShot || tech.isNeedles || tech.nailBotCount > 1 || tech.haveGunCheck("nail gun") || tech.isRivets) && !tech.isIncendiary }, - requires: "nail gun, nails", + requires: "needles, nails, rivets, not incendiary", effect() { tech.isNailCrit = true }, @@ -3921,7 +3938,7 @@ const tech = { 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.isShieldPierce) + 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.isNeedles + tech.isNailShot) * 2 > 1 }, requires: "nail gun, nails, rivets, not ceramic needles", effect() { @@ -4050,56 +4067,6 @@ const tech = { tech.isShotgunReversed = false; } }, - { - name: "slug", - description: "shotgun lobs 1 huge bullet", - isGunTech: true, - maxCount: 1, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIncendiary && !tech.isIceShot && !tech.isFoamShot && !tech.isWormShot && !tech.isNeedleShot - }, - requires: "shotgun, not nail-shot, foam-shot, worm-shot, ice-shot, needle-shot", - effect() { - tech.isSlugShot = true; - for (i = 0, len = b.guns.length; i < len; i++) { //find which gun - if (b.guns[i].name === "shotgun") { - b.guns[i].do = function() { - if (!input.field && input.down) { - ctx.beginPath() - const speed = input.down ? 212 : 160 - const v = { x: speed * Math.cos(m.angle), y: speed * Math.sin(m.angle) } //m.Vy / 2 + removed to make the path less jerky - const where = { x: m.pos.x, y: m.pos.y } - for (let i = 0; i < 20; i++) { - v.x *= 0.9712 - v.y = v.y * 0.977 + 9.87 - where.x += v.x - where.y += v.y - ctx.lineTo(where.x, where.y) - } - ctx.strokeStyle = "rgba(68, 68, 68, 0.2)" //color.map - ctx.lineWidth = 2 - ctx.stroke() - } - } - break - } - } - }, - remove() { - if (tech.isSlugShot) { - for (i = 0, len = b.guns.length; i < len; i++) { //find which gun - if (b.guns[i].name === "shotgun") { - b.guns[i].do = function() {} - break - } - } - } - tech.isSlugShot = false; - } - }, { name: "nail-shot", link: `nail-shot`, @@ -4110,9 +4077,9 @@ const tech = { frequency: 2, frequencyDefault: 2, allowed() { - return tech.haveGunCheck("shotgun") && !tech.isIncendiary && !tech.isSlugShot && !tech.isIceShot && !tech.isFoamShot && !tech.isWormShot && !tech.isNeedleShot + return tech.haveGunCheck("shotgun") && !tech.isIncendiary && !tech.isRivets && !tech.isIceShot && !tech.isFoamShot && !tech.isSporeWorm && !tech.isNeedles }, - requires: "shotgun, not incendiary, slug, foam-shot, worm-shot, ice-shot, needle-shot", + requires: "shotgun, not incendiary, rivets, foam-shot, worm-shot, ice-shot, needles", effect() { tech.isNailShot = true; }, @@ -4120,46 +4087,6 @@ const tech = { tech.isNailShot = false; } }, - { - name: "needle-shot", - link: `needle-shot`, - description: "shotgun propels 11 mob piercing needles", - isGunTech: true, - maxCount: 1, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIncendiary && !tech.isSlugShot && !tech.isFoamShot && !tech.isWormShot && !tech.isIceShot - }, - requires: "shotgun, not incendiary, nail-shot, slug, foam-shot, worm-shot, ice-shot", - effect() { - tech.isNeedleShot = true; - }, - remove() { - tech.isNeedleShot = false; - } - }, - { - name: "worm-shot", - link: `worm-shot`, - description: "shotgun hatches 3-4 mob seeking worms
worms benefit from spore technology", //
worms seek out nearby mobs - isGunTech: true, - maxCount: 1, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIncendiary && !tech.isSlugShot && !tech.isIceShot && !tech.isFoamShot && !tech.isNeedleShot - }, - requires: "shotgun, not incendiary, nail-shot, slug, foam-shot, ice-shot, needle-shot", - effect() { - tech.isWormShot = true; - }, - remove() { - tech.isWormShot = false; - } - }, { name: "foam-shot", link: `foam-shot`, @@ -4170,9 +4097,9 @@ const tech = { frequency: 2, frequencyDefault: 2, allowed() { - return tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIncendiary && !tech.isSlugShot && !tech.isIceShot && !tech.isWormShot && !tech.isNeedleShot + return tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIncendiary && !tech.isRivets && !tech.isIceShot && !tech.isSporeWorm && !tech.isNeedles }, - requires: "shotgun, not incendiary, nail-shot, slug, worm-shot, ice-shot, needle-shot", + requires: "shotgun, not incendiary, nail-shot, rivet, worm-shot, ice-shot, needle", effect() { tech.isFoamShot = true; }, @@ -4190,9 +4117,9 @@ const tech = { frequency: 2, frequencyDefault: 2, allowed() { - return tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIncendiary && !tech.isSlugShot && !tech.isFoamShot && !tech.isWormShot && !tech.isNeedleShot + return tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIncendiary && !tech.isRivets && !tech.isFoamShot && !tech.isSporeWorm && !tech.isNeedles }, - requires: "shotgun, not incendiary, nail-shot, slug, foam-shot, worm-shot", + requires: "shotgun, not incendiary, nail-shot, rivet, foam-shot, worm-shot", effect() { tech.isIceShot = true; }, @@ -4202,16 +4129,16 @@ const tech = { }, { name: "incendiary ammunition", - description: "shotgun, super balls, and drones
are loaded with explosives", + description: "rivets, super balls, and drones
are loaded with explosives", isGunTech: true, maxCount: 1, count: 0, frequency: 1, frequencyDefault: 1, allowed() { - return ((m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && !(tech.isDroneTeleport || tech.isDroneRadioactive || tech.isSporeField || tech.isMissileField || tech.isIceField)) || (tech.haveGunCheck("drones") && !tech.isForeverDrones && !tech.isDroneRadioactive && !tech.isDroneTeleport) || tech.haveGunCheck("super balls") || tech.haveGunCheck("shotgun")) && !tech.isNailShot && !tech.isIceShot && !tech.isFoamShot && !tech.isWormShot && !tech.isNeedleShot + return tech.haveGunCheck("super balls") || (tech.isRivets && !tech.isNailCrit) || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && !(tech.isDroneTeleport || tech.isDroneRadioactive || tech.isSporeField || tech.isMissileField || tech.isIceField)) || (tech.haveGunCheck("drones") && !tech.isForeverDrones && !tech.isDroneRadioactive && !tech.isDroneTeleport) }, - requires: "super balls, basic or slug shotgun, drones, not irradiated drones or burst drones", + requires: "super balls, rivets, drones, not irradiated drones or burst drones", effect() { tech.isIncendiary = true }, @@ -4534,16 +4461,16 @@ const tech = { }, { name: "fragmentation", - description: "some detonations and collisions eject nails
blocks, grenades, missiles, slugs, harpoon", + description: "some detonations and collisions eject nails
blocks, grenades, missiles, rivets, harpoon", isGunTech: true, maxCount: 9, count: 0, frequency: 1, frequencyDefault: 1, allowed() { - return tech.haveGunCheck("harpoon") || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("missiles") || tech.missileBotCount || (tech.haveGunCheck("shotgun") && tech.isSlugShot) || tech.blockDamage > 0.075 + return tech.haveGunCheck("harpoon") || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("missiles") || tech.missileBotCount || tech.isRivets || tech.blockDamage > 0.075 }, - requires: "grenades, missiles, shotgun slugs, harpoon, or mass driver", + requires: "grenades, missiles, rivets, harpoon, or mass driver", effect() { tech.fragments++ }, @@ -4611,14 +4538,14 @@ const tech = { }, { name: "shock wave", - description: "explosions stun mobs for 1-2 seconds
decrease explosive damage by 30%", + description: "mines and explosions stun for 1-2 seconds
decrease explosive damage by 30%", isGunTech: true, maxCount: 1, count: 0, frequency: 1, frequencyDefault: 1, allowed() { - return !tech.isExplodeRadio && tech.hasExplosiveDamageCheck() + return tech.haveGunCheck("mine") || (!tech.isExplodeRadio && tech.hasExplosiveDamageCheck()) }, requires: "an explosive damage source, not iridium-192", effect() { @@ -4628,6 +4555,26 @@ const tech = { tech.isExplosionStun = false; } }, + // { + // name: "blast mines", + // link: `blast mines`, + // description: "when a mine activates
it stuns nearby mobs for 2-4 seconds", + // isGunTech: true, + // maxCount: 1, + // count: 0, + // frequency: 2, + // frequencyDefault: 2, + // allowed() { + // return tech.haveGunCheck("mine") + // }, + // requires: "mines", + // effect() { + // tech.isMineStun = true; + // }, + // remove() { + // tech.isMineStun = false; + // } + // }, { name: "controlled explosion", description: `use ${powerUps.orb.research(3)} to dynamically reduce all
explosions until they do no harm`, @@ -4895,26 +4842,6 @@ const tech = { tech.isMineSentry = false; } }, - { - name: "blast mines", - link: `blast mines`, - description: "when a mine activates
it stuns nearby mobs for 2-4 seconds", - isGunTech: true, - maxCount: 1, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return tech.haveGunCheck("mine") - }, - requires: "mines", - effect() { - tech.isMineStun = true; - }, - remove() { - tech.isMineStun = false; - } - }, { name: "mycelial fragmentation", link: `mycelial fragmentation`, @@ -4965,7 +4892,7 @@ const tech = { frequency: 2, frequencyDefault: 2, allowed() { - return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField || tech.isWormShot + return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField || tech.isSporeWorm }, requires: "spore gun, spores or worms", effect() { @@ -4984,7 +4911,7 @@ const tech = { frequency: 2, frequencyDefault: 2, allowed() { - return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField || tech.isWormShot + return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField || tech.isSporeWorm }, requires: "spore gun, spores or worms", effect() { @@ -5003,7 +4930,7 @@ const tech = { frequency: 2, frequencyDefault: 2, allowed() { - return (tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField) && !tech.isEnergyHealth || tech.isWormShot + return (tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField) && !tech.isEnergyHealth || tech.isSporeWorm }, requires: "spore gun, spores, worms, not mass-energy", effect() { @@ -5013,16 +4940,36 @@ const tech = { tech.isMutualism = false } }, + // { + // name: "worm-shot", + // link: `worm-shot`, + // description: "shotgun hatches 3-4 mob seeking worms
worms benefit from spore technology", //
worms seek out nearby mobs + // isGunTech: true, + // maxCount: 1, + // count: 0, + // frequency: 2, + // frequencyDefault: 2, + // allowed() { + // return tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIncendiary && !tech.isRivets && !tech.isIceShot && !tech.isFoamShot && !tech.isNeedles + // }, + // requires: "shotgun, not incendiary, nail-shot, rivets, foam-shot, ice-shot, needles", + // effect() { + // tech.isWormShot = true; + // }, + // remove() { + // tech.isWormShot = false; + // } + // }, { name: "nematodes", - description: "spores develop into 1/2 as many worms
worms do 250% more damage", + description: "shotgun and sporangium hatch worms", //
worms do 250% more damage isGunTech: true, maxCount: 1, count: 0, frequency: 3, frequencyDefault: 3, allowed() { - return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField || tech.isWormholeSpores + return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField || tech.isWormholeSpores || (tech.haveGunCheck("shotgun") && !tech.isIncendiary && !tech.isRivets && !tech.isIceShot && !tech.isFoamShot && !tech.isNeedles && !tech.isNailShot) }, requires: "spore gun, spores", effect() { @@ -5041,7 +4988,7 @@ const tech = { frequency: 3, frequencyDefault: 3, allowed() { - return tech.isSporeWorm || tech.isWormShot + return tech.isSporeWorm }, requires: "spore gun, shotgun, worms", effect() { @@ -5051,25 +4998,6 @@ const tech = { tech.wormSize = 0 } }, - { - name: "necrophage", - description: "if worms kill their target
they reset their lifespan", - isGunTech: true, - maxCount: 1, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return tech.isSporeWorm || tech.isWormShot - }, - requires: "spore gun, shotgun, worms", - effect() { - tech.wormSurviveDmg = true - }, - remove() { - tech.wormSurviveDmg = false - } - }, { name: "anti-shear topology", link: `anti-shear topology`, @@ -5080,7 +5008,7 @@ const tech = { frequency: 2, frequencyDefault: 2, allowed() { - return m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || tech.haveGunCheck("spores") || tech.haveGunCheck("drones") || tech.haveGunCheck("missiles") || tech.haveGunCheck("foam") || tech.haveGunCheck("matter wave") || tech.isNeutronBomb || tech.isIceField || tech.isIceShot || tech.relayIce || tech.isNeedleIce || tech.blockingIce > 1 || tech.isWormShot || tech.foamBotCount > 1 + return m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || tech.haveGunCheck("spores") || tech.haveGunCheck("drones") || tech.haveGunCheck("missiles") || tech.haveGunCheck("foam") || tech.haveGunCheck("matter wave") || tech.isNeutronBomb || tech.isIceField || tech.isIceShot || tech.relayIce || tech.isNeedleIce || tech.blockingIce > 1 || tech.isSporeWorm || tech.foamBotCount > 1 }, requires: "drones, spores, missiles, foam, matter wave, neutron bomb, ice IX", effect() { @@ -5143,7 +5071,7 @@ const tech = { { name: "drone repair", link: `drone repair`, - description: "after a drone expires it redeploys
for a 25% chance to use 1 drone ammo", + description: "after a drone expires it redeploys
for a 20% chance to use 1 drone ammo", // description: "broken drones repair if the drone gun is active
repairing has a 25% chance to use 1 drone", isGunTech: true, maxCount: 1, @@ -5276,7 +5204,7 @@ const tech = { }, { name: "fault tolerance", - description: "spawn 8 drones that last forever
remove your drone gun", + description: "spawn 6 drones that last forever
remove your drone gun", isGunTech: true, isRemoveGun: true, maxCount: 1, @@ -5288,7 +5216,7 @@ const tech = { }, requires: "drones, not drone repair, anti-shear topology", effect() { - const num = 8 + const num = 6 tech.isForeverDrones += num if (tech.haveGunCheck("drones", false)) b.removeGun("drones") //spawn drones @@ -5311,7 +5239,7 @@ const tech = { }, { name: "surfactant", - description: "trade your foam gun for 2 foam-bots
and upgrade all bots to foam
", + description: "trade your foam gun for 2 foam-bots
and upgrade all bots to foam", isGunTech: true, isRemoveGun: true, maxCount: 1, @@ -5321,9 +5249,9 @@ const tech = { isBot: true, isBotTech: true, isNonRefundable: true, - requires: "foam gun, NOT EXPERIMENT MODE, bot upgrades, fractionation, quantum foam", + requires: "at least 3 guns, foam gun, NOT EXPERIMENT MODE, bot upgrades, fractionation, quantum foam, capacitor", allowed() { - return tech.haveGunCheck("foam", false) && !b.hasBotUpgrade() && !tech.isAmmoFoamSize && !tech.foamFutureFire + return b.inventory.length > 2 && tech.haveGunCheck("foam", false) && !b.hasBotUpgrade() && !tech.isAmmoFoamSize && !tech.foamFutureFire && !tech.isCapacitor }, effect() { tech.giveTech("foam-bot upgrade") @@ -5381,22 +5309,22 @@ const tech = { } }, { - name: "necrophoresis", - description: "foam bubbles grow and split into 3 copies
when the mob they are stuck to dies", + name: "necrophage", + description: "if foam or worms kill their target
grow 3 copies", isGunTech: true, maxCount: 1, count: 0, frequency: 2, frequencyDefault: 2, allowed() { - return tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot + return tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot || tech.isSporeWorm }, - requires: "foam", + requires: "foam, worms", effect() { - tech.isFoamGrowOnDeath = true + tech.isSpawnBulletsOnDeath = true }, remove() { - tech.isFoamGrowOnDeath = false; + tech.isSpawnBulletsOnDeath = false; } }, { @@ -5473,14 +5401,26 @@ const tech = { requires: "throwing blocks, railgun, foam, pulse, tokamak", effect() { tech.isCapacitor = true; + for (i = 0, len = b.guns.length; i < len; i++) { //find which gun + if (b.guns[i].name === "foam") { + b.guns[i].chooseFireMethod() + break + } + } }, remove() { tech.isCapacitor = false; + for (i = 0, len = b.guns.length; i < len; i++) { //find which gun + if (b.guns[i].name === "foam") { + b.guns[i].chooseFireMethod() + break + } + } } }, { name: "railgun", - description: `harpoons are 50% denser, but don't retract
gain 500% more harpoon ammo per ${powerUps.orb.ammo(1)}`, + description: `harpoons are 50% denser, but don't retract
gain 600% more harpoon ammo per ${powerUps.orb.ammo(1)}`, isGunTech: true, maxCount: 1, count: 0, @@ -5490,7 +5430,7 @@ const tech = { return tech.haveGunCheck("harpoon") && !tech.isFilament && !tech.isHarpoonPowerUp && !tech.isGrapple }, requires: "harpoon, not filament, toggling harpoon, grappling hook", - ammoBonus: 5, + ammoBonus: 6, effect() { tech.isRailGun = true; for (i = 0, len = b.guns.length; i < len; i++) { //find which gun @@ -5558,7 +5498,7 @@ const tech = { // }, { name: "grappling hook", - description: `harpoons attach to the map and pull you in
your rope extends while holding fire`, + description: `harpoons attach to the map and pull you
your rope extends while holding fire`, isGunTech: true, maxCount: 1, count: 0, @@ -5630,9 +5570,9 @@ const tech = { frequency: 2, frequencyDefault: 2, allowed() { - return (!tech.isLargeHarpoon && tech.haveGunCheck("harpoon")) || (tech.isNeedles || tech.isNeedleShot) + return (!tech.isLargeHarpoon && tech.haveGunCheck("harpoon")) || tech.isNeedles }, - requires: "nail gun, needle gun, needle-shot, harpoon, not Bessemer process", + requires: "nail gun, needle gun, needle, harpoon, not Bessemer process", effect() { tech.isShieldPierce = true }, @@ -5662,28 +5602,29 @@ const tech = { { name: "smelting", // description: `spend ${powerUps.orb.ammo(2)}to upgrade the harpoon
fire +1 harpoon with each shot`, - description: `forge 2 ammo into a new harpoon
fire +1 harpoon with each shot`, + description: `forge 3 ammo into a new harpoon
fire +1 harpoon with each shot`, // descriptionFunction() { return `forge ${tech.isRailGun? 10: 2} ammo into a new harpoon
fire +1 harpoon with each shot` }, isGunTech: true, maxCount: 9, count: 0, - frequency: 2, - frequencyDefault: 2, + frequency: 1, + frequencyDefault: 1, allowed() { - return tech.haveGunCheck("harpoon") && b.returnGunAmmo('harpoon') > 1 + this.count * 2 + return tech.haveGunCheck("harpoon") && b.returnGunAmmo('harpoon') > 2 + this.count * 3 }, requires: "harpoon", effect() { for (i = 0, len = b.guns.length; i < len; i++) { //find which gun if (b.guns[i].name === "harpoon") { - b.guns[i].ammo -= 2 + this.count + b.guns[i].ammo -= 3 + this.count * 3 + console.log(3 + this.count * 3) if (b.guns[i].ammo < 0) b.guns[i].ammo = 0 simulation.updateGunHUD(); tech.extraHarpoons++; break } } - this.description = `forge ${2+(this.count+1)*2} ammo into a new harpoon
fire +1 harpoon with each shot` + this.description = `forge ${3+(this.count+1)*3} ammo into a new harpoon
fire +1 harpoon with each shot` }, remove() { if (tech.extraHarpoons) { @@ -5930,7 +5871,7 @@ const tech = { }, { name: "output coupler", - description: "widen diffuse laser beam by 40%
increase full beam damage by 40%", + description: "widen diffuse laser beam by 30%
increase full beam damage by 30%", isGunTech: true, maxCount: 9, count: 0, @@ -6167,7 +6108,7 @@ const tech = { }, { name: "eddy current brake", - description: "project a field that limits the top speed of mobs
field radius scales with stored energy", + description: "perfect diamagnetism slows nearby mobs
effect radius scales with stored energy", isFieldTech: true, maxCount: 1, count: 0, @@ -9188,7 +9129,7 @@ const tech = { bulletSize: null, energySiphon: null, healthDrain: null, - isCrouchAmmo: null, + crouchAmmoCount: null, isBulletsLastLonger: null, isImmortal: null, sporesOnDeath: null, @@ -9378,7 +9319,7 @@ const tech = { isFlipFlop: null, isFlipFlopHarm: null, isFlipFlopOn: null, - isFlipFlopLevelReset: null, + // isFlipFlopLevelReset: null, isFlipFlopDamage: null, isFlipFlopEnergy: null, isRelay: null, @@ -9430,17 +9371,13 @@ const tech = { isFastTime: null, isAnthropicTech: null, isSporeWorm: null, - isWormShot: null, isFoamShot: null, isIceShot: null, - isNeedleShot: null, isBlockRestitution: null, isZeno: null, isFieldFree: null, - wormSurviveDmg: null, isExtraGunField: null, isBigField: null, - isMineStun: null, isSmartRadius: null, isFilament: null, isLargeHarpoon: null, diff --git a/todo.txt b/todo.txt index 482b72f..c539424 100644 --- a/todo.txt +++ b/todo.txt @@ -1,19 +1,55 @@ ******************************************************** NEXT PATCH ************************************************** -grapple goes 40% farther before it retracts automatically -grapple now works well with fire delay reduction - or it's annoying, you decide! -smelting cost more ammo as you increase stacks - -grappling hook tech: bulk modulus - immune to harm while grappling, but drain a bit of energy - -particle collider renamed pure science - and it gives 1 research instead of energy when it fails: 4% chance +railgun and foam have a bit more ammo +capacitor bank makes foam gun fire a stream of foam +tech shift registers is now always on + (set ON/OFF to ON at the start of a new level) +tech from applied science doesn't count for various tech that convert tech into other things (pure science, many worlds) +grappling hook now shows hooks on the grapple +merged similar gun tech + needle gun+needle shot + rivet gun+shotgun slug + shockwave+blast mines + nematodes+worm-shot + necrophoresis+necrophage + the worm aspect now spawns 3 copies instead of just a lifespan reset + ******************************************************** TODO ******************************************************** +buff railgun + damage? ammo? + make railgun push blocks in the same direction railgun moves + make block intangible for a sec, like a block throw + +buff drone tech, but not drones? + +const ctx = canvas.getContext('2d', {‘willReadFrequently': true}); + +//deal with game crashes? +canvas.addEventListener("contextlost", onContextLost); +canvas.addEventListener("contextrestored", redraw); +ctx.reset(); + +a mine tech that makes mines you can stand on + works similar to the field block throwing system + but you don't need to find a block to throw + blocks explode after mobs touch them + or 3 seconds after you touch them + benefits from all block tech + +setting to remove UI, except health bar + except active gun? to see ammo + checkbox in pause and in settings + +bug: often game puts player position at NaN + clues: + after apoximis? + vanish level? + very high level for tech, duplication + maybe not about JUNK though + grappling hook - draw the hook part directly - two backwards angled spikes near the front give player more control over motion while hanging and retracting reduce friction effects so player swing around? up down left right push player around? @@ -27,10 +63,6 @@ add coyote jump log game m.cycle when last on ground for jump check if game cycle is < last on ground cycle -2 -setting to remove UI, except health bar - except active gun? to see ammo - checkbox in pause and in settings - tech - Plasma railgun like foam, or phonon? @@ -41,6 +73,8 @@ pause time like invariant for other things... bug - url sharing still broken sometimes +maybe? timing QTE for charging effects, if you fire right before the charge gets full it's better + +damage for each different bot type you have disables bot upgrades?