From 8b3a4c0cb9629b17b597ca9c1d84cf66c97276f8 Mon Sep 17 00:00:00 2001 From: landgreen Date: Sun, 13 Feb 2022 06:48:23 -0800 Subject: [PATCH] sprayBoss new sprayBoss on reactor level shows up 50% of the time unbalanced right now, so give me feedback --- .DS_Store | Bin 6148 -> 6148 bytes js/bullet.js | 4 +- js/index.js | 14 +++-- js/level.js | 51 ++++++++++++----- js/mob.js | 2 +- js/powerup.js | 29 +++++++--- js/simulation.js | 1 - js/spawn.js | 140 +++++++++++++++++++++++++++++++++++++++-------- js/tech.js | 22 ++++---- todo.txt | 41 +++++++------- 10 files changed, 218 insertions(+), 86 deletions(-) diff --git a/.DS_Store b/.DS_Store index 91b905c8340ba9953efc0359996ca8c71c5ba98e..222942803feeeb3b65a9bcc3305a16e65bb9b9dd 100644 GIT binary patch delta 22 dcmZoMXffEJ#muz1cd`z%FO!18=4$3n5dcw+2B!c3 delta 22 dcmZoMXffEJ#mqEq^<*7pUncnvo2!{SMF3V;2X_Df diff --git a/js/bullet.js b/js/bullet.js index 2d85fd0..e3af1fc 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -1371,7 +1371,7 @@ const b = { requestAnimationFrame(() => { who.isShielded = true }); } if (tech.fragments) { - b.targetedNail(this.vertices[2], tech.fragments * 4) + b.targetedNail(this.vertices[2], tech.fragments * 3) if (!isReturn) this.endCycle = 0; } if (!who.isBadTarget) { @@ -5650,7 +5650,7 @@ const b = { Matter.Body.setVelocity(this, { x: -0.4 * this.velocity.x, y: -0.4 * this.velocity.y }); } else { if (tech.fragments && this.speed > 10) { - b.targetedNail(this.position, tech.fragments * 17) + b.targetedNail(this.position, tech.fragments * 13) this.endCycle = 0 //triggers despawn } } diff --git a/js/index.js b/js/index.js index 89ed114..99eb0a9 100644 --- a/js/index.js +++ b/js/index.js @@ -154,6 +154,11 @@ window.addEventListener('load', () => { } if (property === "level") document.getElementById("starting-level").value = Math.max(Number(set[property]) - 1, 0) if (property === "noPower") document.getElementById("no-power-ups").checked = Number(set[property]) + // if (property === "seed") { + // document.getElementById("seed").placeholder = Math.initialSeed = String(set[property]) + // Math.seed = Math.abs(Math.hash(Math.initialSeed)) + // level.populateLevels() + // } } } else if (localSettings.isTrainingNotAttempted && localSettings.runCount < 30) { //make training button more obvious for new players // document.getElementById("training-button").style.border = "0px #333 solid"; @@ -555,6 +560,7 @@ ${simulation.isCheating ? "

lore disabled": ""} }, shareURL(isCustom = false) { let url = "https://landgreen.github.io/sidescroller/index.html?" + url += `&seed=${Math.initialSeed}` let count = 0; for (let i = 0; i < b.inventory.length; i++) { if (b.guns[b.inventory[i]].have) { @@ -585,16 +591,12 @@ ${simulation.isCheating ? "

