minimal HUD

setting - minimal HUD
  remove: defense bar, damage bar, tech, in game console

improved text clarity on coupling
removed tech decoupling

added cloaking and sneak attack graphics
  also, the 50% defense when cloaked is now clear from the defense bar
ternary 44->83% damage but requires current gun to have ammo/3 (was any gun)
wormhole invariant: uses much less energy to pause time
standing wave has less recoil when blocking

new images
bug fixes
This commit is contained in:
landgreen
2023-04-26 19:36:33 -07:00
parent 1b23dec950
commit 0b728fb02c
25 changed files with 759 additions and 606 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 53 KiB

View File

@@ -70,12 +70,15 @@
<label for="seed" title="the randoms seed determines level order, tech choices, and mob types">randomization seed:</label>
<input type="text" id="seed" name="seed" autocomplete="off" spellcheck="false" minlength="1" style="width: 120px;">
<br>
<label for="hide-images" title="hide images for fields, guns, and tech">hide images:</label>
<input onclick="build.showImages('settings')" type="checkbox" id="hide-images" name="hide-images" style="width:17px; height:17px;">
<br>
<span id="previous-seed" style="color:#bbb"></span>
<label for="community-maps" title="add about 12 player made levels the random n-gon level pool">include community maps:</label>
<input onclick="build.showImages('settings')" type="checkbox" id="hide-images" name="hide-images" style="width:17px; height:17px;">
<label for="hide-images" title="hide images for fields, guns, and tech">hide images</label>
<br>
<input onclick="build.hideHUD('settings')" type="checkbox" id="hide-hud" name="hide-hud" style="width:17px; height:17px;">
<label for="hide-hud" title="hide: tech, defense, damage, in game console">minimal HUD</label>
<br>
<input type="checkbox" id="community-maps" name="community-maps" style="width:17px; height:17px;">
<label for="community-maps" title="add about 12 player made levels the random n-gon level pool">community maps</label>
<!-- <br>
<label for="body-damage" title="allow damage from the ground and large fast moving blocks">collision damage from blocks:</label>

View File

