diff --git a/img/blast ball.webp b/img/blast ball.webp new file mode 100644 index 0000000..b716466 Binary files /dev/null and b/img/blast ball.webp differ diff --git a/img/extended magazine.webp b/img/extended magazine.webp new file mode 100644 index 0000000..f3507c3 Binary files /dev/null and b/img/extended magazine.webp differ diff --git a/img/gun/harpoon.webp b/img/gun/harpoon.webp index fcf8bed..5e5298f 100644 Binary files a/img/gun/harpoon.webp and b/img/gun/harpoon.webp differ diff --git a/img/sentry.webp b/img/sentry gun.webp similarity index 100% rename from img/sentry.webp rename to img/sentry gun.webp diff --git a/img/thermal runaway.webp b/img/thermal runaway.webp index 712ad84..eee5738 100644 Binary files a/img/thermal runaway.webp and b/img/thermal runaway.webp differ diff --git a/js/bullet.js b/js/bullet.js index 23fc47a..6c51b66 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -2714,58 +2714,31 @@ const b = { range: 700 - 300 * tech.isFoamMine, beforeDmg() {}, onEnd() { - if (tech.isFoamMine) { - for (let i = 0; i < 14; i++) { - const radius = 13 + 8 * Math.random() - const velocity = { - x: 5.5 * Math.random(), - y: 0 + if (this.isArmed && !tech.isMineSentry) { + if (tech.isFoamMine) { + //send 14 in random directions slowly + for (let i = 0; i < 12; i++) { + const radius = 13 + 8 * Math.random() + const velocity = { x: 0.5 + 5.5 * Math.random(), y: 0 } + b.foam(this.position, Vector.rotate(velocity, this.angle + 1.57 + 3 * (Math.random() - 0.5)), radius) //6.28 * Math.random() } - b.foam(this.position, Vector.rotate(velocity, this.angle + 1.57 + 3 * (Math.random() - 0.5)), radius) //6.28 * Math.random() - } - - let count = 0 - let cycle = () => { - if (count < 40) { - if (!simulation.paused && !simulation.isChoosing) { //!(simulation.cycle % 1) && - count++ - - const targets = [] //target nearby mobs - for (let i = 0, len = mob.length; i < len; i++) { - if ( - Vector.magnitude(Vector.sub(this.position, mob[i].position)) < this.range + mob[i].radius + 300 && - !mob[i].isBadTarget && //|| mob[i].isMobBullet - Matter.Query.ray(map, this.position, mob[i].position).length === 0 && - !mob[i].isInvulnerable - ) { - // targets.push(Vector.add(mob[i].position, Vector.mult(mob[i].velocity, dist / 50))) //predict where the mob will be in a few cycles - targets.push(mob[i]) //predict where the mob will be in a few cycles - } - } - if (targets.length > 0) { // aim near a random target in array - const index = Math.floor(Math.random() * targets.length) //pick random target from list - const radius = 7 + 10 * Math.random() - const SPEED = 23 + 6 * Math.random() - radius * 0.3 + 0.5 * targets[index].speed - const predict = Vector.mult(targets[index].velocity, Vector.magnitude(Vector.sub(this.position, targets[index].position)) / 60) - const where = Vector.add(targets[index].position, predict) - const velocity = Vector.mult(Vector.normalise(Vector.sub(where, this.position)), SPEED) - b.foam(this.position, Vector.rotate(velocity, 0.2 * (Math.random() - 0.5)), radius) - } else { - const radius = 7 + 10 * Math.random() - const velocity = { - x: 10 + 8 * Math.random(), - y: 0 - } - b.foam(this.position, Vector.rotate(velocity, this.angle + 1.57 + 2.8 * (Math.random() - 0.5)), radius) //6.28 * Math.random() + //send 40 targeted + let count = 0 + let cycle = () => { + if (count < 50) { + if (!simulation.paused && !simulation.isChoosing) { //!(simulation.cycle % 1) && + count++ + b.targetedFoam(this.position) } + requestAnimationFrame(cycle); } - requestAnimationFrame(cycle); } + requestAnimationFrame(cycle) + } else if (tech.isSuperMine) { + b.targetedBall(this.position, 22 + 2 * tech.extraSuperBalls) + } else { + b.targetedNail(this.position, 22, 40 + 10 * Math.random(), 1200, true, 2.2) //targetedNail(position, num = 1, speed = 40 + 10 * Math.random(), range = 1200, isRandomAim = true, damage = 1.4) { } - requestAnimationFrame(cycle) - - } else if (this.isArmed && !tech.isMineSentry) { - b.targetedNail(this.position, tech.isMineSentry ? 7 : 22, 40 + 10 * Math.random(), 1200, true, 2.2) //targetedNail(position, num = 1, speed = 40 + 10 * Math.random(), range = 1200, isRandomAim = true, damage = 1.4) { } }, do() { @@ -2779,8 +2752,7 @@ const b = { y: 0 }) Matter.Body.setAngle(this, Math.atan2(collide[i].tangent.y, collide[i].tangent.x)) - //move until touching map again after rotation - for (let j = 0; j < 10; j++) { + for (let j = 0; j < 10; j++) { //move until touching map again after rotation if (Matter.Query.collides(this, map).length > 0) { //touching map if (angle > -0.2 || angle < -1.5) { //don't stick to level ground Matter.Body.setVelocity(this, { @@ -2798,7 +2770,6 @@ const b = { Matter.Body.setAngularVelocity(this, 0) } this.arm(); - //sometimes the mine can't attach to map and it just needs to be reset setTimeout(() => { if (Matter.Query.collides(this, map).length === 0 || Matter.Query.point(map, this.position).length > 0) { @@ -2809,8 +2780,7 @@ const b = { }, 100); break } - //move until you are touching the wall - Matter.Body.setPosition(this, Vector.add(this.position, Vector.mult(collide[i].normal, 2))) + Matter.Body.setPosition(this, Vector.add(this.position, Vector.mult(collide[i].normal, 2))) //move until you are touching the wall } break } @@ -2848,13 +2818,25 @@ const b = { ) { if (tech.isStun) b.AoEStunEffect(this.position, this.range + mob[i].radius + random); //AoEStunEffect(where, range, cycles = 90 + 60 * Math.random()) { if (tech.isMineSentry) { - this.lookFrequency = 6 - this.endCycle = simulation.cycle + 1020 + this.lookFrequency = 15 + 10 * (tech.oneSuperBall && tech.isSuperMine) + Math.floor(3 * Math.random()) + // this.endCycle = Infinity + this.shots = tech.sentryAmmo this.do = function() { //overwrite the do method for this bullet this.force.y += this.mass * 0.002; //extra gravity if (!(simulation.cycle % this.lookFrequency)) { //find mob targets - this.endCycle -= 5 - b.targetedNail(this.position, 1, 45 + 5 * Math.random(), 1100, false, 2.3) //targetedNail(position, num = 1, speed = 40 + 10 * Math.random(), range = 1200, isRandomAim = true, damage = 1.4) { + if (tech.isFoamMine) { + this.shots -= 0.6 * b.targetedFoam(this.position, 1, 21 + 7 * Math.random(), 1200, false) + b.targetedFoam(this.position, 1, 21 + 7 * Math.random(), 1200, false) + } else if (tech.isSuperMine) { + const cost = tech.oneSuperBall ? 2 : 0.7 + this.shots -= cost * b.targetedBall(this.position, 1, 42 + 12 * Math.random(), 1200, false) + for (let i = 0, len = tech.extraSuperBalls / 4; i < len; i++) { + if (Math.random() < 0.33) b.targetedBall(this.position, 1, 42 + 12 * Math.random(), 1200, false) + } + } else { + this.shots -= b.targetedNail(this.position, 1, 45 + 5 * Math.random(), 1100, false, 2.3) //targetedNail(position, num = 1, speed = 40 + 10 * Math.random(), range = 1200, isRandomAim = true, damage = 1.4) { + } + if (this.shots < 0) this.endCycle = 0 if (!(simulation.cycle % (this.lookFrequency * 6))) { simulation.drawList.push({ x: this.position.x, @@ -3769,7 +3751,7 @@ const b = { bullet[me] = Bodies.polygon(where.x, where.y, 12, radius, b.fireAttributes(dir, false)); Composite.add(engine.world, bullet[me]); //add bullet to world Matter.Body.setVelocity(bullet[me], velocity); - Matter.Body.setDensity(bullet[me], 0.0001 + 0.001 * tech.superHarm); + Matter.Body.setDensity(bullet[me], 0.0008 + 0.0008 * tech.superHarm); bullet[me].endCycle = simulation.cycle + Math.floor(300 + 90 * Math.random()); bullet[me].minDmgSpeed = 0; bullet[me].restitution = 1; @@ -3786,7 +3768,7 @@ const b = { bullet[me].collidePlayerDo = function() { if (Matter.Query.collides(this, [player]).length) { this.endCycle = 0 - let dmg = 0.03 * this.mass * tech.superHarm + let dmg = 0.02 * this.mass * tech.superHarm m.damage(dmg); simulation.drawList.push({ //add dmg to draw queue x: this.position.x, @@ -3811,24 +3793,81 @@ const b = { } bullet[me].beforeDmg = function(who) { if (tech.oneSuperBall) mobs.statusStun(who, 120) // (2.3) * 2 / 14 ticks (2x damage over 7 seconds) - // if (tech.isIncendiary) { - // b.explosion(this.position, this.mass * (240+70 * Math.random()) ); //makes bullet do explosive damage at end - // this.endCycle = 0 - // } if (tech.isFoamBall) { for (let i = 0, len = 6 * this.mass; i < len; i++) { const radius = 5 + 8 * Math.random() - // const velocity = { x: Math.max(2, 10 - radius * 0.25), y: 0 } - const velocity = { - x: Math.max(0.5, 2 - radius * 0.1), - y: 0 - } + const velocity = { x: Math.max(0.5, 2 - radius * 0.1), y: 0 } b.foam(this.position, Vector.rotate(velocity, 6.28 * Math.random()), radius) } this.endCycle = 0 } }; }, + targetedBall(position, num = 1, speed = 42 + 12 * Math.random(), range = 1200, isRandomAim = true) { + let shotsFired = 0 + const targets = [] //target nearby mobs + for (let i = 0, len = mob.length; i < len; i++) { + const dist = Vector.magnitude(Vector.sub(position, mob[i].position)); + if ( + dist < range + mob[i].radius && + !mob[i].isBadTarget && + Matter.Query.ray(map, position, mob[i].position).length === 0 && + Matter.Query.ray(body, position, mob[i].position).length === 0 && + !mob[i].isInvulnerable + ) { + targets.push(Vector.add(mob[i].position, Vector.mult(mob[i].velocity, dist / 60))) //predict where the mob will be in a few cycles + } + } + const radius = (11 + 10 * tech.oneSuperBall) * tech.bulletSize + for (let i = 0; i < num; i++) { + if (targets.length > 0) { // aim near a random target in array + const index = Math.floor(Math.random() * targets.length) + const SPREAD = 160 / targets.length + const WHERE = { + x: targets[index].x + SPREAD * (Math.random() - 0.5), + y: targets[index].y + SPREAD * (Math.random() - 0.5) + } + b.superBall(position, Vector.mult(Vector.normalise(Vector.sub(WHERE, position)), speed), radius) + shotsFired++ + } else if (isRandomAim) { // aim in random direction + const ANGLE = 2 * Math.PI * Math.random() + b.superBall(position, { x: speed * Math.cos(ANGLE), y: speed * Math.sin(ANGLE) }, radius) + } + } + return shotsFired + }, + targetedFoam(position, num = 1, speed = 21 + 7 * Math.random(), range = 1200, isRandomAim = true) { + let shotsFired = 0 + const targets = [] //target nearby mobs + for (let i = 0, len = mob.length; i < len; i++) { + const dist = Vector.magnitude(Vector.sub(position, mob[i].position)); + if ( + dist < range + mob[i].radius && + !mob[i].isBadTarget && //|| mob[i].isMobBullet + Matter.Query.ray(map, position, mob[i].position).length === 0 && + !mob[i].isInvulnerable + ) { + targets.push(Vector.add(mob[i].position, Vector.mult(mob[i].velocity, dist / 60))) //predict where the mob will be in a few cycles + } + } + for (let i = 0; i < num; i++) { + if (targets.length > 0) { // aim near a random target in array + const SPREAD = 160 / targets.length + const index = Math.floor(Math.random() * targets.length) + const radius = 11 + 12 * Math.random() + const where = { + x: targets[index].x + SPREAD * (Math.random() - 0.5), + y: targets[index].y + SPREAD * (Math.random() - 0.5) + } + b.foam(position, Vector.mult(Vector.normalise(Vector.sub(where, position)), speed - radius * 0.25), radius) + shotsFired++ + } else if (isRandomAim) { // aim in random direction + const ANGLE = 2 * Math.PI * Math.random() + b.foam(position, { x: speed * Math.cos(ANGLE), y: speed * Math.sin(ANGLE) }, 8 + 11 * Math.random()) + } + } + return shotsFired + }, // plasmaBall(position, velocity, radius) { // // radius *= Math.sqrt(tech.bulletSize) // const me = bullet.length; @@ -4186,6 +4225,7 @@ const b = { } }, targetedNail(position, num = 1, speed = 40 + 10 * Math.random(), range = 1200, isRandomAim = true, damage = 1.4) { + let shotsFired = 0 const targets = [] //target nearby mobs for (let i = 0, len = mob.length; i < len; i++) { const dist = Vector.magnitude(Vector.sub(position, mob[i].position)); @@ -4208,14 +4248,17 @@ const b = { y: targets[index].y + SPREAD * (Math.random() - 0.5) } b.nail(position, Vector.mult(Vector.normalise(Vector.sub(WHERE, position)), speed), damage) + shotsFired++ } else if (isRandomAim) { // aim in random direction const ANGLE = 2 * Math.PI * Math.random() b.nail(position, { x: speed * Math.cos(ANGLE), y: speed * Math.sin(ANGLE) }, damage) + shotsFired++ } } + return shotsFired }, crit(mob, bullet) { if (!mob.shield && Vector.dot(Vector.normalise(Vector.sub(mob.position, bullet.position)), Vector.normalise(bullet.velocity)) > 0.999 - 1 / mob.radius) { @@ -4263,9 +4306,9 @@ const b = { bullet[me].dmg = tech.isNailRadiation ? 0 : dmg bullet[me].beforeDmg = function(who) { //beforeDmg is rewritten with ice crystal tech if (tech.isNailRadiation) mobs.statusDoT(who, dmg * (tech.isFastRadiation ? 1.3 : 0.44), tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles - if (tech.isNailCrit) { + if (tech.isNailCrit) { //makes bullet do explosive damage if it hits center if (!who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.97 - 1 / who.radius) { - b.explosion(this.position, 150 + 30 * Math.random()); //makes bullet do explosive damage at end + b.explosion(this.position, 80 + 90 * (b.activeGun === 0) + 30 * Math.random()); //larger explosions for human aimed nail gun, smaller for auto aimed sources, like bots, and mine } } this.ricochet(who) @@ -7463,6 +7506,15 @@ const b = { ammo: 0, ammoPack: 1.7, have: false, + nameString(suffix = "") { + if (tech.isFoamMine) { + return `foam` + } else if (tech.isSuperMine) { + return `super ball${suffix}` + } else { + return `nail${suffix}` + } + }, do() { if (!input.field && input.down && !tech.isLaserMine) { const cycles = 60 //30 diff --git a/js/level.js b/js/level.js index c694ce2..964b833 100644 --- a/js/level.js +++ b/js/level.js @@ -18,7 +18,7 @@ const level = { // simulation.enableConstructMode() //tech.giveTech('motion sickness') //used to build maps in testing mode // simulation.isHorizontalFlipped = true // tech.giveTech("performance") - // level.difficultyIncrease(30 * 4) //30 is near max on hard //60 is near max on why + // level.difficultyIncrease(10 * 4) //30 is near max on hard //60 is near max on why // m.maxHealth = m.health = 100 // tech.isRerollDamage = true // powerUps.research.changeRerolls(10) @@ -28,15 +28,16 @@ const level = { // m.setField("perfect diamagnetism") //molecular assembler standing wave time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass pilot wave plasma torch // simulation.molecularMode = 2 // m.damage(0.1); - // b.giveGuns("super balls") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser + // b.giveGuns("mine") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser // b.giveGuns("spores") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser // b.guns[0].ammo = 10000 - // tech.giveTech("cordyceps") - // tech.giveTech("Zectron") + // tech.giveTech("blast ball") + // tech.giveTech("elephants toothpaste") + // tech.giveTech("sentry gun") // for (let i = 0; i < 1; ++i) tech.giveTech("super ball") // tech.isFoamBall = true - // for (let i = 0; i < 1; ++i) tech.giveTech("incendiary ammunition") - // for (let i = 0; i < 2; i++) tech.giveTech("unified field theory") + // for (let i = 0; i < 1; ++i) tech.giveTech("super ball") + // for (let i = 0; i < 1; i++) tech.giveTech("irradiated nails") // for (let i = 0; i < 1; i++) tech.giveTech("colony") // for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "tech"); // for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "boost"); @@ -47,7 +48,8 @@ const level = { // spawn.starter(1900, -500, 25) // spawn.sneaker(1900, -500, 25) // spawn.hopper(2538, -950) - // for (let i = 0; i < 2; ++i) spawn.starter(1000 + 1000 * Math.random(), -500 + 300 * Math.random()) + // spawn.zombie(1000 + 1000 * Math.random(), -500 + 300 * Math.random(), 30, 5, "white") // zombie(x, y, radius, sides, color) + // for (let i = 0; i < 20; ++i) spawn.starter(1000 + 1000 * Math.random(), -500 + 300 * Math.random()) // tech.addJunkTechToPool(2) // tech.tech[322].frequency = 100 // spawn.tetherBoss(1900, -500, { x: 1900, y: -500 }) diff --git a/js/mob.js b/js/mob.js index 5a08c18..4fba9c7 100644 --- a/js/mob.js +++ b/js/mob.js @@ -1194,7 +1194,7 @@ const mobs = { if (this.isDropPowerUp) { if (this.isSoonZombie) { //spawn zombie on death this.leaveBody = false; - let count = 45 //delay spawn cycles + let count = 5 //delay spawn cycles let cycle = () => { if (count > 0) { if (m.alive) requestAnimationFrame(cycle); diff --git a/js/player.js b/js/player.js index 6246d82..f43270c 100644 --- a/js/player.js +++ b/js/player.js @@ -1992,7 +1992,7 @@ const m = { // const angleReduction = 0.1 + (Math.PI / 2 - Math.min(Math.PI / 2, Math.abs(m.angle + Math.PI / 2))) if (player.velocity.y > 1) { - player.force.y -= angleReduction * (tech.isBigField ? 0.87 : 0.7) * player.mass * simulation.g; + player.force.y -= angleReduction * (tech.isBigField ? 0.9 : 0.7) * player.mass * simulation.g; Matter.Body.setVelocity(player, { x: player.velocity.x, y: 0.98 * player.velocity.y diff --git a/js/powerup.js b/js/powerup.js index 45db754..32f6d97 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -645,13 +645,20 @@ const powerUps = { }, buildColumns(totalChoices, type) { let width - if (canvas.width < 1500) { - width = "340px" + if (canvas.width < 1710) { + width = "285px" } else if (canvas.width < 1950) { - width = "360px" + width = "340px" } else { width = "384px" } + // if (canvas.width < 1500) { + // width = "340px" + // } else if (canvas.width < 1950) { + // width = "360px" + // } else { + // width = "384px" + // } let text = "" if (localSettings.isHideImages || canvas.width < 1200) { document.getElementById("choose-grid").style.gridTemplateColumns = width @@ -1150,7 +1157,7 @@ const powerUps = { powerUps.research.currentRerollCount = 0 if (tech.isTechDamage && who.name === "tech") m.damage(0.1) if (tech.isMassEnergy) m.energy += 2; - if (tech.isMineDrop && bullet.length < 150 && Math.random() < 0.6) { + if (tech.isMineDrop && bullet.length < 150 && Math.random() < 0.5) { if (tech.isLaserMine && input.down) { b.laserMine(who.position) } else { diff --git a/js/simulation.js b/js/simulation.js index 8f0310c..62e1923 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -447,9 +447,10 @@ const simulation = { } } 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 + if (b.inventory.length > 0) { + 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 + } simulation.updateGunHUD(); simulation.boldActiveGunHUD(); }, @@ -895,7 +896,7 @@ const simulation = { if (tech.isMutualism && !tech.isEnergyHealth) { for (let i = 0; i < bullet.length; i++) { if (bullet[i].isMutualismActive) { - m.health += 0.01 + 0.01 * ((bullet[i].isSpore || bullet[i].isFlea) ? 0: 1) + m.health += 0.01 + 0.01 * ((bullet[i].isSpore || bullet[i].isFlea) ? 0 : 1) if (m.health > m.maxHealth) m.health = m.maxHealth; m.displayHealth(); } @@ -1168,18 +1169,6 @@ const simulation = { m.energy -= 0.1 * simulation.difficultyMode } if (isNaN(player.position.x)) m.death(); - - // if (tech.isEnergyDamage) { - // document.getElementById("tech-capacitor").innerHTML = `(+${(m.energy/0.05).toFixed(0)}%)` - // } - // if (tech.restDamage) { - // if (player.speed < 1) { - // document.getElementById("tech-rest").innerHTML = `(+20%)` - // } else { - // document.getElementById("tech-rest").innerHTML = `(+0%)` - // } - // } - if (m.lastKillCycle + 300 > m.cycle) { //effects active for 5 seconds after killing a mob if (tech.isEnergyRecovery && m.immuneCycle < m.cycle) m.energy += m.maxEnergy * 0.05 if (tech.isHealthRecovery) m.addHealth(0.005 * m.maxHealth) diff --git a/js/spawn.js b/js/spawn.js index 4cad1be..345c000 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -1542,14 +1542,15 @@ const spawn = { zombie(x, y, radius, sides, color) { //mob that attacks other mobs mobs.spawn(x, y, sides, radius, color); let me = mob[mob.length - 1]; - me.damageReduction = 0 //take NO damage until targeting player, but also slowly lose health + me.damageReduction = 0 //take NO damage, but also slowly lose health + Matter.Body.setDensity(me, 0.0001) // normal density is 0.001 // this reduces life by half and decreases knockback me.isZombie = true me.isBadTarget = true; me.isDropPowerUp = false; me.showHealthBar = false; me.stroke = "#83a" - me.accelMag = 0.0015 - me.frictionAir = 0.01 + me.accelMag = 0.001 + me.frictionAir = 0.005 me.collisionFilter.mask = cat.player | cat.map | cat.body | cat.mob me.seeAtDistance2 = 1000000 //1000 vision range // me.onDeath = function() { @@ -1577,39 +1578,36 @@ const spawn = { me.mobSearchIndex = 0; me.target = null me.lookForMobTargets = function() { - if (!(simulation.cycle % 10)) { - if (this.target === null) { //if you have no target - this.mobSearchIndex++ //look for a different mob index every time - if (this.mobSearchIndex > mob.length - 1) this.mobSearchIndex = 0 + if (this.target === null && mob.length > 1 && !(simulation.cycle % this.seePlayerFreq)) { //find mob targets + let closeDist = Infinity; + for (let i = 0, len = mob.length; i < len; ++i) { if ( - mob.length > 1 && - !mob[this.mobSearchIndex].isZombie && - (Vector.magnitudeSquared(Vector.sub(this.position, mob[this.mobSearchIndex].position)) < this.seeAtDistance2 && Matter.Query.ray(map, this.position, mob[this.mobSearchIndex].position).length === 0) + !mob[i].isZombie && + !mob[i].isUnblockable && + Matter.Query.ray(map, this.position, mob[i].position).length === 0 && + Matter.Query.ray(body, this.position, mob[i].position).length === 0 + // !mob[i].isBadTarget && + // !mob[i].isInvulnerable && + // (Vector.magnitudeSquared(Vector.sub(this.position, mob[this.mobSearchIndex].position)) < this.seeAtDistance2) ) { - this.target = mob[this.mobSearchIndex] - } else if (Math.random() < 0.005 * player.speed && (Vector.magnitudeSquared(Vector.sub(this.position, player.position)) < this.seeAtDistance2 || Matter.Query.ray(map, this.position, player.position).length === 0)) { - this.target = player - this.isBadTarget = false; - this.damageReduction = 0.5 - me.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob + const DIST = Vector.magnitude(Vector.sub(this.position, mob[i].position)); + if (DIST < closeDist) { + closeDist = DIST; + this.target = mob[i] + } } } - } - //chance to forget target - if (!(simulation.cycle % this.memory) && this.target) { - if ( - (this.target && this.target !== player && !this.target.alive) || - Vector.magnitudeSquared(Vector.sub(this.position, this.target.position)) > this.seeAtDistance2 || - Matter.Query.ray(map, this.position, this.target.position).length !== 0 - ) { - this.target = null - } + } else if ( + !(simulation.cycle % this.memory) && + this.target && + (!this.target.alive || Matter.Query.ray(map, this.position, this.target.position).length !== 0) + ) { + this.target = null //chance to forget target } } me.zombieHealthBar = function() { - this.health -= 0.0005 //decay + this.health -= 0.0004 //decay if ((this.health < 0.01 || isNaN(this.health)) && this.alive) this.death(); - const h = this.radius * 0.3; const w = this.radius * 2; const x = this.position.x - w / 2; @@ -1624,14 +1622,18 @@ const spawn = { if (this.hitCD < simulation.cycle) { if (this.target) { this.force = Vector.mult(Vector.normalise(Vector.sub(this.target.position, this.position)), this.accelMag * this.mass) - if (this.speed > 6) { // speed cap instead of friction to give more agility - Matter.Body.setVelocity(this, { - x: this.velocity.x * 0.97, - y: this.velocity.y * 0.97 - }); - } + } else { //wonder around + this.torque += 0.0000003 * this.inertia; + const mag = 0.00015 * this.mass + this.force.x += mag * Math.cos(this.angle) + this.force.y += mag * Math.sin(this.angle) + } + if (this.speed > 6) { // speed cap instead of friction to give more agility + Matter.Body.setVelocity(this, { + x: this.velocity.x * 0.93, + y: this.velocity.y * 0.93 + }); } - const hit = (who) => { if (!who.isZombie && who.damageReduction) { this.hitCD = simulation.cycle + 15 @@ -1641,7 +1643,7 @@ const spawn = { this.force.y -= force.y; this.target = null //look for a new target - const dmg = 0.2 * m.dmgScale + const dmg = 1.3 * m.dmgScale who.damage(dmg); who.locatePlayer(); simulation.drawList.push({ @@ -1662,8 +1664,6 @@ const spawn = { } } } - // me.onDamage = function(dmg) { - // } }, starter(x, y, radius = Math.floor(15 + 20 * Math.random())) { //easy mob for on level 1 mobs.spawn(x, y, 8, radius, "#9ccdc6"); @@ -5736,9 +5736,9 @@ const spawn = { me.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob //can't touch player me.showHealthBar = false; me.memory = 30; - me.vanishesLeft = 2+simulation.difficultyMode + me.vanishesLeft = 2 + simulation.difficultyMode me.onDamage = function() { - if (this.vanishesLeft>0 && this.health < 0.1){ //if health is below 10% teleport to a random spot on player history, heal, and cloak + if (this.vanishesLeft > 0 && this.health < 0.1) { //if health is below 10% teleport to a random spot on player history, heal, and cloak this.vanishesLeft-- // const scale = 0.95; @@ -5746,21 +5746,21 @@ const spawn = { // this.radius *= scale; //flash screen to hide vanish - for(let i=0; i<8; i++){ + for (let i = 0; i < 8; i++) { simulation.drawList.push({ x: this.position.x, y: this.position.y, radius: 3000, color: `rgba(0, 0, 0,${1-0.1*i})`, - time: (i+1)*3 + time: (i + 1) * 3 }); } //teleport to near the end of player history - const index = Math.floor( (m.history.length-1)*(0.66+0.2*Math.random() )) + const index = Math.floor((m.history.length - 1) * (0.66 + 0.2 * Math.random())) let history = m.history[(m.cycle - index) % 600] Matter.Body.setPosition(this, history.position) - Matter.Body.setVelocity(this, {x: 0,y: 0}); - + Matter.Body.setVelocity(this, { x: 0, y: 0 }); + this.seePlayer.recall = 0 this.cloak(); this.health = 1; @@ -5774,7 +5774,7 @@ const spawn = { this.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob //can't touch player this.damageReduction = 0.04 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) } - } + } me.deCloak = function() { if (this.isCloaked) { this.damageReduction = 0.4 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) @@ -5828,13 +5828,13 @@ const spawn = { me.memory = 240; me.isVanished = false; me.onDamage = function() { - if (!this.isVanished && this.health < 0.1){ //if health is below 10% teleport to a random spot on player history, heal, and cloak + if (!this.isVanished && this.health < 0.1 && !this.isStunned && !this.isSlowed) { //if health is below 10% teleport to a random spot on player history, heal, and cloak this.health = 1; this.isVanished = true this.cloak(); //teleport to near the end of player history - Matter.Body.setPosition(this, m.history[Math.floor((m.history.length-1)*(0.66+0.33*Math.random()))].position) - Matter.Body.setVelocity(this, {x: 0,y: 0}); + Matter.Body.setPosition(this, m.history[Math.floor((m.history.length - 1) * (0.66 + 0.33 * Math.random()))].position) + Matter.Body.setVelocity(this, { x: 0, y: 0 }); } }; me.cloak = function() { @@ -5847,7 +5847,7 @@ const spawn = { } me.do = function() { this.gravity(); - this.seePlayerByHistory(15); + this.seePlayerByHistory(25); this.checkStatus(); this.attraction(); //draw diff --git a/js/tech.js b/js/tech.js index 665fe8b..f77c8eb 100644 --- a/js/tech.js +++ b/js/tech.js @@ -236,7 +236,7 @@ const tech = { if (tech.isBotDamage) dmg *= 1 + 0.06 * b.totalBots() if (tech.restDamage > 1 && player.speed < 1) dmg *= tech.restDamage if (tech.isLowEnergyDamage) dmg *= 1 + 0.7 * Math.max(0, 1 - m.energy) - if (tech.isEnergyDamage) dmg *= 1 + m.energy * 0.125; + if (tech.energyDamage) dmg *= 1 + m.energy * 0.1 * tech.energyDamage; if (tech.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.007 if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 2 if (tech.isSpeedDamage) dmg *= 1 + Math.min(0.66, player.speed * 0.0165) @@ -396,7 +396,7 @@ const tech = { { name: "arsenal", descriptionFunction() { - return `+22% damage per unequipped gun (${(22 * Math.max(0, b.inventory.length-1)).toFixed(0)}%)
 ` + return `+22% damage per unequipped gun (${(22 * Math.max(0, b.inventory.length-1)).toFixed(0)}%)` }, maxCount: 1, count: 0, @@ -414,7 +414,7 @@ const tech = { { name: "active cooling", descriptionFunction() { - return `+28% fire rate per unequipped gun (${(28 * Math.max(0, b.inventory.length-1)).toFixed(0)}%)
 ` + return `+28% fire rate per unequipped gun (${(28 * Math.max(0, b.inventory.length-1)).toFixed(0)}%)` }, //
but not including your equipped gun` }, maxCount: 1, count: 0, @@ -886,7 +886,7 @@ const tech = { { name: "anti-shear topology", link: `anti-shear topology`, - description: "+30% projectile duration
 ", //
drone spore worm flea missile foam wave neutron ice", + description: "+30% projectile duration", //
drone spore worm flea missile foam wave neutron ice", maxCount: 3, count: 0, frequency: 1, @@ -1019,7 +1019,7 @@ const tech = { }, { name: "reaction inhibitor", - description: "-12% maximum mob health
 ", //health + description: "-12% maximum mob health", //health maxCount: 3, count: 0, frequency: 1, @@ -1084,7 +1084,7 @@ const tech = { { name: "nail-bot", link: `nail-bot`, - description: "a bot fires nails at mobs in line of sight
 ", + description: "a bot fires nails at mobs in line of sight", maxCount: 9, count: 0, frequency: 1, @@ -1142,7 +1142,7 @@ const tech = { { name: "foam-bot", link: `foam-bot`, - description: "a bot fires foam at nearby mobs
 ", + description: "a bot fires foam at nearby mobs", maxCount: 9, count: 0, frequency: 1, @@ -1683,7 +1683,7 @@ const tech = { }, { name: "mass driver", - description: "+300% block collision damage
 ", + description: "+300% block collision damage", maxCount: 1, count: 0, frequency: 1, @@ -2345,7 +2345,7 @@ const tech = { { name: "mass-energy equivalence", // description: "energy protects you instead of health
√ of defense reduction reduces max energy", - description: "energy protects you instead of health
exponentially reduced defense (x^0.1)", + description: "energy protects you instead of health
exponentially reduced defense (~ x^0.1)", maxCount: 1, count: 0, frequency: 1, @@ -2411,10 +2411,10 @@ const tech = { { name: "electronegativity", descriptionFunction() { - return `+1% damage per 8 stored energy
(${(12.5*m.energy).toFixed(0)}%)` + return `+0.1% damage per current stored energy
(+${(10*m.energy).toFixed(0)}%)` }, // description: "+1% damage per 8 stored energy", - maxCount: 1, + maxCount: 9, count: 0, frequency: 1, frequencyDefault: 1, @@ -2423,10 +2423,10 @@ const tech = { }, requires: "", effect() { - tech.isEnergyDamage = true + tech.energyDamage++ }, remove() { - tech.isEnergyDamage = false; + tech.energyDamage = 0; } }, { @@ -2585,7 +2585,7 @@ const tech = { }, { name: "energy conservation", - description: "5% of damage done recovered as energy
 ", + description: "5% of damage done recovered as energy", maxCount: 9, count: 0, frequency: 1, @@ -3447,8 +3447,8 @@ const tech = { }, { name: "dark patterns", - description: "+38% damage
+53% JUNK to tech pool", - maxCount: 1, + description: "+15% damage
+15% JUNK to tech pool", + maxCount: 9, count: 0, frequency: 1, frequencyDefault: 1, @@ -3456,10 +3456,10 @@ const tech = { return true }, requires: "", - damage: 1.38, + damage: 1.15, effect() { tech.damage *= this.damage - this.refundAmount += tech.addJunkTechToPool(0.53) + this.refundAmount += tech.addJunkTechToPool(0.15) }, refundAmount: 0, remove() { @@ -3511,7 +3511,7 @@ const tech = { }, { name: "eternalism", - description: "+34% damage
time can't be paused (time can be dilated)", + description: "+30% damage
time can't be paused (time can be dilated)", maxCount: 1, count: 0, frequency: 1, @@ -3520,7 +3520,7 @@ const tech = { return !tech.isPauseSwitchField && !tech.isPauseEjectTech && !tech.isWormHolePause }, requires: "not unified field theory, paradigm shift, invariant", - damage: 1.34, + damage: 1.3, effect() { tech.damage *= this.damage tech.isNoDraftPause = true @@ -3845,7 +3845,7 @@ const tech = { }, { name: "correlated damage", - description: "duplication increases damage
 ", + description: "duplication increases damage", maxCount: 1, count: 0, frequency: 1, @@ -4153,7 +4153,7 @@ const tech = { }, { name: "needle gun", - description: "nail gun and shotgun fire mob piercing needles
 ", + description: "nail gun and shotgun fire mob piercing needles", isGunTech: true, maxCount: 1, count: 0, @@ -4211,7 +4211,7 @@ const tech = { }, { name: "rivet gun", - description: "nail gun and shotgun slowly lob a heavy rivet
 ", + description: "nail gun and shotgun slowly lob a heavy rivet", isGunTech: true, maxCount: 1, count: 0, @@ -4337,7 +4337,7 @@ const tech = { frequency: 2, frequencyDefault: 2, allowed() { - return tech.isMineDrop + tech.isNailBotUpgrade + tech.fragments + tech.nailsDeathMob + (tech.haveGunCheck("super balls") + (tech.haveGunCheck("mine") && !(tech.isLaserMine || tech.isFoamMine)) + (tech.haveGunCheck("nail gun")) + tech.isNeedles + tech.isNailShot + tech.isRivets) * 2 > 1 + return tech.isMineDrop + tech.isNailBotUpgrade + tech.fragments + tech.nailsDeathMob + (tech.haveGunCheck("super balls") + (tech.haveGunCheck("mine") && !(tech.isFoamMine || tech.isSuperMine)) + (tech.haveGunCheck("nail gun")) + tech.isNeedles + tech.isNailShot + tech.isRivets) * 2 > 1 }, requires: "nails, nail gun, rivets, shotgun, super balls, mine", effect() { @@ -4356,9 +4356,9 @@ const tech = { frequency: 2, frequencyDefault: 2, allowed() { - return (tech.isNailShot || tech.isNeedles || tech.isNailBotUpgrade || tech.haveGunCheck("nail gun") || tech.isRivets) && !tech.isIncendiary && !tech.isCritKill + return (tech.isNailShot || tech.isNeedles || tech.isNailBotUpgrade || tech.haveGunCheck("nail gun") || tech.isRivets || (tech.haveGunCheck("mine") && !(tech.isFoamMine || tech.isSuperMine))) && !tech.isIncendiary && !tech.isCritKill }, - requires: "nail gun, needles, nails, rivets, not incendiary, stress concentration", + requires: "nail gun, mine, needles, nails, rivets, not incendiary, stress concentration", effect() { tech.isNailCrit = true }, @@ -4376,7 +4376,7 @@ const tech = { frequency: 2, frequencyDefault: 2, allowed() { - return tech.isMineDrop || tech.isNailBotUpgrade || tech.fragments || tech.nailsDeathMob || (tech.haveGunCheck("mine") && !(tech.isLaserMine || tech.isFoamMine)) || (tech.haveGunCheck("nail gun") && !tech.isShieldPierce) || (tech.haveGunCheck("shotgun") && (tech.isNeedles || tech.isNailShot)) + return tech.isMineDrop || tech.isNailBotUpgrade || tech.fragments || tech.nailsDeathMob || (tech.haveGunCheck("mine") && !(tech.isFoamMine || tech.isSuperMine)) || (tech.haveGunCheck("nail gun") && !tech.isShieldPierce) || (tech.haveGunCheck("shotgun") && (tech.isNeedles || tech.isNailShot)) }, requires: "nail gun, nails, rivets, mine, not ceramic needles", effect() { @@ -4468,7 +4468,7 @@ const tech = { }, { name: "Newtons 3rd law", - description: "+66% shotgun fire rate and recoil
 ", + description: "+66% shotgun fire rate and recoil", isGunTech: true, maxCount: 1, count: 0, @@ -4508,7 +4508,7 @@ const tech = { { name: "nail-shot", link: `nail-shot`, - description: "shotgun drives a long clip of nails
 ", + description: "shotgun drives a long clip of nails", isGunTech: true, maxCount: 1, count: 0, @@ -4528,7 +4528,7 @@ const tech = { { name: "foam-shot", link: `foam-shot`, - description: "shotgun sprays sticky foam bubbles
 ", + description: "shotgun sprays sticky foam bubbles", isGunTech: true, maxCount: 1, count: 0, @@ -4548,7 +4548,7 @@ const tech = { { name: "ice-shot", link: `ice-shot`, - description: "shotgun grows freezing ice IX crystals
 ", + description: "shotgun grows freezing ice IX crystals", isGunTech: true, maxCount: 1, count: 0, @@ -4567,7 +4567,7 @@ const tech = { }, { name: "freezer burn", - description: "mobs frozen while below 33% durability die
 ", + description: "mobs frozen while below 33% durability die", isGunTech: true, maxCount: 1, count: 0, @@ -4669,7 +4669,7 @@ const tech = { frequency: 1, frequencyDefault: 1, allowed() { - return (tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIceShot && !tech.isRivets && !tech.isFoamShot && !tech.isSporeWorm && !tech.isSporeFlea && !tech.isNeedles) || (tech.haveGunCheck("super balls") && !tech.isFoamBall && !tech.superHarm) || (tech.isRivets && !tech.isNailCrit) || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && simulation.molecularMode === 3) || (tech.haveGunCheck("drones") && !tech.isForeverDrones && !tech.isDroneRadioactive && !tech.isDroneTeleport) + return (tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIceShot && !tech.isRivets && !tech.isFoamShot && !tech.isSporeWorm && !tech.isSporeFlea && !tech.isNeedles) || ((tech.haveGunCheck("super balls") || tech.isSuperMine) && !tech.isFoamBall && !tech.superHarm) || (tech.isRivets && !tech.isNailCrit) || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && simulation.molecularMode === 3) || (tech.haveGunCheck("drones") && !tech.isForeverDrones && !tech.isDroneRadioactive && !tech.isDroneTeleport) }, requires: "shotgun, super balls, rivets, drones, not irradiated drones, burst drones, polyurethane, Zectron", effect() { @@ -4679,6 +4679,44 @@ const tech = { tech.isIncendiary = false; } }, + { + name: "Zectron", + description: `+80% super ball density and damage, but
after colliding with super balls lose health`, + isGunTech: true, + maxCount: 9, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return (tech.haveGunCheck("super balls") || tech.isSuperMine) && !tech.isIncendiary + }, + requires: "super balls not incendiary ammunition", + effect() { + tech.superHarm++ + }, + remove() { + tech.superHarm = 0 + } + }, + { + name: "polyurethane foam", + description: "super balls and harpoons colliding with mobs
catalyzes a reaction that yields foam bubbles", + isGunTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return (tech.haveGunCheck("super balls") || tech.isSuperMine) || (tech.haveGunCheck("harpoon") && !tech.fragments) + }, + requires: "super balls, harpoon, not fragmentation", + effect() { + tech.isFoamBall = true; + }, + remove() { + tech.isFoamBall = false; + } + }, { name: "autocannon", description: "fire +1 extra super ball
balls are quickly released in same direction", @@ -4706,39 +4744,20 @@ const tech = { } } }, - { - name: "Zectron", - description: `+80% super ball density and damage, but
after colliding with super balls lose health`, - isGunTech: true, - maxCount: 9, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return tech.haveGunCheck("super balls") && !tech.isIncendiary - }, - requires: "super balls not incendiary ammunition", - effect() { - tech.superHarm++ - }, - remove() { - tech.superHarm = 0 - } - }, { name: "super duper", - description: `randomly fire +0, +1, or +2 extra super balls
 `, + description: `randomly fire +0, +1, +2, or +3 extra super balls`, isGunTech: true, maxCount: 9, count: 0, frequency: 2, frequencyDefault: 2, allowed() { - return tech.haveGunCheck("super balls") && !tech.oneSuperBall + return (tech.haveGunCheck("super balls") || tech.isSuperMine) && !tech.oneSuperBall }, requires: "super balls, not super ball", effect() { - tech.extraSuperBalls += 3 + tech.extraSuperBalls += 4 }, remove() { tech.extraSuperBalls = 0; @@ -4753,7 +4772,7 @@ const tech = { frequency: 2, frequencyDefault: 2, allowed() { - return tech.haveGunCheck("super balls") && !tech.extraSuperBalls && !tech.superBallDelay + return (tech.haveGunCheck("super balls") || tech.isSuperMine) && !tech.extraSuperBalls && !tech.superBallDelay }, requires: "super balls, not super duper or autocannon", effect() { @@ -4771,26 +4790,6 @@ const tech = { } } }, - { - name: "polyurethane foam", - description: "super balls and harpoons colliding with mobs
catalyzes a reaction that yields foam bubbles", - isGunTech: true, - maxCount: 1, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return tech.haveGunCheck("super balls") || (tech.haveGunCheck("harpoon") && !tech.fragments) - }, - requires: "super balls, harpoon, not fragmentation", - effect() { - tech.isFoamBall = true; - }, - remove() { - tech.isFoamBall = false; - } - }, - // { name: "phase velocity", description: "wave particles propagate faster as solids
+35% wave damage", @@ -5145,7 +5144,7 @@ const tech = { }, { name: "ammonium nitrate", - description: "+24% explosive damage, radius
 ", + description: "+24% explosive damage, radius", isGunTech: true, maxCount: 9, count: 0, @@ -5508,7 +5507,7 @@ const tech = { frequencyDefault: 2, allowed() { // return (tech.haveGunCheck("nail gun") && !tech.isRivets && !tech.isNeedles) || (tech.haveGunCheck("mines")) - return tech.isMineDrop || tech.isNailBotUpgrade || tech.fragments || tech.nailsDeathMob || (tech.haveGunCheck("mine") && !(tech.isLaserMine || tech.isFoamMine)) || (tech.haveGunCheck("nail gun") && !tech.isRivets && !tech.isNeedles) || (tech.haveGunCheck("shotgun") && (tech.isNeedles || tech.isNailShot) && !tech.isRivets && !tech.isNeedles) + return tech.isMineDrop || tech.isNailBotUpgrade || tech.fragments || tech.nailsDeathMob || (tech.haveGunCheck("mine") && !(tech.isLaserMine || tech.isFoamMine || tech.isSuperMine)) || (tech.haveGunCheck("nail gun") && !tech.isRivets && !tech.isNeedles) || (tech.haveGunCheck("shotgun") && (tech.isNeedles || tech.isNailShot) && !tech.isRivets && !tech.isNeedles) }, // requires: "nail gun, not rotary cannon, rivets, or needles", @@ -5521,7 +5520,7 @@ const tech = { }, { name: "booby trap", - description: "60% chance to drop a mine from power ups
+46% JUNK to tech pool", + description: "50% chance to drop a mine from power ups
+36% JUNK to tech pool", isGunTech: true, maxCount: 1, count: 0, @@ -5537,7 +5536,7 @@ const tech = { x: 0, y: 0 }, 0) - this.refundAmount += tech.addJunkTechToPool(0.46) + this.refundAmount += tech.addJunkTechToPool(0.36) }, refundAmount: 0, remove() { @@ -5550,16 +5549,16 @@ const tech = { }, { name: "elephants toothpaste", - description: "mines catalyze a reaction
that yields foam bubbles", + description: "instead of nails mines catalyze a reaction
that yields foam bubbles", isGunTech: true, maxCount: 1, count: 0, frequency: 2, frequencyDefault: 2, allowed() { - return tech.haveGunCheck("mine") && !tech.isMineSentry + return tech.haveGunCheck("mine") && !tech.isSuperMine && !tech.isRicochet && !tech.isNailRadiation && !tech.isNailCrit }, - requires: "mines, not sentry", + requires: "mines, not blast ball, ricochet, irradiated nails, supercritical fission", effect() { tech.isFoamMine = true; }, @@ -5567,6 +5566,27 @@ const tech = { tech.isFoamMine = false; } }, + { + name: "blast ball", + descriptionFunction() { + return `instead of nails mines fire bouncy ${b.guns[10].nameString('s')}` + }, + isGunTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return tech.haveGunCheck("mine") && !tech.isFoamMine && !tech.isRicochet && !tech.isNailRadiation && !tech.isNailCrit + }, + requires: "mines, not elephants toothpaste, ricochet, irradiated nails, supercritical fission", + effect() { + tech.isSuperMine = true; + }, + remove() { + tech.isSuperMine = false; + } + }, { name: "laser-mines", link: `laser-mines`, @@ -5588,8 +5608,10 @@ const tech = { } }, { - name: "sentry", - description: "instead of detonating, mines target mobs
with a stream of nails for about 17 seconds", + name: "sentry gun", + descriptionFunction() { + return `mines fire one ${b.guns[10].nameString()} at a time
mines fire 50% more ${b.guns[10].nameString('s')}` + }, isGunTech: true, maxCount: 1, count: 0, @@ -5606,6 +5628,27 @@ const tech = { tech.isMineSentry = false; } }, + { + name: "extended magazine", + descriptionFunction() { + return `sentry mines fire 50% more ${b.guns[10].nameString('s')}` + }, + isGunTech: true, + maxCount: 9, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return tech.haveGunCheck("mine") && tech.isMineSentry + }, + requires: "mines, sentry", + effect() { + tech.sentryAmmo += 17; + }, + remove() { + tech.sentryAmmo = 33; + } + }, { name: "mycelial fragmentation", link: `mycelial fragmentation`, @@ -5626,25 +5669,28 @@ const tech = { tech.isSporeGrowth = false } }, - // { - // name: "cordyceps", - // description: "mobs infected by sporangium
resurrect and attack other mobs", - // isGunTech: true, - // maxCount: 1, - // count: 0, - // frequency: 2, - // frequencyDefault: 2, - // allowed() { - // return tech.haveGunCheck("spores") - // }, - // requires: "spores", - // effect() { - // tech.isZombieMobs = true - // }, - // remove() { - // tech.isZombieMobs = false - // } - // }, + { + name: "cordyceps", + // descriptionFunction() { + // return `mobs infected by ${b.guns[6].nameString('s')} have a 5% chance
to resurrect and attack other mobs` + // }, + description: "sporangium infect mobs they attach to
infected mobs resurrect and attack other mobs", + isGunTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return tech.haveGunCheck("spores") + }, + requires: "spores", + effect() { + tech.isZombieMobs = true + }, + remove() { + tech.isZombieMobs = false + } + }, { name: "colony", description: "+50% sporangium discharge
40% chance to discharge something different", @@ -5805,7 +5851,7 @@ const tech = { }, { name: "siphonaptera", - description: "sporangium and shotgun hatch fleas
 ", + description: "sporangium and shotgun hatch fleas", isGunTech: true, maxCount: 1, count: 0, @@ -5825,7 +5871,7 @@ const tech = { }, { name: "nematodes", - description: "shotgun and sporangium hatch worms
 ", + description: "shotgun and sporangium hatch worms", isGunTech: true, maxCount: 1, count: 0, @@ -6209,7 +6255,7 @@ const tech = { }, { name: "surface tension", - description: "+43% foam damage
 ", + description: "+43% foam damage", isGunTech: true, maxCount: 9, count: 0, @@ -6417,7 +6463,7 @@ const tech = { }, { name: "alternator", - description: "+90% harpoon energy efficiency
 ", + description: "+90% harpoon energy efficiency", isGunTech: true, maxCount: 1, count: 0, @@ -6652,7 +6698,7 @@ const tech = { }, { name: "relativistic momentum", - description: "lasers push mobs and blocks
 ", + description: "lasers push mobs and blocks", isGunTech: true, maxCount: 1, count: 0, @@ -6737,7 +6783,7 @@ const tech = { }, { name: "specular reflection", - description: "+2 laser beam reflections
 ", + description: "+2 laser beam reflections", isGunTech: true, maxCount: 3, count: 0, @@ -6756,7 +6802,7 @@ const tech = { }, { name: "diffraction grating", - description: `+1 diverging laser gun beam
 `, + description: `+1 diverging laser gun beam`, isGunTech: true, maxCount: 9, count: 0, @@ -7794,7 +7840,7 @@ const tech = { }, { name: "time crystals", - description: "+200% passive energy generation
 ", + description: "+200% passive energy generation", isFieldTech: true, maxCount: 1, count: 0, @@ -8415,7 +8461,7 @@ const tech = { const loop = () => { if ((simulation.isChoosing) && m.alive && !build.isExperimentSelection) { const dmg = Math.floor(27 * Math.random()) * 0.01 - this.text = `+${(dmg*100).toFixed(0).padStart(2, '0')}% damage
 ` + this.text = `+${(dmg*100).toFixed(0).padStart(2, '0')}% damage` this.damage = 1 + dmg if (document.getElementById(`damage-JUNK-id${this.id}`)) document.getElementById(`damage-JUNK-id${this.id}`).innerHTML = this.text setTimeout(() => { @@ -8542,7 +8588,7 @@ const tech = { }, { name: "meteor shower", - description: "take a shower, but meteors instead of water
 ", + description: "take a shower, but meteors instead of water", maxCount: 1, count: 0, frequency: 0, @@ -8688,7 +8734,7 @@ const tech = { // }, { name: "discount", - description: "get 3 random JUNKtech for the price of 1!
 ", + description: "get 3 random JUNKtech for the price of 1!", maxCount: 1, count: 0, frequency: 0, @@ -8757,7 +8803,7 @@ const tech = { }, { name: "harvest", - description: "convert all the mobs on this level into ammo
 ", + description: "convert all the mobs on this level into ammo", maxCount: 1, count: 0, frequency: 0, @@ -8824,7 +8870,7 @@ const tech = { }, { name: "palantír", - description: `see far away lands
 `, + description: `see far away lands`, maxCount: 1, count: 0, frequency: 0, @@ -8855,7 +8901,7 @@ const tech = { }, { name: "motion sickness", - description: `disable camera smoothing
 `, + description: `disable camera smoothing`, maxCount: 1, count: 0, frequency: 0, @@ -8888,7 +8934,7 @@ const tech = { }, { name: "facsimile", - description: `inserts a copy of your current level into the level list
 `, + description: `inserts a copy of your current level into the level list`, maxCount: 1, count: 0, frequency: 0, @@ -8924,7 +8970,7 @@ const tech = { }, { name: "bounce", - description: "you bounce off things. It's annoying, but not that bad.
 ", + description: "you bounce off things. It's annoying, but not that bad.", maxCount: 1, count: 0, frequency: 0, @@ -8942,7 +8988,7 @@ const tech = { }, { name: "mouth", - description: "mobs have a non functional mouth
 ", + description: "mobs have a non functional mouth", maxCount: 1, count: 0, frequency: 0, @@ -8988,7 +9034,7 @@ const tech = { }, { name: "all-stars", - description: "make all mobs look like stars
 ", + description: "make all mobs look like stars", maxCount: 1, count: 0, frequency: 0, @@ -9049,7 +9095,7 @@ const tech = { // }, { name: "true colors", - description: `set all power ups to their real world colors
 `, + description: `set all power ups to their real world colors`, maxCount: 1, count: 0, frequency: 0, @@ -9264,7 +9310,7 @@ const tech = { }, { name: "not a bug", - description: "initiate a totally safe game crash for 10 seconds
 ", + description: "initiate a totally safe game crash for 10 seconds", maxCount: 1, count: 0, frequency: 0, @@ -9291,7 +9337,7 @@ const tech = { }, { name: "spinor", - description: "the direction you aim is determined by your position
 ", + description: "the direction you aim is determined by your position", maxCount: 1, count: 0, frequency: 0, @@ -9320,7 +9366,7 @@ const tech = { }, { name: "p-zombie", - description: "set your health to 1
all mobs die and resurrect as zombies", + description: "set your health to 1
all mobs, not bosses, die and resurrect as zombies", maxCount: 1, count: 0, frequency: 0, @@ -9342,7 +9388,7 @@ const tech = { }, { name: "decomposers", - description: "after they die mobs leave behind spawns
 ", + description: "after they die mobs leave behind spawns", maxCount: 1, count: 0, frequency: 0, @@ -9361,7 +9407,7 @@ const tech = { }, { name: "panopticon", - description: "mobs can always see you
 ", + description: "mobs can always see you", maxCount: 1, count: 0, frequency: 0, @@ -9433,20 +9479,6 @@ const tech = { if (this.count) m.look = m.lookDefault } }, - { - name: "iFrames", - description: "you are invulnerable
when you aren't taking damage", - maxCount: 1, - count: 0, - frequency: 0, - isJunk: true, - allowed() { - return true - }, - requires: "", - effect() {}, - remove() {} - }, { name: "disintegrated armament", description: "spawn a gun
remove your active gun", @@ -9499,7 +9531,7 @@ const tech = { }, { name: "encryption", - description: "secure tech information
 ", + description: "secure tech information", maxCount: 1, count: 0, frequency: 0, @@ -9549,7 +9581,7 @@ const tech = { }, { name: "score", - description: "Add a score to n-gon!
 ", + description: "Add a score to n-gon!", maxCount: 1, count: 0, frequency: 0, @@ -9588,7 +9620,7 @@ const tech = { }, { name: "music", - description: "add music to n-gon
 ", + description: "add music to n-gon", maxCount: 1, count: 0, frequency: 0, @@ -9605,7 +9637,7 @@ const tech = { }, { name: "performance", - description: "display performance stats to n-gon
 ", + description: "display performance stats to n-gon", maxCount: 1, count: 0, frequency: 0, @@ -9661,7 +9693,7 @@ const tech = { }, { name: "defragment", - description: "set the frequency of finding JUNKtech to zero
 ", + description: "set the frequency of finding JUNKtech to zero", maxCount: 1, count: 0, frequency: 0, @@ -9701,7 +9733,7 @@ const tech = { // }, { name: "pitch", - description: "oscillate the pitch of your world
 ", + description: "oscillate the pitch of your world", maxCount: 1, count: 0, frequency: 0, @@ -9738,7 +9770,7 @@ const tech = { }, { name: "lighter", - description: `ctx.globalCompositeOperation = "lighter"
 `, + description: `ctx.globalCompositeOperation = "lighter"`, maxCount: 1, count: 0, frequency: 0, @@ -9755,7 +9787,7 @@ const tech = { }, { name: "rewind", - description: "every 10 seconds rewind 2 seconds
 ", + description: "every 10 seconds rewind 2 seconds", maxCount: 9, count: 0, frequency: 0, @@ -9778,7 +9810,7 @@ const tech = { }, { name: "undo", - description: "every 4 seconds rewind 1/2 a second
 ", + description: "every 4 seconds rewind 1/2 a second", maxCount: 9, count: 0, frequency: 0, @@ -9798,7 +9830,7 @@ const tech = { }, { name: "energy to mass conversion", - description: "convert your energy into blocks
 ", + description: "convert your energy into blocks", maxCount: 9, count: 0, frequency: 0, @@ -9830,7 +9862,7 @@ const tech = { }, { name: "level.nextLevel()", - description: "advance to the next level
 ", + description: "advance to the next level", maxCount: 9, count: 0, frequency: 0, @@ -9916,7 +9948,7 @@ const tech = { }, { name: "missile launching system", - description: "fire missiles for the next 120 seconds
 ", + description: "fire missiles for the next 120 seconds", maxCount: 9, count: 0, frequency: 0, @@ -9941,7 +9973,7 @@ const tech = { }, { name: "grenade production", - description: "drop a grenade every 2 seconds
 ", + description: "drop a grenade every 2 seconds", maxCount: 9, count: 0, frequency: 0, @@ -9994,7 +10026,7 @@ const tech = { // }, { name: "Sleipnir", - description: "grow more legs
 ", + description: "grow more legs", maxCount: 1, count: 0, frequency: 0, @@ -10081,7 +10113,7 @@ const tech = { }, { name: "🐱", - description: "🐈
 ", + description: "🐈", maxCount: 1, count: 0, frequency: 0, @@ -10181,7 +10213,7 @@ const tech = { }, { name: "posture", - description: "stand a bit taller
 ", + description: "stand a bit taller", maxCount: 1, count: 0, frequency: 0, @@ -10200,7 +10232,7 @@ const tech = { }, { name: "rhythm", - description: "you oscillate up and down
 ", + description: "you oscillate up and down", maxCount: 1, count: 0, frequency: 0, @@ -10221,7 +10253,7 @@ const tech = { }, { name: "pareidolia", - description: "don't
 ", + description: "don't", maxCount: 1, count: 0, frequency: 0, @@ -10290,7 +10322,7 @@ const tech = { }, { name: "prism", - description: "you cycle through different colors
 ", + description: "you cycle through different colors", maxCount: 1, count: 0, frequency: 0, @@ -10444,7 +10476,7 @@ const tech = { }, { name: "growth hacking", - description: "increase combat difficulty by 1 level
 ", + description: "increase combat difficulty by 1 level", maxCount: 1, count: 0, frequency: 0, @@ -10461,7 +10493,7 @@ const tech = { }, { name: "stun", - description: "stun all mobs for up to 8 seconds
 ", + description: "stun all mobs for up to 8 seconds", maxCount: 9, count: 0, frequency: 0, @@ -10506,7 +10538,7 @@ const tech = { }, { name: "re-research", - description: `eject all your ${powerUps.orb.research(1)}
 `, + description: `eject all your ${powerUps.orb.research(1)}`, maxCount: 9, count: 0, frequency: 0, @@ -10544,7 +10576,7 @@ const tech = { }, { name: "black hole cluster", - description: `spawn 30 nearby black holes
 `, + description: `spawn 30 nearby black holes`, maxCount: 1, count: 0, frequency: 0, @@ -11049,7 +11081,7 @@ const tech = { isVacuumBomb: null, renormalization: null, fragments: null, - isEnergyDamage: null, + energyDamage: null, botSpawner: null, isBotSpawnerReset: null, isSporeFollow: null, @@ -11323,5 +11355,7 @@ const tech = { isGunChoice: null, railChargeRate: null, superHarm: null, - isZombieMobs: null + isZombieMobs: null, + isSuperMine: null, + sentryAmmo: null, } \ No newline at end of file diff --git a/style.css b/style.css index 7b7565c..9653fee 100644 --- a/style.css +++ b/style.css @@ -85,7 +85,6 @@ td { .key-input { padding: 3px 8px; border: 2px solid #333; - /* border-radius: 50px; */ background-color: #fff; text-align: center; } @@ -98,7 +97,6 @@ td { width: 15px; padding: 0px 2px; border: 2px solid #333; - /* border-radius: 50px; */ background-color: #fff; text-align: center; } @@ -165,21 +163,15 @@ summary { top: 50%; left: 50%; transform: translate(-50%, -50%); - padding: 10px 1px; - /* gap: 1px; */ margin: 0px; border: 0px; z-index: 12; max-height: 99vh; font-size: 1.3em; - display: grid; grid-template-columns: repeat(3, 384px); align-items: stretch; - /* align-items: start; */ - /* align-content: start; */ - /* grid-auto-rows: minmax(auto, 140px); */ visibility: hidden; opacity: 0; transition: opacity 0.25s linear; @@ -192,13 +184,9 @@ summary { } .choose-grid-module { - /* padding: 5px; */ line-height: 160%; - /* border-radius: 8px; */ background-color: #fafcfd; font-size: 0.75em; - /* border: 1px #444 solid; */ - /* box-shadow: 0px 0px 10px 5px rgba(0, 0, 0, 0.25); */ } .choose-grid-module:hover { @@ -216,15 +204,11 @@ summary { .pause-grid { padding: 2px; margin: 0px; - display: none; grid-template-columns: 384px; - /* grid-template-columns: repeat(auto-fit, minmax(310px, 1fr)); */ grid-auto-rows: minmax(auto, auto); align-content: start; align-items: start; - /* align-content: space-between; */ - /* gap: 10px; */ z-index: 2; font-size: 1.3em; } @@ -259,19 +243,9 @@ summary { } .pause-grid-module { - /* margin: -1px; - padding: 10px; line-height: 160%; - border: 1px #333 solid; - border-radius: 8px; - background-color: #fff; - font-size: 0.65em; */ - /* padding: 5px; */ - line-height: 160%; - /* border-radius: 8px; */ background-color: #fafcfd; font-size: 0.75em; - /* border: 2px #444 solid; */ } .pause-eject .card-text { @@ -281,24 +255,14 @@ summary { #experiment-grid { display: flex; justify-content: center; - /* align-content: space-between; */ - /* align-items: start; */ - /* align-items: stretch; */ - /* padding-top: 10px; */ - /* padding: 16px; */ padding: 10px 1px; margin: 0px; border: 0px; background-color: var(--build-bg-color); - /* background-color: #444; */ - display: none; - /* grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); */ grid-template-columns: repeat(auto-fit, 384px); grid-auto-flow: row; grid-auto-rows: minmax(auto, auto); - /* gap: 1px; */ - position: relative; bottom: 0px; z-index: 10; @@ -311,14 +275,9 @@ summary { } .experiment-grid-module { - /* padding: 0.1em; */ - /* padding: 5px; */ line-height: 160%; - /* border-radius: 8px; */ background-color: #fafcfd; font-size: 0.75em; - /* border: 1px #444 solid; */ - /* margin: -0.5px; */ } .experiment-grid-hide { @@ -337,28 +296,22 @@ summary { } .card-background { - /* width:288; */ height:340px; background-size: contain; background-repeat: no-repeat; display: flex; justify-content:flex-end; flex-direction: column; - /* margin: 5px; */ } .card-text { background-color: rgba(255,255,255,1); - /* border-radius: 8px; */ - /* padding: 11px 13px; */ padding: 0.5em 1em; - /* border-top: 1px solid var(--build-bg-color); */ border: 1px solid #444; margin-top: -1px; margin-right: -1px; font-size: 0.92em; min-height: 88px; - /* height:78px; */ } .cancel-card { text-align: center; @@ -369,7 +322,6 @@ summary { margin-top: -1px; margin-right: -1px; padding: 1px; - line-height: 160%; background-color: #fafcfd; } @@ -385,10 +337,39 @@ summary { } -/* media rules for smaller screens -4->3 at 1550 -*/ -@media (1500px <= width < 1950px) { +/* keeps 5 columns at 1440px */ +@media (1710px <= width < 1950px) { + .experiment-grid-module, .choose-grid-module, .pause-grid-module { + line-height: 143%; + font-size: 0.68em; + } + #experiment-grid, #choose-grid, .pause-grid{ + grid-template-columns: repeat(auto-fit, 340px); + } + .card-background{ + height:290px; + } + .card-text { + min-height: 75px; + } +} +@media (width < 1710px) { + .experiment-grid-module, .choose-grid-module, .pause-grid-module { + line-height: 139%; + font-size: 0.58em; + } + #experiment-grid, #choose-grid, .pause-grid{ + grid-template-columns: repeat(auto-fit, 285px); + } + .card-background{ + height:240px; + } + .card-text { + min-height: 64px; + } +} +/* keeps 4 columns at 1440px */ +/* @media (1500px <= width < 1950px) { .experiment-grid-module, .choose-grid-module, .pause-grid-module { line-height: 150%; font-size: 0.72em; @@ -417,59 +398,6 @@ summary { .card-text { min-height: 75px; } -} - -/* default -.experiment-grid-module { - line-height: 160%; - font-size: 0.75em; -} -.card-background { - height:340px; -} -#experiment-grid{ - grid-template-columns: repeat(auto-fit, 384px); -} -*/ - - - - - -/* .no-image-cards{ - border: 1px solid #444; -} */ -/* .card-text:hover { - background-color: #efeff5; -} */ - - -/* .build-field-selected { - background-color: hsl(193, 100%, 75%); -} - -.build-field-selected:hover { - background-color: hsl(193, 100%, 68%); -} - -.build-gun-selected { - background-color: hsl(218, 100%, 81%); -} - -.build-gun-selected:hover { - background-color: hsl(218, 100%, 76%); -} - -.build-tech-selected .card-text{ - background-color: hsl(253, 100%, 84%); -} - -.build-tech-selected:hover .card-text{ - background-color: hsl(253, 100%, 81%); -} */ - -/* .experiment-grid-module:hover .card-text:not(.build-tech-selected, .build-field-selected, .build-gun-selected) { - background-color: #efeff5; } */ .experiment-grid-module:hover .card-text { @@ -495,17 +423,13 @@ summary { } .experiment-grid-disabled { - /* opacity: 0.5; */ background-color: var(--build-bg-color); - /* color: rgba(0, 0, 0, 0.9); */ color: #000; opacity: 0.25; - /* transition: background-color 1s, color 1s; */ } .experiment-grid-disabled[data-descr] { position: relative; - /* opacity: 0; */ } .experiment-grid-disabled[data-descr]:hover::after { @@ -535,7 +459,6 @@ summary { padding: 10px; border-radius: 8px; border: 2px #333 solid; - /* background-color: #eee; */ background-color: #fff; } @@ -670,12 +593,9 @@ summary { transition: opacity 0.25s; pointer-events: none; user-select: none; - /* white-space: pre; - font-family: 'Menlo', 'Monaco', monospace; */ } /* color for in game console output */ - .color-text { color: #000; } @@ -697,32 +617,6 @@ summary { background-color: #ff0; padding: 3px; } -/* colors for pause, selection and experiment */ - -/* #text-log { - z-index: 2; - position: absolute; - bottom: 4px; - left: 6px; - line-height: 130%; - font-size: 1.2em; - color: rgb(237, 15, 148); - transition: opacity 1s; - pointer-events: none; - user-select: none; -} - -.color-text { - color: rgb(0, 164, 164); -} - -.color-symbol { - color: #fff; -} - */ - - - .color-f { color: #0ad; @@ -769,44 +663,11 @@ summary { } .color-dup { - /* color: hsl(243, 100%, 38%); */ font-variant: small-caps; letter-spacing: 1px; text-shadow: 1.5px -1.5px hsla(243, 100%, 38%, 0.2); - /* text-decoration: underline; */ } -/* .mob { - text-shadow: 0px 1px, 1px 0px, 1px 1px; -} */ - -/* @keyframes bounce-munch { - 0% { - vertical-align: -40px; - } - 50% { - vertical-align: 4px; - } - 100% { - vertical-align: 40px; - } - } */ - - -/* .color-bot { */ -/* background-color: #eee; */ -/* color: #555; */ -/* letter-spacing: -1.5px; */ -/* text-transform: uppercase; */ -/* font-variant: all-caps; */ -/* text-decoration: underline solid; */ -/* border: 1px solid #000; */ -/* padding: 10px; */ -/* border-radius: 10%; */ -/* font-family: Lucida Console, Courier, monospace; */ -/* color: #777; */ -/* } */ - .color-cloaked { letter-spacing: 2px; animation: cloak 6s linear infinite alternate; @@ -832,10 +693,6 @@ summary { .color-laser { color: #f02; - /* color: #000bff; */ - /* color: #83f; */ - /* text-shadow: 0px 0px 2px rgba(255, 0, 119, 0.3); */ - /* text-shadow: 0px 0px 1.5px rgba(0, 0, 0, 1), 0px 0px 5px rgba(255, 0, 0, 1); */ font-weight: 100; letter-spacing: -0.8px; } @@ -852,12 +709,9 @@ summary { .color-worm { color: #fff; text-shadow: 1px 0px 2px #234; - /* letter-spacing: 2px; */ } .color-defense { - /* color: */ - /* text-shadow: #FC0 1px 0 10px; */ background-color: hsla(227, 9%, 71%, 0.279); padding: 2px; border-radius: 4px; @@ -882,18 +736,9 @@ summary { .color-junk { letter-spacing: 1px; - /* font-weight: 100; */ font-family: Lucida Console, Courier, monospace; - /* transform: rotate(-90deg); */ } -/* .color-rewind { - background-image: linear-gradient(to left, #fff, #bbb); - border-radius: 5px; - padding: 2px; - letter-spacing: 1px; -} */ - .color-r { color: #f7b; letter-spacing: 1px; @@ -993,20 +838,6 @@ summary { margin-bottom: -0.5px; } -/* .circle-grid-shadow { - width: 43px; - height: 43px; - border-radius: 50%; - display: inline-block; - margin-bottom: -15px; -} */ - -/* .circle-gun-tech { - box-shadow: 0 0 0 3px #025; -} */ - - - @keyframes pulse { 0% { border-radius: 0%; @@ -1017,31 +848,14 @@ summary { } } -/* .circle-grid-gun { - width: 10px; - height: 10px; - border-radius: 50%; - display: inline-block; - margin-bottom: 0px; - background: #025; - box-shadow: 0 0 0 8px hsl(253, 80%, 67%); -} */ - .field { background-color: #0cf; } .tech { - /* background: rgb(116, 102, 238); */ - /* background: hsl(253, 57%, 52%); */ background-color: hsl(255, 100%, 71%); - /* background: hsl(282, 100%, 64%); */ } -/* .grey { - background: #afb6c2; -} */ - .gun { background-color: rgb(0, 80, 218); } @@ -1051,7 +865,6 @@ summary { } .research { - /* #f84 #f99*/ background-color: #f7b; } @@ -1059,7 +872,6 @@ summary { animation: alt 8s linear infinite alternate; font-weight: 400; letter-spacing: 1px; - /* color: rgba(0, 0, 0, 0.5) */ } @keyframes alt { @@ -1096,35 +908,11 @@ summary { } .color-coupling { - /* animation: coupling 1000ms linear infinite alternate; */ - /* animation: vibrate 500ms linear infinite alternate; - display: inline-block; */ - /* text-shadow: 0px 0px 2px #0cf; */ - /* text-shadow: 0px 0px 1.5px #0cf; */ text-shadow: 0px 0px 1.5px #0cf; - /* color: hsl(255, 82%, 59%); */ letter-spacing: 1px; font-weight: 100; } -/* @keyframes coupling{ - 0%{ - letter-spacing: 0.5px; - } - 100%{ - letter-spacing: 1px; - } - } - -@keyframes vibrate{ - 0% { - transform: translateY(-0.25px) - } - 100% { - transform: translateY(0.25px) - } -} */ - .box { padding: 3px 8px 3px 8px; border: 2px solid #444; @@ -1157,13 +945,11 @@ summary { } .entanglement { - /* color: #456; */ font-size: 1.1em; font-weight: 100; text-align: center; letter-spacing: 10px; border: none; - /* border-radius: 50%; */ background-color: #efeff5; } .flipX { @@ -1299,16 +1085,4 @@ summary { .link:hover { text-decoration: underline; - /* color: #0ad; */ -} - -/* #console { - font-family: monospace; - font-size: 1.5em; - width: 300px; - height: 50px; - position: absolute; - bottom: 10px; - right: 10px; - z-index: 3; -} */ \ No newline at end of file +} \ No newline at end of file diff --git a/todo.txt b/todo.txt index 514c3ff..df9d758 100644 --- a/todo.txt +++ b/todo.txt @@ -1,29 +1,29 @@ ******************************************************** NEXT PATCH ************************************************** -card images and text scale based on browser width for smaller screens +tech: cordyceps - sporangium infect mobs, making them fight for you as zombies -tech Zectron - super ball can damage you, but they do more damage to mobs - superBall bullets are converted to run off generic b.superBall() +tech: blast ball - mines fire super balls +tech: extended magazine - sentry fires 50% more shots + sentry works with foam, nails, or super balls -sneakers - after taking damage if sneakers are low on life they teleport to a random point from the player's history and they sneak attack again -sneakBoss - a large sneaker that can hide several times before it dies +dark patterns - stacks to 9 + 38->15% damage, 53->15% JUNK +electronegativity - stacks to 9 + 0.12->0.1% damage per energy bug fixes *********************************************************** TODO ***************************************************** -tech: cordyceps - sporangium infect mobs, making them fight for you - zombies might attack player if there are no mob targets - !! needs to explore when there are no targets - !! mechanics are confusing - !! still needs testing for balance - it's targeting player even when there are mobs -tech - all mobs return as zombies? +super-bot -Now that super balls are generic maybe something else should produce them - super-bot - molecular fabricator - how to aim? - shotgun - too similar to super ball gun +tech - shotgun triple shot, but a bit longer of a delay + +tech - after standing wave runs out of energy from blocking, gain a buff + buff: defense, damage? + +make super balls with Zectron deflectable with field + but is there a simple way to do this? set mob health bar colors based on status effects? make mob damage immunity a mob status effect? @@ -87,6 +87,8 @@ hookBoss fires a hook that pulls player towards it finalBoss add synergies between modes: new modes: + something that needs to be killed quickly + if you don't kill it boss gets a shield rotating quadrant immunity shield, can't take damage from that quadrant maybe also attack player near that quadrant but how to tell the angle of incoming damage @@ -1136,7 +1138,7 @@ possible names for tech ******************************************************** CARS IMAGES ******************************************************** -process: discord midjourney prompts -> "pixelmator pro" -> adjust color, repair, scale to 384x256, export PNG -> webP? -> place in /img folder +process: discord midjourney prompts -> "pixelmator pro" adjust color, repair, scale to 384x256, export PNG -> webP? -> place in /img folder make n-gon a progressive web app to manage image downloads, cache wave function collapse opens the pause menu after it triggers alternate reality this is actually good, maybe reuse this code to get pause menu to open at any time @@ -1155,16 +1157,12 @@ if pause is pressed while selecting power ups, display pause menu on top of sele ***major themes missing*** ***maybe redo*** dynamical systems - harpoon gun - Eiichiro Oda --niji nail-bot homeostasis heuristics thermal runaway - infrared maybe? redo the energy tech images with by Laurie Greasley now that you can use --ar 3:2 --stylize 1000 and photo repair - in general too many black background - redo fractal tech with white background ***past style themes*** field emitter - isometric, clean white robot spherical gun turret on bird legs, blender 3d, style of artstation and behance, Disney Pixar, cute standing wave - concentric transparent blue geometric circles science