lore disabled": ""} navigator.clipboard.writeText(url).then(function() { /* clipboard successfully set */ if (isCustom) { - setTimeout(function() { - alert('n-gon build URL copied to clipboard.\nPaste into browser address bar.') - }, 300); + setTimeout(function() { alert('n-gon build URL copied to clipboard.\nPaste into browser address bar.') }, 300); } }, function() { /* clipboard write failed */ if (isCustom) { - setTimeout(function() { - alert('copy failed') - }, 300); + setTimeout(function() { alert('copy failed') }, 300); } console.log('copy failed') }); diff --git a/js/level.js b/js/level.js index 238bb2d..3ee2458 100644 --- a/js/level.js +++ b/js/level.js @@ -14,22 +14,23 @@ const level = { levels: [], start() { if (level.levelsCleared === 0) { //this code only runs on the first level - // m.immuneCycle = Infinity //you can't take damage - // localSettings.levelsClearedLastGame = 10 - // level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why // simulation.isHorizontalFlipped = true // m.setField("standing wave") // b.giveGuns("harpoon") // for (let i = 0; i < 100; i++) tech.giveTech("slow light") - // tech.giveTech("recycling") + // tech.giveTech("tungsten carbide") // for (let i = 0; i < 2; i++) powerUps.directSpawn(0, 0, "tech"); // tech.giveTech("tinsellated flagella") // for (let i = 0; i < 3; i++) tech.giveTech("undefined") - // tech.giveTech("nail-bot") + // tech.giveTech("decoherence") + // for (let i = 10; i < tech.tech.length; i++) { tech.tech[i].isBanished = true } + // powerUps.research.changeRerolls(100000) // for (let i = 0; i < 1; i++) tech.giveTech("reticulum") // for (let i = 0; i < 2; i++) tech.giveTech("laser-bot") // tech.tech[297].frequency = 100 + // m.immuneCycle = Infinity //you can't take damage + // level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why // simulation.enableConstructMode() //used to build maps in testing mode // level.reactor(); // level.testing(); //not in rotation, used for testing @@ -220,7 +221,7 @@ const level = { simulation.clearNow = true; //triggers in simulation.clearMap to remove all physics bodies and setup for new map } }, - populateLevels() { + populateLevels() { //run a second time if URL is loaded if (document.getElementById("seed").value) { Math.initialSeed = String(document.getElementById("seed").value) Math.seed = Math.abs(Math.hash(Math.initialSeed)) //update randomizer seed in case the player changed it @@ -250,7 +251,9 @@ const level = { } } //set seeded random lists of mobs and bosses + spawn.mobTypeSpawnOrder = [] for (let i = 0; i < level.levels.length; i++) spawn.mobTypeSpawnOrder.push(spawn.fullPickList[Math.floor(Math.seededRandom(0, spawn.fullPickList.length))]) + spawn.bossTypeSpawnOrder = [] for (let i = 0; i < level.levels.length * 2; i++) spawn.bossTypeSpawnOrder.push(spawn.randomBossList[Math.floor(Math.seededRandom(0, spawn.randomBossList.length))]) }, flipHorizontal() { @@ -2609,25 +2612,33 @@ const level = { document.body.style.backgroundColor = "#d0d5df" //"#d8dadf"; // powerUps.spawnStartingPowerUps(1475, -1175); // spawn.debris(750, -2200, 3700, 16); //16 debris per level - spawn.mapRect(-1525, -2825, 1250, 3925); + spawn.mapRect(-1525, -2825, 1250, 4925); spawn.mapRect(-400, -2025, 625, 925); spawn.mapRect(-400, -750, 625, 1200); - spawn.mapRect(-425, 0, 4200, 1100); + // spawn.mapVertex(200, 0, "-200 0 -100 -100 100 -100 200 0"); + spawn.bodyRect(225, -100, 100, 100, 0.5); + spawn.bodyRect(225, -200, 75, 100, 0.5); + spawn.bodyRect(325, -70, 150, 70, 1); + spawn.bodyRect(-275, -850, 75, 100, 0.4); + spawn.bodyRect(1525, -100, 100, 100, 0.3); + spawn.bodyRect(2325, -50, 125, 50, 0.3); + spawn.bodyRect(2375, -100, 50, 50, 0.3); + for (let i = 0; i < 3; ++i) powerUps.spawn(400 + 2000 * Math.random(), -25, "ammo"); + + spawn.mapRect(-425, 0, 4200, 2100); spawn.mapRect(175, -1250, 50, 300); spawn.mapRect(-475, -2825, 4250, 1025); // spawn.mapRect(1200, -1300, 600, 800); const a = 400 //side length const c = 100 //corner offset - spawn.mapVertex(1487, -900, `${-a} ${-a+c} ${-a+c} ${-a} ${a-c} ${-a} ${a} ${-a+c} ${a} ${a-c} ${a-c} ${a} ${-a+c} ${a} ${-a} ${a-c}`); //square with edges cut off + spawn.mapVertex(1487, -900, `${-a} ${-a+c} ${-a+c} ${-a} ${a-c} ${-a} ${a} ${-a+c} ${a} ${a-c} ${a-c} ${a} ${-a+c} ${a} ${-a} ${a-c}`); //square with edges cut off //exit - spawn.mapRect(3300, -2825, 1125, 3925); + spawn.mapRect(3300, -2825, 1125, 4925); spawn.mapRect(2750, -2150, 1025, 1775); spawn.mapRect(2750, -475, 50, 300); - - // spawn.bodyRect(1540, -1110, 300, 25, 0.9); // spawn.randomSmallMob(1300, -70); // spawn.randomMob(2650, -975, 0.8); @@ -2651,6 +2662,8 @@ const level = { let isSpawnedBoss = false level.custom = () => { + // player.force.y -= player.mass * simulation.g * 0.4; //float player + if (isDoorsLocked) { if (!isFightOver && !(simulation.cycle % 120)) { //once a second let isFoundBoss = false @@ -2665,7 +2678,6 @@ const level = { doorIn.isClosing = false doorOut.isClosing = false powerUps.spawnBossPowerUp(2900, -100) - for (let i = 0; i < 3; ++i) powerUps.spawn(2900 + 30 * i, -300, "ammo"); } } @@ -2688,12 +2700,19 @@ const level = { doorOut.isClosing = true if (!isSpawnedBoss) { isSpawnedBoss = true - for (let i = 0, len = simulation.difficulty / 20; i < len; ++i) spawn.bounceBoss(1487 + 300 * i, -1525, 80, false); + if (Math.random() > 0.5) { + for (let i = 0, len = Math.min(simulation.difficulty / 20, 5); i < len; ++i) spawn.bounceBoss(1487 + 200 * i, -1525, 80, false); + } else { + for (let i = 0, len = Math.min(simulation.difficulty / 10, 10); i < len; ++i) spawn.sprayBoss(2400 - 150 * i, -225, 30, false) + } + // for (let i = 0, len = 3 + simulation.difficulty / 20; i < len; ++i) spawn.mantisBoss(1487 + 300 * i, -1525, 35, false) } } doorIn.openClose(); doorOut.openClose(); + ctx.fillStyle = "#d5ebef" + ctx.fillRect(2750, -375, 550, 375) level.enter.draw(); level.exit.drawAndCheck(); }; @@ -2704,6 +2723,10 @@ const level = { // } doorIn.draw(); doorOut.draw(); + ctx.fillStyle = "rgba(0,0,0,0.05)" + ctx.fillRect(-275, -1100, 500, 350); + // ctx.fillStyle = "rgba(0,255,255,0.1)" + // ctx.fillRect(2750, -375, 550, 375) }; // if (simulation.difficulty > 1) spawn.randomLevelBoss(2200, -1300); powerUps.addResearchToLevel() //needs to run after mobs are spawned diff --git a/js/mob.js b/js/mob.js index 035b3c0..9545ada 100644 --- a/js/mob.js +++ b/js/mob.js @@ -1180,7 +1180,7 @@ const mobs = { powerUps.spawn(this.position.x, this.position.y, "tech", false) // if (0.5 < Math.random()) powerUps.spawn(this.position.x, this.position.y, "tech", false) } else { - const amount = 0.005 + const amount = 0.0045 if (tech.isEnergyHealth) { if (m.maxEnergy > amount) { tech.healMaxEnergyBonus -= amount diff --git a/js/powerup.js b/js/powerup.js index c131884..beb02df 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -304,7 +304,14 @@ const powerUps = { const banishLength = tech.isDeterminism ? 1 : 3 + tech.isExtraChoice * 2 for (let i = 0; i < banishLength; i++) { const index = powerUps.tech.choiceLog.length - i - 1 - if (powerUps.tech.choiceLog[index] !== undefined) tech.tech[powerUps.tech.choiceLog[index]].isBanished = true + if (powerUps.tech.choiceLog[index] && tech.tech[powerUps.tech.choiceLog[index]]) { + tech.tech[powerUps.tech.choiceLog[index]].isBanished = true + } else { //if no tech options available eject banish tech + for (let i = 0, len = tech.tech.length; i < len; i++) { + if (tech.tech[i].name === "decoherence") powerUps.ejectTech(i) + } + powerUps.endDraft("tech"); + } } simulation.makeTextLog(`powerUps.tech.length: ${Math.max(0,powerUps.tech.lastTotalChoices - banishLength)}`) } @@ -397,7 +404,18 @@ const powerUps = { const banishLength = tech.isDeterminism ? 1 : 3 + tech.isExtraChoice * 2 for (let i = 0; i < banishLength; i++) { const index = powerUps.tech.choiceLog.length - i - 1 - if (powerUps.tech.choiceLog[index] !== undefined || powerUps.tech.choiceLog[index] !== null) tech.tech[powerUps.tech.choiceLog[index]].isBanished = true + // console.log(index) + // console.log(powerUps.tech.choiceLog.length) + // console.log(powerUps.tech.choiceLog[index]) + // console.log(tech.tech[powerUps.tech.choiceLog[index]]) + if (powerUps.tech.choiceLog[index] && tech.tech[powerUps.tech.choiceLog[index]]) { + tech.tech[powerUps.tech.choiceLog[index]].isBanished = true + } else { //if no tech options available eject banish tech + for (let i = 0, len = tech.tech.length; i < len; i++) { + if (tech.tech[i].name === "decoherence") powerUps.ejectTech(i) + } + powerUps.endDraft("tech"); + } } simulation.makeTextLog(`powerUps.tech.length: ${Math.max(0,powerUps.tech.lastTotalChoices - banishLength)}`) } @@ -686,6 +704,7 @@ const powerUps = { if (!tech.isSuperDeterminism) text += `
` text += `

