From 1a5071cf06e7b833ab1123d99087b958ff5375b8 Mon Sep 17 00:00:00 2001 From: landgreen Date: Fri, 30 Jul 2021 09:47:50 -0700 Subject: [PATCH] Lenz's law tech: Lenz's law -perfect diamagnetism field stays when you aren't holding field tech: Zeno's paradox - every 5s lose 10% of your current health, but get 84% harm reduction --- .DS_Store | Bin 6148 -> 6148 bytes js/level.js | 9 ++-- js/player.js | 116 +++++++++++++++++++++++++++++++++++++++--- js/powerup.js | 2 +- js/simulation.js | 5 +- js/tech.js | 130 +++++++++++++++++++++++++++++++---------------- todo.txt | 20 ++++---- 7 files changed, 212 insertions(+), 70 deletions(-) diff --git a/.DS_Store b/.DS_Store index 7482e0a1af1882d9c434b18e23b383fcb2933782..b8f451506a88675eb01f301f79173da59ad050cf 100644 GIT binary patch delta 22 dcmZoMXffEJ#mqEs!(<(1UnXgX&DG4EA^=j%2G9Ti delta 22 dcmZoMXffEJ#mrP)JXwd?mq}{D=4$3n5dcsE2G0Nh diff --git a/js/level.js b/js/level.js index a1fbcc6..50b2a21 100644 --- a/js/level.js +++ b/js/level.js @@ -14,7 +14,8 @@ const level = { // simulation.enableConstructMode() //used to build maps in testing mode // level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why // simulation.isHorizontalFlipped = true - // m.setField("wormhole") + // tech.isFieldFree = true + // m.setField("perfect diamagnetism") // b.giveGuns("shotgun") // tech.isNeedleShot = true // tech.isIceShot = true @@ -2270,14 +2271,12 @@ const level = { spawn.mapRect(5300, -275, 50, 175); spawn.mapRect(5050, -100, 50, 150); spawn.mapRect(4850, -275, 50, 175); - // spawn.starter(1900, -500, 200) //big boy + spawn.starter(1900, -500, 200) //big boy // spawn.growBossCulture(1900, -500) - // spawn.blinkBoss(1900, -500) // spawn.snakeBoss(1900, -500) // spawn.grenadierBoss(1900, -500) - - spawn.sneaker(1900, -500) + // spawn.sneaker(1900, -500) // spawn.historyBoss(1200, -500) // spawn.laserTargetingBoss(1600, -400) // spawn.focuser(1600, -500) diff --git a/js/player.js b/js/player.js index d196c49..7f73637 100644 --- a/js/player.js +++ b/js/player.js @@ -490,6 +490,7 @@ const m = { harmReduction() { let dmg = 1 dmg *= m.fieldHarmReduction + if (tech.isZeno) dmg *= 0.16 if (tech.isFieldHarmReduction) dmg *= 0.5 if (tech.isHarmMACHO) dmg *= 0.33 if (tech.isImmortal) dmg *= 0.66 @@ -1138,7 +1139,10 @@ const m = { //bullet-like collisions m.holdingTarget.collisionFilter.category = cat.bullet m.holdingTarget.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield; - if (tech.isBlockRestitution) m.holdingTarget.restitution = 0.999 //extra bouncy + if (tech.isBlockRestitution) { + m.holdingTarget.restitution = 0.999 //extra bouncy + m.holdingTarget.friction = m.holdingTarget.frictionStatic = m.holdingTarget.frictionAir = 0.001 + } //check every second to see if player is away from thrown body, and make solid const solid = function(that) { const dx = that.position.x - player.position.x; @@ -1346,7 +1350,7 @@ const m = { pushMobsFacing() { // find mobs in range and in direction looking for (let i = 0, len = mob.length; i < len; ++i) { if ( - Vector.magnitude(Vector.sub(mob[i].position, player.position)) - mob[i].radius < m.fieldRange && + Vector.magnitude(Vector.sub(mob[i].position, m.pos)) - mob[i].radius < m.fieldRange && !mob[i].isShielded && m.lookingAt(mob[i]) && Matter.Query.ray(map, mob[i].position, m.pos).length === 0 @@ -1576,9 +1580,9 @@ const m = { if (input.field) { const oldHarmonicRadius = m.harmonicRadius m.harmonicRadius = 0.985 * m.harmonicRadius + 0.015 * 2.5 - m.energy -= 0.35 * (m.harmonicRadius - oldHarmonicRadius) + m.energy -= 0.1 * (m.harmonicRadius - oldHarmonicRadius) } else { - m.harmonicRadius = 0.997 * m.harmonicRadius + 0.003 * 1 + m.harmonicRadius = 0.995 * m.harmonicRadius + 0.005 } } m.harmonicShield() @@ -1596,6 +1600,86 @@ const m = { m.fieldShieldingScale = 0; m.fieldBlockCD = 4; m.grabPowerUpRange2 = 10000000 + m.fieldPosition = { x: m.pos.x, y: m.pos.y } + m.fieldAngle = m.angle + m.perfectPush = (isFree = false) => { + for (let i = 0, len = mob.length; i < len; ++i) { + if ( + Vector.magnitude(Vector.sub(mob[i].position, m.fieldPosition)) - mob[i].radius < m.fieldRange && + !mob[i].isShielded && + Vector.dot({ x: Math.cos(m.fieldAngle), y: Math.sin(m.fieldAngle) }, Vector.normalise(Vector.sub(mob[i].position, m.fieldPosition))) > m.fieldThreshold && + Matter.Query.ray(map, mob[i].position, m.fieldPosition).length === 0 + ) { + mob[i].locatePlayer(); + m.fieldCDcycle = m.cycle + m.fieldBlockCD; + if (tech.blockingIce) { + for (let i = 0; i < tech.blockingIce; i++) b.iceIX(10, m.fieldAngle + Math.random() - 0.5, m.fieldPosition) + } + const unit = Vector.normalise(Vector.sub(m.fieldPosition, mob[i].position)) + if (tech.blockDmg) { + mob[i].damage(tech.blockDmg * b.dmgScale) + //draw electricity + const step = 40 + ctx.beginPath(); + for (let i = 0, len = 1.5 * tech.blockDmg; i < len; i++) { + let x = m.fieldPosition.x - 20 * unit.x; + let y = m.fieldPosition.y - 20 * unit.y; + ctx.moveTo(x, y); + for (let i = 0; i < 8; i++) { + x += step * (-unit.x + 1.5 * (Math.random() - 0.5)) + y += step * (-unit.y + 1.5 * (Math.random() - 0.5)) + ctx.lineTo(x, y); + } + } + ctx.lineWidth = 3; + ctx.strokeStyle = "#f0f"; + ctx.stroke(); + } else if (!isFree) { + //when blocking draw this graphic + const eye = 15; + const len = mob[i].vertices.length - 1; + ctx.fillStyle = "rgba(110,170,200," + (0.2 + 0.4 * Math.random()) + ")"; + ctx.lineWidth = 1; + ctx.strokeStyle = "#000"; + ctx.beginPath(); + ctx.moveTo(m.fieldPosition.x + eye * Math.cos(m.fieldAngle), m.fieldPosition.y + eye * Math.sin(m.fieldAngle)); + ctx.lineTo(mob[i].vertices[len].x, mob[i].vertices[len].y); + ctx.lineTo(mob[i].vertices[0].x, mob[i].vertices[0].y); + ctx.fill(); + ctx.stroke(); + for (let j = 0; j < len; j++) { + ctx.beginPath(); + ctx.moveTo(m.fieldPosition.x + eye * Math.cos(m.fieldAngle), m.fieldPosition.y + eye * Math.sin(m.fieldAngle)); + ctx.lineTo(mob[i].vertices[j].x, mob[i].vertices[j].y); + ctx.lineTo(mob[i].vertices[j + 1].x, mob[i].vertices[j + 1].y); + ctx.fill(); + ctx.stroke(); + } + } + if (tech.isStunField) mobs.statusStun(mob[i], tech.isStunField) + //knock backs + const massRoot = Math.sqrt(Math.max(0.15, mob[i].mass)); // masses above 12 can start to overcome the push back + Matter.Body.setVelocity(mob[i], { + x: player.velocity.x - (20 * unit.x) / massRoot, + y: player.velocity.y - (20 * unit.y) / massRoot + }); + if (mob[i].isOrbital) Matter.Body.setVelocity(mob[i], { x: 0, y: 0 }); + if (isFree) { + + } else { + if (mob[i].isDropPowerUp && player.speed < 12) { + const massRootCap = Math.sqrt(Math.min(10, Math.max(0.4, mob[i].mass))); // masses above 12 can start to overcome the push back + Matter.Body.setVelocity(player, { + x: 0.9 * player.velocity.x + 0.6 * unit.x * massRootCap, + y: 0.9 * player.velocity.y + 0.6 * unit.y * massRootCap + }); + } + } + + } + } + } + m.hold = function() { const wave = Math.sin(m.cycle * 0.022); m.fieldRange = 170 + 12 * wave @@ -1608,7 +1692,9 @@ const m = { } else if ((input.field && m.fieldCDcycle < m.cycle)) { //not hold but field button is pressed m.grabPowerUp(); m.lookForPickUp(); - //draw field + m.fieldPosition = { x: m.pos.x, y: m.pos.y } + m.fieldAngle = m.angle + //draw field attached to player 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()) + ")" @@ -1632,14 +1718,30 @@ const m = { 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(); + // m.pushMobsFacing(); + m.perfectPush(); } else if (m.holdingTarget && m.fieldCDcycle < m.cycle) { //holding, but field button is released m.pickUp(); } else { m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists) + if (tech.isFieldFree && !input.field && m.fieldCDcycle < m.cycle) { + //draw field free of player + 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.fieldPosition.x, m.fieldPosition.y, m.fieldRange, m.fieldAngle - Math.PI * m.fieldArc, m.fieldAngle + Math.PI * m.fieldArc, false); + ctx.lineWidth = 2.5 - 1.5 * wave; + ctx.lineCap = "butt" + ctx.stroke(); + const curve = 0.8 + 0.06 * wave + const aMag = (1 - curve * 1.2) * Math.PI * m.fieldArc + let a = m.fieldAngle + aMag + ctx.quadraticCurveTo(m.fieldPosition.x + curve * m.fieldRange * Math.cos(a), m.fieldPosition.y + curve * m.fieldRange * Math.sin(a), m.fieldPosition.x + 1 * m.fieldRange * Math.cos(m.fieldAngle - Math.PI * m.fieldArc), m.fieldPosition.y + 1 * m.fieldRange * Math.sin(m.fieldAngle - Math.PI * m.fieldArc)) + ctx.fill(); + m.perfectPush(true); + } } m.drawFieldMeter() - if (tech.isPerfectBrake) { //cap mob speed around player const range = 160 + 140 * wave + 200 * m.energy for (let i = 0; i < mob.length; i++) { diff --git a/js/powerup.js b/js/powerup.js index 6d001ee..c1ccc64 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -723,7 +723,7 @@ const powerUps = { powerUps.spawn(x, y, "tech"); return; } - if (Math.random() < 0.006) { + if (Math.random() < 0.003) { powerUps.spawn(x, y, "field"); return; } diff --git a/js/simulation.js b/js/simulation.js index 3cc9f70..3cf1e5f 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -853,7 +853,10 @@ const simulation = { } if (!(simulation.cycle % 420)) { //once every 7 seconds - + if (tech.isZeno) { + m.health *= 0.9 + m.displayHealth(); + } if (tech.cyclicImmunity && m.immuneCycle < m.cycle + tech.cyclicImmunity) m.immuneCycle = m.cycle + tech.cyclicImmunity; //player is immune to damage for 60 cycles fallCheck = function(who, save = false) { diff --git a/js/tech.js b/js/tech.js index 500d2dc..a3d7969 100644 --- a/js/tech.js +++ b/js/tech.js @@ -1589,6 +1589,42 @@ tech.throwChargeRate = 1 } }, + { + name: "inflation", + description: "throwing a block expands it by 300%
increase throw charge rate by 200%", + maxCount: 1, + count: 0, + frequency: 3, + frequencyDefault: 3, + allowed() { + return (tech.throwChargeRate > 1 || m.fieldUpgrades[m.fieldMode].name === "pilot wave") && !tech.isBlockExplosion + }, + requires: "mass driver, not pilot wave not tokamak", + effect() { + tech.isAddBlockMass = true + }, + remove() { + tech.isAddBlockMass = false + } + }, + { + name: "restitution", + description: "throwing a block makes it very bouncy
increase block collision damage by 150%", + maxCount: 1, + count: 0, + frequency: 3, + frequencyDefault: 3, + allowed() { + return (tech.throwChargeRate > 1 || m.fieldUpgrades[m.fieldMode].name === "pilot wave") && !tech.isBlockExplosion + }, + requires: "mass driver, not pilot wave not tokamak", + effect() { + tech.isBlockRestitution = true + }, + remove() { + tech.isBlockRestitution = false + } + }, { name: "flywheel", description: "after a mob dies its block is flung at mobs
increase block collision damage by 150%", @@ -1607,24 +1643,6 @@ tech.isMobBlockFling = false } }, - { - name: "restitution", - description: "throwing a block makes it very bouncy
increase block collision damage by 150%", - maxCount: 1, - count: 0, - frequency: 3, - frequencyDefault: 3, - allowed() { - return (tech.throwChargeRate > 1 || m.fieldUpgrades[m.fieldMode].name === "pilot wave") && !tech.isBlockExplosion - }, - requires: "mass driver, not pilot wave not tokamak", - effect() { - tech.isBlockRestitution = true - }, - remove() { - tech.isBlockRestitution = false - } - }, // { // name: "fermions", // description: "blocks thrown by you or pilot wave will
collide with intangible mobs, but not you", @@ -1661,24 +1679,6 @@ tech.isBlockHarm = false } }, - { - name: "inflation", - description: "throwing a block expands it by 300%
increase throw charge rate by 200%", - maxCount: 1, - count: 0, - frequency: 3, - frequencyDefault: 3, - allowed() { - return (tech.throwChargeRate > 1 || m.fieldUpgrades[m.fieldMode].name === "pilot wave") && !tech.isBlockExplosion - }, - requires: "mass driver, not pilot wave not tokamak", - effect() { - tech.isAddBlockMass = true - }, - remove() { - tech.isAddBlockMass = false - } - }, { name: "buckling", description: "if a block you threw kills a mob
spawn 1 heal, ammo, or research", @@ -2171,7 +2171,7 @@ allowed() { return (tech.iceEnergy || tech.isWormholeEnergy || tech.isPiezo || tech.isRailEnergyGain || tech.energySiphon || tech.isEnergyRecovery || tech.dynamoBotCount || tech.isFlipFlopEnergy || tech.isBlockExplosion) && tech.energyRegen !== 0.004 && !tech.isEnergyHealth }, - requires: "a way to regen extra energy, but not time crystals", + requires: "a way to regen extra energy, not time crystals", effect: () => { tech.energyRegen = 0; m.fieldRegen = tech.energyRegen; @@ -2186,12 +2186,12 @@ description: "energy protects you instead of health
harm reduction effects provide no benefit", maxCount: 1, count: 0, - frequency: 2, - frequencyDefault: 2, + frequency: 1, + frequencyDefault: 1, allowed() { - return !tech.isAmmoFromHealth && !tech.isNoHeals && !tech.isEnergyLoss && !tech.isPiezo && !tech.isRewindAvoidDeath && !tech.isRewindGun && !tech.isSpeedHarm && m.fieldUpgrades[m.fieldMode].name !== "negative mass field" && !tech.isHealLowHealth && !tech.isTechDamage + return !tech.isZeno && !tech.isAmmoFromHealth && !tech.isNoHeals && !tech.isEnergyLoss && !tech.isPiezo && !tech.isRewindAvoidDeath && !tech.isRewindGun && !tech.isSpeedHarm && m.fieldUpgrades[m.fieldMode].name !== "negative mass field" && !tech.isHealLowHealth && !tech.isTechDamage }, - requires: "not exothermic process, piezoelectricity, CPT, 1st law, negative mass , ...", + requires: "not exothermic, Zeno, piezoelectricity, CPT, 1st law, negative mass, ...", effect: () => { m.health = 0 document.getElementById("health").style.display = "none" @@ -2216,8 +2216,8 @@ description: "each heal power up you collect
increases your maximum energy by 6", maxCount: 1, count: 0, - frequency: 3, - frequencyDefault: 3, + frequency: 2, + frequencyDefault: 2, allowed() { return tech.isEnergyHealth && !tech.isNoHeals }, @@ -2499,6 +2499,25 @@ tech.isHarmReduceAfterKill = false; } }, + { + name: "Zeno's paradox", + description: "reduce harm by 84%, but every 5 seconds
remove 1/10 of your current health", + // description: "every 5 seconds remove 1/10 of your health
reduce harm by 90%", + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return !tech.isEnergyHealth + }, + requires: "not mass-energy", + effect() { + tech.isZeno = true; + }, + remove() { + tech.isZeno = false; + } + }, { name: "negative feedback", description: "increase damage by 5%
for every 10 health below 100", @@ -3059,7 +3078,7 @@ }, { name: "metastability", - description: "20% chance to duplicate spawned power ups
duplicates explode with a 3 second half-life", + description: "20% chance to duplicate spawned power ups
duplicates explode with a 3 second half-life ", maxCount: 1, count: 0, frequency: 1, @@ -5283,6 +5302,25 @@ tech.isPerfectBrake = false; } }, + { + name: "Lenz's law", + description: "after deactivation perfect diamagnetism
maintains at the location you left it", + isFieldTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism" + }, + requires: "perfect diamagnetism", + effect() { + tech.isFieldFree = true; + }, + remove() { + tech.isFieldFree = false; + } + }, { name: "tessellation", description: "use 4 research
reduce harm by 50%", @@ -7732,5 +7770,7 @@ isFoamShot: null, isIceShot: null, isNeedleShot: null, - isBlockRestitution: null + isBlockRestitution: null, + isZeno: null, + isFieldFree: null } \ No newline at end of file diff --git a/todo.txt b/todo.txt index ae25b36..572de14 100644 --- a/todo.txt +++ b/todo.txt @@ -1,23 +1,21 @@ ******************************************************** NEXT PATCH ******************************************************** -tech: restitution: thrown blocks are bouncy and blocks do 150% more damage - the tech previously named restitution is now named buckling - -after getting a bot upgrade, future bot tech will be for the upgraded bot type - (doesn't effect tech that gives random bots) - -bug fixes +tech: Lenz's law -perfect diamagnetism field stays when you aren't holding field +tech: Zeno's paradox - every 5s lose 10% of your current health, but get 84% harm reduction ******************************************************** TODO ******************************************************** -using worming makes you immune to harm and drains energy until you run out +remove cooldown on perfect diamagnetism? + make another var that tracks cooldown for other stuff? + like damage effects + +is lab gun room always backwards? + +using wormhole makes you immune to harm and drains energy until you run out disable incoming energy, by saving current energy and just setting energy in the next cycle to be lower then the saved value pink seeker boss is cool as heck, make an alt version of it -perfect diamagnetism field stays when you aren't holding field - good for perfect because it doesn't use energy - holding field moves it the player block shattering get code from planetesimals