diff --git a/.DS_Store b/.DS_Store index b80255a..4469fa6 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/js/bullet.js b/js/bullet.js index 125b9f7..ded5cbb 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -765,7 +765,7 @@ const b = { bullet[me].explodeRad = 300 * size; bullet[me].onEnd = function() { b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end - if (tech.fragments) b.targetedNail(this.position, tech.fragments * Math.floor(2 + 2 * Math.random())) + if (tech.fragments) b.targetedNail(this.position, tech.fragments * Math.floor(2 + 1.5 * Math.random())) } bullet[me].minDmgSpeed = 1; bullet[me].beforeDmg = function() { @@ -790,7 +790,7 @@ const b = { bullet[me].explodeRad = 305 * size; bullet[me].onEnd = function() { b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end - if (tech.fragments) b.targetedNail(this.position, tech.fragments * Math.floor(2 + 2 * Math.random())) + if (tech.fragments) b.targetedNail(this.position, tech.fragments * Math.floor(2 + 1.5 * Math.random())) } bullet[me].minDmgSpeed = 1; bullet[me].beforeDmg = function() { @@ -825,7 +825,7 @@ const b = { bullet[me].explodeRad = 350 * size + Math.floor(Math.random() * 50) + tech.isBlockExplode * 110 bullet[me].onEnd = function() { b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end - if (tech.fragments) b.targetedNail(this.position, tech.fragments * Math.floor(2 + 2 * Math.random())) + if (tech.fragments) b.targetedNail(this.position, tech.fragments * Math.floor(2 + 1.5 * Math.random())) } bullet[me].minDmgSpeed = 1; bullet[me].beforeDmg = function() { @@ -902,7 +902,7 @@ const b = { bullet[me].explodeRad = 350 * size + Math.floor(Math.random() * 50) + tech.isBlockExplode * 100 bullet[me].onEnd = function() { b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end - if (tech.fragments) b.targetedNail(this.position, tech.fragments * 5) + if (tech.fragments) b.targetedNail(this.position, tech.fragments * Math.floor(2 + 1.5 * Math.random())) } bullet[me].beforeDmg = function() { this.endCycle = 0; //bullet ends cycle after doing damage //this also triggers explosion @@ -1253,7 +1253,7 @@ const b = { requestAnimationFrame(() => { who.isShielded = true }); } if (tech.fragments) { - b.targetedNail(this.vertices[2], tech.fragments * 4) + b.targetedNail(this.vertices[2], tech.fragments * Math.floor(2 + 1.5 * Math.random())) this.endCycle = 0; } if (!who.isBadTarget) { @@ -1373,7 +1373,7 @@ const b = { requestAnimationFrame(() => { who.isShielded = true }); } if (tech.fragments) { - b.targetedNail(this.vertices[2], tech.fragments * 3) + b.targetedNail(this.vertices[2], tech.fragments * Math.floor(2 + Math.random())) } // if (!who.isBadTarget) { // this.do = this.returnToPlayer @@ -1635,7 +1635,7 @@ const b = { requestAnimationFrame(() => { who.isShielded = true }); } if (tech.fragments) { - b.targetedNail(this.vertices[2], tech.fragments * 3) + b.targetedNail(this.vertices[2], tech.fragments * Math.floor(2 + Math.random())) if (!isReturn) this.endCycle = 0; } if (!who.isBadTarget) { @@ -1927,7 +1927,7 @@ const b = { }, onEnd() { b.explosion(this.position, this.explodeRad * size); //makes bullet do explosive damage at end - if (tech.fragments) b.targetedNail(this.position, tech.fragments * Math.floor(2 + 2 * Math.random())) + if (tech.fragments) b.targetedNail(this.position, tech.fragments * Math.floor(2 + 1.5 * Math.random())) }, lockedOn: null, tryToLockOn() { @@ -2002,7 +2002,7 @@ const b = { didExtruderDrain: false, canExtruderFire: true, extruder() { - const DRAIN = 0.0021 + const DRAIN = 0.0018 if (m.energy > DRAIN && b.canExtruderFire) { m.energy -= DRAIN if (m.energy < 0) { @@ -2854,7 +2854,6 @@ const b = { }, minDmgSpeed: 0, lockedOn: null, - isFollowMouse: true, beforeDmg(who) { mobs.statusSlow(who, 180) this.endCycle = simulation.cycle @@ -2923,17 +2922,17 @@ const b = { 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 - bullet.length), classType: "bullet", + isDrone: true, collisionFilter: { category: cat.bullet, mask: cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield //self collide }, minDmgSpeed: 0, lockedOn: null, - isFollowMouse: true, deathCycles: 110 + RADIUS * 5, isImproved: false, beforeDmg(who) { - if (tech.isIncendiary && simulation.cycle + this.deathCycles < this.endCycle) { + if (tech.isIncendiary && simulation.cycle + this.deathCycles < this.endCycle && !tech.isForeverDrones) { const max = Math.max(Math.min(this.endCycle - simulation.cycle - this.deathCycles, 1500), 0) b.explosion(this.position, max * 0.1 + this.isImproved * 110 + 60 * Math.random()); //makes bullet do explosive damage at end if (tech.isForeverDrones) { @@ -3127,6 +3126,7 @@ const b = { 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 * bullet.length), classType: "bullet", + isDrone: true, collisionFilter: { category: cat.bullet, mask: cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield //self collide @@ -3134,7 +3134,6 @@ const b = { minDmgSpeed: 0, speedCap: 5 + 2 * Math.random(), //6 is normal lockedOn: null, - isFollowMouse: true, deathCycles: 110 + RADIUS * 5, isImproved: false, radioRadius: 0, @@ -4790,7 +4789,7 @@ const b = { } 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.bulletSize) + b.targetedNail(this.position, 1.25 * tech.fragments * tech.bulletSize) this.endCycle = 0 //triggers despawn } }; @@ -4861,7 +4860,7 @@ const b = { } 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.bulletSize) + b.targetedNail(this.position, 1.25 * tech.fragments * tech.bulletSize) this.endCycle = 0 //triggers despawn } }; @@ -5017,7 +5016,7 @@ const b = { if (tech.fragments) { bullet[me].beforeDmg = function() { if (this.speed > 4) { - b.targetedNail(this.position, 7 * tech.fragments * tech.bulletSize) + b.targetedNail(this.position, 6 * tech.fragments * tech.bulletSize) this.endCycle = 0 //triggers despawn } } diff --git a/js/level.js b/js/level.js index 91be3b9..38f2131 100644 --- a/js/level.js +++ b/js/level.js @@ -15,13 +15,13 @@ const level = { start() { if (level.levelsCleared === 0) { //this code only runs on the first level // simulation.isHorizontalFlipped = true - // m.setField("time dilation") - // b.giveGuns("foam") - // tech.giveTech("quantum foam") - // tech.giveTech("capacitor bank") - // tech.giveTech("isotropic radiator") + // m.setField("molecular assembler") + // b.giveGuns("drones") + // tech.giveTech("autonomous navigation") + // tech.giveTech("delivery drone") + // tech.giveTech("dynamo-bot upgrade") // 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 = 0; i < 9; i++) tech.giveTech("dynamo-bot") // for (let i = 10; i < tech.tech.length; i++) { tech.tech[i].isBanished = true } // powerUps.research.changeRerolls(100000) // for (let i = 0; i < 2; i++) tech.giveTech("laser-bot") diff --git a/js/mob.js b/js/mob.js index 97fbf9c..296d2f9 100644 --- a/js/mob.js +++ b/js/mob.js @@ -1151,7 +1151,7 @@ const mobs = { for (let i = 0; i < len; i++) b.spore(this.position) } } else if (tech.isExplodeMob) { - b.explosion(this.position, Math.min(600, Math.sqrt(this.mass + 1.5) * (22 + 60 * Math.random()))) + b.explosion(this.position, Math.min(700, Math.sqrt(this.mass + 6) * (30 + 60 * Math.random()))) } else if (tech.nailsDeathMob) { b.targetedNail(this.position, tech.nailsDeathMob, 39 + 6 * Math.random()) } diff --git a/js/player.js b/js/player.js index 62148a7..9306255 100644 --- a/js/player.js +++ b/js/player.js @@ -1957,11 +1957,12 @@ const m = { // 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 (m.energy > m.maxEnergy - 0.02 && m.fieldCDcycle < m.cycle && !input.field && bullet.length < 300 && (m.cycle % 2)) { if (tech.isSporeField) { if (tech.isSporeWorm) { - if (m.energy > 0.16) { - m.energy -= 0.16 + const drain = 0.16 + (Math.max(bullet.length, 130) - 130) * 0.02 + if (m.energy > drain) { + m.energy -= drain b.worm({ x: m.pos.x + 35 * Math.cos(m.angle), y: m.pos.y + 35 * Math.sin(m.angle) }) const SPEED = 2 + 1 * Math.random(); Matter.Body.setVelocity(bullet[bullet.length - 1], { @@ -1970,13 +1971,13 @@ const m = { }); } } else { + const drain = 0.08 + (Math.max(bullet.length, 130) - 130) * 0.01 for (let i = 0, len = Math.random() * 20; i < len; i++) { - m.energy -= 0.08 - if (m.energy > 0) { + if (m.energy > drain) { + m.energy -= drain b.spore(m.pos) } else { - m.energy = 0.001 - break; + break } } } @@ -1987,11 +1988,19 @@ const m = { m.energy -= 0.04; b.iceIX(1) } else if (tech.isDroneRadioactive) { - m.energy -= 0.8; - b.droneRadioactive({ x: m.pos.x + 30 * Math.cos(m.angle) + 10 * (Math.random() - 0.5), y: m.pos.y + 30 * Math.sin(m.angle) + 10 * (Math.random() - 0.5) }, 25) + const drain = 0.8 + (Math.max(bullet.length, 50) - 50) * 0.01 + if (m.energy > drain) { + m.energy -= drain + b.droneRadioactive({ x: m.pos.x + 30 * Math.cos(m.angle) + 10 * (Math.random() - 0.5), y: m.pos.y + 30 * Math.sin(m.angle) + 10 * (Math.random() - 0.5) }, 25) + } } else { - m.energy -= 0.45 * tech.droneEnergyReduction; - b.drone() + //every bullet above 100 adds 0.005 to the energy cost per drone + //at 200 bullets the energy cost is 0.45 + 100*0.006 = 1.05 + const drain = (0.45 + (Math.max(bullet.length, 100) - 100) * 0.006) * tech.droneEnergyReduction + if (m.energy > drain) { + m.energy -= drain + b.drone() + } } } @@ -2775,7 +2784,7 @@ const m = { for (let i = 0, len = body.length; i < len; ++i) { if (Vector.magnitude(Vector.sub(body[i].position, m.fieldPosition)) < m.fieldRadius && !body[i].isNotHoldable) { - const DRAIN = speed * body[i].mass * 0.000006 // * (1 + m.energy * m.energy) //drain more energy when you have more energy + const DRAIN = speed * body[i].mass * 0.000005 // * (1 + m.energy * m.energy) //drain more energy when you have more energy if (m.energy > DRAIN) { m.energy -= DRAIN; Matter.Body.setVelocity(body[i], velocity); //give block mouse velocity diff --git a/js/simulation.js b/js/simulation.js index 5b36918..8fdcf1b 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -821,6 +821,44 @@ const simulation = { level.zones = []; simulation.drawList = []; + if (tech.isDronesTravel) { + //count drones + let count = 0 + let deliveryCount = 0 + for (let i = 0; i < bullet.length; ++i) { + if (bullet[i].isDrone) { + count++ + if (bullet[i].isImproved) deliveryCount++ + } + } + // count *= 2 + //respawn drones in animation frame + let respawnDrones = () => { + if (count > 0) { + requestAnimationFrame(respawnDrones); + if (!simulation.paused && !simulation.isChoosing) { + count-- + const where = { x: level.enter.x + 50, y: level.enter.y - 60 } + if (tech.isDroneRadioactive) { + b.droneRadioactive({ x: where.x + 100 * (Math.random() - 0.5), y: where.y + 100 * (Math.random() - 0.5) }, 0) + } else { + b.drone({ x: where.x + 100 * (Math.random() - 0.5), y: where.y + 120 * (Math.random() - 0.5) }, 0) + if (tech.isDroneGrab && deliveryCount > 0) { + const who = bullet[bullet.length - 1] + who.isImproved = true; + const SCALE = 2.25 + Matter.Body.scale(who, SCALE, SCALE); + who.lookFrequency = 30 + Math.floor(11 * Math.random()); + who.endCycle += 3000 * tech.droneCycleReduction * tech.isBulletsLastLonger + deliveryCount-- + } + } + } + } + } + requestAnimationFrame(respawnDrones); + } + function removeAll(array) { // for (let i = 0; i < array.length; ++i) Matter.Composite.remove(engine.world, array[i]); for (let i = 0; i < array.length; ++i) Matter.Composite.remove(engine.world, array[i]); diff --git a/js/tech.js b/js/tech.js index bfdeed3..37b91cf 100644 --- a/js/tech.js +++ b/js/tech.js @@ -211,6 +211,7 @@ const tech = { }, damageFromTech() { let dmg = 1 //m.fieldDamage + if (tech.isTechDebt) dmg *= 4 - 0.1 * tech.totalCount if (tech.isAxion && tech.isHarmMACHO) dmg *= 1 + 0.75 * (1 - m.harmReduction()) if (tech.OccamDamage) dmg *= tech.OccamDamage if (tech.isCloakingDamage) dmg *= 1.35 @@ -3082,6 +3083,26 @@ const tech = { tech.isPauseEjectTech = false; } }, + { + name: "technical debt", // overengineering + // description: `increase damage by 300% minus 10% for tech you have learned(${4 - 0.1 * tech.totalCount})`, + // description: `increase damage by 300%, but reduce damage
by 10% for tech you have learned`, + descriptionFunction() { + return `increase damage by 300% minus 10%
for tech you have learned (${Math.floor(100*(4 - 0.1 * tech.totalCount))-100}%)` + }, + maxCount: 1, + count: 0, + frequency: 1, + frequencyDefault: 1, + allowed() { return true }, + requires: "", + effect() { + tech.isTechDebt = true; + }, + remove() { + tech.isTechDebt = false; + } + }, { 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`, @@ -5021,7 +5042,7 @@ const tech = { { name: "reduced tolerances", link: `reduced tolerances`, - description: `increase drones per ${powerUps.orb.ammo()} or energy by 66%
reduce the average drone lifetime by 40%`, + description: `increase drones per ${powerUps.orb.ammo()} or energy by 66%
reduce average drone durability by 40%`, isGunTech: true, maxCount: 3, count: 0, @@ -5089,6 +5110,25 @@ const tech = { tech.isDroneRespawn = false } }, + { + name: "autonomous navigation", + description: "drones travel with you through levels
and reset their durability", + isGunTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return tech.haveGunCheck("drones") || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && !(tech.isSporeField || tech.isMissileField || tech.isIceField)) + }, + requires: "drones", + effect() { + tech.isDronesTravel = true + }, + remove() { + tech.isDronesTravel = false + } + }, { name: "brushless motor", description: "drones rapidly rush towards their target
increase drone collision damage by 33%", @@ -5212,9 +5252,9 @@ const tech = { frequency: 1, frequencyDefault: 1, allowed() { - return tech.haveGunCheck("drones", false) && !tech.isDroneRespawn && tech.isBulletsLastLonger === 1 + return tech.haveGunCheck("drones", false) && !tech.isDroneRespawn && tech.isBulletsLastLonger === 1 && !tech.isDronesTravel }, - requires: "drones, not drone repair, anti-shear topology", + requires: "drones, not drone repair, anti-shear topology, autonomous navigation", effect() { const num = 6 tech.isForeverDrones += num @@ -6337,7 +6377,6 @@ const tech = { for (let i = 0; i < 3; i++) { if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) } - //fill array of available bots const notUpgradedBots = [] const num = 2 @@ -9497,4 +9536,6 @@ const tech = { isRailGun: null, isGrapple: null, isImmuneGrapple: null, + isDronesTravel: null, + isTechDebt: null } \ No newline at end of file diff --git a/todo.txt b/todo.txt index 2fbf535..555b5cc 100644 --- a/todo.txt +++ b/todo.txt @@ -1,36 +1,20 @@ ******************************************************** NEXT PATCH ************************************************** -JUNK tech - 🐱 +tech: autonomous navigation - drones travel with you through levels and drones reset durability +tech: technical debt - increase damage by 300%, but reduce damage by 10% for each tech you have -railgun buffs - 600% -> 800% more ammo - more dense (more damage) - only targets mobs when pressing down - does a bit of damage to nearby mobs after you fire - extra damage to mob bullets +molecular assembler now has a higher bullet spawn cap 200->300 + but it increases energy cost per spawn above around 150 -pneumatic hammer renamed caliber - also applies to super balls - 5% less size increase per stack - -pure science and unified field theory have a pause animation to show they are clickable +fragments are about 15% fewer +thermal runaway is about 40% bigger and more damage +plasma torch: extruder uses less energy +pilot wave uses less energy bug fixes ******************************************************** TODO ******************************************************** -github bug report - if you reload, the TInker effect is lost, despite it saying it persists through sessions. Please fix. - -bug: railgun AoE is randomly killing some mobs when it shouldn't - -buff mob death explosions - -buff railgun - make railgun push blocks in the same direction railgun moves - make block intangible for a sec, like a block throw - -buff drone gun / gun tech, but not drones? - const ctx = canvas.getContext('2d', {‘willReadFrequently': true}); //deal with game crashes? @@ -55,13 +39,6 @@ bug: often game puts player position at NaN very high level for tech, duplication maybe not about JUNK though -grappling hook - give player more control over motion while hanging and retracting - reduce friction effects so player swing around? - up down left right push player around? - scale velocity dampening with distance to grapple? - make a variable to track rope length? - tech that does less damage the more tech you have? tech.totalCount