tech

` let choice1 = pick() + console.log(choice1) let choice2 = null let choice3 = null if (choice1 !== null) { @@ -776,12 +795,6 @@ const powerUps = { document.getElementById("choose-grid").innerHTML = text powerUps.showDraft(); - } else if (tech.isBanish) { //if no tech options available eject banish tech - for (let i = 0, len = tech.tech.length; i < len; i++) { - if (tech.tech[i].name === "decoherence") powerUps.ejectTech(i) - } - // simulation.makeTextLog(`powerUps.tech.length: ${Math.max(0,powerUps.tech.lastTotalChoices - powerUps.tech.banishLog.length)}`) - powerUps.endDraft("tech"); } } } diff --git a/js/simulation.js b/js/simulation.js index 53ed42f..30b116a 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -944,7 +944,6 @@ const simulation = { 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 - console.log(`lastKill = ${m.lastKillCycle}, cycle = ${m.cycle}, health = ${m.health}, maxHealth = ${m.maxHealth}`) if (tech.isHealthRecovery) m.addHealth(0.01 * m.maxHealth) } diff --git a/js/spawn.js b/js/spawn.js index 934ec7f..704d314 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -1,10 +1,10 @@ //main object for spawning things in a level const spawn = { nonCollideBossList: ["cellBossCulture", "bomberBoss", "powerUpBoss", "orbitalBoss", "spawnerBossCulture", "growBossCulture"], - // other bosses: suckerBoss, laserBoss, tetherBoss, //these need a particular level to work so they are not included in the random pool + // other bosses: suckerBoss, laserBoss, tetherBoss, mantisBoss, bounceBoss, sprayBoss //these need a particular level to work so they are not included in the random pool randomBossList: ["shieldingBoss", "orbitalBoss", "historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "powerUpBoss", "powerUpBossBaby", "snakeBoss", "streamBoss", "pulsarBoss", "spawnerBossCulture", "grenadierBoss", "growBossCulture", "blinkBoss", - "snakeSpitBoss", "laserBombingBoss", "blockBoss", "revolutionBoss", "mantisBoss", "slashBoss" + "snakeSpitBoss", "laserBombingBoss", "blockBoss", "revolutionBoss", "slashBoss" ], bossTypeSpawnOrder: [], //preset list of boss names calculated at the start of a run by the randomSeed bossTypeSpawnIndex: 0, //increases as the boss type cycles @@ -19,26 +19,15 @@ const spawn = { pickList: ["starter", "starter"], fullPickList: [ "hopper", "hopper", "hopper", - "slasher", "slasher", + "slasher", "slasher", "hopper", + "stabber", "stabber", "stabber", + "springer", "springer", "springer", "shooter", "shooter", "grenadier", "grenadier", "striker", "striker", "laser", "laser", - "stabber", "stabber", - "springer", "springer", "pulsar", "pulsar", - "launcher", - "launcherOne", - "exploder", - "sneaker", - "sucker", - "sniper", - "spinner", - "grower", - "beamer", - "focuser", - "spawner", - "ghoster", + "launcher", "launcherOne", "exploder", "sneaker", "sucker", "sniper", "spinner", "grower", "beamer", "focuser", "spawner", "ghoster", ], mobTypeSpawnOrder: [], //preset list of mob names calculated at the start of a run by the randomSeed mobTypeSpawnIndex: 0, //increases as the mob type cycles @@ -1950,7 +1939,7 @@ const spawn = { spawn.groupShield(targets, x, y, sideLength + 1 * radius + nodes * 5 - 25); spawn.allowShields = true; }, - mantisBoss(x, y, radius = 35) { + mantisBoss(x, y, radius = 35, isSpawnBossPowerUp = true) { mobs.spawn(x, y, 5, radius, "#6ba"); let me = mob[mob.length - 1]; me.babyList = [] //list of mobs that are apart of this boss @@ -2140,7 +2129,7 @@ const spawn = { me.onDeath = function() { this.removeCons(); - powerUps.spawnBossPowerUp(this.position.x, this.position.y) + if (isSpawnBossPowerUp) powerUps.spawnBossPowerUp(this.position.x, this.position.y) for (let i = 0; i < this.babyList.length; i++) { if (this.babyList[i].alive) { this.babyList[i].collisionFilter.mask = cat.map | cat.bullet | cat.player @@ -3537,7 +3526,98 @@ const spawn = { ctx.setLineDash([]); } }, - bounceBoss(x, y, radius = 80, isSpawnBossPOwerUp = true) { + sprayBoss(x, y, radius = 30, isSpawnBossPowerUp = true) { + mobs.spawn(x, y, 16, radius, "rgb(255,255,255)"); + let me = mob[mob.length - 1]; + me.isBoss = true; + me.inertia = Infinity; //no rotation + // me.accelMag = 0.00008 + 0.00007 * simulation.accelScale; + me.burstFireFreq = 20 + Math.floor(20 * simulation.CDScale) + me.burstTotalPhases = 4 + Math.floor(2 / simulation.CDScale) + me.noFireTotalCycles = 390 + me.frictionStatic = 0; + me.friction = 0; + me.frictionAir = 0; + me.restitution = 1 + spawn.spawnOrbitals(me, radius + 50 + 200 * Math.random(), 1) + Matter.Body.setDensity(me, 0.0022 + 0.0002 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger + me.damageReduction = 0.12 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) + me.onDeath = function() { + if (isSpawnBossPowerUp) powerUps.spawnBossPowerUp(this.position.x, this.position.y) + }; + me.onDamage = function() {}; + + //draw radial lines from verticies showing future bullet paths? + me.radialLines = function() { + ctx.beginPath(); + for (let i = 0, len = this.vertices.length; i < len; i++) { + ctx.moveTo(this.vertices[i].x, this.vertices[i].y) + const unit = Vector.add(Vector.mult(Vector.normalise(Vector.sub(this.vertices[i], this.position)), 1000), this.vertices[i]) + ctx.lineTo(unit.x, unit.y) + // console.log(unit, this.vertices, this.position) + } + ctx.lineWidth = 10 + ctx.strokeStyle = "rgb(200,0,200,0.03)" + ctx.stroke(); + } + + me.phaseCycle = 0 + me.normalDoStuff = function() { + // this.seePlayerByHistory(); + // this.attraction(); + this.checkStatus(); + me.seePlayer.recall = 1 + //maintain speed //faster in the vertical to help avoid repeating patterns + if (this.speed < 0.01) { + Matter.Body.setVelocity(this, Vector.mult(Vector.normalise(Vector.sub(player.position, this.position)), 0.1)); + } else { + if (Math.abs(this.velocity.y) < 15) Matter.Body.setVelocity(this, { x: this.velocity.x, y: this.velocity.y * 1.07 }); + if (Math.abs(this.velocity.x) < 11) Matter.Body.setVelocity(this, { x: this.velocity.x * 1.07, y: this.velocity.y }); + } + } + me.noFire = function() { + this.normalDoStuff(); + this.phaseCycle++ + if (this.phaseCycle > this.noFireTotalCycles) { //start burst fire mode + this.phaseCycle = -2 + this.do = this.burstFire + this.frictionAir = 1 + if (!this.isShielded) spawn.shield(this, this.position.x, this.position.y, 1); + } + }; + me.burstFire = function() { + this.normalDoStuff(); + this.radialLines() + if (!(simulation.cycle % this.burstFireFreq)) { + this.phaseCycle++ + if (this.phaseCycle > this.burstTotalPhases) { //start spiral fire mode + this.phaseCycle = -7 + this.do = this.noFire + this.frictionAir = 0; + Matter.Body.setVelocity(this, Vector.rotate({ x: 20, y: 0 }, 2 * Math.PI * Math.random())); + if (this.isShielded) { //remove shield + for (let i = 0; i < mob.length; i++) { + if (mob[i].shield) mob[i].death() + } + } + } + if (this.phaseCycle > -1) { + Matter.Body.rotate(this, 0.08) + for (let i = 0, len = this.vertices.length; i < len; i++) { //fire a bullet from each vertex + spawn.sniperBullet(this.vertices[i].x, this.vertices[i].y, 8, 4); + const velocity = Vector.mult(Vector.normalise(Vector.sub(this.position, this.vertices[i])), -26) + Matter.Body.setVelocity(mob[mob.length - 1], { + x: velocity.x, + y: velocity.y + }); + } + } + } + }; + me.do = me.noFire + Matter.Body.setVelocity(me, { x: 10 * (Math.random() - 0.5), y: 10 * (Math.random() - 0.5) }); + }, + bounceBoss(x, y, radius = 80, isSpawnBossPowerUp = true) { mobs.spawn(x, y, 0, radius, "rgb(255,255,255)") // "rgb(201,202,225)"); let me = mob[mob.length - 1]; Matter.Body.rotate(me, 2 * Math.PI * Math.random()); @@ -3563,7 +3643,7 @@ const spawn = { this.damageReduction = 0 } }; - if (isSpawnBossPOwerUp) me.onDeath = function() { powerUps.spawnBossPowerUp(this.position.x, this.position.y) }; + if (isSpawnBossPowerUp) me.onDeath = function() { powerUps.spawnBossPowerUp(this.position.x, this.position.y) }; me.cycle = 0 me.nextHealthThreshold = 0.75 me.fireCount = 0 @@ -4411,8 +4491,7 @@ const spawn = { } }; }, - sniperBullet(x, y, radius = 9, sides = 4) { - //bullets + sniperBullet(x, y, radius = 9, sides = 4) { //bullets mobs.spawn(x, y, sides, radius, "rgb(255,0,155)"); let me = mob[mob.length - 1]; me.stroke = "transparent"; @@ -4431,10 +4510,23 @@ const spawn = { me.showHealthBar = false; me.collisionFilter.category = cat.mobBullet; me.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet; + me.onDeath = function() { + if (simulation.difficulty > 11) { //explode AoE + const radius = 100 + simulation.difficulty + 60 * Math.random() + if (m.immuneCycle < m.cycle && Vector.magnitude(Vector.sub(this.position, player.position)) < radius) m.damage(0.0004 * radius * simulation.dmgScale); + simulation.drawList.push({ //add dmg to draw queue + x: this.position.x, + y: this.position.y, + radius: radius, + color: "rgba(255,0,155,0.5)", + time: simulation.drawTime + }); + } + }; me.do = function() { // this.gravity(); this.timeLimit(); - if (Matter.Query.collides(this, map).length > 0 || Matter.Query.collides(this, body).length > 0 && this.speed < 3) { + if (Matter.Query.collides(this, map).length > 0 || Matter.Query.collides(this, body).length > 0 && this.speed < 10) { this.isDropPowerUp = false; this.death(); //death with no power up } diff --git a/js/tech.js b/js/tech.js index c8356f3..868c63f 100644 --- a/js/tech.js +++ b/js/tech.js @@ -221,7 +221,7 @@ const tech = { if (tech.isDupDamage) dmg *= 1 + Math.min(1, tech.duplicationChance()) if (tech.isLowEnergyDamage) dmg *= 1 + 0.7 * Math.max(0, 1 - m.energy) if (tech.isMaxEnergyTech) dmg *= 1.5 - if (tech.isEnergyNoAmmo) dmg *= 1.66 + if (tech.isEnergyNoAmmo) dmg *= 1.70 if (tech.isDamageForGuns) dmg *= 1 + 0.12 * b.inventory.length if (tech.isLowHealthDmg) dmg *= 1 + Math.max(0, 1 - m.health) * 0.5 if (tech.isHarmDamage && m.lastHarmCycle + 600 > m.cycle) dmg *= 3; @@ -230,7 +230,7 @@ const tech = { if (tech.restDamage > 1 && player.speed < 1) dmg *= tech.restDamage if (tech.isEnergyDamage) dmg *= 1 + m.energy * 0.125; if (tech.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.007 - if (tech.isRerollDamage) dmg *= 1 + 0.037 * powerUps.research.count + if (tech.isRerollDamage) dmg *= 1 + 0.038 * powerUps.research.count if (tech.isOneGun && b.inventory.length < 2) dmg *= 1.25 if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 2 if (tech.isSpeedDamage) dmg *= 1 + Math.min(0.66, player.speed * 0.0165) @@ -580,7 +580,7 @@ const tech = { }, { name: "exciton", - description: `increase damage by 66%, but
${powerUps.orb.ammo()} will no longer spawn`, + description: `increase damage by 70%, but
${powerUps.orb.ammo()} will no longer spawn`, maxCount: 1, count: 0, frequency: 1, @@ -2879,7 +2879,7 @@ const tech = { }, { name: "Bayesian statistics", - description: `increase damage by 3.7%
for each ${powerUps.orb.research(1)} in your inventory`, + description: `increase damage by 3.8%
for each ${powerUps.orb.research(1)} in your inventory`, maxCount: 1, count: 0, frequency: 2, @@ -3067,7 +3067,7 @@ const tech = { }, { name: "particle collider", - description: `clicking tech while paused ejects them
4% chance to convert that tech into energy`, + description: `clicking tech while paused ejects them
4% chance to convert that tech into energy`, maxCount: 1, count: 0, frequency: 1, @@ -3340,9 +3340,9 @@ const tech = { frequencyDefault: 10, isNonRefundable: true, allowed() { - return tech.duplicationChance() > 0.99 + return tech.duplicationChance() > 0.7 }, - requires: "duplication chance above 99%", + requires: "duplication chance above 70%", effect() { tech.is111Duplicate = true; tech.maxDuplicationEvent() @@ -3522,7 +3522,7 @@ const tech = { }, { name: "reinforcement learning", - description: "increase the frequency of finding copies of
recursive tech you already have by 1000%", + description: "increase the frequency of finding copies of
your current recursive tech by 1000%", maxCount: 1, count: 0, frequency: 1, @@ -6723,7 +6723,7 @@ const tech = { }, { name: "no-cloning theorem", - description: `40% chance to duplicate spawned power ups
after a mob dies, lose 2% duplication chance`, + description: `45% chance to duplicate spawned power ups
after a mob dies, lose 2% duplication chance`, isFieldTech: true, maxCount: 1, count: 0, @@ -6734,7 +6734,7 @@ const tech = { }, requires: "cloaking, time dilation", effect() { - tech.cloakDuplication = 0.4 + tech.cloakDuplication = 0.45 powerUps.setDupChance(); //needed after adjusting duplication chance if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.4); }, @@ -6745,7 +6745,7 @@ const tech = { }, { name: "symbiosis", - description: "after a mob dies, lose 0.5 max health
bosses spawn 1 extra tech after they die", + description: "after a mob dies, lose 0.45 max health
bosses spawn 1 extra tech after they die", isFieldTech: true, maxCount: 1, count: 0, diff --git a/todo.txt b/todo.txt index 585502c..453bdd2 100644 --- a/todo.txt +++ b/todo.txt @@ -1,20 +1,21 @@ ******************************************************** NEXT PATCH ************************************************** -harpoon's crouch is now a harpoon sized railgun -tech: halfwave rectifier now gives energy on harpoon/railgun charge and also stops harpoon from draining energy when it retracts -toggling harpoon does 800 -> 600% more damage - -perfect diamagnetism default field is a bit larger - -bug fix with several periodic checks running off simulation time - they now run on player time and will be active during time dilation -fixed a bug where lore wasn't working +new sprayBoss on reactor level + shows up 50% of the time + unbalanced right now, so give me feedback ******************************************************** TODO ******************************************************** +tech doing damage refunds up to 50% of damage take in last 10 seconds + use history to manage this? + +tech: frozen mobs dies at 10% life + +CPt disables the falling damage tech + make a seed/hash system that controls only the tech/guns/fields shown URL sharing could include a seed - seed will control: + seed controls: seeded random at start - random level boss, mob types list, level order, horizontal flip seeded random during run - tech, gun, field choices not seeded random - mob spawns, mob size, minor level differences, custom level boss choices, ammo rewards, tech effect randomness @@ -22,11 +23,6 @@ make a seed/hash system that controls only the tech/guns/fields shown make option for a daily seed: seed = day+year give 1 extra tech for doing the daily seeded run make the option for the daily run, a secret exit in the intro level? - when you die - randomize seed - display new seed - show previous run seed - edit div in settings tech upgrade to anthropic principle to make it trigger at 50% life and 0% once per map @@ -35,13 +31,20 @@ JUNK tech: https://bindingofisaacrebirth.fandom.com/wiki/Damocles cloaking field doesn't show energy over max -junk tech or regular tech with this named - wiki: List of common misconceptions - run more profiles of n-gon to fix performance issues +sprayBoss + reactor or everywhere? + reactor - hopBoss + life-like cellular automata boss + https://scratch.mit.edu/projects/77724260/ + night/day? + boss on far right produces more "on" cells + tailBoss + story the last 5 seconds of position, draw damage circles over those positions, like a tail + limit mantis boss to only reactor? + laserBoss? swoopBoss: hides in top center take a lap around the map that you have to dodge spawn mobs