@@ -333,8 +333,8 @@ const b = {
// ctx.fill();
simulation.drawList.push({ //add dmg to draw queue
x: m.pos.x + 35 * Math.cos(m.angle),
y: m.pos.y + 35 * Math.sin(m.angle),
x: m.pos.x + 20 * Math.cos(m.angle),
y: m.pos.y + 20 * Math.sin(m.angle),
radius: radius,
color: "#fb0",
time: 1
@@ -1747,9 +1747,14 @@ const b = {
x: player.velocity.x * 0.8,
y: player.velocity.y * 0.8
});
//need to scale the friction differently based on distance?
if (dist > 500) {
const pull = Vector.mult(Vector.normalise(sub), 0.0008 * Math.min(Math.max(15, dist), 200))
player.force.x += pull.x
player.force.y += pull.y
}
if (dist > 500) {
m.energy -= this.drain
@@ -1806,6 +1811,321 @@ const b = {
});
Composite.add(engine.world, bullet[me]); //add bullet to world
},
// grapple(where, angle = m.angle, harpoonSize = 1) {
// const me = bullet.length;
// const returnRadius = 100 * Math.sqrt(harpoonSize)
// bullet[me] = Bodies.fromVertices(where.x, where.y, [{
// x: -50 * harpoonSize,
// y: 2 * harpoonSize,
// index: 0,
// isInternal: false
// }, {
// x: -50 * harpoonSize,
// y: -2 * harpoonSize,
// index: 1,
// isInternal: false
// }, {
// x: 45 * harpoonSize,
// y: -3 * harpoonSize,
// index: 2,
// isInternal: false
// }, {
// x: 50 * harpoonSize,
// y: 0,
// index: 3,
// isInternal: false
// }, {
// x: 45 * harpoonSize,
// y: 3 * harpoonSize,
// index: 4,
// isInternal: false
// }], {
// angle: angle,
// friction: 1,
// frictionAir: 0.4,
// thrustMag: 0.1,
// dmg: 6, //damage done in addition to the damage from momentum
// classType: "bullet",
// endCycle: simulation.cycle + 70,
// collisionFilter: {
// category: cat.bullet,
// mask: tech.isShieldPierce ? cat.body | cat.mob | cat.mobBullet : cat.body | cat.mob | cat.mobBullet | cat.mobShield,
// },
// minDmgSpeed: 4,
// lookFrequency: Math.floor(7 + Math.random() * 3),
// density: tech.harpoonDensity, //0.001 is normal for blocks, 0.004 is normal for harpoon, 0.004*6 when buffed
// drain: tech.isRailEnergy ? 0.0006 : 0.006,
// beforeDmg(who) {
// if (tech.isShieldPierce && who.isShielded) { //disable shields
// who.isShielded = false
// requestAnimationFrame(() => {
// who.isShielded = true
// });
// }
// if (tech.fragments) {
// b.targetedNail(this.vertices[2], tech.fragments * Math.floor(2 + Math.random()))
// }
// if (tech.isFoamBall) {
// for (let i = 0, len = 4 * this.mass; i < len; i++) {
// const radius = 5 + 8 * Math.random()
// const velocity = {
// x: Math.max(0.5, 2 - radius * 0.1),
// y: 0
// }
// b.foam(this.position, Vector.rotate(velocity, 6.28 * Math.random()), radius)
// }
// // this.endCycle = 0;
// }
// },
// caughtPowerUp: null,
// dropCaughtPowerUp() {
// if (this.caughtPowerUp) {
// this.caughtPowerUp.collisionFilter.category = cat.powerUp
// this.caughtPowerUp.collisionFilter.mask = cat.map | cat.powerUp
// this.caughtPowerUp = null
// }
// },
// onEnd() {
// if (this.caughtPowerUp && !simulation.isChoosing && (this.caughtPowerUp.name !== "heal" || m.health !== m.maxHealth || tech.isOverHeal)) {
// let index = null //find index
// for (let i = 0, len = powerUp.length; i < len; ++i) {
// if (powerUp[i] === this.caughtPowerUp) index = i
// }
// if (index !== null) {
// powerUps.onPickUp(this.caughtPowerUp);
// this.caughtPowerUp.effect();
// Matter.Composite.remove(engine.world, this.caughtPowerUp);
// powerUp.splice(index, 1);
// if (tech.isHarpoonPowerUp) tech.harpoonDensity = 0.004 * 6 //0.005 is normal
// } else {
// this.dropCaughtPowerUp()
// }
// } else {
// this.dropCaughtPowerUp()
// }
// },
// draw() {
// const where = {
// x: m.pos.x + 30 * Math.cos(m.angle),
// y: m.pos.y + 30 * Math.sin(m.angle)
// }
// const sub = Vector.sub(where, this.vertices[0])
// const controlPoint = Vector.add(where, Vector.mult(sub, -0.5))
// ctx.strokeStyle = "#000" // "#0ce"
// ctx.lineWidth = 0.5
// ctx.beginPath();
// ctx.moveTo(where.x, where.y);
// ctx.quadraticCurveTo(controlPoint.x, controlPoint.y, this.vertices[0].x, this.vertices[0].y)
// // ctx.lineTo(this.vertices[0].x, this.vertices[0].y);
// ctx.stroke();
// //draw harpoon spikes
// const spikeLength = 2
// ctx.beginPath();
// const spike1 = Vector.add(this.vertices[1], Vector.mult(Vector.sub(this.vertices[1], this.vertices[2]), spikeLength))
// ctx.moveTo(this.vertices[2].x, this.vertices[2].y);
// ctx.lineTo(spike1.x, spike1.y);
// ctx.lineTo(this.vertices[3].x, this.vertices[3].y);
// const spike2 = Vector.add(this.vertices[3], Vector.mult(Vector.sub(this.vertices[3], this.vertices[2]), spikeLength))
// ctx.moveTo(this.vertices[2].x, this.vertices[2].y);
// ctx.lineTo(spike2.x, spike2.y);
// ctx.lineTo(this.vertices[1].x, this.vertices[1].y);
// ctx.fillStyle = '#000'
// ctx.fill();
// },
// returnToPlayer() {
// if (Vector.magnitude(Vector.sub(this.position, m.pos)) < returnRadius) { //near player
// this.endCycle = 0;
// // if (m.energy < 0.05) {
// // m.fireCDcycle = m.cycle + 120; //fire cooldown
// // } else if (m.cycle + 15 * b.fireCDscale < m.fireCDcycle) {
// // m.fireCDcycle = m.cycle + 15 * b.fireCDscale //lower cd to 25 if it is above 25
// // }
// if (m.energy < 0.05) this.dropCaughtPowerUp()
// //recoil on catching
// const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (m.crouch ? 0.0001 : 0.0002))
// player.force.x += momentum.x
// player.force.y += momentum.y
// // refund ammo
// b.guns[9].ammo++;
// simulation.updateGunHUD();
// // for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
// // if (b.guns[i].name === "harpoon") {
// // b.guns[i].ammo++;
// // simulation.updateGunHUD();
// // break;
// // }
// // }
// } else {
// if (m.energy > this.drain) m.energy -= this.drain
// const sub = Vector.sub(this.position, m.pos)
// const rangeScale = 1 + 0.000001 * Vector.magnitude(sub) * Vector.magnitude(sub) //return faster when far from player
// const returnForce = Vector.mult(Vector.normalise(sub), rangeScale * this.thrustMag * this.mass)
// this.force.x -= returnForce.x
// this.force.y -= returnForce.y
// this.grabPowerUp()
// }
// this.draw();
// },
// grabPowerUp() { //grab power ups near the tip of the harpoon
// if (this.caughtPowerUp) {
// Matter.Body.setPosition(this.caughtPowerUp, Vector.add(this.vertices[2], this.velocity))
// Matter.Body.setVelocity(this.caughtPowerUp, {
// x: 0,
// y: 0
// })
// } else { //&& simulation.cycle % 2
// for (let i = 0, len = powerUp.length; i < len; ++i) {
// const radius = powerUp[i].circleRadius + 50
// if (Vector.magnitudeSquared(Vector.sub(this.vertices[2], powerUp[i].position)) < radius * radius) {
// if (powerUp[i].name !== "heal" || m.health !== m.maxHealth || tech.isOverHeal) {
// this.caughtPowerUp = powerUp[i]
// Matter.Body.setVelocity(powerUp[i], {
// x: 0,
// y: 0
// })
// Matter.Body.setPosition(powerUp[i], this.vertices[2])
// powerUp[i].collisionFilter.category = 0
// powerUp[i].collisionFilter.mask = 0
// this.thrustMag *= 0.6
// this.endCycle += 0.5 //it pulls back slower, so this prevents it from ending early
// break //just pull 1 power up if possible
// }
// }
// }
// }
// },
// do() {
// if (input.fire) { //&& !Matter.Query.collides(this, body).length
// this.grabPowerUp()
// if (this.endCycle < simulation.cycle + 1) { //if at end of lifespan, but player is holding down fire, force retraction
// this.endCycle = simulation.cycle + 60
// // m.fireCDcycle = m.cycle + 120 // cool down
// this.do = this.returnToPlayer
// Matter.Body.setDensity(this, 0.0005); //reduce density on return
// if (this.angularSpeed < 0.5) this.torque += this.inertia * 0.001 * (Math.random() - 0.5) //(Math.round(Math.random()) ? 1 : -1)
// this.collisionFilter.mask = cat.map | cat.mob | cat.mobBullet | cat.mobShield // | cat.body
// }
// } else {
// //if not enough energy
// if (m.energy < 0.05) this.dropCaughtPowerUp()
// // const returnForce = Vector.mult(Vector.normalise(Vector.sub(this.position, m.pos)), 3 * this.thrustMag * this.mass)
// // this.force.x -= returnForce.x
// // this.force.y -= returnForce.y
// // this.frictionAir = 0.002
// // this.do = () => {
// // if (this.speed < 20) this.force.y += 0.0005 * this.mass;
// // }
// // } else {
// //return to player
// this.do = this.returnToPlayer
// this.endCycle = simulation.cycle + 60
// Matter.Body.setDensity(this, 0.0005); //reduce density on return
// if (this.angularSpeed < 0.5) this.torque += this.inertia * 0.001 * (Math.random() - 0.5) //(Math.round(Math.random()) ? 1 : -1)
// this.collisionFilter.mask = cat.map | cat.mob | cat.mobBullet | cat.mobShield // | cat.body
// //recoil on catching
// const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (m.crouch ? 0.0001 : 0.0002))
// player.force.x += momentum.x
// player.force.y += momentum.y
// // }
// }
// //grappling hook
// if (input.fire && Matter.Query.collides(this, map).length) {
// Matter.Body.setPosition(this, Vector.add(this.position, {
// x: 20 * Math.cos(this.angle),
// y: 20 * Math.sin(this.angle)
// }))
// if (Matter.Query.collides(this, map).length) {
// Matter.Body.setVelocity(this, {
// x: 0,
// y: 0
// });
// Matter.Sleeping.set(this, true)
// this.endCycle = simulation.cycle + 5
// this.dropCaughtPowerUp()
// this.do = () => {
// //between player nose and the grapple
// const sub = Vector.sub(this.vertices[0], {
// x: m.pos.x + 30 * Math.cos(m.angle),
// y: m.pos.y + 30 * Math.sin(m.angle)
// })
// let dist = Vector.magnitude(sub)
// if (input.fire) {
// // m.fireCDcycle = m.cycle + 30; // cool down if out of energy
// m.fireCDcycle = m.cycle + 5 + 40 * b.fireCDscale + 60 * (m.energy < 0.05)
// this.endCycle = simulation.cycle + 10
// if (input.down) { //down
// dist = 0
// player.force.y += 5 * player.mass * simulation.g;
// }
// if (m.energy > this.drain) {
// Matter.Body.setVelocity(player, {
// x: player.velocity.x * 0.8,
// y: player.velocity.y * 0.8
// });
// const pull = Vector.mult(Vector.normalise(sub), 0.0008 * Math.min(Math.max(15, dist), 200))
// player.force.x += pull.x
// player.force.y += pull.y
// if (dist > 500) {
// m.energy -= this.drain
// if (m.energy < 0) {
// this.endCycle = 0;
// if (m.cycle + 50 < m.fireCDcycle) m.fireCDcycle = m.cycle + 50
// // refund ammo
// b.guns[9].ammo++;
// simulation.updateGunHUD();
// // for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
// // if (b.guns[i].name === "harpoon") {
// // break;
// // }
// // }
// }
// }
// }
// if (tech.isImmuneGrapple && m.immuneCycle < m.cycle + 10) {
// m.immuneCycle = m.cycle + 10;
// if (m.energy > 0.001) {
// m.energy -= 0.001
// } else { //out of energy
// Matter.Sleeping.set(this, false)
// this.collisionFilter.category = 0
// this.collisionFilter.mask = 0
// this.do = this.returnToPlayer
// this.endCycle = simulation.cycle + 60
// m.fireCDcycle = m.cycle + 120; //fire cooldown
// //recoil on catching
// const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (m.crouch ? 0.0001 : 0.0002))
// player.force.x += momentum.x
// player.force.y += momentum.y
// }
// }
// } else {
// Matter.Sleeping.set(this, false)
// this.collisionFilter.category = 0
// this.collisionFilter.mask = 0
// this.do = this.returnToPlayer
// this.endCycle = simulation.cycle + 60
// //recoil on catching
// const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (m.crouch ? 0.0001 : 0.0002))
// player.force.x += momentum.x
// player.force.y += momentum.y
// }
// this.draw();
// }
// }
// }
// this.force.x += this.thrustMag * this.mass * Math.cos(this.angle);
// this.force.y += this.thrustMag * this.mass * Math.sin(this.angle);
// this.draw()
// },
// });
// Composite.add(engine.world, bullet[me]); //add bullet to world
// },
harpoon(where, target, angle = m.angle, harpoonSize = 1, isReturn = false, totalCycles = 35, isReturnAmmo = true, thrust = 0.1) {
const me = bullet.length;
const returnRadius = 100 * Math.sqrt(harpoonSize)
@@ -2803,16 +3123,26 @@ const b = {
if (simulation.cycle > this.lookFrequency) {
this.isArmed = true
this.lookFrequency = 55 + Math.floor(22 * Math.random())
simulation.drawList.push({
x: this.position.x,
y: this.position.y,
radius: 10,
color: "#f00",
time: 4
});
simulation.drawList.push({ x: this.position.x, y: this.position.y, radius: 10, color: "#f00", time: 4 });
this.do = function () { //overwrite the do method for this bullet
//make mobs think the mine is where the player is
// for (let i = 0; i < mob.length; i++) {
// mob[i].seePlayer.recall = mob[i].memory + Math.round(mob[i].memory * Math.random()); //cycles before mob falls a sleep
// mob[i].seePlayer.position.x = this.position.x;
// mob[i].seePlayer.position.y = this.position.y;
// mob[i].seePlayer.yes = true;
// }
this.force.y += this.mass * 0.002; //extra gravity
if (!(simulation.cycle % this.lookFrequency)) { //find mob targets
const random = 300 * Math.random()
for (let i = 0, len = mob.length; i < len; ++i) {
if (
@@ -2843,13 +3173,7 @@ const b = {
}
if (this.shots < 0) this.endCycle = 0
if (!(simulation.cycle % (this.lookFrequency * 6))) {
simulation.drawList.push({
x: this.position.x,
y: this.position.y,
radius: 8,
color: "#fe0",
time: 4
});
simulation.drawList.push({ x: this.position.x, y: this.position.y, radius: 8, color: "#fe0", time: 4 });
}
}
}
@@ -5111,9 +5435,9 @@ const b = {
dmg: 0, //damage done in addition to the damage from momentum
minDmgSpeed: 2,
lookFrequency: 20 + Math.floor(7 * Math.random()) - 13 * tech.isLaserBotUpgrade,
range: (700 + 500 * tech.isLaserBotUpgrade) * (1 + 0.1 * Math.random()),
range: (600 + 375 * tech.isLaserBotUpgrade) * (1 + 0.12 * Math.random()),
drainThreshold: 0.15 + 0.5 * Math.random() + (tech.isEnergyHealth ? 0.3 : 0),// laser bot will not attack if the player is below this energy
drain: (0.57 - 0.45 * tech.isLaserBotUpgrade) * tech.laserDrain,
drain: (0.57 - 0.43 * tech.isLaserBotUpgrade) * tech.laserDrain,
laserDamage: 0.75 + 0.75 * tech.isLaserBotUpgrade,
endCycle: Infinity,
classType: "bullet",
@@ -6126,7 +6450,7 @@ const b = {
for (let i = 0; i < num; i++) {
const me = bullet.length;
const dir = m.angle + (Math.random() - 0.5) * spread
bullet[me] = Bodies.rectangle(m.pos.x + 35 * Math.cos(m.angle) + 15 * (Math.random() - 0.5), m.pos.y + 35 * Math.sin(m.angle) + 15 * (Math.random() - 0.5), side, side, b.fireAttributes(dir));
bullet[me] = Bodies.rectangle(m.pos.x, m.pos.y, side, side, b.fireAttributes(dir));
Composite.add(engine.world, bullet[me]); //add bullet to world
const SPEED = 52 + Math.random() * 8
Matter.Body.setVelocity(bullet[me], {

View File

@@ -107,7 +107,7 @@ function collisionChecks(event) {
!mob[k].isSlowed && !mob[k].isStunned
) {
let dmg = Math.min(Math.max(0.025 * Math.sqrt(mob[k].mass), 0.05), 0.3) * simulation.dmgScale; //player damage is capped at 0.3*dmgScale of 1.0
if (m.isCloak) dmg *= 0.5
// if (m.isCloak) dmg *= 0.5
mob[k].foundPlayer();
if (tech.isRewindAvoidDeath && (m.energy + 0.05) > Math.min(0.95, m.maxEnergy) && dmg > 0.01) { //CPT reversal runs in m.damage, but it stops the rest of the collision code here too
m.damage(dmg);
@@ -119,25 +119,11 @@ function collisionChecks(event) {
if (document.getElementById("tech-flip-flop")) document.getElementById("tech-flip-flop").innerHTML = ` = <strong>OFF</strong>`
m.eyeFillColor = 'transparent'
m.damage(dmg);
if (tech.isFlipFlopCoupling) {
m.couplingChange(-5)
for (let i = 0; i < mob.length; i++) {
if (mob[i].isDecoupling) mob[i].alive = false //remove WIMP
}
spawn.WIMP()
mob[mob.length - 1].isDecoupling = true //so you can find it to remove
}
} else {
tech.isFlipFlopOn = true //immune to damage this hit, lose immunity for next hit
if (document.getElementById("tech-flip-flop")) document.getElementById("tech-flip-flop").innerHTML = ` = <strong>ON</strong>`
m.eyeFillColor = m.fieldMeterColor //'#0cf'
if (!tech.isFlipFlopHarm) m.damage(dmg);
if (tech.isFlipFlopCoupling) {
m.couplingChange(5)
for (let i = 0; i < mob.length; i++) {
if (mob[i].isDecoupling) mob[i].alive = false //remove WIMP
}
}
}
if (tech.isFlipFlopHealth) {
m.setMaxHealth();
@@ -161,7 +147,7 @@ function collisionChecks(event) {
}
if (tech.isPiezo) m.energy += 20.48;
if (tech.isCouplingNoHit && m.coupling > 0) {
m.couplingChange(-0.5)
m.couplingChange(-5)
const unit = Vector.rotate({ x: 1, y: 0 }, 6.28 * Math.random())
let where = Vector.add(m.pos, Vector.mult(unit, 17))
@@ -295,7 +281,7 @@ function collisionChecks(event) {
}
}
let dmg = tech.blockDamage * m.dmgScale * v * obj.mass * (tech.isMobBlockFling ? 2.5 : 1) * (tech.isBlockRestitution ? 2.5 : 1) * ((m.fieldMode === 0 || m.fieldMode === 8) ? 1 + 0.4 * m.coupling : 1);
let dmg = tech.blockDamage * m.dmgScale * v * obj.mass * (tech.isMobBlockFling ? 2.5 : 1) * (tech.isBlockRestitution ? 2.5 : 1) * ((m.fieldMode === 0 || m.fieldMode === 8) ? 1 + 0.04 * m.coupling : 1);
if (mob[k].isShielded) dmg *= 0.7
mob[k].damage(dmg, true);

View File

@@ -302,6 +302,32 @@ const build = {
document.getElementById("hide-images").checked = localSettings.isHideImages
// console.log(localSettings.isHideImages, from)
},
hideHUD() {
localSettings.isHideHUD = !localSettings.isHideHUD
if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
document.getElementById("hide-hud").checked = localSettings.isHideHUD
document.getElementById("hide-hud").classList.toggle("ticked")
simulation.removeEphemera("dmgDefBars")
if (!localSettings.isHideHUD) {
simulation.ephemera.push({
name: "dmgDefBars", count: 0, do() {
if (!(m.cycle % 15)) { //4 times a second
const defense = m.defense() //update defense bar
if (m.lastCalculatedDefense !== defense) {
document.getElementById("defense-bar").style.width = Math.floor(300 * m.maxHealth * (1 - defense)) + "px";
m.lastCalculatedDefense = defense
}
const damage = tech.damageFromTech() //update damage bar
if (m.lastCalculatedDamage !== damage) {
document.getElementById("damage-bar").style.height = Math.floor((Math.atan(0.25 * damage - 0.25) + 0.25) * 0.53 * canvas.height) + "px";
m.lastCalculatedDamage = damage
}
}
},
})
}
},
pauseGrid() {
// build.pixelDraw();
//used for junk estimation
@@ -330,15 +356,18 @@ const build = {
<g stroke='none' fill='#333' stroke-width="2" font-size="14px" font-family="Ariel, sans-serif"> <text x="5" y="15">copy build url</text></g>
</svg><span style="font-size:1.5em;font-weight: 600; float: right;">PAUSED</span>
<br>
<label for="hide-images-pause" title="hide images for fields, guns, and tech" style="font-size:1.3em;" >hide images:</label>
<input onclick="build.showImages('pause')" type="checkbox" id="hide-images-pause" name="hide-images-pause" ${localSettings.isHideImages ? "checked" : ""}>
<label for="hide-images-pause" title="hide images for fields, guns, and tech" style="font-size:1.3em;" >hide images</label>
<span style="float: right;">press ${input.key.pause} to resume</span>
<br>
<input onclick="build.hideHUD('settings')" type="checkbox" id="hide-hud" name="hide-hud" ${localSettings.isHideHUD ? "checked" : ""}>
<label for="hide-hud" title="hide: tech, defense, damage, in game console" style="font-size:1.3em;">minimal HUD</label>
<br>
<br><strong class='color-d'>damage</strong>: ${((tech.damageFromTech())).toPrecision(4)} &nbsp; &nbsp; difficulty: ${((m.dmgScale)).toPrecision(4)}
<br><strong class='color-defense'>defense</strong>: ${tech.isEnergyHealth ? (1 - Math.pow(m.defense(), 0.13)).toPrecision(5) : (1 - m.defense()).toPrecision(5)} &nbsp; &nbsp; difficulty: ${(1 / simulation.dmgScale).toPrecision(4)}
<br><strong><em>fire rate</em></strong>: ${((1 - b.fireCDscale) * 100).toFixed(b.fireCDscale < 0.1 ? 2 : 0)}%
${tech.duplicationChance() ? `<br><strong class='color-dup'>duplication</strong>: ${(tech.duplicationChance() * 100).toFixed(0)}%` : ""}
${m.coupling ? `<br><strong class='color-coupling'>coupling</strong>: ${(m.coupling).toFixed(2)} &nbsp; <span style = 'font-size:90%;'>` + m.couplingDescription() + "</span>" : ""}
${m.coupling ? `<br><span style = 'font-size:90%;'>` + m.couplingDescription(m.coupling) + `</span> from ${(m.coupling).toFixed(0)} ${powerUps.orb.coupling(1)}` : ""}
${botText}
<br>
<br><strong class='color-h'>health</strong>: (${(m.health * 100).toFixed(0)} / ${(m.maxHealth * 100).toFixed(0)})
@@ -380,7 +409,7 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
<div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${build.nameLink(b.guns[b.inventory[i]].name)} - <span style="font-size:100%;font-weight: 100;">${b.guns[b.inventory[i]].ammo}</span></div>
${b.guns[b.inventory[i]].description}</div> </div>`
}
text += `<div class="pause-grid-module pause-console" style = "background-color: rgba(255,255,255,0.3);">${document.getElementById("text-log").innerHTML}</div>` //show last in game console message
if (!localSettings.isHideHUD) text += `<div class="pause-grid-module pause-console" style = "background-color: rgba(255,255,255,0.3);">${document.getElementById("text-log").innerHTML}</div>` //show last in game console message
let el = document.getElementById("pause-grid-left")
el.style.display = "grid"
el.innerHTML = text
@@ -432,7 +461,7 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
text += build.techText(i) + "</div>"
}
} else if (tech.tech[i].isLost) {
text += `<div class="pause-grid-module" style="text-decoration: line-through;"><div class="grid-title">${tech.tech[i].link}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() : tech.tech[i].description}</div></div>`
text += `<div class="pause-grid-module" style="text-decoration: line-through; padding-left: 8px; opacity: 0.4;"><div class="grid-title">${tech.tech[i].link}</div>${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() : tech.tech[i].description}</div></div>`
}
}
el = document.getElementById("pause-grid-right")
@@ -454,7 +483,6 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
},
unPauseGrid() {
document.getElementById("tech").style.display = "inline"
document.getElementById("guns").style.display = "inline"
document.getElementById("field").style.display = "inline"
if (tech.isEnergyHealth) {
@@ -464,8 +492,11 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>" : ""}
document.getElementById("health").style.display = "inline"
document.getElementById("health-bg").style.display = "inline"
}
if (!localSettings.isHideHUD) {
document.getElementById("tech").style.display = "inline"
document.getElementById("defense-bar").style.display = "inline"
document.getElementById("damage-bar").style.display = "inline"
}
// document.body.style.overflow = "hidden"
document.getElementById("pause-grid-left").style.display = "none"
document.getElementById("pause-grid-right").style.display = "none"
@@ -1494,6 +1525,10 @@ if (localSettings.isAllowed && !localSettings.isEmpty) {
}
if (localSettings.isHideImages === undefined) localSettings.isHideImages = true //default to hide images
document.getElementById("hide-images").checked = localSettings.isHideImages
if (localSettings.isHideHUD === undefined) localSettings.isHideHUD = false
document.getElementById("hide-hud").checked = localSettings.isHideHUD
} else {
console.log('setting default localSettings')
const isAllowed = localSettings.isAllowed //don't overwrite isAllowed value
@@ -1513,6 +1548,7 @@ if (localSettings.isAllowed && !localSettings.isEmpty) {
isHuman: false,
key: undefined,
isHideImages: true, //default to hide images
isHideHUD: false,
};
input.setDefault()
if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage

View File

@@ -26,31 +26,31 @@ const level = {
// powerUps.research.changeRerolls(11)
// m.immuneCycle = Infinity //you can't take damage
// tech.tech[297].frequency = 100
// m.couplingChange(5)
// m.setField("standing wave") //1 standing wave 2 perfect diamagnetism 3 negative mass 4 molecular assembler 5 plasma torch 6 time dilation 7 metamaterial cloaking 8 pilot wave 9 wormhole
// m.couplingChange(10)
// m.setField("metamaterial cloaking") //1 standing wave 2 perfect diamagnetism 3 negative mass 4 molecular assembler 5 plasma torch 6 time dilation 7 metamaterial cloaking 8 pilot wave 9 wormhole
// m.energy = 0
// simulation.molecularMode = 2
// m.damage(0.1);
// b.giveGuns("harpoon") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.giveGuns("foam") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.giveGuns("shotgun") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.guns[3].ammo = 100000000
// tech.giveTech("induction brake")
// tech.giveTech("grappling hook")
// tech.giveTech("null hypothesis")
// for (let i = 0; i < 1; ++i) tech.giveTech("dye laser")
// for (let i = 0; i < 1; ++i) tech.giveTech("free-electron laser")
// for (let i = 0; i < 1; ++i) tech.giveTech("waste heat recovery")
// 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 < 1; ++i) tech.giveTech("Occams razor")
// for (let i = 0; i < 3; i++) powerUps.directSpawn(450, -50, "tech");
// 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.superNgonBros();
// level.testing();
// spawn.nodeGroup(3200, -300, "sniper")
// spawn.nodeGroup(2200, -300, "sniper")
// spawn.nodeGroup(2200, -300, "sniper")
// spawn.mantisBoss(1900, -500)
// spawn.cellBoss(1900, -500)
// for (let i = 0; i < 5; ++i) spawn.starter(1900, -500, 50)
// for (let i = 0; i < 2; ++i) spawn.starter(1900, -500, 50)
// spawn.sneaker(1900, -500, 25)
// spawn.sniper(2000, -450)
// spawn.zombie(1000 + 1000 * Math.random(), -500 + 300 * Math.random(), 30, 5, "white") // zombie(x, y, radius, sides, color)
@@ -139,12 +139,6 @@ const level = {
tech.isFlipFlopOn = true
if (tech.isFlipFlopHealth) m.setMaxHealth()
if (tech.isRelayEnergy) m.setMaxEnergy()
if (tech.isFlipFlopCoupling) {
m.couplingChange(5)
for (let i = 0; i < mob.length; i++) {
if (mob[i].isDecoupling) mob[i].alive = false //remove WIMP
}
}
m.eyeFillColor = m.fieldMeterColor
simulation.makeTextLog(`tech.isFlipFlopOn <span class='color-symbol'>=</span> true`);
}
@@ -1192,7 +1186,7 @@ const level = {
y = y + height / 2
const doorBlock = body[body.length] = Bodies.rectangle(x, y, width, height, {
collisionFilter: {
category: cat.map,
category: cat.body,//cat.map,
mask: cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet //cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet
},
isNoSetCollision: true,
@@ -1252,7 +1246,7 @@ const level = {
return this.position.y > y - 1
},
draw() {
ctx.fillStyle = "#555"
ctx.fillStyle = "#666"
ctx.beginPath();
const v = this.vertices;
ctx.moveTo(v[0].x, v[0].y);
@@ -3175,6 +3169,8 @@ const level = {
const doorIn = level.door(-313, -950, 525, 200, 190, 2) //x, y, width, height, distance, speed = 1
const doorOut = level.door(2762, -175, 525, 200, 190, 2) //x, y, width, height, distance, speed = 1
doorIn.collisionFilter.category = cat.map;
doorOut.collisionFilter.category = cat.map; // to prevent boson composite from letting the player skip the level
// doorOut.isClosing = true
let isDoorsLocked = false
let isFightOver = false
@@ -5186,6 +5182,10 @@ const level = {
portal[3].query()
};
level.customTopLayer = () => {
doorButtonRight.draw();
doorCenterRight.draw();
doorCenterLeft.draw();
doorLeft.draw();
hazardSlimeLeft.query();
hazardSlimeRight.query();
portal[0].draw();
@@ -22147,8 +22147,10 @@ const level = {
m.addHealth(0.25)
document.getElementById("health").style.display = "inline" //show your health bar
document.getElementById("health-bg").style.display = "inline"
if (!localSettings.isHideHUD) {
document.getElementById("defense-bar").style.display = "inline"
document.getElementById("damage-bar").style.display = "inline"
}
level.setPosToSpawn(60, -50); //normal spawn
spawn.mapRect(10, -10, 100, 20); //small platform for player
level.exit.x = 1775;

View File

@@ -239,7 +239,7 @@ const mobs = {
deathCount: 0,
mobSpawnWithHealth: 1,
setMobSpawnHealth() {
mobs.mobSpawnWithHealth = 0.88 ** (tech.mobSpawnWithHealth) //+ (m.fieldMode === 0 || m.fieldMode === 7) * m.coupling
mobs.mobSpawnWithHealth = 0.88 ** (tech.mobSpawnWithHealth)
},
//**********************************************************************************************
//**********************************************************************************************
@@ -337,7 +337,7 @@ const mobs = {
},
alwaysSeePlayer() {
if (!m.isCloak) {
this.seePlayer.recall = true;
this.seePlayer.recall = 1;
this.seePlayer.position.x = player.position.x;
this.seePlayer.position.y = player.position.y;
}
@@ -1228,15 +1228,6 @@ const mobs = {
simulation.timePlayerSkip((this.isBoss ? 45 : 25) * tech.deathSkipTime)
simulation.loop(); //ending with a wipe and normal loop fixes some very minor graphical issues where things are draw in the wrong locations
}); //wrapping in animation frame prevents errors, probably
// if (tech.isFlipFlopOn) {
// m.rewind(this.isBoss ? 45 : 25)
// } else {
// requestAnimationFrame(() => {
// simulation.timePlayerSkip(this.isBoss ? 45 : 25)
// simulation.loop(); //ending with a wipe and normal loop fixes some very minor graphical issues where things are draw in the wrong locations
// }); //wrapping in animation frame prevents errors, probably
// }
}
if (tech.isEnergyLoss) m.energy *= 0.8;
powerUps.spawnRandomPowerUp(this.position.x, this.position.y);

View File

@@ -525,7 +525,7 @@ const m = {
},
baseHealth: 1,
setMaxHealth() {
m.maxHealth = m.baseHealth + tech.extraMaxHealth + 2.22 * tech.isFallingDamage + 4 * tech.isFlipFlop * tech.isFlipFlopOn * tech.isFlipFlopHealth //+ (m.fieldMode === 0 || m.fieldMode === 5) * 0.5 * m.coupling
m.maxHealth = m.baseHealth + tech.extraMaxHealth + 2.22 * tech.isFallingDamage + 4 * tech.isFlipFlop * tech.isFlipFlopOn * tech.isFlipFlopHealth
document.getElementById("health-bg").style.width = `${Math.floor(300 * m.maxHealth)}px`
simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-h'>maxHealth</span> <span class='color-symbol'>=</span> ${m.maxHealth.toFixed(2)}`)
if (m.health > m.maxHealth) m.health = m.maxHealth;
@@ -549,7 +549,7 @@ const m = {
if (tech.isSlowFPS) dmg *= 0.8
if (tech.energyRegen === 0) dmg *= 0.34
// if (tech.healthDrain) dmg *= 1 + 3.33 * tech.healthDrain //tech.healthDrain = 0.03 at one stack //cause more damage
if (m.fieldMode === 0 || m.fieldMode === 3) dmg *= 0.73 ** m.coupling
if (m.fieldMode === 0 || m.fieldMode === 3) dmg *= 0.73 ** (0.1 * m.coupling)
if (tech.isLowHealthDefense) dmg *= 1 - Math.max(0, 1 - m.health) * 0.8
if (tech.isHarmReduceNoKill && m.lastKillCycle + 300 < m.cycle) dmg *= 0.33
if (tech.squirrelFx !== 1) dmg *= Math.pow(0.7, (tech.squirrelFx - 1) / 0.4) //cause more damage
@@ -1893,7 +1893,7 @@ const m = {
}
},
setMaxEnergy(isMessage = true) {
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) + (m.fieldMode === 0 || m.fieldMode === 1) * 0.5 * m.coupling + 0.4 * tech.isStandingWaveExpand
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) + (m.fieldMode === 0 || m.fieldMode === 1) * 0.05 * m.coupling + 0.4 * tech.isStandingWaveExpand
if (isMessage) simulation.makeTextLog(`<span class='color-var'>m</span>.<span class='color-f'>maxEnergy</span> <span class='color-symbol'>=</span> ${(m.maxEnergy.toFixed(2))}`)
},
fieldMeterColor: "#0cf",
@@ -1945,7 +1945,7 @@ const m = {
} else {
m.fieldRegen = 0.001 //6 energy per second
}
if (m.fieldMode === 0 || m.fieldMode === 4) m.fieldRegen += 0.00133 * m.coupling //return `generate <strong>${(6*couple).toFixed(0)}</strong> <strong class='color-f'>energy</strong> per second`
if (m.fieldMode === 0 || m.fieldMode === 4) m.fieldRegen += 0.000133 * m.coupling //return `generate <strong>${(6*couple).toFixed(0)}</strong> <strong class='color-f'>energy</strong> per second`
if (tech.isTimeCrystals) {
m.fieldRegen *= 2.5
} else if (tech.isGroundState) {
@@ -2290,7 +2290,7 @@ const m = {
}
if (!who.isInvulnerable && (m.coupling && m.fieldMode === 0) && bullet.length < 200) { //for field emitter iceIX
for (let i = 0; i < m.coupling; i++) {
if (m.coupling - i > 1.25 * Math.random()) {
if (0.1 * m.coupling - i > 1.25 * Math.random()) {
const sub = Vector.mult(Vector.normalise(Vector.sub(who.position, m.pos)), (m.fieldRange * m.harmonicRadius) * (0.4 + 0.3 * Math.random())) //m.harmonicRadius should be 1 unless you are standing wave expansion
const rad = Vector.rotate(sub, 1 * (Math.random() - 0.5))
const angle = Math.atan2(sub.y, sub.x)
@@ -2457,28 +2457,27 @@ const m = {
couplingDescription(couple = m.coupling) {
switch (m.fieldMode) {
case 0: //field emitter
return `gain the <strong class='color-coupling'>coupling</strong> effects of <strong>all</strong> <strong class='color-f'>fields</strong>`
return `<strong>all</strong> other <strong class='color-f'>field</strong> effects`
case 1: //standing wave
// return `<span style = 'font-size:95%;'><strong>deflecting</strong> condenses +${couple.toFixed(1)} <strong class='color-s'>ice IX</strong></span>`
// return `<span style = 'font-size:95%;'><strong>deflecting</strong> condenses +${couple.toFixed(1)} <strong class='color-s'>ice IX</strong></span>`
return `+${(couple * 50).toFixed(0)} maximum <strong class='color-f'>energy</strong>`
return `+${(couple * 5).toFixed(0)} maximum <strong class='color-f'>energy</strong>`
case 2: //perfect diamagnetism
return `<span style = 'font-size:95%;'><strong>deflecting</strong> condenses +${couple.toFixed(1)} <strong class='color-s'>ice IX</strong></span>`
return `<span style = 'font-size:95%;'><strong>deflecting</strong> condenses ${0.1 * couple.toFixed(2)} <strong class='color-s'>ice IX</strong></span>`
// return `<span style = 'font-size:89%;'><strong>invulnerable</strong> <strong>+${2*couple}</strong> seconds post collision</span>`
case 3: //negative mass
return `<strong>+${((1 - 0.73 ** couple) * 100).toFixed(1)}%</strong> <strong class='color-defense'>defense</strong>`
return `<strong>+${((1 - 0.73 ** couple) * 10).toFixed(1)}%</strong> <strong class='color-defense'>defense</strong>`
case 4: //assembler
return `generate <strong>${(8 * couple).toFixed(0)}</strong> <strong class='color-f'>energy</strong> per second`
return `generate <strong>${(0.8 * couple).toFixed(1)}</strong> <strong class='color-f'>energy</strong> per second`
case 5: //plasma
return `<strong>+${(15 * couple).toFixed(0)}%</strong> <strong class='color-d'>damage</strong>`
return `<strong>+${(1.5 * couple).toFixed(1)}%</strong> <strong class='color-d'>damage</strong>`
case 6: //time dilation
return `<strong>+${(50 * couple).toFixed(0)}%</strong> longer <strong style='letter-spacing: 2px;'>stopped time</strong>` //<strong>movement</strong>, <strong>jumping</strong>, and
return `<strong>+${(5 * couple).toFixed(0)}%</strong> longer <strong style='letter-spacing: 2px;'>stopped time</strong>` //<strong>movement</strong>, <strong>jumping</strong>, and
case 7: //cloaking
return `<strong>+${(33 * couple).toFixed(0)}%</strong> ambush <strong class='color-d'>damage</strong>`
return `<strong>+${(3.3 * couple).toFixed(1)}%</strong> ambush <strong class='color-d'>damage</strong>`
case 8: //pilot wave
return `<strong>+${(40 * couple).toFixed(0)}%</strong> <strong class='color-block'>block</strong> collision <strong class='color-d'>damage</strong>`
return `<strong>+${(4 * couple).toFixed(0)}%</strong> <strong class='color-block'>block</strong> collision <strong class='color-d'>damage</strong>`
case 9: //wormhole
return `<span style = 'font-size:89%;'>after eating <strong class='color-block'>blocks</strong> <strong>+${(20 * couple).toFixed(0)}</strong> <strong class='color-f'>energy</strong></span>`
return `<span style = 'font-size:89%;'>after eating <strong class='color-block'>blocks</strong> <strong>+${(2 * couple).toFixed(0)}</strong> <strong class='color-f'>energy</strong></span>`
}
},
couplingChange(change = 0) {
@@ -2490,11 +2489,10 @@ const m = {
if (powerUp[i].name === "coupling") {
Matter.Composite.remove(engine.world, powerUp[i]);
powerUp.splice(i, 1);
m.coupling += 0.1
m.coupling += 1
if (!(m.coupling < 0)) break
}
}
m.coupling = 0 //can't go negative
}
m.setMaxEnergy(false);
@@ -2503,33 +2501,7 @@ const m = {
mobs.setMobSpawnHealth();
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
// switch (m.fieldMode) {
// case 0: //field emitter
// // m.fieldFireRate = 0.8 ** (m.coupling)
// // b.setFireCD();
// break
// // case 1: //standing wave
// // break
// // case 2: //perfect diamagnetism
// // break
// // case 3: //negative mass
// // break
// // case 4: //assembler
// // break
// // case 5: //plasma
// // break
// case 6: //time dilation
// // m.fieldFireRate = 0.75 * 0.8 ** (m.coupling)
// break
// // case 7: //cloaking
// // break
// // case 8: //pilot wave
// // break
// // case 9: //wormhole
// // break
// }
// if ((m.fieldMode === 0 || m.fieldMode === 9) && !build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.4);
},
setField(index) {
if (isNaN(index)) { //find index by name
@@ -2577,6 +2549,12 @@ const m = {
}
}
},
// <div id="cube" style="width: 4em; height: 8em;">
// <div style="transform: translate3d(1em, 0em, 0em)">1</div>
// <div style="transform: translate3d(2em, 0em, 0em)">2</div>
// <div style="transform: translate3d(3em, 0em, 0em)">3</div>
// <div style="transform: translate3d(4em, 0em, 0em)">4</div>
// </div>
{
name: "standing wave",
//<strong>deflecting</strong> protects you in every <strong>direction</strong>
@@ -2586,7 +2564,7 @@ const m = {
drainCD: 0,
effect: () => {
m.fieldBlockCD = 0;
m.blockingRecoil = 2 //4 is normal
m.blockingRecoil = 1.5 //4 is normal
m.fieldRange = 185
m.fieldShieldingScale = 1.6 * Math.pow(0.5, (tech.harmonics - 2))
// m.fieldHarmReduction = 0.66; //33% reduction
@@ -2717,7 +2695,7 @@ const m = {
m.fieldCDcycle = m.cycle + m.fieldBlockCD + (mob[i].isShielded ? 10 : 0);
if (!mob[i].isInvulnerable && bullet.length < 250) {
for (let i = 0; i < m.coupling; i++) {
if (m.coupling - i > Math.random()) {
if (0.1 * m.coupling - i > Math.random()) {
const angle = m.fieldAngle + 4 * m.fieldArc * (Math.random() - 0.5)
const radius = m.fieldRange * (0.6 + 0.3 * Math.random())
b.iceIX(6 + 6 * Math.random(), angle, Vector.add(m.fieldPosition, {
@@ -2853,16 +2831,18 @@ const m = {
}); //set velocity to cap, but keep the direction
}
// go invulnerable while field is active, but also drain energy
// if (true && m.energy > 2 * m.fieldRegen && m.immuneCycle < m.cycle + tech.cyclicImmunity) {
// m.immuneCycle = m.cycle + 1; //player is immune to damage for 60 cycles
// m.energy -= 2 * m.fieldRegen
// if (m.energy < m.fieldRegen) m.fieldCDcycle = m.cycle + 90;
// }
if (m.energy > m.fieldRegen) m.energy -= m.fieldRegen
m.grabPowerUp();
m.lookForPickUp();
m.fieldPosition = {
x: m.pos.x,
y: m.pos.y
}
m.fieldPosition = { x: m.pos.x, y: m.pos.y }
m.fieldAngle = m.angle
//draw field attached to player
if (m.holdingTarget) {
@@ -3215,61 +3195,6 @@ const m = {
}
}
},
// {
// name: "plasma torch",
// description: "use <strong class='color-f'>energy</strong> to emit short range <strong class='color-plasma'>plasma</strong><br><strong class='color-d'>damages</strong> and <strong>pushes</strong> mobs away",
// effect() {
// m.fieldMeterColor = "#f0f"
// m.eyeFillColor = m.fieldMeterColor
// m.hold = function() {
// b.isExtruderOn = false
// if (m.isHolding) {
// m.drawHold(m.holdingTarget);
// m.holding();
// m.throwBlock();
// } else if (input.field && m.fieldCDcycle < m.cycle) { //not hold but field button is pressed
// m.grabPowerUp();
// m.lookForPickUp();
// if (tech.isExtruder) {
// b.extruder();
// } else {
// b.plasma();
// }
// } 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)
// }
// m.drawRegenEnergy("rgba(0, 0, 0, 0.2)")
// if (tech.isExtruder) {
// if (input.field) {
// b.wasExtruderOn = true
// } else {
// b.wasExtruderOn = false
// b.canExtruderFire = true
// }
// ctx.beginPath(); //draw all the wave bullets
// for (let i = 0, len = bullet.length; i < len; i++) {
// if (bullet[i].isWave) {
// if (bullet[i].isBranch) {
// ctx.moveTo(bullet[i].position.x, bullet[i].position.y)
// } else {
// ctx.lineTo(bullet[i].position.x, bullet[i].position.y)
// }
// }
// }
// if (b.wasExtruderOn && b.isExtruderOn) ctx.lineTo(m.pos.x + 15 * Math.cos(m.angle), m.pos.y + 15 * Math.sin(m.angle))
// ctx.lineWidth = 4;
// ctx.strokeStyle = "#f07"
// ctx.stroke();
// ctx.lineWidth = tech.extruderRange;
// ctx.strokeStyle = "rgba(255,0,110,0.05)"
// ctx.stroke();
// }
// }
// }
// },
{
name: "plasma torch",
description: "use <strong class='color-f'>energy</strong> to emit short range <strong class='color-plasma'>plasma</strong><br><strong class='color-d'>damages</strong> and <strong>pushes</strong> mobs away<br>generate <strong>10</strong> <strong class='color-f'>energy</strong> per second",
@@ -3721,7 +3646,7 @@ const m = {
m.throwBlock();
m.wakeCheck();
} else if (input.field && m.fieldCDcycle < m.cycle) { //not hold but field button is pressed
const drain = 0.0014 / (1 + 0.5 * m.coupling)
const drain = 0.0014 / (1 + 0.05 * m.coupling)
if (m.energy > drain) m.energy -= drain
m.grabPowerUp();
if (this.rewindCount === 0) {
@@ -3810,7 +3735,7 @@ const m = {
m.holding();
m.throwBlock();
} else if (input.field && m.fieldCDcycle < m.cycle) {
const drain = 0.0026 / (1 + 0.3 * m.coupling)
const drain = 0.0026 / (1 + 0.03 * m.coupling)
if (m.energy > drain) m.energy -= drain
m.grabPowerUp();
m.lookForPickUp(); //this drains energy 0.001
@@ -3870,6 +3795,33 @@ const m = {
m.isSneakAttack = true;
m.sneakAttackCycle = 0;
m.enterCloakCycle = 0;
m.drawCloakedM = function () {
m.walk_cycle -= m.flipLegs * m.Vx;
m.draw();
// let history = m.history[(m.cycle - 1) % 600]
// m.pos.x = history.position.x
// m.pos.y = history.position.y + m.yPosDifference - history.yOff
// m.pos.x += 4
// ctx.fillStyle = m.fillColor;
// ctx.save();
// ctx.translate(m.pos.x, m.pos.y);
// m.calcLeg(Math.PI, -3);
// m.drawLeg("#ccc");
// m.calcLeg(0, 0);
// m.drawLeg("#ccc");
// ctx.rotate(m.angle);
// ctx.beginPath();
// ctx.arc(0, 0, 30, 0, 2 * Math.PI);
// ctx.fillStyle = "#fff"
// ctx.fill();
// ctx.arc(15, 0, 4, 0, 2 * Math.PI);
// ctx.strokeStyle = "#333";
// ctx.lineWidth = 2;
// ctx.stroke();
// ctx.restore()
}
m.drawCloak = function () {
m.fieldPhase += 0.007
const wiggle = 0.15 * Math.sin(m.fieldPhase * 0.5)
@@ -3905,6 +3857,7 @@ const m = {
if (!m.isCloak && m.energy > drain + 0.03) {
m.energy -= drain
m.isCloak = true //enter cloak
m.fieldHarmReduction = 0.5;
m.enterCloakCycle = m.cycle
if (tech.isCloakHealLastHit && m.lastHit > 0) {
const heal = Math.min(0.75 * m.lastHit, m.energy)
@@ -3930,6 +3883,8 @@ const m = {
} else if (m.isCloak) { //exit cloak
m.sneakAttackCycle = m.cycle
m.isCloak = false
m.fieldHarmReduction = 1
if (tech.isIntangible) {
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType && bullet[i].botType !== "orbit") bullet[i].collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield
@@ -3963,6 +3918,9 @@ const m = {
m.fieldRange = m.fieldRange * 0.85 + 130
m.fieldDrawRadius = m.fieldRange * 1.1 //* 0.88 //* Math.min(1, 0.3 + 0.5 * Math.min(1, energy * energy));
m.drawCloak()
ctx.globalCompositeOperation = "lighter";
m.drawCloakedM()
ctx.globalCompositeOperation = "source-over";
} else if (m.fieldRange < 4000) {
m.fieldRange += 90
m.fieldDrawRadius = m.fieldRange //* Math.min(1, 0.3 + 0.5 * Math.min(1, energy * energy));
@@ -3985,153 +3943,14 @@ const m = {
}
}
this.drawRegenEnergyCloaking()
//show sneak attack status
// if (m.cycle > m.lastKillCycle + 240) {
// if (m.sneakAttackCharge > 0) {
// if (m.sneakAttackCycle + Math.min(120, 0.7 * (m.cycle - m.enterCloakCycle)) > m.cycle) {
// ctx.strokeStyle = "rgba(0,0,0,0.5)" //m.fieldMeterColor; //"rgba(255,255,0,0.2)" //ctx.strokeStyle = `rgba(0,0,255,${0.5+0.5*Math.random()})`
// ctx.beginPath();
// ctx.arc(simulation.mouseInGame.x, simulation.mouseInGame.y, 16, 0, 2 * Math.PI);
// ctx.fillStyle = "rgba(0,0,0,0.2)"
// ctx.fill();
// }
if (m.isSneakAttack && m.sneakAttackCycle + Math.min(120, 0.5 * (m.cycle - m.enterCloakCycle)) > m.cycle) { //show sneak attack status
ctx.globalCompositeOperation = "multiply";
m.drawCloakedM()
ctx.globalCompositeOperation = "source-over";
}
}
}
},
// {
// name: "phase decoherence field",
// description: "use <strong class='color-f'>energy</strong> to become <strong>intangible</strong><br><strong>firing</strong> and touching <strong>shields</strong> <strong>drains</strong> <strong class='color-f'>energy</strong><br>unable to <strong>see</strong> and be <strong>seen</strong> by mobs",
// effect: () => {
// m.fieldFire = true;
// m.fieldMeterColor = "#fff";
// m.fieldPhase = 0;
// m.hold = function () {
// function drawField(radius) {
// radius *= Math.min(4, 0.9 + 2.2 * m.energy * m.energy);
// const rotate = m.cycle * 0.005;
// m.fieldPhase += 0.5 - 0.5 * Math.sqrt(Math.max(0.01, Math.min(m.energy, 1)));
// const off1 = 1 + 0.06 * Math.sin(m.fieldPhase);
// const off2 = 1 - 0.06 * Math.sin(m.fieldPhase);
// ctx.beginPath();
// ctx.ellipse(m.pos.x, m.pos.y, radius * off1, radius * off2, rotate, 0, 2 * Math.PI);
// if (m.fireCDcycle > m.cycle && (input.field)) {
// ctx.lineWidth = 5;
// ctx.strokeStyle = `rgba(0, 204, 255,1)`
// ctx.stroke()
// }
// ctx.fillStyle = "#fff" //`rgba(0,0,0,${0.5+0.5*m.energy})`;
// ctx.globalCompositeOperation = "destination-in"; //in or atop
// ctx.fill();
// ctx.globalCompositeOperation = "source-over";
// ctx.clip();
// }
// m.isCloak = false //isCloak disables most uses of foundPlayer()
// player.collisionFilter.mask = cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield //normal collisions
// if (m.isHolding) {
// if (this.fieldRange < 2000) {
// this.fieldRange += 100
// drawField(this.fieldRange)
// }
// m.drawHold(m.holdingTarget);
// m.holding();
// m.throwBlock();
// } else if (input.field) {
// m.grabPowerUp();
// m.lookForPickUp();
// if (m.fieldCDcycle < m.cycle) {
// // simulation.draw.bodyFill = "transparent"
// // simulation.draw.bodyStroke = "transparent"
// const DRAIN = 0.00013 + (m.fireCDcycle > m.cycle ? 0.005 : 0)
// if (m.energy > DRAIN) {
// m.energy -= DRAIN;
// // if (m.energy < 0.001) {
// // m.fieldCDcycle = m.cycle + 120;
// // m.energy = 0;
// // 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)
// // }
// this.fieldRange = this.fieldRange * 0.8 + 0.2 * 160
// drawField(this.fieldRange)
// m.isCloak = true //isCloak disables most uses of foundPlayer()
// player.collisionFilter.mask = cat.map
// let inPlayer = Matter.Query.region(mob, player.bounds)
// if (inPlayer.length > 0) {
// for (let i = 0; i < inPlayer.length; i++) {
// if (inPlayer[i].shield) {
// m.energy -= 0.005; //shields drain player energy
// //draw outline of shield
// ctx.fillStyle = `rgba(140,217,255,0.5)`
// ctx.fill()
// } else if (tech.superposition && inPlayer[i].isDropPowerUp) {
// // inPlayer[i].damage(0.4 * m.dmgScale); //damage mobs inside the player
// // m.energy += 0.005;
// mobs.statusStun(inPlayer[i], 300)
// //draw outline of mob in a few random locations to show blurriness
// const vertices = inPlayer[i].vertices;
// const off = 30
// for (let k = 0; k < 3; k++) {
// const xOff = off * (Math.random() - 0.5)
// const yOff = off * (Math.random() - 0.5)
// ctx.beginPath();
// ctx.moveTo(xOff + vertices[0].x, yOff + vertices[0].y);
// for (let j = 1, len = vertices.length; j < len; ++j) {
// ctx.lineTo(xOff + vertices[j].x, yOff + vertices[j].y);
// }
// ctx.lineTo(xOff + vertices[0].x, yOff + vertices[0].y);
// ctx.fillStyle = "rgba(0,0,0,0.1)"
// ctx.fill()
// }
// break;
// }
// }
// }
// } else {
// m.fieldCDcycle = m.cycle + 120;
// m.energy = 0;
// 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)
// drawField(this.fieldRange)
// }
// }
// } else if (m.holdingTarget && m.fieldCDcycle < m.cycle) { //holding, but field button is released
// m.pickUp();
// if (this.fieldRange < 2000) {
// this.fieldRange += 100
// drawField(this.fieldRange)
// }
// } else {
// // this.fieldRange = 3000
// if (this.fieldRange < 2000 && m.holdingTarget === null) {
// this.fieldRange += 100
// drawField(this.fieldRange)
// }
// 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 (m.energy < m.maxEnergy) {
// m.energy += m.fieldRegen;
// const xOff = m.pos.x - m.radius * m.maxEnergy
// const yOff = m.pos.y - 50
// ctx.fillStyle = "rgba(0, 0, 0, 0.3)";
// ctx.fillRect(xOff, yOff, 60 * m.maxEnergy, 10);
// ctx.fillStyle = m.fieldMeterColor;
// ctx.fillRect(xOff, yOff, 60 * m.energy, 10);
// ctx.beginPath()
// ctx.rect(xOff, yOff, 60 * m.maxEnergy, 10);
// ctx.strokeStyle = "rgb(0, 0, 0)";
// ctx.lineWidth = 1;
// ctx.stroke();
// }
// if (m.energy < 0) m.energy = 0
// }
// }
// },
{
name: "pilot wave",
//<br><strong class='color-block'>blocks</strong> can't <strong>collide</strong> with <strong>intangible</strong> mobs
@@ -4450,7 +4269,7 @@ const m = {
Matter.Composite.remove(engine.world, body[i]);
body.splice(i, 1);
m.fieldRange *= 0.8
if ((m.fieldMode === 0 || m.fieldMode === 9) && m.immuneCycle < m.cycle) m.energy += 0.2 * m.coupling
if ((m.fieldMode === 0 || m.fieldMode === 9) && m.immuneCycle < m.cycle) m.energy += 0.02 * m.coupling
if (tech.isWormholeWorms) { //pandimensional spermia
b.worm(Vector.add(m.hole.pos2, Vector.rotate({ x: m.fieldRange * 0.4, y: 0 }, 2 * Math.PI * Math.random())))
Matter.Body.setVelocity(bullet[bullet.length - 1], Vector.mult(Vector.rotate(m.hole.unit, Math.PI / 2), -10));
@@ -4474,8 +4293,8 @@ const m = {
m.fieldRange *= 0.8
// if (tech.isWormholeEnergy && m.energy < m.maxEnergy * 2) m.energy = m.maxEnergy * 2
// if (tech.isWormholeEnergy && m.immuneCycle < m.cycle) m.energy += 0.5
if ((m.fieldMode === 0 || m.fieldMode === 9) && m.immuneCycle < m.cycle) m.energy += 0.2 * m.coupling
if (m.fieldMode === 0 || m.fieldMode === 9) m.energy += 0.2 * m.coupling
if ((m.fieldMode === 0 || m.fieldMode === 9) && m.immuneCycle < m.cycle) m.energy += 0.02 * m.coupling
if (m.fieldMode === 0 || m.fieldMode === 9) m.energy += 0.02 * m.coupling
if (tech.isWormholeWorms) { //pandimensional spermia
b.worm(Vector.add(m.hole.pos1, Vector.rotate({
x: m.fieldRange * 0.4,
@@ -4528,7 +4347,7 @@ const m = {
if (input.field) {
if (tech.isWormHolePause) {
const drain = m.fieldRegen + 0.0002
const drain = m.fieldRegen + 0.00004
if (m.energy > drain) {
m.energy -= drain
if (m.immuneCycle < m.cycle + 1) m.immuneCycle = m.cycle + 1; //player is immune to damage for 1 cycle

View File

@@ -351,7 +351,7 @@ const powerUps = {
simulation.paused = true;
document.getElementById("choose-grid").style.opacity = "1"
}
document.getElementById("choose-grid").style.transitionDuration = "0.25s"; //how long is the fade in on
document.getElementById("choose-grid").style.transitionDuration = "0.5s"; //how long is the fade in on
document.getElementById("choose-grid").style.visibility = "visible"
requestAnimationFrame(() => {
@@ -429,7 +429,7 @@ const powerUps = {
return 13;
},
effect() {
m.couplingChange(0.1)
m.couplingChange(1)
},
// spawnDelay(num) {
// let count = num
@@ -1069,7 +1069,6 @@ const powerUps = {
for (let j = 0, len = tech.tech[i].frequency; j < len; j++) options.push(i);
}
}
function removeOption(index) {
for (let i = options.length - 1; i > -1; i--) {
if (index === options[i]) {
@@ -1321,24 +1320,10 @@ const powerUps = {
tech.isFlipFlopOn = false
if (document.getElementById("tech-switch")) document.getElementById("tech-switch").innerHTML = ` = <strong>OFF</strong>`
m.eyeFillColor = 'transparent'
if (tech.isFlipFlopCoupling) {
m.couplingChange(-5)
for (let i = 0; i < mob.length; i++) {
if (mob[i].isDecoupling) mob[i].alive = false //remove WIMP
}
spawn.WIMP()
mob[mob.length - 1].isDecoupling = true //so you can find it to remove
}
} else {
tech.isFlipFlopOn = true //immune to damage this hit, lose immunity for next hit
if (document.getElementById("tech-switch")) document.getElementById("tech-switch").innerHTML = ` = <strong>ON</strong>`
m.eyeFillColor = m.fieldMeterColor //'#0cf'
if (tech.isFlipFlopCoupling) {
m.couplingChange(5)
for (let i = 0; i < mob.length; i++) {
if (mob[i].isDecoupling) mob[i].alive = false //remove WIMP
}
}
}
if (tech.isRelayEnergy) m.setMaxEnergy();
}

View File

@@ -20,7 +20,6 @@ const simulation = {
mobs.draw();
simulation.draw.cons();
simulation.draw.body();
simulation.checks();
if (!m.isBodiesAsleep) mobs.loop();
mobs.healthBar();
m.draw();
@@ -51,7 +50,6 @@ const simulation = {
}
m.move();
m.look();
simulation.checks();
simulation.camera();
level.custom();
m.draw();
@@ -90,7 +88,6 @@ const simulation = {
}
m.move();
level.custom();
simulation.checks();
mobs.loop();
m.walk_cycle += m.flipLegs * m.Vx;
m.hold();
@@ -111,7 +108,6 @@ const simulation = {
Engine.update(engine, simulation.delta);
// level.custom();
// level.customTopLayer();
simulation.checks();
if (!m.isBodiesAsleep) mobs.loop();
if (m.fieldMode !== 7) m.hold();
b.bulletRemove();
@@ -153,7 +149,6 @@ const simulation = {
// simulation.draw.cons();
// simulation.draw.body();
// if (!m.isBodiesAsleep) {
// simulation.checks();
// // mobs.loop();
// }
// mobs.healthBar();
@@ -464,7 +459,7 @@ const simulation = {
// SVGleftMouse: '<svg viewBox="750 0 200 765" class="mouse-icon" width="40px" height = "60px" stroke-linecap="round" stroke-linejoin="round" stroke-width="25px" stroke="#000" fill="none"> <path fill="#fff" stroke="none" d="M827,112 h30 a140,140,0,0,1,140,140 v268 a140,140,0,0,1-140,140 h-60 a140,140,0,0,1-140-140v-268 a140,140,0,0,1,140-140h60" /> <path d="M832.41,106.64 V323.55 H651.57 V256.64 c0-82.5,67.5-150,150-150 Z" fill="#149" stroke="none" /> <path fill="none" d="M827,112 h30 a140,140,0,0,1,140,140 v268 a140,140,0,0,1-140,140 h-60 a140,140,0,0,1-140-140v-268 a140,140,0,0,1,140-140h60" /> <path d="M657 317 h 340 h-170 v-207" /> <ellipse fill="#fff" cx="827.57" cy="218.64" rx="29" ry="68" /> </svg>',
// SVGrightMouse: '<svg viewBox="750 0 200 765" class="mouse-icon" width="40px" height = "60px" stroke-linecap="round" stroke-linejoin="round" stroke-width="25px" stroke="#000" fill="none"> <path fill="#fff" stroke="none" d="M827,112 h30 a140,140,0,0,1,140,140 v268 a140,140,0,0,1-140,140 h-60 a140,140,0,0,1-140-140v-268 a140,140,0,0,1,140-140h60" /> <path d="M827,112 h30 a140,140,0,0,1,140,140 v68 h-167 z" fill="#0cf" stroke="none" /> <path fill="none" d="M827,112 h30 a140,140,0,0,1,140,140 v268 a140,140,0,0,1-140,140 h-60 a140,140,0,0,1-140-140v-268 a140,140,0,0,1,140-140h60" /> <path d="M657 317 h 340 h-170 v-207" /> <ellipse fill="#fff" cx="827.57" cy="218.64" rx="29" ry="68" /> </svg>',
makeTextLog(text, time = 240) {
if (simulation.isTextLogOpen && !build.isExperimentSelection) {
if (!localSettings.isHideHUD && simulation.isTextLogOpen && !build.isExperimentSelection) {
if (simulation.lastLogTime > m.cycle) { //if there is an older message
document.getElementById("text-log").innerHTML = document.getElementById("text-log").innerHTML + '<br>' + text;
simulation.lastLogTime = m.cycle + time;
@@ -735,12 +730,18 @@ const simulation = {
document.getElementById("dmg").style.display = "inline";
document.getElementById("health").style.display = "inline"
document.getElementById("health-bg").style.display = "inline";
if (!localSettings.isHideHUD) {
document.getElementById("tech").style.display = "inline"
document.getElementById("defense-bar").style.display = "inline"
document.getElementById("damage-bar").style.display = "inline"
document.getElementById("tech").style.display = "inline"
} else {
document.getElementById("tech").style.display = "none"
document.getElementById("defense-bar").style.display = "none"
document.getElementById("damage-bar").style.display = "none"
}
document.getElementById("guns").style.display = "inline"
document.getElementById("field").style.display = "inline"
// document.body.style.overflow = "hidden"
document.getElementById("pause-grid-left").style.display = "none"
document.getElementById("pause-grid-right").style.display = "none"
@@ -878,6 +879,138 @@ const simulation = {
build.isExperimentSelection = false;
build.isExperimentRun = false;
//setup checks
if (!localSettings.isHideHUD) {
simulation.ephemera.push({
name: "dmgDefBars", count: 0, do() {
if (!(m.cycle % 15)) { //4 times a second
const defense = m.defense() //update defense bar
if (m.lastCalculatedDefense !== defense) {
document.getElementById("defense-bar").style.width = Math.floor(300 * m.maxHealth * (1 - defense)) + "px";
m.lastCalculatedDefense = defense
}
const damage = tech.damageFromTech() //update damage bar
if (m.lastCalculatedDamage !== damage) {
document.getElementById("damage-bar").style.height = Math.floor((Math.atan(0.25 * damage - 0.25) + 0.25) * 0.53 * canvas.height) + "px";
m.lastCalculatedDamage = damage
}
}
},
})
}
simulation.ephemera.push({
name: "uniqueName", count: 0, do() {
if (!(m.cycle % 60)) { //once a second
//energy overfill
if (m.energy > m.maxEnergy) {
m.energy = m.maxEnergy + (m.energy - m.maxEnergy) * tech.overfillDrain //every second energy above max energy loses 25%
if (m.energy > 1000000) m.energy = 1000000
}
if (tech.isFlipFlopEnergy && m.immuneCycle < m.cycle) {
if (tech.isFlipFlopOn) {
if (m.immuneCycle < m.cycle) m.energy += 0.2;
} else {
m.energy -= 0.01;
if (m.energy < 0) m.energy = 0
}
}
if (tech.relayIce && tech.isFlipFlopOn) {
for (let j = 0; j < tech.relayIce; j++) {
for (let i = 0, len = 3 + Math.ceil(9 * Math.random()); i < len; i++) b.iceIX(2)
}
}
if (m.pos.y > simulation.fallHeight) { // if 4000px deep
Matter.Body.setVelocity(player, {
x: 0,
y: 0
});
Matter.Body.setPosition(player, {
x: level.enter.x + 50,
y: level.enter.y - 20
});
// move bots
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType) {
Matter.Body.setPosition(bullet[i], Vector.add(player.position, {
x: 250 * (Math.random() - 0.5),
y: 250 * (Math.random() - 0.5)
}));
Matter.Body.setVelocity(bullet[i], {
x: 0,
y: 0
});
}
}
m.damage(0.1 * simulation.difficultyMode);
m.energy -= 0.1 * simulation.difficultyMode
}
if (isNaN(player.position.x)) m.death();
if (m.lastKillCycle + 300 > m.cycle) { //effects active for 5 seconds after killing a mob
if (tech.isEnergyRecovery && m.immuneCycle < m.cycle) {
m.energy += m.maxEnergy * 0.05
simulation.drawList.push({ //add dmg to draw queue
x: m.pos.x,
y: m.pos.y - 45,
radius: Math.sqrt(m.maxEnergy * 0.05) * 60,
color: "rgba(0, 204, 255,0.4)", //#0cf
time: 4
});
}
if (tech.isHealthRecovery) {
const heal = 0.005 * m.maxHealth
m.addHealth(heal)
simulation.drawList.push({ //add dmg to draw queue
x: m.pos.x,
y: m.pos.y,
radius: Math.sqrt(heal) * 150,
color: "rgba(0,255,200,0.5)",
time: 4
});
}
}
if (!(m.cycle % 420)) { //once every 7 seconds
if (tech.isZeno) {
if (tech.isEnergyHealth) {
m.energy *= 0.95
} else {
m.health *= 0.95 //remove 5%
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) {
let i = who.length;
while (i--) {
if (who[i].position.y > simulation.fallHeight) {
if (save) {
Matter.Body.setVelocity(who[i], {
x: 0,
y: 0
});
Matter.Body.setPosition(who[i], {
x: level.exit.x + 30 * (Math.random() - 0.5),
y: level.exit.y + 30 * (Math.random() - 0.5)
});
} else {
Matter.Composite.remove(engine.world, who[i]);
who.splice(i, 1);
}
}
}
};
fallCheck(mob);
fallCheck(body);
fallCheck(powerUp, true);
}
}
},
})
//setup FPS cap
simulation.fpsInterval = 1000 / simulation.fpsCap;
simulation.then = Date.now();
@@ -1172,127 +1305,6 @@ const simulation = {
// }
// }
// },
checks() {
if (!(m.cycle % 15)) { //4 times a second
const defense = m.defense() //update defense bar
if (m.lastCalculatedDefense !== defense) {
document.getElementById("defense-bar").style.width = Math.floor(300 * m.maxHealth * (1 - defense)) + "px";
m.lastCalculatedDefense = defense
}
const damage = tech.damageFromTech() //update damage bar
if (m.lastCalculatedDamage !== damage) {
document.getElementById("damage-bar").style.height = Math.floor((Math.atan(0.25 * damage - 0.25) + 0.25) * 0.53 * canvas.height) + "px";
m.lastCalculatedDamage = damage
}
}
if (!(m.cycle % 60)) { //once a second
//energy overfill
if (m.energy > m.maxEnergy) {
m.energy = m.maxEnergy + (m.energy - m.maxEnergy) * tech.overfillDrain //every second energy above max energy loses 25%
if (m.energy > 1000000) m.energy = 1000000
}
if (tech.isFlipFlopEnergy && m.immuneCycle < m.cycle) {
if (tech.isFlipFlopOn) {
if (m.immuneCycle < m.cycle) m.energy += 0.2;
} else {
m.energy -= 0.01;
if (m.energy < 0) m.energy = 0
}
}
if (tech.relayIce && tech.isFlipFlopOn) {
for (let j = 0; j < tech.relayIce; j++) {
for (let i = 0, len = 3 + Math.ceil(9 * Math.random()); i < len; i++) b.iceIX(2)
}
}
if (m.pos.y > simulation.fallHeight) { // if 4000px deep
Matter.Body.setVelocity(player, {
x: 0,
y: 0
});
Matter.Body.setPosition(player, {
x: level.enter.x + 50,
y: level.enter.y - 20
});
// move bots
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType) {
Matter.Body.setPosition(bullet[i], Vector.add(player.position, {
x: 250 * (Math.random() - 0.5),
y: 250 * (Math.random() - 0.5)
}));
Matter.Body.setVelocity(bullet[i], {
x: 0,
y: 0
});
}
}
m.damage(0.1 * simulation.difficultyMode);
m.energy -= 0.1 * simulation.difficultyMode
}
if (isNaN(player.position.x)) m.death();
if (m.lastKillCycle + 300 > m.cycle) { //effects active for 5 seconds after killing a mob
if (tech.isEnergyRecovery && m.immuneCycle < m.cycle) {
m.energy += m.maxEnergy * 0.05
simulation.drawList.push({ //add dmg to draw queue
x: m.pos.x,
y: m.pos.y - 45,
radius: Math.sqrt(m.maxEnergy * 0.05) * 60,
color: "rgba(0, 204, 255,0.4)", //#0cf
time: 4
});
}
if (tech.isHealthRecovery) {
const heal = 0.005 * m.maxHealth
m.addHealth(heal)
simulation.drawList.push({ //add dmg to draw queue
x: m.pos.x,
y: m.pos.y,
radius: Math.sqrt(heal) * 150,
color: "rgba(0,255,200,0.5)",
time: 4
});
}
}
if (!(m.cycle % 420)) { //once every 7 seconds
if (tech.isZeno) {
if (tech.isEnergyHealth) {
m.energy *= 0.95
} else {
m.health *= 0.95 //remove 5%
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) {
let i = who.length;
while (i--) {
if (who[i].position.y > simulation.fallHeight) {
if (save) {
Matter.Body.setVelocity(who[i], {
x: 0,
y: 0
});
Matter.Body.setPosition(who[i], {
x: level.exit.x + 30 * (Math.random() - 0.5),
y: level.exit.y + 30 * (Math.random() - 0.5)
});
} else {
Matter.Composite.remove(engine.world, who[i]);
who.splice(i, 1);
}
}
}
};
fallCheck(mob);
fallCheck(body);
fallCheck(powerUp, true);
}
}
},
testingOutput() {
ctx.fillStyle = "#000";
ctx.textAlign = "center";

View File

@@ -220,20 +220,21 @@ const tech = {
damage: 1, //used for tech changes to player damage that don't have complex conditions
damageFromTech() {
let dmg = tech.damage //m.fieldDamage
if (tech.isDivisor) {
for (let i = 0; i < b.inventory.length; i++) {
if (b.guns[b.inventory[i]].ammo % 3 === 0) {
dmg *= 1.44
break
}
}
}
// if (tech.isDivisor) {
// for (let i = 0; i < b.inventory.length; i++) {
// if (b.guns[b.inventory[i]].ammo % 3 === 0) {
// dmg *= 1.44
// break
// }
// }
// }
if (tech.isDivisor && b.guns[b.activeGun].ammo % 3 === 0) dmg *= 1.83
if (tech.isNoGroundDamage) dmg *= m.onGround ? 0.78 : 1.88
if (tech.isDilate) dmg *= 1.5 + 0.6 * Math.sin(m.cycle * 0.0075)
if (tech.isGunChoice && tech.buffedGun === b.inventoryGun) dmg *= 1 + 0.31 * b.inventory.length
if (powerUps.boost.endCycle > m.cycle) dmg *= 1 + powerUps.boost.damage
if (m.coupling && (m.fieldMode === 0 || m.fieldMode === 5)) dmg *= 1 + 0.15 * m.coupling
if (m.isSneakAttack && m.sneakAttackCycle + Math.min(120, 0.5 * (m.cycle - m.enterCloakCycle)) > m.cycle) dmg *= 4.33 * (1 + 0.33 * m.coupling)
if (m.coupling && (m.fieldMode === 0 || m.fieldMode === 5)) dmg *= 1 + 0.015 * m.coupling
if (m.isSneakAttack && m.sneakAttackCycle + Math.min(120, 0.5 * (m.cycle - m.enterCloakCycle)) > m.cycle) dmg *= 4.33 * (1 + 0.033 * m.coupling)
if (tech.deathSkipTime) dmg *= 1 + 0.6 * tech.deathSkipTime
if (tech.isTechDebt) dmg *= tech.totalCount > 2 ? Math.pow(0.85, tech.totalCount - 20) : 4 - 0.15 * tech.totalCount // if (tech.isTechDebt) dmg *= Math.min(Math.pow(0.85, tech.totalCount - 20), 4 - 0.15 * tech.totalCount)
if (tech.isFlipFlopDamage && tech.isFlipFlopOn) dmg *= 1.555
@@ -258,7 +259,7 @@ const tech = {
return dmg
},
duplicationChance() {
return Math.min(1, Math.max(0, (tech.isPowerUpsVanish ? 0.12 : 0) + (tech.isStimulatedEmission ? 0.15 : 0) + tech.duplication + tech.duplicateChance + 0.05 * tech.isExtraGunField + m.duplicateChance + tech.fieldDuplicate + tech.cloakDuplication + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.5 : 0) + tech.isQuantumEraserDuplication * (1 - 0.016 * (simulation.difficultyMode ** 2)))) // + (m.fieldMode === 0 || m.fieldMode === 9) * 0.03 * m.coupling)
return Math.min(1, Math.max(0, (tech.isPowerUpsVanish ? 0.12 : 0) + (tech.isStimulatedEmission ? 0.15 : 0) + tech.duplication + tech.duplicateChance + 0.05 * tech.isExtraGunField + m.duplicateChance + tech.fieldDuplicate + tech.cloakDuplication + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.5 : 0) + tech.isQuantumEraserDuplication * (1 - 0.016 * (simulation.difficultyMode ** 2))))
},
isScaleMobsWithDuplication: false,
maxDuplicationEvent() {
@@ -541,7 +542,7 @@ const tech = {
{
name: "ternary", //"divisor",
descriptionFunction() {
return `<strong>+44%</strong> <strong class='color-d'>damage</strong> while one of your <strong class='color-g'>guns</strong><br>has <strong class='color-ammo'>ammo</strong> divisible by <strong>3</strong>`
return `<strong>+83%</strong> <strong class='color-d'>damage</strong> while your current <strong class='color-g'>gun</strong><br>has <strong class='color-ammo'>ammo</strong> divisible by <strong>3</strong>`
},
maxCount: 1,
count: 0,
@@ -2146,12 +2147,6 @@ const tech = {
tech.isFlipFlop = true //do you have this tech?
if (!tech.isFlipFlopOn) {
tech.isFlipFlopOn = true //what is the state of flip-Flop?
if (tech.isFlipFlopCoupling) {
m.couplingChange(5)
for (let i = 0; i < mob.length; i++) {
if (mob[i].isDecoupling) mob[i].alive = false //remove WIMP
}
}
}
// if (!m.isShipMode) {
// m.skin.flipFlop()
@@ -2161,12 +2156,6 @@ const tech = {
tech.isFlipFlop = false
if (tech.isFlipFlopOn) {
tech.isFlipFlopOn = false //what is the state of flip-Flop?
if (tech.isFlipFlopCoupling) {
m.couplingChange(5)
for (let i = 0; i < mob.length; i++) {
if (mob[i].isDecoupling) mob[i].alive = false //remove WIMP
}
}
}
m.eyeFillColor = 'transparent'
// m.resetSkin();
@@ -2226,49 +2215,49 @@ const tech = {
tech.isFlipFlopEnergy = false;
}
},
{
name: "decoupling",
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Decoupling_(cosmology)' class="link">decoupling</a>`,
descriptionFunction() {
//<span style = 'font-size:80%;'>(${ m.couplingDescription(this.bonus)})</span>
return `if <strong class='color-flop'>ON</strong> <strong>+5</strong> <strong class='color-coupling'>coupling</strong><br>if <strong class='color-flop'>OFF</strong> a dangerous particle slowly <strong>chases</strong> you`
},
maxCount: 1,
count: 0,
frequency: 3,
frequencyDefault: 3,
bonus: 5, //coupling given
allowed() {
return tech.isFlipFlop || tech.isRelay
},
requires: "ON/OFF tech",
effect() {
tech.isFlipFlopCoupling = true;
if (tech.isFlipFlopOn) {
m.couplingChange(this.bonus)
} else {
for (let i = 0; i < mob.length; i++) {
if (mob[i].isDecoupling) mob[i].alive = false //remove WIMP
}
spawn.WIMP()
mob[mob.length - 1].isDecoupling = true //so you can find it to remove
}
},
remove() {
tech.isFlipFlopCoupling = false;
if (this.count) {
if (tech.isFlipFlop || tech.isRelay) {
if (tech.isFlipFlopOn) {
m.couplingChange(-this.bonus)
} else {
for (let i = 0; i < mob.length; i++) {
if (mob[i].isDecoupling) mob[i].alive = false //remove WIMP
}
}
}
}
}
},
// {
// name: "decoupling",
// link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Decoupling_(cosmology)' class="link">decoupling</a>`,
// descriptionFunction() {
// //<span style = 'font-size:80%;'>(${ m.couplingDescription(this.bonus)})</span>
// return `if <strong class='color-flop'>ON</strong> <strong>+5</strong> <strong class='color-coupling'>coupling</strong><br>if <strong class='color-flop'>OFF</strong> a dangerous particle slowly <strong>chases</strong> you`
// },
// maxCount: 1,
// count: 0,
// frequency: 3,
// frequencyDefault: 3,
// bonus: 5, //coupling given
// allowed() {
// return tech.isFlipFlop || tech.isRelay
// },
// requires: "ON/OFF tech",
// effect() {
// tech.isFlipFlopCoupling = true;
// if (tech.isFlipFlopOn) {
// m.couplingChange(this.bonus)
// } else {
// for (let i = 0; i < mob.length; i++) {
// if (mob[i].isDecoupling) mob[i].alive = false //remove WIMP
// }
// spawn.WIMP()
// mob[mob.length - 1].isDecoupling = true //so you can find it to remove
// }
// },
// remove() {
// tech.isFlipFlopCoupling = false;
// if (this.count) {
// if (tech.isFlipFlop || tech.isRelay) {
// if (tech.isFlipFlopOn) {
// m.couplingChange(-this.bonus)
// } else {
// for (let i = 0; i < mob.length; i++) {
// if (mob[i].isDecoupling) mob[i].alive = false //remove WIMP
// }
// }
// }
// }
// }
// },
{
name: "relay switch",
description: `toggle <strong class="color-flop">ON</strong> and <strong class="color-flop">OFF</strong> after picking up a <strong>power up</strong><br>unlock advanced <strong class='color-m'>tech</strong> that runs if <strong class="color-flop">ON</strong>`,
@@ -2299,12 +2288,6 @@ const tech = {
tech.isRelay = true //do you have this tech?
if (!tech.isFlipFlopOn) {
tech.isFlipFlopOn = true //what is the state of flip-Flop?
if (tech.isFlipFlopCoupling) {
m.couplingChange(5)
for (let i = 0; i < mob.length; i++) {
if (mob[i].isDecoupling) mob[i].alive = false //remove WIMP
}
}
}
// if (!m.isShipMode) {
// m.skin.flipFlop()
@@ -2314,12 +2297,6 @@ const tech = {
tech.isRelay = false
if (tech.isFlipFlopOn) {
tech.isFlipFlopOn = false //what is the state of flip-Flop?
if (tech.isFlipFlopCoupling) {
m.couplingChange(-5)
for (let i = 0; i < mob.length; i++) {
if (mob[i].isDecoupling) mob[i].alive = false //remove WIMP
}
}
}
m.eyeFillColor = 'transparent'
// m.resetSkin();
@@ -3726,7 +3703,8 @@ const tech = {
{
name: "field coupling",
descriptionFunction() {
return `spawn ${powerUps.orb.coupling(10)}<br>that each give <strong>+0.1</strong> <strong class='color-coupling'>coupling</strong>` //<br>${m.couplingDescription(1)} ${m.fieldMode === 0 ? "" : "per <strong class='color-coupling'>coupling</strong>"}
// return `spawn ${powerUps.orb.coupling(10)}<br>that each give <strong>+0.1</strong> <strong class='color-coupling'>coupling</strong>` //<br>${m.couplingDescription(1)} ${m.fieldMode === 0 ? "" : "per <strong class='color-coupling'>coupling</strong>"}
return `spawn ${powerUps.orb.coupling(10)}<br><em>${m.couplingDescription(1)} per ${powerUps.orb.coupling(1)}</em>`
},
maxCount: 9,
count: 0,
@@ -3740,9 +3718,7 @@ const tech = {
powerUps.spawnDelay("coupling", 10)
},
remove() {
if (this.count) {
m.couplingChange(-this.count)
}
if (this.count) m.couplingChange(-this.count * 10)
}
},
{
@@ -3757,7 +3733,9 @@ const tech = {
} else {
orbText = powerUps.orb.coupling(converted)
}
return `use all your ${powerUps.orb.research(1)} to spawn <strong>${orbText}</strong><br>that each give <strong>+0.1</strong> <strong class='color-coupling'>coupling</strong>`//<br>${m.couplingDescription(1)} ${m.fieldMode === 0 ? "" : "per <strong class='color-coupling'>coupling</strong>"}
// return `use all your ${powerUps.orb.research(1)} to spawn <strong>${orbText}</strong><br>that each give <strong>+0.1</strong> <strong class='color-coupling'>coupling</strong>`//<br>${m.couplingDescription(1)} ${m.fieldMode === 0 ? "" : "per <strong class='color-coupling'>coupling</strong>"}
return `use all your ${powerUps.orb.research(1)} to spawn <strong>${orbText}</strong><br><em>${m.couplingDescription(1)} per ${powerUps.orb.coupling(1)}</em>`
},
maxCount: 1,
count: 0,
@@ -3768,7 +3746,7 @@ const tech = {
},
requires: "",
researchUsed: 0,
couplingToResearch: 0.25,
couplingToResearch: 3,
effect() {
// let count = 0
// while (powerUps.research.count > 0 && powerUps.research.count !== Infinity) {
@@ -3802,7 +3780,8 @@ const tech = {
{
name: "virtual particles",
descriptionFunction() {
return `after mobs <strong>die</strong> they have a <strong>17%</strong> chance to<br>spawn ${powerUps.orb.coupling(1)} that each give <strong>+0.1</strong> <strong class='color-coupling'>coupling</strong>` //<br>${m.couplingDescription(1)} ${m.fieldMode === 0 ? "" : "per <strong class='color-coupling'>coupling</strong>"}
return `<strong>17%</strong> chance after mobs <strong>die</strong> to spawn ${powerUps.orb.coupling(1)}<br><em>${m.couplingDescription(1)} per ${powerUps.orb.coupling(1)}</em>`
// return `<strong>17%</strong> chance after mobs <strong>die</strong> to spawn ${powerUps.orb.coupling(1)} that each give <strong>+0.1</strong> <strong class='color-coupling'>coupling</strong>` //<br>${m.couplingDescription(1)} ${m.fieldMode === 0 ? "" : "per <strong class='color-coupling'>coupling</strong>"}
},
maxCount: 1,
count: 0,
@@ -3820,7 +3799,8 @@ const tech = {
{
name: "fine-structure constant",
descriptionFunction() {
return `spawn ${this.value} ${powerUps.orb.coupling(1)} that each give <strong>+0.1</strong> <strong class='color-coupling'>coupling</strong><br><strong>-0.5</strong> <strong class='color-coupling'>coupling</strong> after mob <strong>collisions</strong>`//<br>${m.couplingDescription(1)} ${m.fieldMode === 0 ? "" : "per <strong class='color-coupling'>coupling</strong>"}
// return `spawn ${this.value} ${powerUps.orb.coupling(1)} that each give <strong>+0.1</strong> <strong class='color-coupling'>coupling</strong><br><strong>-0.5</strong> <strong class='color-coupling'>coupling</strong> after mob <strong>collisions</strong>`//<br>${m.couplingDescription(1)} ${m.fieldMode === 0 ? "" : "per <strong class='color-coupling'>coupling</strong>"}
return `spawn ${this.value} ${powerUps.orb.coupling(1)}, but <strong>lose</strong> ${powerUps.orb.coupling(5)} after mob <strong>collisions</strong><br><em>${m.couplingDescription(1)} per ${powerUps.orb.coupling(1)}</em>`
},
maxCount: 1,
count: 0,
@@ -3835,16 +3815,15 @@ const tech = {
powerUps.spawnDelay("coupling", this.value)
},
remove() {
if (this.count) {
m.couplingChange(-this.value)
}
if (this.count) m.couplingChange(-this.value)
tech.isCouplingNoHit = false
}
},
{
name: "residual dipolar coupling",
descriptionFunction() {
return `clicking <strong class='color-cancel'>cancel</strong> for a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>spawns ${powerUps.orb.coupling(5)}that each give <strong>+0.1</strong> <strong class='color-coupling'>coupling</strong>`//<br>${m.couplingDescription(1)} ${m.fieldMode === 0 ? "" : "per <strong class='color-coupling'>coupling</strong>"}
// return `clicking <strong class='color-cancel'>cancel</strong> for a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong><br>spawns ${powerUps.orb.coupling(5)}that each give <strong>+0.1</strong> <strong class='color-coupling'>coupling</strong>`//<br>${m.couplingDescription(1)} ${m.fieldMode === 0 ? "" : "per <strong class='color-coupling'>coupling</strong>"}
return `clicking <strong class='color-cancel'>cancel</strong> spawns ${powerUps.orb.coupling(5)}<br><em>${m.couplingDescription(1)} per ${powerUps.orb.coupling(1)}</em>`
},
maxCount: 1,
count: 0,
@@ -4092,7 +4071,7 @@ const tech = {
tech.damage *= this.damage
},
remove() {
if (this.count > 0) {
if (this.count > 0 && m.alive) {
tech.damage /= this.damage
powerUps.spawnDelay("research", 15)
this.frequency = 0
@@ -7267,9 +7246,9 @@ const tech = {
frequency: 2,
frequencyDefault: 2,
allowed() {
return (m.fieldMode === 4 && tech.deflectEnergy === 0) || (m.fieldMode === 1 && tech.harmonics === 2) || m.fieldMode === 0
return (m.fieldMode === 4 && tech.deflectEnergy === 0) || (m.fieldMode === 1 && tech.harmonics === 2)
},
requires: "molecular assembler, standing wave, field emitter, not electric generator",
requires: "molecular assembler, standing wave, not electric generator",
effect() {
tech.isLaserField = true
},
@@ -7408,7 +7387,7 @@ const tech = {
{
name: "triple point",
descriptionFunction() {
return `<strong>+1.5</strong> second <strong class='color-s'>ice IX</strong> freeze effect<br>spawn ${powerUps.orb.coupling(10)} that each give <strong>+0.1</strong> <strong class='color-coupling'>coupling</strong>` //<br>${m.couplingDescription(1)} ${m.fieldMode === 0 ? "" : "per <strong class='color-coupling'>coupling</strong>"}
return `<strong>+1.5</strong> second <strong class='color-s'>ice IX</strong> freeze and spawn ${powerUps.orb.coupling(10)}<br><em>${m.couplingDescription(1)} per ${powerUps.orb.coupling(1)}</em>`
},
isFieldTech: true,
maxCount: 3,
@@ -7425,7 +7404,7 @@ const tech = {
},
remove() {
tech.iceIXFreezeTime = 150
if (this.count) m.couplingChange(-this.count)
if (this.count) m.couplingChange(-10 * this.count)
}
},
{
@@ -8369,28 +8348,28 @@ const tech = {
},
{
name: "vacuum fluctuation",
description: `use ${powerUps.orb.research(4)}to exploit your <strong class='color-f'>field</strong> for a<br><strong>+11%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong>`,
description: `use ${powerUps.orb.research(3)}to exploit your <strong class='color-f'>field</strong> for a<br><strong>+11%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong>`,
isFieldTech: true,
maxCount: 1,
count: 0,
frequency: 3,
frequencyDefault: 3,
allowed() {
return (m.fieldMode === 8 || m.fieldMode === 3 || m.fieldMode === 6 || m.fieldMode === 9) && (build.isExperimentSelection || powerUps.research.count > 3)
return (m.fieldMode === 8 || m.fieldMode === 3 || m.fieldMode === 6 || m.fieldMode === 9) && (build.isExperimentSelection || powerUps.research.count > 2)
},
requires: "wormhole, time dilation, negative mass, pilot wave",
effect() {
tech.fieldDuplicate = 0.11
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.11);
for (let i = 0; i < 4; i++) {
for (let i = 0; i < 3; i++) {
if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1)
}
},
remove() {
tech.fieldDuplicate = 0
powerUps.setPowerUpMode(); //needed after adjusting duplication chance
if (this.count > 0) powerUps.research.changeRerolls(4)
if (this.count > 0) powerUps.research.changeRerolls(3)
}
},
// {
@@ -11523,7 +11502,6 @@ const tech = {
isCouplingPowerUps: null,
isBoostPowerUps: null,
isBoostReplaceAmmo: null,
isFlipFlopCoupling: null,
isInfiniteWaveAmmo: null,
isJunkDNA: null,
buffedGun: 0,

View File

@@ -9,6 +9,7 @@ body {
margin: 0;
overflow: hidden;
cursor: auto;
transition: background-color 0.2s ease-in-out;
}
canvas {
@@ -183,6 +184,9 @@ summary {
scrollbar-width: none;
}
.choose-grid-no-images {
border-radius: 8px;
border: 10px solid #444;
@@ -219,6 +223,9 @@ summary {
line-height: 160%;
background-color: var(--card-color);
font-size: 0.75em;
/* transform-style: preserve-3d;
transition: transform 2s;
transform: rotateX(180deg); */
}
.choose-grid-module:hover {

View File

@@ -1,27 +1,40 @@
******************************************************** NEXT PATCH **************************************************
new community level - superNgonBros by DesBoot
setting - minimal HUD
remove: defense bar, damage bar, tech, in game console
tech: induction brake - after using a heal slow nearby mobs for 15 seconds
tech: null hypothesis - +9 damage, spawn several research after removing
reworked: strange attractor - +7% damage, +10% duplication after removing
improved text clarity on coupling
removed tech decoupling
bremsstrahlung does 50% more damage
time crystals 200 -> 150% passive energy regen
it also tells you how much energy regen you will get
aperture (-50 to +150) -> (-10 to +110) damage
diaphragm (-33 to +100) -> (+8 to +80) defense
tungsten carbide 200 -> 222 health
CPT symmetry 30 -> 20 energy per second of rewind
quenching gives more max health, but also does more damage per over heal
added cloaking and sneak attack graphics
also, the 50% defense when cloaked is now clear from the defense bar
ternary 44->83% damage but requires current gun to have ammo/3 (was any gun)
wormhole invariant: uses much less energy to pause time
standing wave has less recoil when blocking
final boss has 50% faster armor decay
so it takes even more damage the longer you fight it
a few more images
some bug fixes
new images
bug fixes
*********************************************************** TODO *****************************************************
use ephemera to replace things
JUNK?
request animation stuff
simulation checks
damage and defense bars
disable and enable ephemera with settings
drones target anything that moves: speed > 1
including player, blocks?, mobs, power ups
maybe target the fastest mobs?
perfect diamagnatism - invulnerable while field is active?
also drain energy while field is active?
mobs attack mines
mines periodically set all mobs to have player location to be the mine
is this going to work with all mob vision types?
maybe use ⚆ in game text?
increase font?
@@ -30,10 +43,6 @@ rework quantum eraser
test bremsstrahlung damage
and make sure it actually does more damage with the dot tech
use ephemera to replace things
JUNK?
request animation stuff
tech: choose next map by name after exiting current map
use modified tech selection code?
this might be too much work without much reward
@@ -1228,6 +1237,7 @@ if pause is pressed while selecting power ups, display pause menu on top of sele
time dilation - graphic of a hyperbolic equation Luminogram
negative mass - Blacklight painting by Moebius
plasma torch - by Dan Mumford
metamaterial cloaking - Scientific photography by Miki Asai, by Bruce Munro
molecular assembler - by Laurie Greasley 16-bit Isometric
wormhole - by Tim White