diff --git a/.DS_Store b/.DS_Store index 72b112c..b80255a 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/js/bullet.js b/js/bullet.js index e3d5b5e..125b9f7 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -3542,9 +3542,9 @@ const b = { } }, nail(pos, velocity, dmg = 1) { - dmg *= tech.nailSize + dmg *= tech.bulletSize const me = bullet.length; - bullet[me] = Bodies.rectangle(pos.x, pos.y, 25 * tech.nailSize, 2 * tech.nailSize, b.fireAttributes(Math.atan2(velocity.y, velocity.x))); + bullet[me] = Bodies.rectangle(pos.x, pos.y, 25 * tech.bulletSize, 2 * tech.bulletSize, b.fireAttributes(Math.atan2(velocity.y, velocity.x))); Matter.Body.setVelocity(bullet[me], velocity); Composite.add(engine.world, bullet[me]); //add bullet to world bullet[me].endCycle = simulation.cycle + 60 + 18 * Math.random(); @@ -3559,7 +3559,7 @@ const b = { }, needle(angle = m.angle) { const me = bullet.length; - bullet[me] = Bodies.rectangle(m.pos.x + 40 * Math.cos(m.angle), m.pos.y + 40 * Math.sin(m.angle), 75 * tech.nailSize, 0.75 * tech.nailSize, b.fireAttributes(angle)); + bullet[me] = Bodies.rectangle(m.pos.x + 40 * Math.cos(m.angle), m.pos.y + 40 * Math.sin(m.angle), 75 * tech.bulletSize, 0.75 * tech.bulletSize, b.fireAttributes(angle)); Matter.Body.setDensity(bullet[me], 0.00001); //0.001 is normal bullet[me].immuneList = [] bullet[me].dmg = 6 @@ -3584,12 +3584,12 @@ const b = { } if (!immune) { 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, 220 * tech.nailSize + 50 * Math.random()); //makes bullet do explosive damage at end + b.explosion(this.position, 220 * tech.bulletSize + 50 * Math.random()); //makes bullet do explosive damage at end } this.immuneList.push(who.id) //remember that this needle has hit this mob once already - let dmg = this.dmg * tech.nailSize * m.dmgScale + let dmg = this.dmg * tech.bulletSize * m.dmgScale if (tech.isNailRadiation) { - mobs.statusDoT(who, (tech.isFastRadiation ? 6 : 2) * tech.nailSize, tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles + mobs.statusDoT(who, (tech.isFastRadiation ? 6 : 2) * tech.bulletSize, tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles dmg *= 0.25 } if (tech.isCrit && who.isStunned) dmg *= 4 @@ -3639,12 +3639,12 @@ const b = { } if (!immune) { 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, 220 * tech.nailSize + 50 * Math.random()); //makes bullet do explosive damage at end + b.explosion(this.position, 220 * tech.bulletSize + 50 * Math.random()); //makes bullet do explosive damage at end } this.immuneList.push(who.id) //remember that this needle has hit this mob once already - let dmg = this.dmg * tech.nailSize * m.dmgScale + let dmg = this.dmg * tech.bulletSize * m.dmgScale if (tech.isNailRadiation) { - mobs.statusDoT(who, (tech.isFastRadiation ? 6 : 2) * tech.nailSize, tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles + mobs.statusDoT(who, (tech.isFastRadiation ? 6 : 2) * tech.bulletSize, tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles dmg *= 0.25 } if (tech.isCrit && who.isStunned) dmg *= 4 @@ -4768,7 +4768,7 @@ const b = { m.fireCDcycle = m.cycle + Math.floor((input.down ? 25 : 17) * b.fireCDscale); // cool down const me = bullet.length; - const size = tech.nailSize * 8 + const size = tech.bulletSize * 8 bullet[me] = Bodies.rectangle(m.pos.x + 35 * Math.cos(m.angle), m.pos.y + 35 * Math.sin(m.angle), 5 * size, size, b.fireAttributes(m.angle)); bullet[me].dmg = tech.isNailRadiation ? 0 : 2.75 Matter.Body.setDensity(bullet[me], 0.002); @@ -4790,7 +4790,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.nailSize) + b.targetedNail(this.position, 1.5 * tech.fragments * tech.bulletSize) this.endCycle = 0 //triggers despawn } }; @@ -4840,7 +4840,7 @@ const b = { m.fireCDcycle = m.cycle + Math.floor(CD * b.fireCDscale); // cool down const me = bullet.length; - const size = tech.nailSize * 8 + const size = tech.bulletSize * 8 bullet[me] = Bodies.rectangle(m.pos.x + 35 * Math.cos(m.angle), m.pos.y + 35 * Math.sin(m.angle), 5 * size, size, b.fireAttributes(m.angle)); bullet[me].dmg = tech.isNailRadiation ? 0 : 2.75 Matter.Body.setDensity(bullet[me], 0.002); @@ -4861,7 +4861,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.nailSize) + b.targetedNail(this.position, 1.5 * tech.fragments * tech.bulletSize) this.endCycle = 0 //triggers despawn } }; @@ -4979,7 +4979,7 @@ const b = { 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)); + bullet[me] = Bodies.rectangle(m.pos.x + 35 * Math.cos(m.angle), m.pos.y + 35 * Math.sin(m.angle), 60 * tech.bulletSize, 27 * tech.bulletSize, b.fireAttributes(m.angle)); Matter.Body.setDensity(bullet[me], 0.007 * (tech.isShotgunReversed ? 1.6 : 1)); Composite.add(engine.world, bullet[me]); //add bullet to world @@ -5002,7 +5002,7 @@ const b = { bullet[me].minDmgSpeed = 7 // bullet[me].restitution = 0.4 bullet[me].frictionAir = 0.006; - bullet[me].turnMag = 0.04 * Math.pow(tech.nailSize, 3.75) + bullet[me].turnMag = 0.04 * Math.pow(tech.bulletSize, 3.75) bullet[me].do = function() { this.force.y += this.mass * 0.0022 if (this.speed > 6) { //rotates bullet to face current velocity? @@ -5017,7 +5017,7 @@ const b = { if (tech.fragments) { bullet[me].beforeDmg = function() { if (this.speed > 4) { - b.targetedNail(this.position, 7 * tech.fragments * tech.nailSize) + b.targetedNail(this.position, 7 * tech.fragments * tech.bulletSize) this.endCycle = 0 //triggers despawn } } @@ -6008,11 +6008,21 @@ const b = { for (let i = 0, len = mob.length; i < len; ++i) { //push away mobs when firing const SUB = Vector.sub(mob[i].position, m.pos) const DISTANCE = Vector.magnitude(SUB) - if (DISTANCE < range) { - const DEPTH = Math.min(range - DISTANCE, 1500) + if (DISTANCE < range + mob[i].radius) { + const DEPTH = 100 + Math.min(range - DISTANCE + mob[i].radius, 1500) const FORCE = Vector.mult(Vector.normalise(SUB), 0.0015 * Math.sqrt(DEPTH) * mob[i].mass) mob[i].force.x += FORCE.x; mob[i].force.y += FORCE.y; + + let dmg = m.dmgScale * (mob[i].isDropPowerUp ? 0.1 : 0.4) + simulation.drawList.push({ //add dmg to draw queue + x: mob[i].position.x, + y: mob[i].position.y, + radius: Math.log(dmg + 1.1) * 40 * mob[i].damageReduction + 3, + color: 'rgba(100, 0, 200, 0.2)', + time: 15 + }); + mob[i].damage(dmg); } } for (let i = 0, len = body.length; i < len; ++i) { //push away blocks when firing @@ -6039,7 +6049,7 @@ const b = { const recoil = Vector.mult(Vector.normalise(Vector.sub(where, m.pos)), input.down ? 0.03 : 0.06) player.force.x -= recoil.x player.force.y -= recoil.y - tech.harpoonDensity = 0.006 //0.001 is normal for blocks, 0.006 is normal for harpoon, 0.006*6 when buffed + tech.harpoonDensity = 0.01 //0.001 is normal for blocks, 0.006 is normal for harpoon, 0.006*6 when buffed const harpoonSize = tech.isLargeHarpoon ? 1 + 0.1 * Math.sqrt(this.ammo) : 1 if (tech.extraHarpoons) { let targetCount = 0 @@ -6055,7 +6065,7 @@ const b = { if (dot > 0.95 - Math.min(dist * 0.00015, 0.3)) { //lower dot product threshold for targeting then if you only have one harpoon //target closest mob that player is looking at and isn't too close to target if (this.ammo > -1) { this.ammo-- - b.harpoon(where, mob[i], angle, harpoonSize, false) //Vector.angle(Vector.sub(where, mob[i].position), { x: 0, y: 0 }) + b.harpoon(where, input.down ? mob[i] : null, angle, harpoonSize, false) //Vector.angle(Vector.sub(where, mob[i].position), { x: 0, y: 0 }) angle += SPREAD targetCount++ if (targetCount > tech.extraHarpoons) break @@ -6089,7 +6099,7 @@ const b = { } } } - b.harpoon(where, closest.target, m.angle, harpoonSize, false) + b.harpoon(where, input.down ? closest.target : null, m.angle, harpoonSize, false) } this.charge = 0; diff --git a/js/index.js b/js/index.js index ab77e25..071c08b 100644 --- a/js/index.js +++ b/js/index.js @@ -248,7 +248,7 @@ const build = { // } // }, pauseGrid() { - //right side + //left side let botText = "" if (tech.nailBotCount) botText += `
nail-bots: ${tech.nailBotCount}` if (tech.orbitBotCount) botText += `
orbital-bots: ${tech.orbitBotCount}` @@ -299,30 +299,36 @@ ${simulation.isCheating ? "

lore disabled": ""} el.style.display = "grid" el.innerHTML = text - //left side + //right side text = ""; - text += `
  ${build.nameLink(m.fieldUpgrades[m.fieldMode].name)}
${m.fieldUpgrades[m.fieldMode].description}
` + if (tech.isPauseSwitchField) { + text += `
  ${build.nameLink(m.fieldUpgrades[m.fieldMode].name)}
${m.fieldUpgrades[m.fieldMode].description}
` + } else { + text += `
  ${build.nameLink(m.fieldUpgrades[m.fieldMode].name)}
${m.fieldUpgrades[m.fieldMode].description}
` + } + + const style = tech.isPauseEjectTech ? 'style="animation: techColorCycle 1s linear infinite alternate;"' : '' for (let i = 0, len = tech.tech.length; i < len; i++) { if (tech.tech[i].count > 0 && !tech.tech[i].isNonRefundable) { const techCountText = tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : ""; if (tech.tech[i].isFieldTech) { - text += `
+ text += `
        ${tech.tech[i].link} ${techCountText}
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}
` } else if (tech.tech[i].isGunTech) { - text += `
+ text += `
        ${tech.tech[i].link} ${techCountText}
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}
` } else if (tech.tech[i].isLore) { - text += `
  ${tech.tech[i].name} ${techCountText}
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}
` + text += `
  ${tech.tech[i].name} ${techCountText}
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}
` } else { - text += `
  ${tech.tech[i].link} ${techCountText}
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}
` + text += `
  ${tech.tech[i].link} ${techCountText}
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}
` } } else if (tech.tech[i].isLost) { text += `
${tech.tech[i].link}
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}
` diff --git a/js/level.js b/js/level.js index 90a88b1..91be3b9 100644 --- a/js/level.js +++ b/js/level.js @@ -16,9 +16,9 @@ const level = { if (level.levelsCleared === 0) { //this code only runs on the first level // simulation.isHorizontalFlipped = true // m.setField("time dilation") - // b.giveGuns("harpoon") - // tech.giveTech("railgun") - // tech.giveTech("necrophage") + // b.giveGuns("foam") + // tech.giveTech("quantum foam") + // tech.giveTech("capacitor bank") // 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") @@ -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.highrise() + // level.perplex() if (simulation.isTraining) { level.walk(); } else { level.intro(); } // powerUps.research.changeRerolls(3000) @@ -237,6 +237,7 @@ const level = { level.levels = level.levels.concat(level.communityLevels) level.levels = shuffle(level.levels); //shuffles order of maps level.levels.splice(0, 9); //remove some random levels to make up for adding the community levels + simulation.isHorizontalFlipped = false; } else { level.levels = shuffle(level.levels); //shuffles order of maps } @@ -2539,11 +2540,11 @@ const level = { spawn.mapRect(4850, -275, 50, 175); //??? - level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why + level.difficultyIncrease(5) //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.launcher(1900, -500) // spawn.slashBoss(1900, -500) // spawn.launcherBoss(3200, -500) // spawn.laserTargetingBoss(1700, -500) diff --git a/js/powerup.js b/js/powerup.js index 31783e6..fd272a0 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -1052,6 +1052,7 @@ const powerUps = { powerUps.ejectTech(index) } document.getElementById(`${index}-pause-tech`).style.textDecoration = "line-through" + document.getElementById(`${index}-pause-tech`).style.animation = "" document.getElementById(`${index}-pause-tech`).onclick = null } }, diff --git a/js/simulation.js b/js/simulation.js index 3e37190..5b36918 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -691,7 +691,6 @@ const simulation = { level.onLevel = 0; level.levelsCleared = 0; - //resetting difficulty // simulation.difficulty = 0; level.setDifficulty() @@ -713,6 +712,7 @@ const simulation = { document.getElementById("health").style.display = "inline" document.getElementById("health-bg").style.display = "inline" m.alive = true; + m.onGround = false m.setMaxHealth() m.health = 0; m.addHealth(0.25) diff --git a/js/tech.js b/js/tech.js index b581cf6..bfdeed3 100644 --- a/js/tech.js +++ b/js/tech.js @@ -3797,23 +3797,42 @@ const tech = { // tech.isSlugShot = false; // } // }, + // { + // name: "super sized", + // description: `increase super ball radius by 14%
increases damage by about 27%`, + // isGunTech: true, + // maxCount: 9, + // count: 0, + // frequency: 2, + // frequencyDefault: 2, + // allowed() { + // return tech.haveGunCheck("super balls") + // }, + // requires: "super balls", + // effect() { + // tech.bulletSize += 0.14 + // }, + // remove() { + // tech.bulletSize = 1; + // } + // }, { - name: "pneumatic hammer", - description: `rivets, needles, and nails are 18% larger
increases mass and physical damage`, + name: "caliber", + description: `rivets, needles, super balls, and nails
have 16% increased mass and physical damage`, isGunTech: true, maxCount: 9, count: 0, frequency: 2, frequencyDefault: 2, allowed() { - 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 + return tech.isMineDrop + tech.nailBotCount + tech.fragments + tech.nailsDeathMob + (tech.haveGunCheck("super balls") + (tech.haveGunCheck("mine") && !tech.isLaserMine) + (tech.haveGunCheck("nail gun")) + tech.isNeedles + tech.isNailShot + tech.isRivets) * 2 > 1 }, requires: "nails, nail gun, rivets, shotgun", effect() { - tech.nailSize += 0.18 + tech.bulletSize += 0.16 }, remove() { - tech.nailSize = 1; + tech.bulletSize = 1; } }, { @@ -4174,25 +4193,6 @@ const tech = { } } }, - { - name: "super sized", - description: `increase super ball radius by 14%
increases damage by about 27%`, - isGunTech: true, - maxCount: 9, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return tech.haveGunCheck("super balls") - }, - requires: "super balls", - effect() { - tech.bulletSize += 0.14 - }, - remove() { - tech.bulletSize = 1; - } - }, { name: "super duper", description: `randomly fire +0, +1, or +2 extra super balls`, @@ -5420,7 +5420,7 @@ const tech = { }, { name: "railgun", - description: `harpoons are 50% denser, but don't retract
gain 600% more harpoon ammo per ${powerUps.orb.ammo(1)}`, + description: `harpoons are 50% denser, but don't retract
gain 800% more harpoon ammo per ${powerUps.orb.ammo(1)}`, isGunTech: true, maxCount: 1, count: 0, @@ -5430,7 +5430,7 @@ const tech = { return tech.haveGunCheck("harpoon") && !tech.isFilament && !tech.isHarpoonPowerUp && !tech.isGrapple }, requires: "harpoon, not filament, toggling harpoon, grappling hook", - ammoBonus: 6, + ammoBonus: 8, effect() { tech.isRailGun = true; for (i = 0, len = b.guns.length; i < len; i++) { //find which gun @@ -8776,6 +8776,87 @@ const tech = { }, remove() {} }, + { + name: "🐱", + description: "🐈", + maxCount: 1, + count: 0, + frequency: 0, + isNonRefundable: true, + isJunk: true, + allowed() { + return !m.isShipMode + }, + requires: "", + effect() { + m.draw = function() { + ctx.fillStyle = m.fillColor; + m.walk_cycle += m.flipLegs * m.Vx; + ctx.save(); + ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5 + ctx.translate(m.pos.x, m.pos.y); + m.calcLeg(Math.PI, -3); + m.drawLeg("#4a4a4a"); + + + if (!(m.angle > -Math.PI / 2 && m.angle < Math.PI / 2)) { + ctx.scale(1, -1); + ctx.rotate(Math.PI); + } + ctx.beginPath(); + ctx.moveTo(-30, 0); + ctx.bezierCurveTo(-65, -75, + -5, 150 + (5 * Math.sin(simulation.cycle / 10)), + -70 + (10 * Math.sin(simulation.cycle / 10)), 0 + (10 * Math.sin(simulation.cycle / 10))); + ctx.strokeStyle = "#333"; + ctx.lineWidth = 4; + ctx.stroke(); + + if (!(m.angle > -Math.PI / 2 && m.angle < Math.PI / 2)) { + ctx.scale(1, -1); + ctx.rotate(0 - Math.PI); + } + m.calcLeg(0, 0); + m.drawLeg("#333"); + + ctx.rotate(m.angle); + if (!(m.angle > -Math.PI / 2 && m.angle < Math.PI / 2)) ctx.scale(1, -1); + ctx.beginPath(); + ctx.moveTo(5, -30); + ctx.lineTo(20, -40); + ctx.lineTo(20, -20); + ctx.lineWidth = 2; + ctx.fillStyle = "#f3f"; + ctx.fill(); + ctx.stroke(); + + ctx.beginPath(); + ctx.arc(0, 0, 30, 0, 2 * Math.PI); + ctx.fillStyle = this.bodyGradient + ctx.fill(); + ctx.stroke(); + ctx.moveTo(19, 0); + ctx.arc(15, 0, 4, Math.PI, 2 * Math.PI); + ctx.stroke(); + ctx.beginPath(); + ctx.arc(24.3, 6, 5, Math.PI * 2, Math.PI); + ctx.stroke(); + + ctx.beginPath(); + ctx.moveTo(30, 6); + ctx.lineTo(32, 0); + ctx.lineTo(26, 0); + ctx.lineTo(30, 6); + ctx.fillStyle = "#f3f"; + ctx.fill(); + ctx.stroke(); + + ctx.restore(); + m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal + } + }, + remove() {} + }, { name: "pareidolia", description: "don't", @@ -9404,7 +9485,7 @@ const tech = { isAxion: null, isWormholeMapIgnore: null, isLessDamageReduction: null, - nailSize: null, + // bulletSize: null, needleTunnel: null, isBrainstorm: null, isBrainstormActive: null, diff --git a/style.css b/style.css index 2a9eb57..9d68c28 100644 --- a/style.css +++ b/style.css @@ -936,6 +936,27 @@ summary { animation: textColor 3s linear infinite; } + +@keyframes fieldColorCycle { + 0% { + background-color: rgb(255, 255, 255) + } + + 100% { + background-color: rgb(200, 255, 255) + } +} + +@keyframes techColorCycle { + 0% { + background-color: hsl(253, 100%, 100%) + } + + 100% { + background-color: hsl(253, 100%, 90%) + } +} + @keyframes bgColor { 0% { background-color: rgb(63, 218, 216) diff --git a/todo.txt b/todo.txt index c539424..2fbf535 100644 --- a/todo.txt +++ b/todo.txt @@ -1,28 +1,35 @@ ******************************************************** NEXT PATCH ************************************************** -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 +JUNK tech - 🐱 + +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 + +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 + +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 - 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? +buff drone gun / gun tech, but not drones? const ctx = canvas.getContext('2d', {‘willReadFrequently': true}); @@ -45,7 +52,6 @@ setting to remove UI, except health bar bug: often game puts player position at NaN clues: after apoximis? - vanish level? very high level for tech, duplication maybe not about JUNK though