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
This commit is contained in:
landgreen
2021-07-30 09:47:50 -07:00
parent c7c837672e
commit 1a5071cf06
7 changed files with 212 additions and 70 deletions

BIN
.DS_Store vendored

Binary file not shown.

View File

@@ -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)

View File

@@ -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++) {

View File

@@ -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;
}

View File

@@ -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) {

View File

@@ -1589,6 +1589,42 @@
tech.throwChargeRate = 1
}
},
{
name: "inflation",
description: "<strong>throwing</strong> a <strong class='color-block'>block</strong> expands it by <strong>300%</strong><br>increase <strong>throw</strong> charge rate by <strong>200%</strong>",
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: "<strong>throwing</strong> a <strong class='color-block'>block</strong> makes it very <strong>bouncy</strong><br>increase <strong class='color-block'>block</strong> collision <strong class='color-d'>damage</strong> by <strong>150%</strong>",
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 <strong>dies</strong> its <strong class='color-block'>block</strong> is <strong>flung</strong> at mobs<br>increase <strong class='color-block'>block</strong> collision <strong class='color-d'>damage</strong> by <strong>150%</strong>",
@@ -1607,24 +1643,6 @@
tech.isMobBlockFling = false
}
},
{
name: "restitution",
description: "throwing a <strong class='color-block'>block</strong> makes it very <strong>bouncy</strong><br>increase <strong class='color-block'>block</strong> collision <strong class='color-d'>damage</strong> by <strong>150%</strong>",
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: "<strong class='color-block'>blocks</strong> thrown by you or <strong>pilot wave</strong> will<br><strong>collide</strong> with <strong>intangible</strong> mobs, but not you",
@@ -1661,24 +1679,6 @@
tech.isBlockHarm = false
}
},
{
name: "inflation",
description: "<strong>throwing</strong> a <strong class='color-block'>block</strong> expands it by <strong>300%</strong><br>increase <strong>throw</strong> charge rate by <strong>200%</strong>",
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 <strong class='color-block'>block</strong> you threw kills a mob<br>spawn <strong>1</strong> <strong class='color-h'>heal</strong>, <strong class='color-g'>ammo</strong>, or <strong class='color-r'>research</strong>",
@@ -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: "<strong class='color-f'>energy</strong> protects you instead of <strong class='color-h'>health</strong><br><strong class='color-harm'>harm</strong> <strong>reduction</strong> effects provide <strong>no</strong> 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 <strong class='color-h'>heal</strong> <strong>power up</strong> you collect<br>increases your <strong>maximum</strong> <strong class='color-f'>energy</strong> by <strong>6</strong>",
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 <strong class='color-harm'>harm</strong> by <strong>84%</strong>, but every <strong>5</strong> seconds<br>remove <strong>1/10</strong> of your current <strong class='color-h'>health</strong>",
// description: "every <strong>5</strong> seconds remove <strong>1/10</strong> of your <strong class='color-h'>health</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>90%</strong>",
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 <strong class='color-d'>damage</strong> by <strong>5%</strong><br>for every <strong>10</strong> <strong class='color-h'>health</strong> below <strong>100</strong>",
@@ -3059,7 +3078,7 @@
},
{
name: "metastability",
description: "<strong>20%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br><strong class='color-dup'>duplicates</strong> <strong class='color-e'>explode</strong> with a <strong>3</strong> second half-life",
description: "<strong>20%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br><strong class='color-dup'>duplicates</strong> <strong class='color-e'>explode</strong> with a <strong>3</strong> second <strong>half-life</strong> ",
maxCount: 1,
count: 0,
frequency: 1,
@@ -5283,6 +5302,25 @@
tech.isPerfectBrake = false;
}
},
{
name: "Lenz's law",
description: "after deactivation <strong>perfect diamagnetism</strong><br>maintains at the <strong>location</strong> 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 <strong>4</strong> <strong class='color-r'>research</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>50%</strong>",
@@ -7732,5 +7770,7 @@
isFoamShot: null,
isIceShot: null,
isNeedleShot: null,
isBlockRestitution: null
isBlockRestitution: null,
isZeno: null,
isFieldFree: null
}

View File

@@ -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