From 36d44c2569eafe85ac0aa3895e9099dafcc32101 Mon Sep 17 00:00:00 2001 From: landgreen Date: Sun, 13 Jun 2021 05:41:37 -0700 Subject: [PATCH] balance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit over all game difficulty scaling occurs faster your damage will feel lower, and you will take more harm, so you should probably play on a lower difficulty tech: Higgs manism gives 50% reduced fire delay instead of harm reduction tech: inertial frame is removed tech: automatic is now a junk tech balance: dead reckoning gives 36% damage when at rest (was 30%) overcharge gives 10 more energy, but adds 10 junk tech 1st ionization energy gives 6 energy per heal (was 5) dormancy increases damage by 100% but lowers it by 33% if no recent kills (was +50%, -15%) torpor decreases harm by 66% increases harm by 15% if no recent kills (was -50%, +10%) Ψ(t) collapse spawns 3 more research, so it's at 15 fragmentation gives 30% more nails for railgun ammonium nitrate +25% (was 20%) generalist gives 8 guns (was 6) arsenal gives 10% per gun (was 14%) rivet gun fires 25% faster, rivets are 15% larger shotgun slug is 33% bigger missile bot fires 10% more often tinsellated flagella gives 40% speed increase (was 50%), base spore speed is 10% faster beamSplitter has a 20% lower divergence nano manufacturing tech is all buffed 15% traversable geodesics gives 2 guns and ammo (was 1) mines have 25% more nails, laser mines use 20% less energy sentry mines last 33% seconds longer zoospore vector has an 11% chance to spawn (was 9%) negentropy spawns a heal for every 33 missing health (was 50 health) exciton-lattice gives 60% damage thermocouple spawns 1-8 ice-IX (was 1-5) WIMPs spawn 2-6 research (was 2-3) quantum immortality reduces harm by 33% (was 23%) commodities exchange gives 10 power ups (was 8) super balls are 17% bigger (this means they do about 25% more damage) exothermic process increases damage by (was 45%) heat engine increases damage by 50% (was 40%) replication gives 10% duplication chance (was 8%) stimulated emission gives 22% duplication chance futures exchange gives 4.7% duplication chance per cancel (was 4.3%) needles are 10% slower and do 15% more damage bug fixes: reduced tolerances text rewritten to clarify that it gives more ammo per ammo pack hazards on horizontal flipped levels now correctly do damage ship mode aims properly after you die although it still doesn't reset experiment mode selections are highlighted better --- .DS_Store | Bin 6148 -> 6148 bytes js/bullet.js | 64 ++++++++------- js/index.js | 12 +-- js/level.js | 172 ++++++++++++++++++++------------------- js/player.js | 61 +++++++------- js/powerup.js | 8 +- js/simulation.js | 4 +- js/spawn.js | 2 +- js/tech.js | 206 ++++++++++++++++++++--------------------------- todo.txt | 55 +++++++++++++ 10 files changed, 311 insertions(+), 273 deletions(-) diff --git a/.DS_Store b/.DS_Store index 2a571effa03a254c2621f5bf9733d5efd5b27f0c..2c71cdff089ee28a1c41112cfed80d828c59548b 100644 GIT binary patch delta 21 ccmZoMXffEJ#mwaRe6kL+FQfS8D&{T`07^s#WdHyG delta 21 ccmZoMXffEJ#mwX)JXwd?mr-nU6?2ye06=vGlK=n! diff --git a/js/bullet.js b/js/bullet.js index 950a4a3..fb46c60 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -9,12 +9,14 @@ const b = { setFireMethod() { if (tech.isFireMoveLock) { b.fire = b.fireFloat - } else if (tech.isFireNotMove) { - if (tech.isAlwaysFire) { - b.fire = b.fireNotMoveAlwaysFire - } else { - b.fire = b.fireNotMove - } + // } else if (tech.isFireNotMove) { + // if (tech.isAlwaysFire) { + // b.fire = b.fireAlwaysFire + // } else { + // b.fire = b.fireNotMove + // } + } else if (tech.isAlwaysFire) { + b.fire = b.fireAlwaysFire } else { b.fire = b.fireNormal } @@ -46,7 +48,7 @@ const b = { b.guns[b.activeGun].do(); } }, - fireNotMoveAlwaysFire() { //added && player.speed < 0.5 && m.onGround //removed input.fire && (!input.field || m.fieldFire) + fireAlwaysFire() { //added && player.speed < 0.5 && m.onGround //removed input.fire && (!input.field || m.fieldFire) if (b.inventory.length) { if (m.fireCDcycle < m.cycle && player.speed < 0.5 && m.onGround && Math.abs(m.yOff - m.yOffGoal) < 1) { if (b.guns[b.activeGun].ammo > 0) { @@ -222,7 +224,7 @@ const b = { setFireCD() { b.fireCD = tech.fireRate * tech.slowFire * tech.researchHaste * tech.aimDamage / tech.fastTime if (tech.isFireRateForGuns) b.fireCD *= Math.pow(0.86, b.inventory.length) - if (tech.isFireNotMove) b.fireCD *= 0.33 + if (tech.isFireMoveLock) b.fireCD *= 0.5 }, fireAttributes(dir, rotate = true) { if (rotate) { @@ -1579,7 +1581,7 @@ const b = { dmg: 0, // 0.14 //damage done in addition to the damage from momentum minDmgSpeed: 2, lookFrequency: 67 + Math.floor(7 * Math.random()), - drain: 0.7 * tech.isLaserDiode * tech.laserFieldDrain, + drain: 0.6 * tech.isLaserDiode * tech.laserFieldDrain, isArmed: false, torqueMagnitude: 0.000003 * (Math.round(Math.random()) ? 1 : -1), range: 1500, @@ -1728,7 +1730,7 @@ const b = { sentry() { this.collisionFilter.mask = cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield | cat.bullet //can now collide with other bullets this.lookFrequency = simulation.cycle + 60 - this.endCycle = simulation.cycle + 1260 + this.endCycle = simulation.cycle + 1620 this.do = function() { //overwrite the do method for this bullet this.force.y += this.mass * 0.002; //extra gravity if (simulation.cycle > this.lookFrequency) { @@ -1759,7 +1761,7 @@ const b = { this.force.y += this.mass * 0.002; //extra gravity if (simulation.cycle > this.lookFrequency) { this.isArmed = true - this.lookFrequency = 50 + Math.floor(27 * Math.random()) + this.lookFrequency = 55 + Math.floor(22 * Math.random()) simulation.drawList.push({ x: this.position.x, y: this.position.y, @@ -1786,7 +1788,7 @@ const b = { }, onEnd() { if (this.isArmed) { - b.targetedNail(this.position, 18) + b.targetedNail(this.position, 22) } if (tech.isMineAmmoBack && (!this.isArmed || Math.random() < 0.2)) { //get ammo back from tech.isMineAmmoBack for (i = 0, len = b.guns.length; i < len; i++) { //find which gun @@ -1823,7 +1825,7 @@ const b = { angle: Math.random() * 2 * Math.PI, friction: 0, frictionAir: 0.025, - thrust: (tech.isFastSpores ? 0.001 : 0.0004) * (1 + 0.3 * (Math.random() - 0.5)), + thrust: (tech.isFastSpores ? 0.0009 : 0.00045) * (1 + 0.3 * (Math.random() - 0.5)), dmg: tech.isMutualism ? 16.8 : 7, //bonus damage from tech.isMutualism lookFrequency: 100 + Math.floor(117 * Math.random()), classType: "bullet", @@ -2436,6 +2438,7 @@ const b = { b.zeroBotCount() b.clearPermanentBots() for (let i = 0; i < totalTechToConvert; i++) tech.giveTech(type) //spawn tech for the correct bot type + //find index of new bot type tech effect let index = null for (let i = 0; i < tech.tech.length; i++) { @@ -2445,6 +2448,13 @@ const b = { } } for (let i = 0, len = totalPermanentBots - totalTechToConvert; i < len; i++) tech.tech[index].effect(); //also convert any permanent bots that didn't come from a tech + //in experiment mode set the unselect color for bot tech that was converted + if (build.isExperimentSelection) { + + + + + } }, clearPermanentBots() { for (let i = 0; i < bullet.length; i++) { @@ -2679,7 +2689,7 @@ const b = { minDmgSpeed: 2, lookFrequency: 70, cd: 0, - delay: 90, + delay: 80, range: 70 + 3 * b.totalBots(), endCycle: Infinity, classType: "bullet", @@ -3298,7 +3308,7 @@ const b = { if (tech.isNailRadiation) { mobs.statusDoT(who, tech.isFastRadiation ? 12 : 3, tech.isSlowRadiation ? 240 : (tech.isFastRadiation ? 30 : 120)) // one tick every 30 cycles } else { - let dmg = b.dmgScale * 3.75 + let dmg = b.dmgScale * 4.5 if (tech.isCrit && who.isStunned) dmg *= 4 who.damage(dmg, tech.isNeedleShieldPierce); simulation.drawList.push({ //add dmg to draw queue @@ -3326,7 +3336,7 @@ const b = { this.force.y += this.mass * 0.001; //no gravity until it slows down to improve aiming } }; - const SPEED = 100 + const SPEED = 90 Matter.Body.setVelocity(bullet[me], { x: m.Vx / 2 + SPEED * Math.cos(angle), y: m.Vy / 2 + SPEED * Math.sin(angle) @@ -3356,10 +3366,10 @@ const b = { // makeNeedle(m.angle - spread) }, fireRivets() { - m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 30 : 25) * b.fireCD); // cool down + m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 23 : 17) * b.fireCD); // cool down const me = bullet.length; - const size = tech.rivetSize * 6 + const size = tech.rivetSize * 7 bullet[me] = Bodies.rectangle(m.pos.x + 35 * Math.cos(m.angle), m.pos.y + 35 * Math.sin(m.angle), 5 * size, size, b.fireAttributes(m.angle)); bullet[me].dmg = tech.isNailRadiation ? 0 : 2.75 Matter.Body.setDensity(bullet[me], 0.002); @@ -3470,7 +3480,7 @@ const b = { if (tech.isSlugShot) { const me = bullet.length; const dir = m.angle + 0.02 * (Math.random() - 0.5) - bullet[me] = Bodies.rectangle(m.pos.x + 35 * Math.cos(m.angle), m.pos.y + 35 * Math.sin(m.angle), 45, 20, b.fireAttributes(dir)); + bullet[me] = Bodies.rectangle(m.pos.x + 35 * Math.cos(m.angle), m.pos.y + 35 * Math.sin(m.angle), 60, 27, b.fireAttributes(dir)); Matter.Body.setDensity(bullet[me], 0.004); World.add(engine.world, bullet[me]); //add bullet to world @@ -3490,7 +3500,7 @@ const b = { } else { bullet[me].endCycle = simulation.cycle + 180 } - bullet[me].minDmgSpeed = 15 + bullet[me].minDmgSpeed = 7 // bullet[me].restitution = 0.4 bullet[me].frictionAir = 0.006; bullet[me].do = function() { @@ -3502,7 +3512,7 @@ const b = { x: Math.cos(this.angle), y: Math.sin(this.angle) } - const mag = 0.0033 + const mag = 0.017 if (Vector.cross(Vector.normalise(this.velocity), facing) < 0) { this.torque += mag } else { @@ -3613,7 +3623,7 @@ const b = { if (tech.oneSuperBall) { let dir = m.angle const me = bullet.length; - bullet[me] = Bodies.polygon(m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle), 12, 20 * tech.bulletSize, b.fireAttributes(dir, false)); + bullet[me] = Bodies.polygon(m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle), 12, 21 * tech.bulletSize, b.fireAttributes(dir, false)); World.add(engine.world, bullet[me]); //add bullet to world Matter.Body.setVelocity(bullet[me], { x: SPEED * Math.cos(dir), @@ -3640,7 +3650,7 @@ const b = { let dir = m.angle - SPREAD * (tech.superBallNumber - 1) / 2; for (let i = 0; i < tech.superBallNumber; i++) { const me = bullet.length; - bullet[me] = Bodies.polygon(m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle), 12, 7.5 * tech.bulletSize, b.fireAttributes(dir, false)); + bullet[me] = Bodies.polygon(m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle), 12, 9 * tech.bulletSize, b.fireAttributes(dir, false)); World.add(engine.world, bullet[me]); //add bullet to world Matter.Body.setVelocity(bullet[me], { x: SPEED * Math.cos(dir), @@ -4252,7 +4262,7 @@ const b = { // Matter.Body.setDensity(this, 0.001); } if (tech.fragments && this.speed > 10) { - b.targetedNail(this.position, tech.fragments * 10) + b.targetedNail(this.position, tech.fragments * 15) this.endCycle = 0 //triggers despawn } }, @@ -4340,7 +4350,7 @@ const b = { // Matter.Body.setDensity(this, 0.001); } if (tech.fragments && this.speed > 10) { - b.targetedNail(this.position, tech.fragments * 16) + b.targetedNail(this.position, tech.fragments * 20) this.endCycle = 0 //triggers despawn } }, @@ -4584,7 +4594,7 @@ const b = { if (this.charge > 5) { m.fireCDcycle = m.cycle + 35; // cool down if (tech.beamSplitter) { - const divergence = m.crouch ? 0.2 : 0.5 + const divergence = m.crouch ? 0.15 : 0.35 const angle = m.angle - tech.beamSplitter * divergence / 2 for (let i = 0; i < 1 + tech.beamSplitter; i++) b.pulse(this.charge, angle + i * divergence) } else { @@ -4639,7 +4649,7 @@ const b = { x: m.pos.x + 20 * Math.cos(m.angle), y: m.pos.y + 20 * Math.sin(m.angle) } - const divergence = m.crouch ? 0.2 : 0.5 + const divergence = m.crouch ? 0.15 : 0.35 const angle = m.angle - tech.beamSplitter * divergence / 2 for (let i = 0; i < 1 + tech.beamSplitter; i++) { b.laser(where, { diff --git a/js/index.js b/js/index.js index bbb08e6..b37ed73 100644 --- a/js/index.js +++ b/js/index.js @@ -299,13 +299,15 @@ const build = { } } else if (type === "tech") { if (tech.tech[index].count < tech.tech[index].maxCount) { - if (!tech.tech[index].isLore && !tech.tech[index].isNonRefundable && !who.classList.contains("build-tech-selected")) who.classList.add("build-tech-selected"); + // if (!tech.tech[index].isLore && !tech.tech[index].isNonRefundable && !who.classList.contains("build-tech-selected")) who.classList.add("build-tech-selected"); + if (!who.classList.contains("build-tech-selected")) who.classList.add("build-tech-selected"); tech.giveTech(index) } else if (!tech.tech[index].isNonRefundable) { tech.totalCount -= tech.tech[index].count tech.removeTech(index); who.classList.remove("build-tech-selected"); } else { + // for non refundable tech this makes it flash off for a second, but return to on to show that it can't be set off who.classList.remove("build-tech-selected") setTimeout(() => { who.classList.add("build-tech-selected") @@ -313,7 +315,6 @@ const build = { } } - // } else if (type === "tech") { //remove tech if you have too many // if (tech.tech[index].count < tech.tech[index].maxCount) { // if (!who.classList.contains("build-tech-selected")) who.classList.add("build-tech-selected"); @@ -327,12 +328,9 @@ const build = { // setTimeout(() => { //return energy // who.classList.add("build-tech-selected") // }, 50); - // } // } - - //update tech text //disable not allowed tech for (let i = 0, len = tech.tech.length; i < len; i++) { const techID = document.getElementById("tech-" + i) @@ -367,12 +365,14 @@ const build = { } else { techID.innerHTML = `
  ${tech.tech[i].name} ${isCount}
