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
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 67 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 35 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 66 KiB |
BIN
img/sentry.webp
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 57 KiB |
BIN
img/tokamak.webp
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 53 KiB |
11
index.html
@@ -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>
|
||||
|
||||
362
js/bullet.js
@@ -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], {
|
||||
|
||||
20
js/engine.js
@@ -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);
|
||||
|
||||
46
js/index.js
@@ -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)} 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)} 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)} <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> ${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
|
||||
|
||||
32
js/level.js
@@ -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;
|
||||
|
||||
13
js/mob.js
@@ -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);
|
||||
|
||||
333
js/player.js
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
270
js/simulation.js
@@ -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";
|
||||
|
||||
180
js/tech.js
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
52
todo.txt
@@ -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
|
||||
|
||||