new favicon
heal power up overheals don't consume the entire heal power up

accretion works with all fields except wormhole
  (only because wormhole eat up heals so it's bad)
  spawns 6 -> 3 heals

pilot wave 1 -> 2 extra power up choices
standing wave 66 -> 150 max energy
electronegativity  0.1% -> 0.15% energy per energy  (10->15% damage at 100 energy)

a few more images
bug fixes
This commit is contained in:
landgreen
2023-03-31 07:32:38 -07:00
parent c6144515cd
commit 1752453c1d
18 changed files with 207 additions and 188 deletions

View File

@@ -3439,7 +3439,7 @@ const b = {
for (let i = 0, len = powerUp.length; i < len; ++i) { //grab, but don't lock onto nearby power up
if (
Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 20000 &&
(powerUp[i].name !== "heal" || m.health < 0.94 * m.maxHealth || tech.isDroneGrab) &&
(powerUp[i].name !== "heal" || m.health < 0.93 * m.maxHealth || tech.isDroneGrab) &&
(powerUp[i].name !== "field" || !tech.isSuperDeterminism)
// &&(b.inventory.length > 1 || powerUp[i].name !== "ammo" || b.guns[b.activeGun].ammo !== Infinity || tech.isDroneGrab)
) {
@@ -3470,7 +3470,7 @@ const b = {
let closeDist = Infinity;
for (let i = 0, len = powerUp.length; i < len; ++i) {
if (
(powerUp[i].name !== "heal" || m.health < 0.94 * m.maxHealth || tech.isDroneGrab) &&
(powerUp[i].name !== "heal" || m.health < 0.93 * m.maxHealth || tech.isDroneGrab) &&
(powerUp[i].name !== "field" || !tech.isSuperDeterminism)
// &&(b.inventory.length > 1 || powerUp[i].name !== "ammo" || b.guns[b.activeGun].ammo !== Infinity || tech.isDroneGrab)
) {
@@ -3647,7 +3647,7 @@ const b = {
for (let i = 0, len = powerUp.length; i < len; ++i) {
if (
Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 20000 &&
(powerUp[i].name !== "heal" || m.health < 0.94 * m.maxHealth || tech.isDroneGrab) &&
(powerUp[i].name !== "heal" || m.health < 0.93 * m.maxHealth || tech.isDroneGrab) &&
(powerUp[i].name !== "field" || !tech.isSuperDeterminism)
// &&(powerUp[i].name !== "ammo" || b.guns[b.activeGun].ammo !== Infinity || tech.isDroneGrab)
) {
@@ -3679,7 +3679,7 @@ const b = {
let closeDist = Infinity;
for (let i = 0, len = powerUp.length; i < len; ++i) {
if (
(powerUp[i].name !== "heal" || m.health < 0.94 * m.maxHealth || tech.isDroneGrab) &&
(powerUp[i].name !== "heal" || m.health < 0.93 * m.maxHealth || tech.isDroneGrab) &&
(powerUp[i].name !== "field" || !tech.isSuperDeterminism)
// &&(powerUp[i].name !== "ammo" || b.guns[b.activeGun].ammo !== Infinity || tech.isDroneGrab)
) {
@@ -4988,7 +4988,7 @@ const b = {
cd: 0,
fireCount: 0,
fireLimit: 5 + 2 * tech.isFoamBotUpgrade,
delay: Math.floor((200 + (tech.isFoamBotUpgrade ? 0 : 300)) * b.fireCDscale),// + 30 - 20 * tech.isFoamBotUpgrade,//20 + Math.floor(85 * b.fireCDscale) - 20 * tech.isFoamBotUpgrade,
delay: Math.floor((175 + (tech.isFoamBotUpgrade ? 0 : 250)) * b.fireCDscale),// + 30 - 20 * tech.isFoamBotUpgrade,//20 + Math.floor(85 * b.fireCDscale) - 20 * tech.isFoamBotUpgrade,
acceleration: 0.005 * (1 + 0.5 * Math.random()),
range: 60 * (1 + 0.3 * Math.random()) + 3 * b.totalBots(), //how far from the player the bot will move
endCycle: Infinity,
@@ -7161,7 +7161,7 @@ const b = {
}
}, {
name: "drones", //7
description: "deploy drones that <strong>crash</strong> into mobs<br>or <strong>collect</strong> nearby power ups", //crashes reduce their <strong>lifespan</strong> by 1 second
description: "deploy <strong>autonomous</strong> drones that <strong>smash</strong> into mobs<br>and <strong>collect</strong> nearby power ups", //crashes reduce their <strong>lifespan</strong> by 1 second
ammo: 0,
ammoPack: 16,
defaultAmmoPack: 16,

View File

@@ -23,7 +23,7 @@ const level = {
// spawn.setSpawnList();
// m.maxHealth = m.health = 100
// tech.isRerollDamage = true
// powerUps.research.changeRerolls(500)
// powerUps.research.changeRerolls(11)
// m.immuneCycle = Infinity //you can't take damage
// tech.tech[297].frequency = 100
// m.couplingChange(5)
@@ -35,13 +35,13 @@ const level = {
// b.guns[3].ammo = 100000000
// tech.giveTech("recycling")
// tech.giveTech("pressure vessel")
// for (let i = 0; i < 1; ++i) tech.giveTech("cavitation")
// for (let i = 0; i < 1; ++i) tech.giveTech("bot fabrication")
// for (let i = 0; i < 1; ++i) tech.giveTech("accretion")
// for (let i = 0; i < 1; ++i) tech.giveTech("superdeterminism")
// requestAnimationFrame(() => { for (let i = 0; i < 1; i++) tech.giveTech("foam-bot") });
// for (let i = 0; i < 1; i++) tech.giveTech("foam-bot upgrade")
// for (let i = 0; i < 3; i++) powerUps.directSpawn(450, -50, "tech");
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "boost");
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "research");
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "coupling");
// level.testing();
// spawn.nodeGroup(3200, -300, "sniper")
@@ -59,6 +59,7 @@ const level = {
// spawn.tetherBoss(1900, -500, { x: 1900, y: -500 })
// for (let i = 0; i < 40; ++i) tech.giveTech()
level[simulation.isTraining ? "walk" : "intro"]() //normal starting level ************************************************
// simulation.isAutoZoom = false; //look in close
@@ -1314,7 +1315,7 @@ const level = {
Matter.Body.setVelocity(bullet[i], { x: 0, y: 0 });
}
}
if (tech.isHealAttract && (m.fieldMode === 3 || m.fieldMode === 5)) {
if (tech.isHealAttract) { //send heals to next portal
for (let i = 0; i < powerUp.length; i++) {
if (powerUp[i].name === "heal" && Vector.magnitudeSquared(Vector.sub(powerUp[i].position, m.pos)) < 1000000) {
Matter.Body.setPosition(powerUp[i], Vector.add(this.portalPair.portal.position, { x: 500 * (Math.random() - 0.5), y: 500 * (Math.random() - 0.5) }));
@@ -15999,9 +16000,12 @@ const level = {
commandeer() {
simulation.makeTextLog(`<strong>commandeer</strong> by <span class='color-var'>Desboot</span>`);
let waterFallWidth = 400
let waterFallX = 15900
let waterFallSmoothX = 0
const elevator = level.elevator(-80.4, -931.6, 180, 50, -1550)
15900 && player.position.x < 16300 && player.position.y > -960.2
const slime = level.hazard(15900, -960, 400, 6000);
//const slime = level.hazard(15900, -960, 400, 6000);
const slime2 = level.hazard(15147.2, -1782.4, 2000, 822);
const boost1 = level.boost(5950, -20, 700)
const boost2 = level.boost(21088, -1672, 700)
@@ -16037,7 +16041,6 @@ const level = {
//spawn.mapRect(22330, -804.25, 400, 800);//-46.25*3
ctx.fillStyle = "rgba(250,250,250,0.8)"//lights
ctx.beginPath()
ctx.moveTo(1124, -628)
@@ -16073,7 +16076,6 @@ const level = {
ctx.fillRect(6237, -1830.7, 550, 700)
ctx.fillRect(6237, -840.4, 550, 700)
ctx.fillRect(15845.0, -1262.2, 550, 300)
ctx.fillStyle = "rgba(200,200,200,0.8)"
ctx.fillRect(-192, -1973, 6484, 2071)
ctx.fillStyle = "rgba(240,240,240,0.8)"
@@ -16099,12 +16101,10 @@ const level = {
buttonDoor3.draw();
slime.query();
//slime.query();
slime2.query();
ctx.fillStyle = `hsla(160, 100%, 43%,${0.3 + 0.07 * Math.random()})`
ctx.fillRect(15900 + 400 * Math.random(), -1360, 2, 6000)
ctx.fillRect(15900 + 400 * Math.random(), -1360, 2, 6000)
if (buttonDoor.isUp) {
door.isClosing = true
} else {
@@ -16172,6 +16172,17 @@ const level = {
ctx.fillRect(20820, -243, 410, 300)
ctx.fillRect(5772, -609, 469, 700)
ctx.fillRect(5772, -609, 469, 700)
ctx.fillStyle = "rgba(48,184,140,255)"
ctx.fillRect(waterFallX, -960, waterFallWidth, 6000)
ctx.fillStyle = `hsla(160, 100%, 43%,${0.3 + 0.07 * Math.random()})`
ctx.fillRect(waterFallX + waterFallWidth * Math.random(), -900 - Math.random() * 400, Math.random() * 5 + 8, 6000)
ctx.fillRect(waterFallX + waterFallWidth * Math.random(), -900 - Math.random() * 400, Math.random() * 5 + 5, 6000)
waterFallWidth = 0.995 * waterFallWidth + 4 * Math.random()//4.7
waterFalSmoothlX = 0.96 * waterFallSmoothX + 20 * Math.random()//3.5
waterFallX = waterFallSmoothX + 15900
ctx.fillStyle = "rgba(0,0,0,0.4)"//wires
ctx.fillRect(20990, -2672, 20, 112)
ctx.fillRect(21090, -2506, 72, 20)
@@ -16304,7 +16315,7 @@ const level = {
if (player.position.x > 15900 && player.position.x < 16300 && player.position.y > -1360.2) {
Matter.Body.setVelocity(player, {
x: player.velocity.x,
y: player.velocity.y + 10
y: player.velocity.y + 2
});
} else {
if (Math.abs(player.velocity.x) > 0.5) {
@@ -16576,9 +16587,7 @@ const level = {
let randomBoss = Math.floor(Math.random() * 5);//change the bosses
spawn[["blinkBoss", "shooterBoss", "launcherBoss", "pulsarBoss", "beetleBoss", "bladeBoss", "revolutionBoss", "dragonFlyBoss", "spiderBoss"][randomBoss]](17902, -1689, 100, false);
spawn.randomLevelBoss(17902, -1689, ["blinkBoss", "shooterBoss", "launcherBoss", "pulsarBoss", "blockBoss", "bladeBoss", "revolutionBoss", "spawnerBossCulture", "spiderBoss", "sneakBoss", "snakeSpitBoss"])
// powerUps.spawnStartingPowerUps(1475, -1175);
@@ -18373,19 +18382,6 @@ const level = {
ctx.fill()
ctx.fillRect(6100, -2000, 400, 50)
// -2000 -> 2500
// Math.random() * 5000 -2500
ctx.fillStyle = "rgba(0,0,0,0.6)"

View File

@@ -201,7 +201,7 @@ const mobs = {
}
}
},
endEffect() {},
endEffect() { },
dmg: tickDamage,
type: "dot",
endCycle: simulation.cycle + cycles,
@@ -506,7 +506,7 @@ const mobs = {
}
},
laser() {
const vertexCollision = function(v1, v1End, domain) {
const vertexCollision = function (v1, v1End, domain) {
for (let i = 0; i < domain.length; ++i) {
let vertices = domain[i].vertices;
const len = vertices.length - 1;
@@ -658,7 +658,7 @@ const mobs = {
ctx.fillStyle = "rgba(0,0,0,0.07)";
ctx.fill();
//spring to random place on map
const vertexCollision = function(v1, v1End, domain) {
const vertexCollision = function (v1, v1End, domain) {
for (let i = 0; i < domain.length; ++i) {
let vertices = domain[i].vertices;
const len = vertices.length - 1;
@@ -756,7 +756,7 @@ const mobs = {
},
curl(range = 1000, mag = -10) {
//cause all mobs, and bodies to rotate in a circle
applyCurl = function(center, array, isAntiGravity = true) {
applyCurl = function (center, array, isAntiGravity = true) {
for (let i = 0; i < array.length; ++i) {
if (!array[i].isNotHoldable) {
const sub = Vector.sub(center, array[i].position)
@@ -924,7 +924,7 @@ const mobs = {
//be sure to declare searchTarget in mob spawn
//accelerate towards the searchTarget
if (!this.seePlayer.recall) {
const newTarget = function(that) {
const newTarget = function (that) {
if (Math.random() < 0.0007) {
that.searchTarget = player.position; //chance to target player
} else {
@@ -1297,7 +1297,7 @@ const mobs = {
}
if (tech.cloakDuplication && !this.isBoss) {
tech.cloakDuplication -= 0.02
powerUps.setDupChance(); //needed after adjusting duplication chance
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
}
} else if (tech.isShieldAmmo && this.shield && !this.isExtraShield) {
let type = tech.isEnergyNoAmmo ? "heal" : "ammo"
@@ -1350,7 +1350,7 @@ const mobs = {
for (let i = 0, len = consBB.length; i < len; ++i) {
if (consBB[i].bodyA === this) {
if (consBB[i].bodyB.shield) { //&& !this.shield
consBB[i].bodyB.do = function() { this.death() }
consBB[i].bodyB.do = function () { this.death() }
}
consBB[i].bodyA = consBB[i].bodyB;
consBB.splice(i, 1);
@@ -1358,7 +1358,7 @@ const mobs = {
break;
} else if (consBB[i].bodyB === this) {
if (consBB[i].bodyA.shield) {
consBB[i].bodyA.do = function() { this.death() }
consBB[i].bodyA.do = function () { this.death() }
}
consBB[i].bodyB = consBB[i].bodyA;
consBB.splice(i, 1);
@@ -1415,7 +1415,7 @@ const mobs = {
//large mobs shrink so they don't block paths
if (body[len].mass + body[len2].mass > 16) {
const massLimit = 8 + 6 * Math.random()
const shrink = function(that1, that2) {
const shrink = function (that1, that2) {
if (that1.mass + that2.mass > massLimit) {
const scale = 0.95;
Matter.Body.scale(that1, scale, scale);
@@ -1438,7 +1438,7 @@ const mobs = {
//large mobs shrink so they don't block paths
if (body[len].mass > 9) {
const massLimit = 7 + 4 * Math.random()
const shrink = function(that) {
const shrink = function (that) {
if (that.mass > massLimit) {
const scale = 0.95;
Matter.Body.scale(that, scale, scale);

View File

@@ -916,6 +916,48 @@ const m = {
none() {
m.isAltSkin = true
},
favicon() { //used to render the favicon, not actually in game
m.yOffWhen.jump = 70
m.yOffWhen.stand = 49
m.yOffWhen.crouch = 22
m.isAltSkin = false
m.color = {
hue: 0,
sat: 0,
light: 100,
}
m.fillColor = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light}%)`
m.fillColorDark = `hsl(${m.color.hue},${m.color.sat}%,${m.color.light - 10}%)`
let grd = ctx.createLinearGradient(-30, 0, 30, 0);
grd.addColorStop(0, m.fillColorDark);
grd.addColorStop(1, m.fillColor);
m.bodyGradient = grd
m.draw = function () {
ctx.fillStyle = m.fillColor;
m.walk_cycle += m.flipLegs * m.Vx;
ctx.save();
ctx.globalAlpha = (m.immuneCycle < m.cycle) ? 1 : 0.5 //|| (m.cycle % 40 > 20)
ctx.translate(m.pos.x, m.pos.y);
// m.calcLeg(Math.PI, -3);
// m.drawLeg("#4a4a4a");
// m.calcLeg(0, 0);
// m.drawLeg("#333");
// ctx.rotate(m.angle);
ctx.beginPath();
ctx.arc(0, 0, 30, 0, 2 * Math.PI);
ctx.fillStyle = m.bodyGradient
ctx.fill();
ctx.arc(12, 0, 4.5, 0, 2 * Math.PI);
ctx.strokeStyle = "#333";
ctx.lineWidth = 4.5;
ctx.stroke();
ctx.restore();
m.yOff = m.yOff * 0.85 + m.yOffGoal * 0.15; //smoothly move leg height towards height goal
powerUps.boost.draw()
}
},
mech() {
m.isAltSkin = true
m.yOffWhen.stand = 52
@@ -1801,11 +1843,11 @@ const m = {
m.fieldThreshold = Math.cos((m.fieldArc) * Math.PI)
},
setHoldDefaults() {
if (tech.isFreeWormHole && m.fieldUpgrades[m.fieldMode].name !== "wormhole") {
if (tech.isFreeWormHole && m.fieldMode !== 9) { //not wormhole
const removed = tech.removeTech("charmed baryon") //neutronum can get player stuck so it has to be removed if player has wrong field
if (removed) powerUps.directSpawn(m.pos.x, m.pos.y, "tech");
}
if (tech.isNeutronium && m.fieldUpgrades[m.fieldMode].name !== "negative mass") {
if (tech.isNeutronium && m.fieldMode !== 3) { //not negative mass field
const removed = tech.removeTech("neutronium") //neutronum can get player stuck so it has to be removed if player has wrong field
if (removed) powerUps.directSpawn(m.pos.x, m.pos.y, "tech");
}
@@ -1854,7 +1896,7 @@ const m = {
},
setMaxEnergy() {
// (m.fieldMode === 0 || m.fieldMode === 1) * 0.4 * m.coupling +
m.maxEnergy = (tech.isMaxEnergyTech ? 0.5 : 1) + tech.bonusEnergy + tech.healMaxEnergyBonus + tech.harmonicEnergy + 2 * tech.isGroundState + 3 * tech.isRelay * tech.isFlipFlopOn * tech.isRelayEnergy + 0.66 * (m.fieldMode === 1)
m.maxEnergy = (tech.isMaxEnergyTech ? 0.5 : 1) + tech.bonusEnergy + tech.healMaxEnergyBonus + tech.harmonicEnergy + 2 * tech.isGroundState + 3 * tech.isRelay * tech.isFlipFlopOn * tech.isRelayEnergy + 1.5 * (m.fieldMode === 1)
// if (tech.isEnergyHealth) m.maxEnergy *= Math.sqrt(m.defense())
simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-f'>maxEnergy</span> <span class='color-symbol'>=</span> ${(m.maxEnergy.toFixed(2))}`)
},
@@ -2211,7 +2253,7 @@ const m = {
if ( //use power up if it is close enough
dist2 < 5000 &&
!simulation.isChoosing &&
(powerUp[i].name !== "heal" || m.health !== m.maxHealth || tech.isOverHeal)
(powerUp[i].name !== "heal" || m.maxHealth - m.health > 0.01 || tech.isOverHeal)
) {
powerUps.onPickUp(powerUp[i]);
Matter.Body.setVelocity(player, { //player knock back, after grabbing power up
@@ -2471,7 +2513,7 @@ const m = {
// m.setMaxHealth();
m.setFieldRegen()
mobs.setMobSpawnHealth();
powerUps.setDupChance();
powerUps.setPowerUpMode();
if ((m.fieldMode === 0 || m.fieldMode === 9) && !build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.4);
// m.collisionImmuneCycles = 30 + m.coupling * 120 //2 seconds
@@ -2551,7 +2593,7 @@ const m = {
name: "standing wave",
//<strong>deflecting</strong> protects you in every <strong>direction</strong>
description: `<strong>3</strong> oscillating <strong>shields</strong> are permanently active
<br><strong>+66</strong> max <strong class='color-f'>energy</strong>
<br><strong>+150</strong> max <strong class='color-f'>energy</strong>
<br>generate <strong>6</strong> <strong class='color-f'>energy</strong> per second`,
drainCD: 0,
effect: () => {
@@ -2565,7 +2607,7 @@ const m = {
const fieldRange1 = (0.75 + 0.3 * Math.sin(m.cycle / 23)) * m.fieldRange * m.harmonicRadius
const fieldRange2 = (0.68 + 0.37 * Math.sin(m.cycle / 37)) * m.fieldRange * m.harmonicRadius
const fieldRange3 = (0.7 + 0.35 * Math.sin(m.cycle / 47)) * m.fieldRange * m.harmonicRadius
const netfieldRange = Math.max(fieldRange1, fieldRange2, fieldRange3)
const netFieldRange = Math.max(fieldRange1, fieldRange2, fieldRange3)
ctx.fillStyle = "rgba(110,170,200," + Math.min(0.6, (0.04 + m.energy * (0.1 + 0.11 * Math.random()))) + ")";
ctx.beginPath();
ctx.arc(m.pos.x, m.pos.y, fieldRange1, 0, 2 * Math.PI);
@@ -2578,7 +2620,7 @@ const m = {
ctx.fill();
//360 block
for (let i = 0, len = mob.length; i < len; ++i) {
if (Vector.magnitude(Vector.sub(mob[i].position, m.pos)) - mob[i].radius < netfieldRange && !mob[i].isUnblockable) { // && Matter.Query.ray(map, mob[i].position, m.pos).length === 0
if (Vector.magnitude(Vector.sub(mob[i].position, m.pos)) - mob[i].radius < netFieldRange && !mob[i].isUnblockable) { // && Matter.Query.ray(map, mob[i].position, m.pos).length === 0
mob[i].locatePlayer();
if (this.drainCD > m.cycle) {
m.pushMass(mob[i], 0);
@@ -3052,17 +3094,17 @@ const m = {
m.drawRegenEnergy("rgba(0,0,0,0.2)")
if (tech.isHealAttract) {
for (let i = 0; i < powerUp.length; i++) {
if (powerUp[i].name === "heal") {
//&& Vector.magnitudeSquared(Vector.sub(powerUp[i].position, m.pos)) < 500000
let attract = Vector.mult(Vector.normalise(Vector.sub(m.pos, powerUp[i].position)), 0.01 * powerUp[i].mass)
powerUp[i].force.x += attract.x;
powerUp[i].force.y += attract.y - powerUp[i].mass * simulation.g; //negate gravity
Matter.Body.setVelocity(powerUp[i], Vector.mult(powerUp[i].velocity, 0.7));
}
}
}
// if (tech.isHealAttract) {
// for (let i = 0; i < powerUp.length; i++) {
// if (powerUp[i].name === "heal") {
// //&& Vector.magnitudeSquared(Vector.sub(powerUp[i].position, m.pos)) < 500000
// let attract = Vector.mult(Vector.normalise(Vector.sub(m.pos, powerUp[i].position)), 0.01 * powerUp[i].mass)
// powerUp[i].force.x += attract.x;
// powerUp[i].force.y += attract.y - powerUp[i].mass * simulation.g; //negate gravity
// Matter.Body.setVelocity(powerUp[i], Vector.mult(powerUp[i].velocity, 0.7));
// }
// }
// }
// powerUp[i].force.x += 0.05 * (dxP / Math.sqrt(dist2)) * powerUp[i].mass;
@@ -3562,17 +3604,6 @@ const m = {
}
m.drawRegenEnergy("rgba(0, 0, 0, 0.2)")
m.plasmaBall.do()
if (tech.isHealAttract) {
for (let i = 0; i < powerUp.length; i++) {
if (powerUp[i].name === "heal") {
//&& Vector.magnitudeSquared(Vector.sub(powerUp[i].position, m.pos)) < 500000
let attract = Vector.mult(Vector.normalise(Vector.sub(m.pos, powerUp[i].position)), 0.01 * powerUp[i].mass)
powerUp[i].force.x += attract.x;
powerUp[i].force.y += attract.y - powerUp[i].mass * simulation.g; //negate gravity
Matter.Body.setVelocity(powerUp[i], Vector.mult(powerUp[i].velocity, 0.7));
}
}
}
}
} else if (tech.isExtruder) {
m.hold = function () {
@@ -3615,17 +3646,6 @@ const m = {
ctx.lineWidth = tech.extruderRange;
ctx.strokeStyle = "rgba(255,0,110,0.06)"
ctx.stroke();
if (tech.isHealAttract) {
for (let i = 0; i < powerUp.length; i++) {
if (powerUp[i].name === "heal") {
//&& Vector.magnitudeSquared(Vector.sub(powerUp[i].position, m.pos)) < 500000
let attract = Vector.mult(Vector.normalise(Vector.sub(m.pos, powerUp[i].position)), 0.01 * powerUp[i].mass)
powerUp[i].force.x += attract.x;
powerUp[i].force.y += attract.y - powerUp[i].mass * simulation.g; //negate gravity
Matter.Body.setVelocity(powerUp[i], Vector.mult(powerUp[i].velocity, 0.7));
}
}
}
}
} else {
m.hold = function () {
@@ -3644,17 +3664,6 @@ const m = {
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)
}
m.drawRegenEnergy("rgba(0, 0, 0, 0.2)")
if (tech.isHealAttract) {
for (let i = 0; i < powerUp.length; i++) {
if (powerUp[i].name === "heal") {
//&& Vector.magnitudeSquared(Vector.sub(powerUp[i].position, m.pos)) < 500000
let attract = Vector.mult(Vector.normalise(Vector.sub(m.pos, powerUp[i].position)), 0.01 * powerUp[i].mass)
powerUp[i].force.x += attract.x;
powerUp[i].force.y += attract.y - powerUp[i].mass * simulation.g; //negate gravity
Matter.Body.setVelocity(powerUp[i], Vector.mult(powerUp[i].velocity, 0.7));
}
}
}
}
}
},
@@ -4133,7 +4142,7 @@ const m = {
//<br><strong class='color-block'>blocks</strong> can't <strong>collide</strong> with <strong>intangible</strong> mobs
//field <strong>radius</strong> decreases out of <strong>line of sight</strong>
//<strong>unlock</strong> <strong class='color-m'>tech</strong> from other <strong class='color-f'>fields</strong>
description: "use <strong class='color-f'>energy</strong> to guide <strong class='color-block'>blocks</strong><br><strong class='color-m'>tech</strong>, <strong class='color-f'>fields</strong>, and <strong class='color-g'>guns</strong> have <strong>+1</strong> <strong>choice</strong><br>generate <strong>10</strong> <strong class='color-f'>energy</strong> per second",
description: "use <strong class='color-f'>energy</strong> to guide <strong class='color-block'>blocks</strong><br><strong class='color-m'>tech</strong>, <strong class='color-f'>fields</strong>, and <strong class='color-g'>guns</strong> have <strong>+2</strong> <strong>choice</strong><br>generate <strong>10</strong> <strong class='color-f'>energy</strong> per second",
effect: () => {
m.fieldMeterColor = "#333"
m.eyeFillColor = m.fieldMeterColor
@@ -4213,7 +4222,7 @@ const m = {
if (
dist2 < 5000 &&
!simulation.isChoosing &&
(powerUp[i].name !== "heal" || m.health !== m.maxHealth || tech.isOverHeal)
(powerUp[i].name !== "heal" || m.maxHealth - m.health > 0.01 || tech.isOverHeal)
// (powerUp[i].name !== "heal" || m.health < 0.94 * m.maxHealth)
// (powerUp[i].name !== "ammo" || b.guns[b.activeGun].ammo !== Infinity)
) { //use power up if it is close enough
@@ -4340,7 +4349,7 @@ const m = {
m.duplicateChance = 0.03
m.fieldRange = 0
powerUps.setDupChance(); //needed after adjusting duplication chance
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
m.hold = function () {
// m.hole = { //this is reset with each new field, but I'm leaving it here for reference

View File

@@ -165,17 +165,17 @@ const powerUps = {
},
totalPowerUps: 0, //used for tech that count power ups at the end of a level
do() { },
setDupChance() {
setPowerUpMode() {
if (tech.duplicationChance() > 0 || tech.isAnthropicTech) {
if (tech.isPowerUpsVanish) {
powerUps.do = powerUps.doDuplicatesVanish
} else if (tech.isPowerUpsAttract) {
} else if (tech.isHealAttract) {
powerUps.do = powerUps.doAttractDuplicates
} else {
powerUps.do = powerUps.doDuplicates
}
tech.maxDuplicationEvent() //check to see if hitting 100% duplication
} else if (tech.isPowerUpsAttract) {
} else if (tech.isHealAttract) {
powerUps.do = powerUps.doAttract
} else {
powerUps.do = powerUps.doDefault
@@ -194,16 +194,32 @@ const powerUps = {
},
doAttract() {
powerUps.doDefault();
//pull in
for (let i = 0, len = powerUp.length; i < len; ++i) {
const force = Vector.mult(Vector.normalise(Vector.sub(m.pos, powerUp[i].position)), 0.0015 * powerUp[i].mass)
powerUp[i].force.x += force.x
powerUp[i].force.y = force.y - simulation.g
for (let i = 0; i < powerUp.length; i++) { //attract heal power ups to player
if (powerUp[i].name === "heal") {
//&& Vector.magnitudeSquared(Vector.sub(powerUp[i].position, m.pos)) < 500000
let attract = Vector.mult(Vector.normalise(Vector.sub(m.pos, powerUp[i].position)), 0.015 * powerUp[i].mass)
powerUp[i].force.x += attract.x;
powerUp[i].force.y += attract.y - powerUp[i].mass * simulation.g; //negate gravity
Matter.Body.setVelocity(powerUp[i], Vector.mult(powerUp[i].velocity, 0.7));
}
}
// for (let i = 0, len = powerUp.length; i < len; ++i) {
// const force = Vector.mult(Vector.normalise(Vector.sub(m.pos, powerUp[i].position)), 0.0015 * powerUp[i].mass)
// powerUp[i].force.x += force.x
// powerUp[i].force.y = force.y - simulation.g
// }
},
doAttractDuplicates() {
powerUps.doDuplicates();
//pull in
for (let i = 0; i < powerUp.length; i++) { //attract heal power ups to player
if (powerUp[i].name === "heal") {
//&& Vector.magnitudeSquared(Vector.sub(powerUp[i].position, m.pos)) < 500000
let attract = Vector.mult(Vector.normalise(Vector.sub(m.pos, powerUp[i].position)), 0.015 * powerUp[i].mass)
powerUp[i].force.x += attract.x;
powerUp[i].force.y += attract.y - powerUp[i].mass * simulation.g; //negate gravity
Matter.Body.setVelocity(powerUp[i], Vector.mult(powerUp[i].velocity, 0.7));
}
}
},
doDuplicates() { //draw power ups but give duplicates some electricity
ctx.globalAlpha = 0.4 * Math.sin(m.cycle * 0.15) + 0.6;
@@ -448,20 +464,18 @@ const powerUps = {
effect() {
powerUps.research.changeRerolls(1)
},
isMakingBots: false, //to prevent bot fabrication from running 2 sessions at once
changeRerolls(amount) {
if (amount !== 0) {
powerUps.research.count += amount
// if (powerUps.research.count < 0) powerUps.research.count = 0
// else {
// simulation.makeTextLog(`powerUps.research.count <span class='color-symbol'>+=</span> ${amount}`) // <br>${powerUps.research.count}
// }
}
if (tech.isRerollBots) {
if (amount !== 0) powerUps.research.count += amount
if (tech.isRerollBots && !this.isMakingBots) {
let cycle = () => {
const cost = 2 + Math.floor(0.2 * b.totalBots())
if (m.alive && powerUps.research.count >= cost) requestAnimationFrame(cycle);
if (m.alive && powerUps.research.count >= cost) {
requestAnimationFrame(cycle);
this.isMakingBots = true
} else {
this.isMakingBots = false
}
if (!simulation.paused && !simulation.isChoosing && !(simulation.cycle % 60)) {
powerUps.research.count -= cost
b.randomBot()
@@ -476,24 +490,6 @@ const powerUps = {
}
}
requestAnimationFrame(cycle);
// let delay = 0
// for (let cost = 2 + Math.floor(0.2 * b.totalBots()); powerUps.research.count > cost - 1; powerUps.research.count -= cost) { // 1/5 = 0.2
// cost = 2 + Math.floor(0.2 * b.totalBots())
// delay += 500
// setTimeout(() => {
// b.randomBot()
// if (tech.renormalization) {
// for (let i = 0; i < cost; i++) {
// if (Math.random() < 0.44) {
// m.fieldCDcycle = m.cycle + 20;
// powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "research");
// }
// }
// }
// }, delay);
// }
}
if (tech.isDeathAvoid && document.getElementById("tech-anthropic")) {
document.getElementById("tech-anthropic").innerHTML = `-${powerUps.research.count}`
@@ -563,6 +559,11 @@ const powerUps = {
});
tech.extraMaxHealth += scaledOverHeal * simulation.healScale //increase max health
m.setMaxHealth();
} else if (overHeal > 0.1) {
requestAnimationFrame(() => {
powerUps.directSpawn(this.position.x, this.position.y, "heal", true, null, overHeal * 40 * (simulation.healScale ** 0.25))// directSpawn(x, y, target, moving = true, mode = null, size = powerUps[target].size()) {
});
}
}
}
@@ -875,7 +876,7 @@ const powerUps = {
for (let i = 0; i < b.guns.length; i++) {
if (!b.guns[i].have) options.push(i);
}
let totalChoices = Math.min(options.length, (tech.isDeterminism ? 1 : 2 + tech.extraChoices + (m.fieldMode === 8)))
let totalChoices = Math.min(options.length, (tech.isDeterminism ? 1 : 2 + tech.extraChoices + 2 * (m.fieldMode === 8)))
if (tech.isFlipFlopChoices) totalChoices += tech.isRelay ? (tech.isFlipFlopOn ? -1 : 7) : (tech.isFlipFlopOn ? 7 : -1) //flip the order for relay
function removeOption(index) {
for (let i = 0; i < options.length; i++) {
@@ -939,7 +940,7 @@ const powerUps = {
for (let i = 1; i < m.fieldUpgrades.length; i++) { //skip field emitter
if (i !== m.fieldMode) options.push(i);
}
let totalChoices = Math.min(options.length, (tech.isDeterminism ? 1 : 2 + tech.extraChoices + (m.fieldMode === 8)))
let totalChoices = Math.min(options.length, (tech.isDeterminism ? 1 : 2 + tech.extraChoices + 2 * (m.fieldMode === 8)))
if (tech.isFlipFlopChoices) totalChoices += tech.isRelay ? (tech.isFlipFlopOn ? -1 : 7) : (tech.isFlipFlopOn ? 7 : -1) //flip the order for relay
function removeOption(index) {
@@ -1022,7 +1023,7 @@ const powerUps = {
}
}
//set total choices
let totalChoices = (tech.isDeterminism ? 1 : 3 + tech.extraChoices + (m.fieldMode === 8))
let totalChoices = (tech.isDeterminism ? 1 : 3 + tech.extraChoices + 2 * (m.fieldMode === 8))
if (tech.isFlipFlopChoices) totalChoices += tech.isRelay ? (tech.isFlipFlopOn ? -1 : 7) : (tech.isFlipFlopOn ? 7 : -1) //flip the order for relay
if (optionLengthNoDuplicates < totalChoices + 1) { //if not enough options for all the choices
totalChoices = optionLengthNoDuplicates

View File

@@ -943,8 +943,7 @@ const simulation = {
m.hole.isOn = false;
simulation.drawList = [];
//send health power ups to the next level
if (tech.isHealAttract && m.alive && (m.fieldMode === 3 || m.fieldMode === 5)) {
if (tech.isHealAttract && m.alive) { //send health power ups to the next level
let healCount = 0
for (let i = 0, len = powerUp.length; i < len; i++) {
if (powerUp[i].name === "heal" && Vector.magnitudeSquared(Vector.sub(powerUp[i].position, m.pos)) < 1000000) healCount++

View File

@@ -246,7 +246,7 @@ const tech = {
if (tech.isBotDamage) dmg *= 1 + 0.06 * b.totalBots()
if (tech.restDamage > 1 && player.speed < 1) dmg *= tech.restDamage
if (tech.isLowEnergyDamage) dmg *= 1 + 0.7 * Math.max(0, 1 - m.energy)
if (tech.energyDamage) dmg *= 1 + m.energy * 0.1 * tech.energyDamage;
if (tech.energyDamage) dmg *= 1 + m.energy * 0.15 * tech.energyDamage;
if (tech.isDamageFromBulletCount) dmg *= 1 + bullet.length * 0.007
if (tech.isNoFireDamage && m.cycle > m.fireCDcycle + 120) dmg *= 2
if (tech.isSpeedDamage) dmg *= 1 + Math.min(0.66, player.speed * 0.0165)
@@ -1271,6 +1271,7 @@ const tech = {
count: 0,
frequency: 1,
frequencyDefault: 1,
isHealTech: true,
allowed() {
return true
},
@@ -2553,7 +2554,7 @@ const tech = {
{
name: "electronegativity",
descriptionFunction() {
return `<strong>+0.1%</strong> <strong class='color-d'>damage</strong> per current stored <strong class='color-f'>energy</strong><br><em>(+${(10 * m.energy).toFixed(0)}%)</em>`
return `<strong>+0.15%</strong> <strong class='color-d'>damage</strong> per current stored <strong class='color-f'>energy</strong><br><em>(+${(15 * m.energy).toFixed(0)}%)</em>`
},
// description: "<strong>+1%</strong> <strong class='color-d'>damage</strong> per <strong>8</strong> stored <strong class='color-f'>energy</strong>",
maxCount: 9,
@@ -3017,6 +3018,7 @@ const tech = {
count: 0,
frequency: 1,
frequencyDefault: 1,
isHealTech: true,
allowed() {
return !tech.isHealAttract
},
@@ -3028,6 +3030,29 @@ const tech = {
tech.isOverHeal = false;
}
},
{
name: "accretion",
description: `${powerUps.orb.heal(1)} follow you, even between levels<br>spawn ${powerUps.orb.heal(3)}`,
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
isHealTech: true,
allowed() {
return m.fieldMode !== 9 && !tech.isOverHeal
},
requires: "not wormhole, quenching",
effect() {
tech.isHealAttract = true
powerUps.setPowerUpMode();
for (let i = 0; i < 6; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "heal");
},
remove() {
tech.isHealAttract = false
powerUps.setPowerUpMode();
},
},
{
name: "negative entropy",
descriptionFunction() {
@@ -3137,11 +3162,11 @@ const tech = {
requires: "anthropic principle",
effect() {
tech.isAnthropicTech = true
powerUps.setDupChance(); //needed after adjusting duplication chance
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
},
remove() {
tech.isAnthropicTech = false
powerUps.setDupChance(); //needed after adjusting duplication chance
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
}
},
{
@@ -3889,11 +3914,11 @@ const tech = {
requires: "below 100% duplication chance, not superdeterminism",
effect() {
tech.isCancelDuplication = true //search for tech.cancelCount to balance
powerUps.setDupChance(); //needed after adjusting duplication chance
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
},
remove() {
tech.isCancelDuplication = false
powerUps.setDupChance(); //needed after adjusting duplication chance
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
}
},
{
@@ -3909,14 +3934,14 @@ const tech = {
requires: "below 100% duplication chance",
effect() {
tech.duplicateChance += 0.1
powerUps.setDupChance(); //needed after adjusting duplication chance
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.11);
this.refundAmount += tech.addJunkTechToPool(0.33)
},
refundAmount: 0,
remove() {
tech.duplicateChance = 0
powerUps.setDupChance(); //needed after adjusting duplication chance
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
if (this.count > 0 && this.refundAmount > 0) {
tech.removeJunkTechFromPool(this.refundAmount)
this.refundAmount = 0
@@ -3936,12 +3961,12 @@ const tech = {
requires: "below 1% duplication chance",
effect() {
tech.isStimulatedEmission = true
powerUps.setDupChance(); //needed after adjusting duplication chance
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.15);
},
remove() {
tech.isStimulatedEmission = false
powerUps.setDupChance(); //needed after adjusting duplication chance
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
}
},
{
@@ -3957,12 +3982,12 @@ const tech = {
requires: "below 100% duplication chance",
effect() {
tech.isPowerUpsVanish = true
powerUps.setDupChance(); //needed after adjusting duplication chance
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.11);
},
remove() {
tech.isPowerUpsVanish = false
powerUps.setDupChance(); //needed after adjusting duplication chance
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
}
},
{
@@ -7465,26 +7490,6 @@ const tech = {
}
}
},
{
name: "accretion",
description: `${powerUps.orb.heal(1)} follow you, even between levels<br>spawn ${powerUps.orb.heal(6)}`,
isFieldTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return (m.fieldMode === 3 || m.fieldMode === 5) && !tech.isOverHeal
},
requires: "negative mass, plasma torch, not quenching",
effect() {
tech.isHealAttract = true
for (let i = 0; i < 6; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "heal");
},
remove() {
tech.isHealAttract = false
},
},
{
name: "aerostat",
description: `<strong>+88%</strong> <strong class='color-d'>damage</strong> while <strong>off</strong> the <strong>ground</strong><br><strong>-22%</strong> <strong class='color-d'>damage</strong> while <strong>on</strong> the <strong>ground</strong>`,
@@ -8042,9 +8047,9 @@ const tech = {
frequency: 3,
frequencyDefault: 3,
allowed() {
return (m.fieldMode === 6) && (build.isExperimentSelection || powerUps.research.count > 2)
return (m.fieldMode === 6 || m.fieldMode === 8) && (build.isExperimentSelection || powerUps.research.count > 2)
},
requires: "time dilation",
requires: "time dilation or pilot wave",
effect() {
tech.isFastTime = true
m.setMovement();
@@ -8096,12 +8101,12 @@ const tech = {
requires: "cloaking, time dilation, not quantum eraser",
effect() {
tech.cloakDuplication = 0.45
powerUps.setDupChance(); //needed after adjusting duplication chance
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.4);
},
remove() {
tech.cloakDuplication = 0
powerUps.setDupChance(); //needed after adjusting duplication chance
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
}
},
{
@@ -8296,7 +8301,7 @@ const tech = {
requires: "wormhole, time dilation, negative mass, pilot wave",
effect() {
tech.fieldDuplicate = 0.11
powerUps.setDupChance(); //needed after adjusting duplication chance
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.11);
for (let i = 0; i < 4; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
@@ -8304,7 +8309,7 @@ const tech = {
},
remove() {
tech.fieldDuplicate = 0
powerUps.setDupChance(); //needed after adjusting duplication chance
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
if (this.count > 0) powerUps.research.changeRerolls(4)
}
},