From 5aa7233bc8fb0cca4ffbd044389f698f06b21fd1 Mon Sep 17 00:00:00 2001 From: landgreen Date: Fri, 12 Feb 2021 06:02:34 -0800 Subject: [PATCH] quantum foam all mobs that move through walls and blocks now have a transparent fill player and power ups float in hazards tech: apomixis - after reaching 100% duplication spawn 4 level bosses tech: quantum foam - +153% foam damage, fire 0.35s into the future bullets are bigger, and easier to see --- .DS_Store | Bin 6148 -> 6148 bytes js/bullet.js | 84 ++++++++++++++++++++++++++++++++++------- js/level.js | 38 ++++++++++++++++--- js/mob.js | 4 +- js/player.js | 4 +- js/powerup.js | 7 +++- js/spawn.js | 69 +++++++++++++++++++--------------- js/tech.js | 102 ++++++++++++++++++++++++++++++++++++++++++-------- todo.txt | 49 ++++++++++-------------- 9 files changed, 254 insertions(+), 103 deletions(-) diff --git a/.DS_Store b/.DS_Store index 523eb0246ac9b14eb918884c3e63d2bcd05b0eac..f7316f4826e6a4aa10f26592f2a63a7fbb847ecf 100644 GIT binary patch delta 21 ccmZoMXffEJ#mp3NaIy}wALEA2)y$nD08HNo=l}o! delta 21 ccmZoMXffEJ#mwYXF { + // if (!simulation.paused) { + // b.foam(position, velocity, radius) + // bullet[bullet.length - 1].damage = (1 + 1.53 * tech.foamFutureFire) * (tech.isFastFoam ? 0.048 : 0.012) //double damage + // } + // }, 350 * tech.foamFutureFire); + + let knock, spread if (m.crouch) { spread = 0.75 @@ -3832,19 +3858,49 @@ const b = { ammoPack: 36, have: false, fire() { - m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 15 : 5) * b.fireCD); // cool down - const radius = (m.crouch ? 10 + 5 * Math.random() : 4 + 6 * Math.random()) + (tech.isAmmoFoamSize && this.ammo < 300) * 12 - const SPEED = 18 - radius * 0.4; - const dir = m.angle + 0.2 * (Math.random() - 0.5) - const velocity = { - x: SPEED * Math.cos(dir), - y: SPEED * Math.sin(dir) + if (tech.foamFutureFire) { + m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 15 : 5) * b.fireCD); // cool down + const radius = (m.crouch ? 10 + 5 * Math.random() : 4 + 6 * Math.random()) + (tech.isAmmoFoamSize && this.ammo < 300) * 12 + const SPEED = 18 - radius * 0.4; + const dir = m.angle + 0.2 * (Math.random() - 0.5) + const velocity = { + x: SPEED * Math.cos(dir), + y: SPEED * Math.sin(dir) + } + const position = { + x: m.pos.x + 30 * Math.cos(m.angle), + y: m.pos.y + 30 * Math.sin(m.angle) + } + simulation.drawList.push({ //add dmg to draw queue + x: position.x, + y: position.y, + radius: 5, + color: "rgba(0,0,0,0.1)", + time: 21 * tech.foamFutureFire + }); + + setTimeout(() => { + if (!simulation.paused) { + b.foam(position, velocity, radius) + bullet[bullet.length - 1].damage = (1 + 1.53 * tech.foamFutureFire) * (tech.isFastFoam ? 0.048 : 0.012) //double damage + } + }, 350 * tech.foamFutureFire); + + } else { + m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 15 : 5) * b.fireCD); // cool down + const radius = (m.crouch ? 10 + 5 * Math.random() : 4 + 6 * Math.random()) + (tech.isAmmoFoamSize && this.ammo < 300) * 12 + const SPEED = 18 - radius * 0.4; + const dir = m.angle + 0.2 * (Math.random() - 0.5) + const velocity = { + x: SPEED * Math.cos(dir), + y: SPEED * Math.sin(dir) + } + const position = { + x: m.pos.x + 30 * Math.cos(m.angle), + y: m.pos.y + 30 * Math.sin(m.angle) + } + b.foam(position, velocity, radius) } - const position = { - x: m.pos.x + 30 * Math.cos(m.angle), - y: m.pos.y + 30 * Math.sin(m.angle) - } - b.foam(position, velocity, radius) } }, { diff --git a/js/level.js b/js/level.js index fe5a8fe..c27da10 100644 --- a/js/level.js +++ b/js/level.js @@ -760,7 +760,7 @@ const level = { mapB.portalPair = mapA return [portalA, portalB, mapA, mapB] }, - hazard(x, y, width, height, damage = 0.0005, color = "hsla(160, 100%, 35%,0.75)", isOptical = false) { + hazard(x, y, width, height, damage = 0.0008, color = "hsla(160, 100%, 35%,0.75)", isOptical = false) { return { min: { x: x, @@ -791,6 +791,29 @@ const level = { } const drain = 0.005 if (m.energy > drain) m.energy -= drain + + //float + if (!isOptical) { + if (player.velocity.y > 3) player.force.y -= 0.96 * player.mass * simulation.g + const slowY = (player.velocity.y > 0) ? Math.max(0.3, 1 - 0.0015 * player.velocity.y * player.velocity.y) : Math.max(0.98, 1 - 0.001 * Math.abs(player.velocity.y)) //down : up + Matter.Body.setVelocity(player, { + x: Math.max(0.6, 1 - 0.07 * Math.abs(player.velocity.x)) * player.velocity.x, + y: slowY * player.velocity.y + }); + } + } + //float power ups + if (!isOptical) { + powerUpCollide = Matter.Query.region(powerUp, this) + for (let i = 0, len = powerUpCollide.length; i < len; i++) { + const diameter = 2 * powerUpCollide[i].size + const buoyancy = 1 - 0.2 * Math.max(0, Math.min(diameter, this.min.y - powerUpCollide[i].position.y + powerUpCollide[i].size)) / diameter + powerUpCollide[i].force.y -= buoyancy * 1.1 * powerUpCollide[i].mass * simulation.g; + Matter.Body.setVelocity(powerUpCollide[i], { + x: powerUpCollide[i].velocity.x, + y: 0.95 * powerUpCollide[i].velocity.y + }); + } } }, draw() { @@ -1054,18 +1077,19 @@ const level = { // spawn.boost(1500, 0, 900); // spawn.starter(1900, -500, 200) //big boy - spawn.starter(1900, -500) + // spawn.starter(1900, -500) // spawn.historyBoss(1900, -500) - // spawn.sneaker(2900, -500) + // spawn.ghoster(2900, -500) // spawn.launcherBoss(1200, -500) // spawn.laserTargetingBoss(1600, -400) // spawn.striker(1600, -500) // spawn.shooter(1700, -120) // spawn.bomberBoss(1400, -500) - // spawn.sniper(1800, -120) - // spawn.cellBossCulture(1600, -500) - // spawn.cellBossCulture(1600, -500) + spawn.sniper(1800, -120) // spawn.streamBoss(1600, -500) + // spawn.cellBossCulture(1600, -500) + // spawn.cellBossCulture(1600, -500) + // spawn.bomberBoss(1600, -500) // spawn.beamer(1200, -500) // spawn.shield(mob[mob.length - 1], 1800, -120, 1); @@ -1139,8 +1163,10 @@ const level = { powerUps.spawn(1675, -50, "ammo"); powerUps.spawn(3350, -75, "ammo"); powerUps.spawn(3925, -50, "ammo"); + powerUps.spawn(4250, -75, "ammo"); powerUps.spawn(4550, -75, "ammo"); powerUps.spawn(5025, -50, "ammo"); + powerUps.spawn(4725, -50, "ammo"); powerUps.spawn(4975, -350, "ammo"); powerUps.spawn(5125, -350, "ammo"); powerUps.spawn(5075, -425, "ammo"); diff --git a/js/mob.js b/js/mob.js index c4e12ff..0780166 100644 --- a/js/mob.js +++ b/js/mob.js @@ -874,7 +874,7 @@ const mobs = { Matter.Query.ray(map, this.position, this.mPosRange()).length === 0 && //see player Matter.Query.ray(body, this.position, this.mPosRange()).length === 0 ) { - spawn.bomb(this.position.x, this.position.y + this.radius * 0.5, 10 + Math.ceil(this.radius / 15), 5); + spawn.bomb(this.position.x, this.position.y + this.radius * 0.7, 9 + Math.ceil(this.radius / 15), 5); //add spin and speed Matter.Body.setAngularVelocity(mob[mob.length - 1], (Math.random() - 0.5) * 0.5); Matter.Body.setVelocity(mob[mob.length - 1], { @@ -909,7 +909,7 @@ const mobs = { this.torque -= 0.000004 * this.inertia; } else if (this.noseLength > 1.5) { //fire - spawn.bullet(this.vertices[1].x, this.vertices[1].y, 5 + Math.ceil(this.radius / 15), 5); + spawn.bullet(this.vertices[1].x, this.vertices[1].y, 9 + Math.ceil(this.radius / 15)); const v = 15; Matter.Body.setVelocity(mob[mob.length - 1], { x: this.velocity.x + this.fireDir.x * v + 3 * Math.random(), diff --git a/js/player.js b/js/player.js index 7f419af..763e4ce 100644 --- a/js/player.js +++ b/js/player.js @@ -497,7 +497,7 @@ const m = { harmReduction() { let dmg = 1 dmg *= m.fieldHarmReduction - if (tech.isBlockHarm && m.isHolding) dmg *= 0.4 + if (tech.isBlockHarm && m.isHolding) dmg *= 0.25 if (tech.squirrelFx !== 1) dmg *= 1 + (tech.squirrelFx - 1) / 5 //cause more damage if (tech.isSpeedHarm) dmg *= 1 - Math.min(player.speed * 0.0185, 0.55) if (tech.isSlowFPS) dmg *= 0.8 @@ -506,7 +506,7 @@ const m = { if (tech.isBotArmor) dmg *= 0.96 ** tech.totalBots() if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.33; if (tech.isNoFireDefense && m.cycle > m.fireCDcycle + 120) dmg *= 0.6 - if (tech.energyRegen === 0) dmg *= 0.4 + if (tech.energyRegen === 0) dmg *= 0.34 if (tech.isTurret && m.crouch) dmg *= 0.5; if (tech.isFireMoveLock && input.fire) dmg *= 0.4; if (tech.isEntanglement && b.inventory[0] === b.activeGun) { diff --git a/js/powerup.js b/js/powerup.js index 7e9e878..040680e 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -36,7 +36,10 @@ const powerUps = { }, endDraft(type, isCanceled = false) { if (isCanceled) { - if (tech.isCancelDuplication) tech.cancelCount++ + if (tech.isCancelDuplication) { + tech.cancelCount++ + tech.maxDuplicationEvent() + } if (tech.isCancelRerolls) { for (let i = 0; i < 8; i++) { let spawnType = (m.health < 0.25 || tech.isEnergyNoAmmo) ? "heal" : "ammo" @@ -174,7 +177,7 @@ const powerUps = { if (tech.isAmmoForGun && b.inventory.length > 0 && b.activeGun) { const target = b.guns[b.activeGun] if (target.ammo !== Infinity) { - const ammoAdded = Math.ceil(Math.random() * target.ammoPack) + Math.ceil(Math.random() * target.ammoPack) + const ammoAdded = Math.ceil(Math.random() * target.ammoPack) + Math.ceil(0.7 * Math.random() * target.ammoPack) target.ammo += ammoAdded simulation.makeTextLog(`${target.name}.ammo += ${ammoAdded}`) } diff --git a/js/spawn.js b/js/spawn.js index 4bb5d7b..313794d 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -112,18 +112,23 @@ const spawn = { } else { //reset game setTimeout(() => { - simulation.makeTextLog(`simulation.end()`); + simulation.makeTextLog(`simulation.complete()`); let delay = 1000 - for (let i = 20; i > 0; i--) { + for (let i = 0; i < 1.01; i += 0.01 + 0.1 * Math.random()) { setTimeout(function() { - simulation.makeTextLog(`delay = ${i*1000}`); + simulation.makeTextLog(`simulation.analysis = ${(i).toFixed(3)}`); }, delay); delay += 1000 } - delay += 1000 + setTimeout(function() { + simulation.makeTextLog(`simulation.analysis = 1`); + }, delay); + delay += 2000 setTimeout(() => { - simulation.makeTextLog(`World.clear(engine.world)`); - setTimeout(() => { m.death() }, 1000); + if (!simulation.paused && !simulation.testing) { + simulation.makeTextLog(`World.clear(engine.world)`); + setTimeout(() => { m.death() }, 2000); + } }, delay); }, 5000); } @@ -514,22 +519,21 @@ const spawn = { } }, cellBoss(x, y, radius = 20, cellID) { - mobs.spawn(x + Math.random(), y + Math.random(), 20, radius * (1 + 1.2 * Math.random()), "rgba(0,150,155,0.7)"); + mobs.spawn(x + Math.random(), y + Math.random(), 20, radius * (1 + 1.2 * Math.random()), "rgba(0,100,105,0)"); let me = mob[mob.length - 1]; + me.stroke = "#099" me.isBoss = true; me.isCell = true; me.cellID = cellID - me.accelMag = 0.00015 * simulation.accelScale; + me.accelMag = 0.00016 * simulation.accelScale; me.memory = 40; me.isVerticesChange = true me.frictionAir = 0.012 me.seePlayerFreq = Math.floor(11 + 7 * Math.random()) me.seeAtDistance2 = 1400000; me.cellMassMax = 70 - - me.collisionFilter.mask = cat.player | cat.bullet - Matter.Body.setDensity(me, 0.0005) // normal density is 0.001 // this reduces life by half and decreases knockback - // console.log(me.mass, me.radius) + me.collisionFilter.mask = cat.player | cat.bullet //| cat.map | cat.body + Matter.Body.setDensity(me, 0.001) // normal density is 0.001 // this reduces life by half and decreases knockback const k = 642 //k=r^2/m me.split = function() { Matter.Body.scale(this, 0.4, 0.4); @@ -556,16 +560,16 @@ const spawn = { this.radius = Math.sqrt(this.mass * k / Math.PI) } if (!(simulation.cycle % this.seePlayerFreq)) { //move away from other mobs - const repelRange = 200 - const attractRange = 800 + const repelRange = 150 + const attractRange = 700 for (let i = 0, len = mob.length; i < len; i++) { if (mob[i].isCell && mob[i].id !== this.id) { const sub = Vector.sub(this.position, mob[i].position) const dist = Vector.magnitude(sub) if (dist < repelRange) { - this.force = Vector.mult(Vector.normalise(sub), this.mass * 0.006) + this.force = Vector.mult(Vector.normalise(sub), this.mass * 0.002) } else if (dist > attractRange) { - this.force = Vector.mult(Vector.normalise(sub), -this.mass * 0.004) + this.force = Vector.mult(Vector.normalise(sub), -this.mass * 0.003) } } } @@ -594,7 +598,7 @@ const spawn = { me.frictionAir = 0.01 me.seeAtDistance2 = 1000000; me.accelMag = 0.0005 * simulation.accelScale; - Matter.Body.setDensity(me, 0.0006); //normal is 0.001 + Matter.Body.setDensity(me, 0.001); //normal is 0.001 me.collisionFilter.mask = cat.bullet | cat.player me.memory = Infinity; me.seePlayerFreq = 30 @@ -908,7 +912,7 @@ const spawn = { me.collisionFilter.mask = cat.player | cat.bullet // me.frictionAir = 0.005; me.memory = 1600; - Matter.Body.setDensity(me, 0.05); //extra dense //normal is 0.001 //makes effective life much larger + Matter.Body.setDensity(me, 0.075); //extra dense //normal is 0.001 //makes effective life much larger me.onDeath = function() { //applying forces to player doesn't seem to work inside this method, not sure why powerUps.spawnBossPowerUp(this.position.x, this.position.y) @@ -1008,7 +1012,7 @@ const spawn = { let targets = [] //track who is in the node boss, for shields mobs.spawn(x, y, 6, radius, "#b386e8"); let me = mob[mob.length - 1]; - Matter.Body.setDensity(me, 0.002); //extra dense //normal is 0.001 //makes effective life much larger + Matter.Body.setDensity(me, 0.003); //extra dense //normal is 0.001 //makes effective life much larger me.isBoss = true; targets.push(me.id) //add to shield protection me.friction = 0; @@ -1510,7 +1514,7 @@ const spawn = { me.count = 0; me.frictionAir = 0.03; // me.torque -= me.inertia * 0.002 - Matter.Body.setDensity(me, 0.03); //extra dense //normal is 0.001 //makes effective life much larger + Matter.Body.setDensity(me, 0.05); //extra dense //normal is 0.001 //makes effective life much larger // spawn.shield(me, x, y, 1); //not working, not sure why me.onDeath = function() { powerUps.spawnBossPowerUp(this.position.x, this.position.y) @@ -2023,7 +2027,7 @@ const spawn = { if (dist > 50) this.force = Vector.mult(Vector.normalise(sub), this.mass * 0.0002) }; }, - bullet(x, y, radius = 6, sides = 0) { + bullet(x, y, radius = 9, sides = 0) { //bullets mobs.spawn(x, y, sides, radius, "rgb(255,0,0)"); let me = mob[mob.length - 1]; @@ -2038,6 +2042,7 @@ const spawn = { me.restitution = 0.8; me.leaveBody = false; me.dropPowerUp = false; + me.showHealthBar = false; me.collisionFilter.category = cat.mobBullet; me.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet; @@ -2046,7 +2051,7 @@ const spawn = { this.timeLimit(); }; }, - bomb(x, y, radius = 6, sides = 5) { + bomb(x, y, radius = 9, sides = 5) { mobs.spawn(x, y, sides, radius, "rgb(255,0,0)"); let me = mob[mob.length - 1]; me.stroke = "transparent"; @@ -2155,7 +2160,7 @@ const spawn = { this.torque -= 0.000004 * this.inertia; } else if (this.noseLength > 1.5) { //fire - spawn.sniperBullet(this.vertices[1].x, this.vertices[1].y, 5 + Math.ceil(this.radius / 15), 4); + spawn.sniperBullet(this.vertices[1].x, this.vertices[1].y, 7 + Math.ceil(this.radius / 15), 4); const v = 20 * simulation.accelScale; Matter.Body.setVelocity(mob[mob.length - 1], { x: this.velocity.x + this.fireDir.x * v + Math.random(), @@ -2208,7 +2213,7 @@ const spawn = { } }; }, - sniperBullet(x, y, radius = 6, sides = 4) { + sniperBullet(x, y, radius = 9, sides = 4) { //bullets mobs.spawn(x, y, sides, radius, "rgb(255,0,155)"); let me = mob[mob.length - 1]; @@ -2252,7 +2257,7 @@ const spawn = { Matter.Body.setAngularVelocity(this, 0.14) //fire a bullet from each vertex for (let i = 0, len = this.vertices.length; i < len; i++) { - spawn.seeker(this.vertices[i].x, this.vertices[i].y, 6) + spawn.seeker(this.vertices[i].x, this.vertices[i].y, 7) //give the bullet a rotational velocity as if they were attached to a vertex const velocity = Vector.mult(Vector.perp(Vector.normalise(Vector.sub(this.position, this.vertices[i]))), -8) Matter.Body.setVelocity(mob[mob.length - 1], { @@ -2290,7 +2295,7 @@ const spawn = { Matter.Body.setAngularVelocity(this, 0.11) //fire a bullet from each vertex for (let i = 0, len = this.vertices.length; i < len; i++) { - spawn.seeker(this.vertices[i].x, this.vertices[i].y, 6) + spawn.seeker(this.vertices[i].x, this.vertices[i].y, 8) //give the bullet a rotational velocity as if they were attached to a vertex const velocity = Vector.mult(Vector.perp(Vector.normalise(Vector.sub(this.position, this.vertices[i]))), -10) Matter.Body.setVelocity(mob[mob.length - 1], { @@ -2342,14 +2347,14 @@ const spawn = { // this.force.x -= 2 * forceMag * Math.cos(angle); // this.force.y -= 2 * forceMag * Math.sin(angle); // - 0.0007 * this.mass; //antigravity } - spawn.seeker(this.vertices[this.closestVertex1].x, this.vertices[this.closestVertex1].y, 4) + spawn.seeker(this.vertices[this.closestVertex1].x, this.vertices[this.closestVertex1].y, 6) Matter.Body.setDensity(mob[mob.length - 1], 0.000001); //normal is 0.001 const velocity = Vector.mult(Vector.normalise(Vector.sub(this.position, this.vertices[this.closestVertex1])), -10) Matter.Body.setVelocity(mob[mob.length - 1], { x: this.velocity.x + velocity.x, y: this.velocity.y + velocity.y }); - spawn.seeker(this.vertices[this.closestVertex2].x, this.vertices[this.closestVertex2].y, 4) + spawn.seeker(this.vertices[this.closestVertex2].x, this.vertices[this.closestVertex2].y, 6) Matter.Body.setDensity(mob[mob.length - 1], 0.000001); //normal is 0.001 const velocity2 = Vector.mult(Vector.normalise(Vector.sub(this.position, this.vertices[this.closestVertex2])), -10) Matter.Body.setVelocity(mob[mob.length - 1], { @@ -2378,7 +2383,7 @@ const spawn = { } }; }, - seeker(x, y, radius = 5, sides = 6) { + seeker(x, y, radius = 8, sides = 6) { //bullets mobs.spawn(x, y, sides, radius, "rgb(255,0,255)"); let me = mob[mob.length - 1]; @@ -2511,8 +2516,8 @@ const spawn = { }); World.add(engine.world, consBB[consBB.length - 1]); }, - snakeBody(x, y, radius = 20) { - mobs.spawn(x, y, 4, radius, "rgb(55,170,170)"); + snakeBody(x, y, radius = 14) { + mobs.spawn(x, y, 8, radius, "transparent"); let me = mob[mob.length - 1]; // me.onHit = function() { // //run this function on hitting player @@ -2523,6 +2528,8 @@ const spawn = { me.leaveBody = false; me.frictionAir = 0.02; me.isSnakeTail = true; + me.stroke = "#099" + me.onDeath = function() { if (this.isSnakeTail) { //wake up tail mobs for (let i = 0; i < mob.length; i++) { diff --git a/js/tech.js b/js/tech.js index 8768e86..588ef76 100644 --- a/js/tech.js +++ b/js/tech.js @@ -132,6 +132,17 @@ const tech = { duplicationChance() { return (tech.isBayesian ? 0.2 : 0) + tech.cancelCount * 0.045 + tech.duplicateChance + m.duplicateChance }, + maxDuplicationEvent() { + if (tech.is100Duplicate && tech.duplicationChance() > 0.99) { + tech.is100Duplicate = false + const range = 1000 + const bossOptions = ["historyBoss", "cellBossCulture", "bomberBoss", "powerUpBoss", "suckerBoss"] + spawn.randomLevelBoss(m.pos.x + range, m.pos.y, bossOptions); + spawn.randomLevelBoss(m.pos.x, m.pos.y + range, bossOptions); + spawn.randomLevelBoss(m.pos.x - range, m.pos.y, bossOptions); + spawn.randomLevelBoss(m.pos.x, m.pos.y - range, bossOptions); + } + }, totalBots() { return tech.dynamoBotCount + tech.foamBotCount + tech.nailBotCount + tech.laserBotCount + tech.boomBotCount + tech.orbitBotCount + tech.plasmaBotCount + tech.missileBotCount }, @@ -1115,7 +1126,7 @@ const tech = { }, { name: "inelastic collision", - description: "while you are holding a block
reduce harm by 60%", + description: "while you are holding a block
reduce harm by 75%", maxCount: 1, count: 0, allowed() { @@ -1814,6 +1825,7 @@ const tech = { effect: () => { tech.isBayesian = true simulation.draw.powerUp = simulation.draw.powerUpBonus //change power up draw + tech.maxDuplicationEvent() }, remove() { tech.isBayesian = false @@ -1822,7 +1834,7 @@ const tech = { }, { name: "replication", - description: "7.5% chance to duplicate spawned power ups
add 16 junk tech to the potential pool", + description: "7% chance to duplicate spawned power ups
add 11 junk tech to the potential pool", maxCount: 9, count: 0, allowed() { @@ -1832,7 +1844,8 @@ const tech = { effect() { tech.duplicateChance += 0.075 simulation.draw.powerUp = simulation.draw.powerUpBonus //change power up draw - tech.addJunkTechToPool(16) + tech.addJunkTechToPool(11) + tech.maxDuplicationEvent() }, remove() { tech.duplicateChance = 0 @@ -1892,12 +1905,12 @@ const tech = { } }, { - name: "cloning", + name: "parthenogenesis", description: "each level has a chance to spawn a level boss
equal to double your duplication chance", maxCount: 1, count: 0, allowed() { - return tech.duplicationChance() > 0.2 + return tech.duplicationChance() > 0 }, requires: "some duplication chance", effect() { @@ -1907,6 +1920,22 @@ const tech = { tech.isDuplicateBoss = false; } }, + { + name: "apomixis", + description: "after reaching 100% duplication chance
immediately spawn 4 level bosses", + maxCount: 1, + count: 0, + allowed() { + return tech.isDuplicateBoss + }, + requires: "parthenogenesis", + effect() { + tech.is100Duplicate = true; + }, + remove() { + tech.is100Duplicate = false; + } + }, { name: "exchange symmetry", description: "convert 1 a random tech into 3 new guns
recursive tech lose all stacks", @@ -3189,6 +3218,24 @@ const tech = { tech.isAmmoFoamSize = false; } }, + { + name: "quantum foam", + description: "foam gun fires 0.35 seconds into the future
increase foam gun damage by 153%", + isGunTech: true, + maxCount: 9, + count: 0, + allowed() { + return tech.haveGunCheck("foam") + }, + requires: "foam", + effect() { + tech.foamFutureFire++ + }, + remove() { + tech.foamFutureFire = 0; + } + }, + // { // name: "foam size", // description: "increase foam damage by 200%
foam dissipates 50% faster", @@ -3869,7 +3916,7 @@ const tech = { maxCount: 1, count: 0, allowed() { - return m.fieldUpgrades[m.fieldMode].name === "plasma torch" || m.fieldUpgrades[m.fieldMode].name === "pilot wave" + return m.fieldUpgrades[m.fieldMode].name === "plasma torch" }, requires: "plasma torch", effect() { @@ -3960,7 +4007,7 @@ const tech = { }, { name: "phase decoherence", - description: "become intangible while cloaked
but, passing through mobs drains your energy", + description: "intangible to blocks and mobs while cloaked
passing through mobs drains your energy", isFieldTech: true, maxCount: 1, count: 0, @@ -4221,10 +4268,31 @@ const tech = { // }, // remove() {} // }, + { + name: "lubrication", + description: "reduce block density and friction for this level", + maxCount: 9, + count: 0, + numberInPool: 0, + isNonRefundable: true, + isCustomHide: true, + isJunk: true, + allowed() { + return true + }, + requires: "", + effect() { + for (let i = 0; i < body.length; i++) { + Matter.Body.setDensity(body[i], 0.0001) // 0.001 is normal + body[i].friction = 0.01 + } + }, + remove() {} + }, { name: "pitch", description: "oscillate the pitch of your world", - maxCount: 9, + maxCount: 1, count: 0, numberInPool: 0, isNonRefundable: true, @@ -4242,7 +4310,7 @@ const tech = { { name: "umbra", description: "produce a blue glow around everything
and probably some simulation lag", - maxCount: 9, + maxCount: 1, count: 0, numberInPool: 0, isNonRefundable: true, @@ -4261,7 +4329,7 @@ const tech = { { name: "lighter", description: `ctx.globalCompositeOperation = "lighter"`, - maxCount: 9, + maxCount: 1, count: 0, numberInPool: 0, isNonRefundable: true, @@ -4736,7 +4804,7 @@ const tech = { { name: "stun", description: "stun all mobs for up to 8 seconds", - maxCount: 1, + maxCount: 9, count: 0, numberInPool: 0, isNonRefundable: true, @@ -4754,7 +4822,7 @@ const tech = { { name: "re-arm", description: "eject all your guns", - maxCount: 1, + maxCount: 9, count: 0, numberInPool: 0, isNonRefundable: true, @@ -4782,7 +4850,7 @@ const tech = { { name: "re-research", description: "eject all your research", - maxCount: 1, + maxCount: 9, count: 0, numberInPool: 0, isNonRefundable: true, @@ -4801,7 +4869,7 @@ const tech = { { name: "quantum black hole", description: "use all your energy to spawn inside the event horizon of a huge black hole", - maxCount: 1, + maxCount: 9, count: 0, numberInPool: 0, isNonRefundable: true, @@ -4820,7 +4888,7 @@ const tech = { { name: "black hole cluster", description: "spawn 2 research
spawn 40 nearby black holes", - maxCount: 1, + maxCount: 9, count: 0, numberInPool: 0, isNonRefundable: true, @@ -5038,7 +5106,9 @@ const tech = { isGunSwitchField: null, isNeedleShieldPierce: null, isDuplicateBoss: null, + is100Duplicate: null, isDynamoBotUpgrade: null, isBlockPowerUps: null, - isBlockHarm: null + isBlockHarm: null, + foamFutureFire: null } \ No newline at end of file diff --git a/todo.txt b/todo.txt index c76d1be..c3393ab 100644 --- a/todo.txt +++ b/todo.txt @@ -1,10 +1,11 @@ ******************************************************** NEXT PATCH ******************************************************** -several new junk tech -unified field theory: now cycles fields after you click the field box when paused +all mobs that move through walls and blocks now have a transparent fill +player and power ups float in hazards -tech: restitution - mobs killed by blocks spawn power ups -tech: inelastic collision - 60% harm reduction when holding a block +tech: apomixis - after reaching 100% duplication spawn 4 level bosses +tech: quantum foam - +153% foam damage, fire 0.35s into the future +bullets are bigger, and easier to see ******************************************************** BUGS ******************************************************** @@ -33,38 +34,26 @@ use the floor of portal sensor on the player? to unstuck player (repeatable almost every time) bug - mines spawn extra mines when fired at thin map wall while jumping ******************************************************** TODO ******************************************************** - -holding a block gives some defense - can still block? - just make the block more transparent so it's clear you can't block +increase bullet size, but don't increase bullet damage -When you beat the boss without lore the output thing should read simulation complete, processing results, terminating simulation -shutdown progress: 0% -And count up by ten to 100% before you die, so that players know they won and don't think theyre stuck or something, and so its not surprising when you die +final boss: hide boss after spawning mobs + reduce health by 1/3? -Additionally, a stats screen would be nice. Like when you die, and it fades to white, output reads simulation result: failure (or success if you beat the boss) -Then reads some stats like kills, tech picked up, research picked up, damage dealt/taken, etc +tech: after using anthropic principle do 100% more damage for the rest of the level +mechanic: immune to next collision + track number of possible collisions, if number is > 0 immune and -- + graphical indication? (recolor health bar while immune) +tech: after taking damage go immune to next collision +tech: at the start of each level go immune to 1 collision +copy time-like foam to other guns? + wave gun + shotgun + nail gun - -tech fire gun in the future - laser doesn't work because of draw, needs to be a bullet - foam? shotgun? - const where = { - x: m.pos.x + 20 * Math.cos(m.angle), - y: m.pos.y + 20 * Math.sin(m.angle) - } - setTimeout(() => { - }, 1000); - -tech: when you switch guns switch a random bot to a different bot. If the bot you had was upgraded the new one will be too. - or switch all bots - -tech: buff block throwing - require +100% damage for blocks - works with pilot wave? +tech: when you switch guns switch all bots to a different bot lore: a tutorial / lore intro needs to be optional so it doesn't slow experienced players