${tech.tech[i].description}` } + //deselect selected tech options if you don't have the tech any more // for example: when bot techs are converted after a bot upgrade tech is taken + if (tech.tech[i].count === 0 && techID.classList.contains("build-tech-selected")) techID.classList.remove("build-tech-selected"); if (techID.classList.contains("experiment-grid-disabled")) { techID.classList.remove("experiment-grid-disabled"); techID.setAttribute("onClick", `javascript: build.choosePowerUp(this,${i},'tech')`); } - } else { + } else { //disabled color // techID.innerHTML = `
${tech.tech[i].name}
requires: ${tech.tech[i].requires}` // techID.innerHTML = `
${tech.tech[i].name}
requires: ${tech.tech[i].requires}` techID.innerHTML = `
${tech.tech[i].name}
${tech.tech[i].description}` diff --git a/js/level.js b/js/level.js index 166ccf7..c651f69 100644 --- a/js/level.js +++ b/js/level.js @@ -37,7 +37,7 @@ const level = { // level.final() //final boss level // level.gauntlet(); //before final boss level // level.testChamber() - // level.sewers(); + // level.sewers(); // level.satellite(); // level.skyscrapers(); // level.aerie(); @@ -95,13 +95,13 @@ const level = { powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "tech", false); } if (tech.isHealLowHealth) { - const len = Math.floor((m.maxHealth - m.health) / 0.5) - for (let i = 0; i < len; i++) powerUps.spawn(player.position.x + 60 * (Math.random() - 0.5), player.position.y + 60 * (Math.random() - 0.5), "heal", false); + const len = Math.floor((m.maxHealth - m.health) / 0.33) + for (let i = 0; i < len; i++) powerUps.spawn(player.position.x + 90 * (Math.random() - 0.5), player.position.y + 90 * (Math.random() - 0.5), "heal", false); } if (tech.isMACHO) spawn.MACHO() for (let i = 0; i < tech.wimpCount; i++) { spawn.WIMP() - for (let j = 0, len = 1 + 2 * Math.random(); j < len; j++) powerUps.spawn(level.exit.x + 100 * (Math.random() - 0.5), level.exit.y - 100 + 100 * (Math.random() - 0.5), "research", false) + for (let j = 0, len = 1 + 5 * Math.random(); j < len; j++) powerUps.spawn(level.exit.x + 100 * (Math.random() - 0.5), level.exit.y - 100 + 100 * (Math.random() - 0.5), "research", false) } for (let i = 0; i < tech.wimpExperiment; i++) spawn.WIMP() if (tech.isFlipFlopLevelReset && !tech.isFlipFlopOn) { @@ -115,24 +115,24 @@ const level = { difficultyIncrease(num = 1) { for (let i = 0; i < num; i++) { simulation.difficulty++ - b.dmgScale *= 0.94; //damage done by player decreases each level + b.dmgScale *= 0.92; //damage done by player decreases each level if (simulation.accelScale < 5) simulation.accelScale *= 1.02 //mob acceleration increases each level if (simulation.lookFreqScale > 0.2) simulation.lookFreqScale *= 0.98 //mob cycles between looks decreases each level if (simulation.CDScale > 0.2) simulation.CDScale *= 0.97 //mob CD time decreases each level } - simulation.dmgScale = 0.36 * simulation.difficulty //damage done by mobs increases each level + simulation.dmgScale = 0.385 * simulation.difficulty //damage done by mobs increases each level simulation.healScale = 1 / (1 + simulation.difficulty * 0.055) //a higher denominator makes for lower heals // m.health += heal * simulation.healScale; }, difficultyDecrease(num = 1) { //used in easy mode for simulation.reset() for (let i = 0; i < num; i++) { simulation.difficulty-- - b.dmgScale /= 0.94; //damage done by player decreases each level + b.dmgScale /= 0.92; //damage done by player decreases each level if (simulation.accelScale > 0.2) simulation.accelScale /= 1.02 //mob acceleration increases each level if (simulation.lookFreqScale < 5) simulation.lookFreqScale /= 0.98 //mob cycles between looks decreases each level if (simulation.CDScale < 5) simulation.CDScale /= 0.97 //mob CD time decreases each level } if (simulation.difficulty < 1) simulation.difficulty = 0; - simulation.dmgScale = 0.36 * simulation.difficulty //damage done by mobs increases each level + simulation.dmgScale = 0.385 * simulation.difficulty //damage done by mobs increases each level if (simulation.dmgScale < 0.1) simulation.dmgScale = 0.1; simulation.healScale = 1 / (1 + simulation.difficulty * 0.055) }, @@ -1569,8 +1569,8 @@ const level = { spawn.mapRect(1225, -1955, 175, 30); const removeIndex2 = map.length - 1 //so much work to catch blocks caught at the bottom of the vertical portals let portal, portal2, portal3 - const hazard = level.hazard(350, -2025, 700, 10, 0.4, "hsl(0, 100%, 50%)") //laser - const hazard2 = level.hazard(1775, -2550, 150, 10, 0.4, "hsl(0, 100%, 50%)") //laser + const hazard = level.hazard((simulation.isHorizontalFlipped ? -350 - 700 : 350), -2025, 700, 10, 0.4, "hsl(0, 100%, 50%)") //laser + const hazard2 = level.hazard((simulation.isHorizontalFlipped ? -1775 - 150 : 1775), -2550, 150, 10, 0.4, "hsl(0, 100%, 50%)") //laser const button = level.button(2100, -2600) const buttonDoor = level.button(600, -550) const door = level.door(312, -750, 25, 190, 185) @@ -1758,11 +1758,13 @@ const level = { button.max.x = -button.max.x + 126 // flip the button horizontally buttonDoor.min.x = -buttonDoor.min.x - 126 // flip the button horizontally buttonDoor.max.x = -buttonDoor.max.x + 126 // flip the button horizontally - hazard.min.x = -hazard.min.x - 700 //-x-width - hazard.max.x = -hazard.max.x - 700 //-x-width - hazard2.min.x = -hazard2.min.x - 150 //-x-width - hazard2.max.x = -hazard2.max.x - 150 //-x-width + //this makes the hazard draw, but not collide for reasons I don't understand + //so don't use it, instead just call the hazard differently based on this flip flag + // hazard.min.x = -hazard.min.x - hazard.width //-x-width + // hazard.max.x = -hazard.max.x - hazard.width //-x-width + // hazard2.min.x = -hazard2.min.x - hazard2.width //-x-width + // hazard2.max.x = -hazard2.max.x - hazard2.width //-x-width portal = level.portal({ x: -2475, y: -140 @@ -1789,6 +1791,7 @@ const level = { // level.custom = () => { }; // level.customTopLayer = () => {}; + } else { portal = level.portal({ x: 2475, @@ -1816,7 +1819,8 @@ const level = { }, sewers() { const button1 = level.button(6600, 2675) - const hazard = level.hazard(4550, 2750, 4550, 150) + // const hazard = level.hazard(4550, 2750, 4550, 150) + const hazard = level.hazard(simulation.isHorizontalFlipped ? -4550 - 4550 : 4550, 2750, 4550, 150) let balance1, balance2, balance3, balance4, rotor const drip1 = level.drip(6100, 1900, 2900, 100) // drip(x, yMin, yMax, period = 100, color = "hsla(160, 100%, 35%, 0.5)") { @@ -1969,8 +1973,6 @@ const level = { drip1.x *= -1 drip2.x *= -1 drip3.x *= -1 - hazard.min.x = -hazard.min.x - 4550 //-x-width - hazard.max.x = -hazard.max.x - 4550 //-x-width level.custom = () => { drip1.draw(); drip2.draw(); @@ -6120,7 +6122,7 @@ const level = { addConstraint(x + 3100 * s, y - height, 0, -10 * s, stiffness, composite[composite.length - 1], pin); } }, - tunnel() { + tunnel() { // by Scarlettt level.custom = () => { level.playerExitCheck(); @@ -6229,21 +6231,7 @@ const level = { secretHazard.draw(); button.draw(); - function drawFlame(x, y, color = "#f81", angle = Math.PI / 2) { - ctx.beginPath(); - ctx.moveTo(x, y); - ctx.strokeStyle = color; - ctx.lineWidth = 3; - for (let i = 0; i < 3; i++) { - let randAng = (Math.random() - 0.5) * 2 + angle; - randLen = 30 + Math.random() * 10; - x = x + Math.cos(randAng) * randLen; - y = y - Math.sin(randAng) * randLen; - ctx.lineTo(x, y); - } - ctx.stroke(); - } // Fire damage let isInRange = flames.reduce((a, i) => a || Math.sqrt((m.pos.x - i[0]) * (m.pos.x - i[0]) + (m.pos.y + 90 - i[1]) * (m.pos.y + 90 - i[1])) < 50, false); @@ -6314,54 +6302,6 @@ const level = { ctx.fillRect(1480, -5000, 1070, 1710); } - function drawProject(startPos, endPos1, endPos2, tValue, tValueM) { - ctx.strokeStyle = "#003"; - ctx.fillStyle = "#0055aa" + ('0' + (tValue * 60 / tValueM).toString(16)).slice(-2); - - let inter = (tValueM - tValue) / tValueM; - let endpos1i = endPos1.map((i, j) => (startPos[j] - i) * inter), - endpos2i = endPos2.map((i, j) => (startPos[j] - i) * inter); - - ctx.beginPath(); - ctx.moveTo(endPos1[0] + endpos1i[0], endPos1[1] + endpos1i[1]); - ctx.lineTo(...startPos); - ctx.lineTo(endPos2[0] + endpos2i[0], endPos1[1] + endpos1i[1]); - ctx.fill(); - ctx.stroke(); - - ctx.beginPath(); - ctx.moveTo(endPos1[0] + endpos1i[0], endPos1[1] + endpos1i[1]); - ctx.lineTo(...startPos); - ctx.lineTo(endPos1[0] + endpos1i[0], endPos2[1] + endpos2i[1]); - ctx.fill(); - ctx.stroke(); - - ctx.beginPath(); - ctx.moveTo(endPos1[0] + endpos1i[0], endPos2[1] + endpos2i[1]); - ctx.lineTo(...startPos); - ctx.lineTo(endPos2[0] + endpos2i[0], endPos2[1] + endpos2i[1]); - ctx.fill(); - ctx.stroke(); - - ctx.beginPath(); - ctx.moveTo(endPos2[0] + endpos2i[0], endPos2[1] + endpos2i[1]); - ctx.lineTo(...startPos); - ctx.lineTo(endPos2[0] + endpos2i[0], endPos1[1] + endpos1i[1]); - ctx.fill(); - ctx.stroke(); - - if (tValue >= tValueM * 2 / 3) { - ctx.fillStyle = "#0055aa" + ('0' + Math.floor((tValue - tValueM * 2 / 3) * 6.25 * 60 / tValueM).toString(16)).slice(-2); - ctx.strokeStyle = "#000033" + ('0' + Math.floor((tValue - tValueM * 2 / 3) * 12.75 * 60 / tValueM).toString(16)).slice(-2); - ctx.fillRect(endPos1[0], endPos1[1], endPos2[0] - endPos1[0], endPos2[1] - endPos1[1]); - ctx.shadowColor = "#00aaaa" + ('0' + Math.floor((tValue - tValueM * 2 / 3) * 12.75 * 60 / tValueM).toString(16)).slice(-2); - ctx.shadowBlur = 10; - ctx.strokeRect(endPos1[0], endPos1[1], endPos2[0] - endPos1[0], endPos2[1] - endPos1[1]); - ctx.shadowBlur = 0; - ctx.shadowColor = "#0000"; - } - } - if (secretAnimTrans > 0) { drawProject([3614, -3530], [2900, -3900], [3400, -3600], secretAnimTrans, 60); if (secretAnimTrans >= 42) { @@ -6399,7 +6339,7 @@ const level = { ctx.fillText("Entity name: m", 1560, -3830); ctx.fillStyle = (tech.totalCount < 25 ? (tech.totalCount < 10 ? "#ffff44" : "#22ff22") : "#ff6644") + Math.floor((secretAnimTrans2 - 40) * 12.75).toString(16); ctx.fillText("Threat level: " + (tech.totalCount < 25 ? (tech.totalCount < 10 ? "Low" : "Medium") : "HIGH"), 1560, -3790); - if (tech.totalCount >= 10) ctx.fillText("PROCEDURE ACTIVATED", 1560, -3750); + if (tech.totalCount >= 15) ctx.fillText("PROCEDURE ACTIVATED", 1560, -3750); ctx.strokeStyle = "#00ff00" + Math.floor((secretAnimTrans2 - 40) * 6).toString(16); ctx.beginPath(); ctx.arc(1950, -3730, 60, 0, 2 * Math.PI); @@ -6416,9 +6356,8 @@ const level = { if (secretAnimTrans2 >= 60) { if (!emergencyActivated && tech.totalCount >= 10) { for (let i = 0; i < 5; i++) { - let randomNum = Math.random() * Math.PI; - spawn.exploder(m.pos.x + Math.cos(randomNum) * 200, m.pos.y + Math.sin(randomNum) * 200); - if (tech.totalCount >= 25) spawn.randomMob(m.pos.x + Math.cos(randomNum) * 200, m.pos.y + Math.sin(randomNum) * 200, Infinity); + spawn.exploder(1614, -3900); + if (tech.totalCount >= 25) spawn.randomMob(1614, -3900, Infinity); } emergencyActivated = true; } @@ -6592,5 +6531,70 @@ const level = { if (simulation.difficulty > 5) spawn[["shooterBoss", "launcherBoss"][randomBoss]](7500, -150); else spawn[["shooter", "launcher"][randomBoss]](7500, -150, 150); spawn[["shooter", "launcher"][randomBoss]](8500, -150, 150); + + // canvas stuff + function drawFlame(x, y, color = "#f81", angle = Math.PI / 2) { + ctx.beginPath(); + ctx.moveTo(x, y); + ctx.strokeStyle = color; + ctx.lineWidth = 3; + for (let i = 0; i < 3; i++) { + let randAng = (Math.random() - 0.5) * 2 + angle; + randLen = 30 + Math.random() * 10; + + x = x + Math.cos(randAng) * randLen; + y = y - Math.sin(randAng) * randLen; + ctx.lineTo(x, y); + } + ctx.stroke(); + } + + function drawProject(startPos, endPos1, endPos2, tValue, tValueM) { + ctx.strokeStyle = "#003"; + ctx.fillStyle = "#0055aa" + ('0' + (tValue * 60 / tValueM).toString(16)).slice(-2); + + let inter = (tValueM - tValue) / tValueM; + let endpos1i = endPos1.map((i, j) => (startPos[j] - i) * inter), + endpos2i = endPos2.map((i, j) => (startPos[j] - i) * inter); + + ctx.beginPath(); + ctx.moveTo(endPos1[0] + endpos1i[0], endPos1[1] + endpos1i[1]); + ctx.lineTo(...startPos); + ctx.lineTo(endPos2[0] + endpos2i[0], endPos1[1] + endpos1i[1]); + ctx.fill(); + ctx.stroke(); + + ctx.beginPath(); + ctx.moveTo(endPos1[0] + endpos1i[0], endPos1[1] + endpos1i[1]); + ctx.lineTo(...startPos); + ctx.lineTo(endPos1[0] + endpos1i[0], endPos2[1] + endpos2i[1]); + ctx.fill(); + ctx.stroke(); + + ctx.beginPath(); + ctx.moveTo(endPos1[0] + endpos1i[0], endPos2[1] + endpos2i[1]); + ctx.lineTo(...startPos); + ctx.lineTo(endPos2[0] + endpos2i[0], endPos2[1] + endpos2i[1]); + ctx.fill(); + ctx.stroke(); + + ctx.beginPath(); + ctx.moveTo(endPos2[0] + endpos2i[0], endPos2[1] + endpos2i[1]); + ctx.lineTo(...startPos); + ctx.lineTo(endPos2[0] + endpos2i[0], endPos1[1] + endpos1i[1]); + ctx.fill(); + ctx.stroke(); + + if (tValue >= tValueM * 2 / 3) { + ctx.fillStyle = "#0055aa" + ('0' + Math.floor((tValue - tValueM * 2 / 3) * 6.25 * 60 / tValueM).toString(16)).slice(-2); + ctx.strokeStyle = "#000033" + ('0' + Math.floor((tValue - tValueM * 2 / 3) * 12.75 * 60 / tValueM).toString(16)).slice(-2); + ctx.fillRect(endPos1[0], endPos1[1], endPos2[0] - endPos1[0], endPos2[1] - endPos1[1]); + ctx.shadowColor = "#00aaaa" + ('0' + Math.floor((tValue - tValueM * 2 / 3) * 12.75 * 60 / tValueM).toString(16)).slice(-2); + ctx.shadowBlur = 10; + ctx.strokeRect(endPos1[0], endPos1[1], endPos2[0] - endPos1[0], endPos2[1] - endPos1[1]); + ctx.shadowBlur = 0; + ctx.shadowColor = "#0000"; + } + } } }; \ No newline at end of file diff --git a/js/player.js b/js/player.js index 555d38d..daf7242 100644 --- a/js/player.js +++ b/js/player.js @@ -499,8 +499,8 @@ const m = { let dmg = 1 dmg *= m.fieldHarmReduction if (tech.isHarmMACHO) dmg *= 0.33 - if (tech.isImmortal) dmg *= 0.79 - if (tech.isHarmReduceAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 0.50 : 1.1 + if (tech.isImmortal) dmg *= 0.66 + if (tech.isHarmReduceAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 0.33 : 1.15 if (tech.healthDrain) dmg *= 1 + 2.667 * tech.healthDrain //tech.healthDrain = 0.03 at one stack //cause more damage if (tech.squirrelFx !== 1) dmg *= 1 + (tech.squirrelFx - 1) / 5 //cause more damage if (tech.isBlockHarm && m.isHolding) dmg *= 0.15 @@ -513,7 +513,6 @@ const m = { if (tech.isNoFireDefense && m.cycle > m.fireCDcycle + 120) dmg *= 0.34 if (tech.energyRegen === 0) dmg *= 0.34 if (tech.isTurret && m.crouch) dmg *= 0.55; - if (tech.isFireMoveLock && input.fire) dmg *= 0.4; if (tech.isEntanglement && b.inventory[0] === b.activeGun) { for (let i = 0, len = b.inventory.length; i < len; i++) dmg *= 0.87 // 1 - 0.15 } @@ -1601,33 +1600,31 @@ const m = { } else if ((input.field && m.fieldCDcycle < m.cycle)) { //not hold but field button is pressed m.grabPowerUp(); m.lookForPickUp(); - if (m.energy > 0.05) { - //draw field - if (m.holdingTarget) { - ctx.fillStyle = "rgba(110,170,200," + (0.06 + 0.03 * Math.random()) + ")"; - ctx.strokeStyle = "rgba(110, 200, 235, " + (0.35 + 0.05 * Math.random()) + ")" - } else { - ctx.fillStyle = "rgba(110,170,200," + (0.27 + 0.2 * Math.random() - 0.1 * wave) + ")"; - ctx.strokeStyle = "rgba(110, 200, 235, " + (0.4 + 0.5 * Math.random()) + ")" - } - ctx.beginPath(); - ctx.arc(m.pos.x, m.pos.y, m.fieldRange, m.angle - Math.PI * m.fieldArc, m.angle + Math.PI * m.fieldArc, false); - ctx.lineWidth = 2.5 - 1.5 * wave; - ctx.lineCap = "butt" - ctx.stroke(); - const curve = 0.57 + 0.04 * wave - const aMag = (1 - curve * 1.2) * Math.PI * m.fieldArc - let a = m.angle + aMag - let cp1x = m.pos.x + curve * m.fieldRange * Math.cos(a) - let cp1y = m.pos.y + curve * m.fieldRange * Math.sin(a) - ctx.quadraticCurveTo(cp1x, cp1y, m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle)) - a = m.angle - aMag - cp1x = m.pos.x + curve * m.fieldRange * Math.cos(a) - cp1y = m.pos.y + curve * m.fieldRange * Math.sin(a) - ctx.quadraticCurveTo(cp1x, cp1y, m.pos.x + 1 * m.fieldRange * Math.cos(m.angle - Math.PI * m.fieldArc), m.pos.y + 1 * m.fieldRange * Math.sin(m.angle - Math.PI * m.fieldArc)) - ctx.fill(); - m.pushMobsFacing(); + //draw field + if (m.holdingTarget) { + ctx.fillStyle = "rgba(110,170,200," + (0.06 + 0.03 * Math.random()) + ")"; + ctx.strokeStyle = "rgba(110, 200, 235, " + (0.35 + 0.05 * Math.random()) + ")" + } else { + ctx.fillStyle = "rgba(110,170,200," + (0.27 + 0.2 * Math.random() - 0.1 * wave) + ")"; + ctx.strokeStyle = "rgba(110, 200, 235, " + (0.4 + 0.5 * Math.random()) + ")" } + ctx.beginPath(); + ctx.arc(m.pos.x, m.pos.y, m.fieldRange, m.angle - Math.PI * m.fieldArc, m.angle + Math.PI * m.fieldArc, false); + ctx.lineWidth = 2.5 - 1.5 * wave; + ctx.lineCap = "butt" + ctx.stroke(); + const curve = 0.57 + 0.04 * wave + const aMag = (1 - curve * 1.2) * Math.PI * m.fieldArc + let a = m.angle + aMag + let cp1x = m.pos.x + curve * m.fieldRange * Math.cos(a) + let cp1y = m.pos.y + curve * m.fieldRange * Math.sin(a) + ctx.quadraticCurveTo(cp1x, cp1y, m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle)) + a = m.angle - aMag + cp1x = m.pos.x + curve * m.fieldRange * Math.cos(a) + cp1y = m.pos.y + curve * m.fieldRange * Math.sin(a) + ctx.quadraticCurveTo(cp1x, cp1y, m.pos.x + 1 * m.fieldRange * Math.cos(m.angle - Math.PI * m.fieldArc), m.pos.y + 1 * m.fieldRange * Math.sin(m.angle - Math.PI * m.fieldArc)) + ctx.fill(); + m.pushMobsFacing(); } else if (m.holdingTarget && m.fieldCDcycle < m.cycle) { //holding, but field button is released m.pickUp(); } else { @@ -1664,7 +1661,7 @@ const m = { if (m.energy > m.maxEnergy - 0.02 && m.fieldCDcycle < m.cycle && !input.field && bullet.length < 150 && (m.cycle % 2)) { if (tech.isSporeField) { for (let i = 0, len = Math.random() * 20; i < len; i++) { - m.energy -= 0.085 + m.energy -= 0.08 if (m.energy > 0) { b.spore(m.pos) } else { @@ -1673,10 +1670,10 @@ const m = { } } } else if (tech.isMissileField) { - m.energy -= 0.32; + m.energy -= 0.3; b.missile({ x: m.pos.x, y: m.pos.y - 40 }, -Math.PI / 2 + 0.5 * (Math.random() - 0.5), 0, 1) } else if (tech.isIceField) { - m.energy -= 0.046; + m.energy -= 0.04; b.iceIX(1) } else { m.energy -= 0.45 * tech.droneEnergyReduction; diff --git a/js/powerup.js b/js/powerup.js index 3fa9a3d..7cb9513 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -164,7 +164,7 @@ const powerUps = { tech.maxDuplicationEvent() } if (tech.isCancelRerolls) { - for (let i = 0; i < 8; i++) { + for (let i = 0; i < 10; i++) { let spawnType = (m.health < 0.25 || tech.isEnergyNoAmmo) ? "heal" : "ammo" if (Math.random() < 0.33) { spawnType = "heal" @@ -286,7 +286,7 @@ const powerUps = { } } if (tech.healGiveMaxEnergy) { - tech.healMaxEnergyBonus += 0.05 + tech.healMaxEnergyBonus += 0.06 m.setMaxEnergy(); } }, @@ -308,7 +308,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(0.7 * Math.random() * target.ammoPack) * (tech.isAlwaysFire ? 3 : 1) + 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}`) } @@ -316,7 +316,7 @@ const powerUps = { for (let i = 0, len = b.inventory.length; i < len; i++) { const target = b.guns[b.inventory[i]] if (target.ammo !== Infinity) { - const ammoAdded = Math.ceil(Math.random() * target.ammoPack) * (tech.isAlwaysFire ? 3 : 1) + const ammoAdded = Math.ceil(Math.random() * target.ammoPack) target.ammo += ammoAdded simulation.makeTextLog(`${target.name}.ammo += ${ammoAdded}`) } diff --git a/js/simulation.js b/js/simulation.js index 103c5e8..8e6a2b6 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -506,10 +506,10 @@ const simulation = { if (!m.isShipMode) { m.draw = m.drawDefault //set the play draw to normal, undoing some junk tech m.spawn(); //spawns the player + m.look = m.lookDefault } else { World.add(engine.world, [player]) } - m.look = m.lookDefault simulation.isHorizontalFlipped = (Math.random() < 0.5) ? true : false //if true, some maps are flipped horizontally level.levels = level.playableLevels.slice(0) //copy array, not by just by assignment @@ -790,7 +790,7 @@ const simulation = { } if (tech.relayIce && tech.isFlipFlopOn) { for (let j = 0; j < tech.relayIce; j++) { - for (let i = 0, len = Math.ceil(5 * Math.random()); i < len; i++) b.iceIX(2) + for (let i = 0, len = Math.ceil(8 * Math.random()); i < len; i++) b.iceIX(2) } } diff --git a/js/spawn.js b/js/spawn.js index 6551bb6..a4fd140 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -1474,7 +1474,7 @@ const spawn = { } mobs.spawn(x, y, 0, radius, "transparent"); let me = mob[mob.length - 1]; - Matter.Body.setDensity(me, 0.3); //extra dense //normal is 0.001 + Matter.Body.setDensity(me, 0.25); //extra dense //normal is 0.001 me.laserRange = 350; me.seeAtDistance2 = 2000000; me.isBoss = true; diff --git a/js/tech.js b/js/tech.js index 1bcea61..af7fa03 100644 --- a/js/tech.js +++ b/js/tech.js @@ -158,17 +158,17 @@ let dmg = 1 //m.fieldDamage if (tech.isFlipFlopDamage && tech.isFlipFlopOn) dmg *= 1.45 if (tech.isAnthropicDamage && tech.isDeathAvoidedThisLevel) dmg *= 2.3703599 - if (tech.isDamageAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 1.5 : 0.85 + if (tech.isDamageAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 2 : 0.66 if (m.isSneakAttack && m.cycle > m.lastKillCycle + 240) dmg *= 4 if (tech.isTechDamage) dmg *= 1.9 if (tech.isDupDamage) dmg *= 1 + Math.min(1, tech.duplicationChance()) if (tech.isLowEnergyDamage) dmg *= 1 + Math.max(0, 1 - m.energy) * 0.5 - if (tech.isMaxEnergyTech) dmg *= 1.4 - if (tech.isEnergyNoAmmo) dmg *= 1.5 - if (tech.isDamageForGuns) dmg *= 1 + 0.14 * b.inventory.length + if (tech.isMaxEnergyTech) dmg *= 1.5 + if (tech.isEnergyNoAmmo) dmg *= 1.6 + if (tech.isDamageForGuns) dmg *= 1 + 0.1 * b.inventory.length if (tech.isLowHealthDmg) dmg *= 1 + 0.5 * Math.max(0, 1 - m.health) if (tech.isHarmDamage && m.lastHarmCycle + 600 > m.cycle) dmg *= 3; - if (tech.isEnergyLoss) dmg *= 1.45; + if (tech.isEnergyLoss) dmg *= 1.55; if (tech.isAcidDmg && m.health > 1) dmg *= 1.35; if (tech.restDamage > 1 && player.speed < 1) dmg *= tech.restDamage if (tech.isEnergyDamage) dmg *= 1 + m.energy / 9; @@ -181,7 +181,7 @@ return dmg * tech.slowFire * tech.aimDamage }, duplicationChance() { - return (tech.isPowerUpsVanish ? 0.2 : 0) + (tech.isStimulatedEmission ? 0.2 : 0) + tech.cancelCount * 0.043 + tech.duplicateChance + m.duplicateChance + return (tech.isPowerUpsVanish ? 0.2 : 0) + (tech.isStimulatedEmission ? 0.22 : 0) + tech.cancelCount * 0.047 + tech.duplicateChance + m.duplicateChance }, maxDuplicationEvent() { if (tech.is100Duplicate && tech.duplicationChance() > 0.99) { @@ -250,7 +250,7 @@ }, { name: "arsenal", - description: "increase damage by 14%
for each gun in your inventory", + description: "increase damage by 10%
for each gun in your inventory", maxCount: 1, count: 0, frequency: 2, @@ -286,7 +286,7 @@ }, { name: "generalist", - description: "spawn 6 guns, but you can't switch guns
guns cycle automatically with each new level", + description: "spawn 8 guns, but you can't switch guns
guns cycle automatically with each new level", maxCount: 1, count: 0, frequency: 2, @@ -296,11 +296,11 @@ requires: "arsenal or active cooling", effect() { tech.isGunCycle = true; - for (let i = 0; i < 6; i++) powerUps.spawn(m.pos.x + 10 * Math.random(), m.pos.y + 10 * Math.random(), "gun"); + for (let i = 0; i < 8; i++) powerUps.spawn(m.pos.x + 10 * Math.random(), m.pos.y + 10 * Math.random(), "gun"); }, remove() { if (tech.isGunCycle) { - for (let i = 0; i < 6; i++) { + for (let i = 0; i < 8; i++) { if (b.inventory.length) b.removeGun(b.guns[b.inventory[b.inventory.length - 1]].name) //remove your last gun } tech.isGunCycle = false; @@ -447,63 +447,19 @@ tech.isTurret = false; } }, - { - name: "inertial frame", - description: "66% decreased delay after firing
you can only fire when at rest", - maxCount: 1, - count: 0, - frequency: 2, - allowed() { - return !m.isShipMode - }, - requires: "not ship mode", - effect: () => { - tech.isFireNotMove = true; - b.setFireCD(); - b.setFireMethod(); - }, - remove() { - if (tech.isFireNotMove) { - tech.isFireNotMove = false - b.setFireCD(); - b.setFireMethod(); - } - } - }, - { - name: "automatic", - description: "always fire when at rest
ammo power ups give 250% ammo", - maxCount: 1, - count: 0, - frequency: 4, - allowed() { - return tech.isFireNotMove && !tech.isFireMoveLock - }, - requires: "inertial frame, not Higgs mechanism", - effect: () => { - tech.isAlwaysFire = true; - b.setFireMethod(); - }, - remove() { - if (tech.isAlwaysFire) { - tech.isAlwaysFire = false - b.setFireMethod(); - } - } - }, { name: "dead reckoning", - description: "increase damage by 30% when at rest", + description: "increase damage by 36% when at rest", maxCount: 9, count: 0, - frequency: 4, - frequencyDefault: 4, + frequency: 1, + frequencyDefault: 1, allowed() { - return tech.isFireNotMove + return true }, - requires: "inertial frame", + requires: "", effect: () => { - tech.restDamage += 0.3 + tech.restDamage += 0.36 }, remove() { tech.restDamage = 1; @@ -511,21 +467,23 @@ }, { name: "Higgs mechanism", - description: "while firing your position is locked
and harm is reduced by 60%", + description: "while firing your position is locked
50% decreased delay after firing", maxCount: 1, count: 0, frequency: 2, allowed() { - return !tech.isEnergyHealth && !m.isShipMode && !tech.isAlwaysFire + return !m.isShipMode && !tech.isAlwaysFire }, - requires: "not mass energy, not ship mode, not automatic", + requires: "not ship mode, not automatic", effect: () => { tech.isFireMoveLock = true; + b.setFireCD(); b.setFireMethod(); }, remove() { if (tech.isFireMoveLock) { tech.isFireMoveLock = false + b.setFireCD(); b.setFireMethod(); } } @@ -585,23 +543,6 @@ tech.isSpeedDamage = false } }, - // { - // name: "Galilean group", - // description: "reduce harm by 50% when at rest", - // maxCount: 1, - // count: 0, - // frequency: 2, - // allowed() { - // return tech.isFireNotMove || tech.isFireMoveLock - // }, - // requires: "inertial frame or Higgs manism", - // effect() { - // tech.isRestHarm = true - // }, - // remove() { - // tech.isRestHarm = false; - // } - // }, { name: "kinetic bombardment", description: "increase damage by up to 33%
at a distance of 40 steps from the target", @@ -762,7 +703,7 @@ }, { name: "ammonium nitrate", - description: "increase explosive damage by 20%
increase explosive radius by 20%", + description: "increase explosive damage by 25%
increase explosive radius by 25%", maxCount: 9, count: 0, frequency: 2, @@ -771,7 +712,7 @@ }, requires: "an explosive damage source, not iridium-192", effect: () => { - tech.explosiveRadius += 0.2; + tech.explosiveRadius += 0.25; }, remove() { tech.explosiveRadius = 1; @@ -918,7 +859,7 @@ }, { name: "zoospore vector", - description: "mobs produce spores when they die
9% chance", + description: "mobs produce spores when they die
11% chance", maxCount: 9, count: 0, frequency: 2, @@ -927,7 +868,7 @@ }, requires: "no other mob death tech", effect() { - tech.sporesOnDeath += 0.09; + tech.sporesOnDeath += 0.11; for (let i = 0; i < 8; i++) { b.spore(m.pos) } @@ -965,7 +906,7 @@ count: 0, frequency: 2, allowed() { - return (b.totalBots() > 1 || tech.haveGunCheck("drones") || tech.haveGunCheck("mine") || tech.haveGunCheck("spores") || m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing") && !tech.isEnergyHealth + return (b.totalBots() > 1 || tech.haveGunCheck("mine") || tech.haveGunCheck("spores") || m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing") && !tech.isEnergyHealth }, requires: "drones, spores, mines, or bots", effect() { @@ -1708,7 +1649,7 @@ }, { name: "thermocouple", - description: "if relay switch is in the ON state
condense 1-5 ice IX crystals every second", + description: "if relay switch is in the ON state
condense 1-7 ice IX crystals every second", maxCount: 9, count: 0, frequency: 4, @@ -2078,7 +2019,7 @@ }, { name: "1st ionization energy", - description: "each heal power up you collect
increases your maximum energy by 5", + description: "each heal power up you collect
increases your maximum energy by 6", maxCount: 1, count: 0, frequency: 3, @@ -2121,7 +2062,7 @@ }, { name: "exciton-lattice", - description: `increase damage by 50%, but
ammo will no longer spawn`, + description: `increase damage by 60%, but
ammo will no longer spawn`, maxCount: 1, count: 0, frequency: 2, @@ -2138,7 +2079,7 @@ }, { name: "exothermic process", - description: "increase damage by 45%
if a mob dies drain energy by 25%", + description: "increase damage by 50%
if a mob dies drain energy by 25%", maxCount: 1, count: 0, frequency: 2, @@ -2155,7 +2096,7 @@ }, { name: "heat engine", - description: `increase damage by 40%, but
reduce maximum energy by 50`, + description: `increase damage by 50%, but
reduce maximum energy by 50`, maxCount: 1, count: 0, frequency: 4, @@ -2193,7 +2134,7 @@ }, { name: "overcharge", - description: "increase your maximum energy by 50", + description: "increase your maximum energy by 60
add 10 JUNK tech to the potential pool", maxCount: 9, count: 0, frequency: 1, @@ -2204,15 +2145,17 @@ effect() { tech.bonusEnergy += 0.5 m.setMaxEnergy() + tech.addJunkTechToPool(10) }, remove() { tech.bonusEnergy = 0; m.setMaxEnergy() + if (this.count > 0) tech.removeJunkTechFromPool(10) } }, { name: "Maxwell's demon", - description: "energy above your max decays 92% slower
add 17 JUNK tech to the potential pool", + description: "energy above your max decays 92% slower
add 18 JUNK tech to the potential pool", maxCount: 1, count: 0, frequency: 2, @@ -2222,11 +2165,11 @@ requires: "a source of overfilled energy", effect() { tech.overfillDrain = 0.87 //70% = 1-(1-0.75)/(1-0.15) //92% = 1-(1-0.75)/(1-0.87) - tech.addJunkTechToPool(17) + tech.addJunkTechToPool(18) }, remove() { tech.overfillDrain = 0.75 - if (this.count > 0) tech.removeJunkTechFromPool(17) + if (this.count > 0) tech.removeJunkTechFromPool(18) } }, { @@ -2285,7 +2228,7 @@ }, { name: "dormancy", - description: "if a mob has died in the last 5 seconds
increase damage by 50% else decrease it by 15%", + description: "if a mob has died in the last 5 seconds
increase damage by 100% else decrease it by 33%", maxCount: 1, count: 0, frequency: 2, @@ -2302,7 +2245,7 @@ }, { name: "torpor", - description: "if a mob has died in the last 5 seconds
reduce harm by 50% else increase it by 10%", + description: "if a mob has died in the last 5 seconds
reduce harm by 66% else increase it by 15%", maxCount: 1, count: 0, frequency: 4, @@ -2468,7 +2411,7 @@ }, { name: "negentropy", - description: `at the start of each level
spawn a heal for every 50 missing health`, + description: `at the start of each level
spawn a heal for every 33 missing health`, maxCount: 1, count: 0, frequency: 2, @@ -2571,7 +2514,7 @@ }, { name: "quantum immortality", - description: "after dying, continue in an alternate reality
reduce harm by 23%", //spawn 4 research + description: "after dying, continue in an alternate reality
reduce harm by 33%", //spawn 4 research maxCount: 1, count: 0, frequency: 4, @@ -2629,7 +2572,7 @@ }, { name: "Ψ(t) collapse", - description: "enter an alternate reality after you research
spawn 12 research", + description: "enter an alternate reality after you research
spawn 15 research", maxCount: 1, count: 0, frequency: 1, @@ -2640,7 +2583,7 @@ requires: "not quantum immortality, many-worlds, non-unitary", effect() { tech.isResearchReality = true; - for (let i = 0; i < 12; i++) powerUps.spawn(m.pos.x + Math.random() * 10, m.pos.y + Math.random() * 10, "research", false); + for (let i = 0; i < 15; i++) powerUps.spawn(m.pos.x + Math.random() * 60, m.pos.y + Math.random() * 60, "research", false); }, remove() { tech.isResearchReality = false; @@ -2772,7 +2715,7 @@ { name: "WIMPs", //harmful - description: "a harmful particle slowly chases you
spawn 2-3 research at the end of each level", + description: "a harmful particle slowly chases you
spawn 2-6 research at the end of each level", maxCount: 9, count: 0, frequency: 1, @@ -2826,7 +2769,7 @@ }, { name: "replication", - description: "8% chance to duplicate spawned power ups
add 18 JUNK tech to the potential pool", + description: "10% chance to duplicate spawned power ups
add 18 JUNK tech to the potential pool", maxCount: 9, count: 0, frequency: 1, @@ -2836,7 +2779,7 @@ }, requires: "below 100% duplication chance", effect() { - tech.duplicateChance += 0.08 + tech.duplicateChance += 0.1 powerUps.setDo(); //needed after adjusting duplication chance tech.addJunkTechToPool(18) }, @@ -2848,7 +2791,7 @@ }, { name: "stimulated emission", - description: "20% chance to duplicate spawned power ups
but, after a collision eject 1 tech", + description: "22% chance to duplicate spawned power ups
but, after a collision eject 1 tech", maxCount: 1, count: 0, frequency: 1, @@ -2908,7 +2851,7 @@ // }, { name: "futures exchange", - description: "clicking × to cancel a field, tech, or gun
adds 4.3% power up duplication chance", + description: "clicking × to cancel a field, tech, or gun
adds 4.7% power up duplication chance", maxCount: 1, count: 0, frequency: 1, @@ -2930,7 +2873,7 @@ }, { name: "commodities exchange", - description: "clicking × to cancel a field, tech, or gun
spawns 8 heals, ammo, and research", + description: "clicking × to cancel a field, tech, or gun
spawns 10 heals, ammo, and research", maxCount: 1, count: 0, frequency: 1, @@ -4107,7 +4050,7 @@ }, { name: "tinsellated flagella", - description: "sporangium release 2 more spores
spores accelerate 50% faster", + description: "sporangium release 2 more spores
spores accelerate 40% faster", isGunTech: true, maxCount: 1, count: 0, @@ -4216,7 +4159,7 @@ }, { name: "reduced tolerances", - description: "reduce drone energy/ammo costs by 66%
reduce the average drone lifetime by 40%", + description: "increase drone ammo/efficiency by 66%
reduce the average drone lifetime by 40%", isGunTech: true, maxCount: 3, count: 0, @@ -4947,7 +4890,7 @@ }, { name: "annihilation", - description: "touching normal mobs annihilates them
drains 33% of your maximum energy", + description: "touching normal mobs annihilates them
but drains 33% of your maximum energy", isFieldTech: true, maxCount: 1, count: 0, @@ -5306,7 +5249,7 @@ }, { name: "traversable geodesics", - description: "your bullets can traverse wormholes
spawn a gun and ammo", + description: "your bullets can traverse wormholes
spawn 2 guns and ammo", isFieldTech: true, maxCount: 1, count: 0, @@ -5317,11 +5260,18 @@ requires: "wormhole", effect() { tech.isWormBullets = true - powerUps.spawn(m.pos.x, m.pos.y, "gun"); - powerUps.spawn(m.pos.x, m.pos.y, "ammo"); + for (let i = 0; i < 2; i++) { + powerUps.spawn(m.pos.x, m.pos.y, "gun"); + powerUps.spawn(m.pos.x, m.pos.y, "ammo"); + } }, remove() { - tech.isWormBullets = false + if (tech.isWormBullets) { + for (let i = 0; i < 2; i++) { + if (b.inventory.length) b.removeGun(b.guns[b.inventory[b.inventory.length - 1]].name) //remove your last gun + } + tech.isWormBullets = false; + } } }, //************************************************** @@ -5338,7 +5288,7 @@ isBadRandomOption: true, isExperimentalMode: true, allowed() { - return build.isExperimentSelection && !m.isShipMode && m.fieldUpgrades[m.fieldMode].name !== "negative mass field" && !tech.isFireNotMove + return build.isExperimentSelection && !m.isShipMode && m.fieldUpgrades[m.fieldMode].name !== "negative mass field" }, requires: "", effect() { @@ -5499,6 +5449,29 @@ // }, // remove() {} // }, + { + name: "automatic", + description: "you can't fire when moving
always fire when at rest", + maxCount: 1, + count: 0, + frequency: 0, + isExperimentHide: true, + isJunk: true, + allowed() { + return !tech.isFireMoveLock + }, + requires: "not Higgs mechanism", + effect: () => { + tech.isAlwaysFire = true; + b.setFireMethod(); + }, + remove() { + if (tech.isAlwaysFire) { + tech.isAlwaysFire = false + b.setFireMethod(); + } + } + }, { name: "hidden variable", description: "spawn 30 heal power ups
but hide your health bar", @@ -5613,7 +5586,7 @@ } }, remove() { - m.look = m.lookDefault + if (this.count) m.look = m.lookDefault } }, { @@ -5709,7 +5682,7 @@ } }, remove() { - m.look = m.lookDefault + if (this.count) m.look = m.lookDefault } }, { @@ -6868,7 +6841,6 @@ isFireRateForGuns: null, cyclicImmunity: null, isTechDamage: null, - isFireNotMove: null, isRestHarm: null, isFireMoveLock: null, isRivets: null, diff --git a/todo.txt b/todo.txt index d4075bf..e68e5ad 100644 --- a/todo.txt +++ b/todo.txt @@ -1,5 +1,54 @@ ******************************************************** NEXT PATCH ******************************************************** +over all game difficulty scaling occurs faster + your damage will feel lower, and you will take more harm, + so you should probably play on a lower difficulty + +tech: Higgs manism gives 50% reduced fire delay instead of harm reduction +tech: inertial frame is removed +tech: automatic is now a junk tech + +balance: + dead reckoning gives 36% damage when at rest (was 30%) + overcharge gives 10 more energy, but adds 10 junk tech + 1st ionization energy gives 6 energy per heal (was 5) + dormancy increases damage by 100% but lowers it by 33% if no recent kills (was +50%, -15%) + torpor decreases harm by 66% increases harm by 15% if no recent kills (was -50%, +10%) + Ψ(t) collapse spawns 3 more research, so it's at 15 + fragmentation gives 30% more nails for railgun + ammonium nitrate +25% (was 20%) + generalist gives 8 guns (was 6) + arsenal gives 10% per gun (was 14%) + rivet gun fires 25% faster, rivets are 15% larger + shotgun slug is 33% bigger + missile bot fires 10% more often + tinsellated flagella gives 40% speed increase (was 50%), base spore speed is 10% faster + beamSplitter has a 20% lower divergence + nano manufacturing tech is all buffed 15% + traversable geodesics gives 2 guns and ammo (was 1) + mines have 25% more nails, laser mines use 20% less energy sentry mines last 33% seconds longer + zoospore vector has an 11% chance to spawn (was 9%) + negentropy spawns a heal for every 33 missing health (was 50 health) + exciton-lattice gives 60% damage + thermocouple spawns 1-8 ice-IX (was 1-5) + WIMPs spawn 2-6 research (was 2-3) + quantum immortality reduces harm by 33% (was 23%) + commodities exchange gives 10 power ups (was 8) + super balls are 17% bigger (this means they do about 25% more damage) + exothermic process increases damage by (was 45%) + heat engine increases damage by 50% (was 40%) + replication gives 10% duplication chance (was 8%) + stimulated emission gives 22% duplication chance + futures exchange gives 4.7% duplication chance per cancel (was 4.3%) + needles are 10% slower and do 15% more damage + +bug fixes: + reduced tolerances text rewritten to clarify that it gives more ammo per ammo pack + hazards on horizontal flipped levels now correctly do damage + ship mode aims properly after you die + although it still doesn't reset + experiment mode selections are highlighted better + ******************************************************** BUGS ******************************************************** @@ -28,6 +77,12 @@ is there a way to check if the player is stuck inside the map or block ******************************************************** TODO ******************************************************** +* inductive coupling - sucks without catabolism, too much delayed gratification. should probably be bundled with transceiver chip + +tech: cloaking field - decrease/increase cooldown on sneak attack? + decrease/increase damage bonus? + decrease/increase visual radius? + have throw charge scale with fire delay in testing mode console log the body you click on