time dilation rework
time dilation field rework
2x energy regen, but pausing time now uses much more energy
you are immune to harm while time is paused
but this stops energy regen
tech timelike is removed
eternalism gives 50% damage instead of ammo
also disables the pause button, and other pause effects
tech: polyurethane foam - super balls turn into foam after hitting a mob
supertemporal renamed autocannon
now gives +1 ball, and has a shorter delay between balls
harpoon and grapple no longer lose ammo when you run out of energy
they just trigger a 2 second fire CD
slashBoss doesn't slash as often at higher difficulty levels
field descriptions rewritten
bug fixes
This commit is contained in:
401
js/bullet.js
401
js/bullet.js
@@ -1437,7 +1437,14 @@ const b = {
|
||||
returnToPlayer() {
|
||||
if (Vector.magnitude(Vector.sub(this.position, m.pos)) < returnRadius) { //near player
|
||||
this.endCycle = 0;
|
||||
if (m.cycle + 25 * b.fireCDscale < m.fireCDcycle) m.fireCDcycle = m.cycle + 35 * b.fireCDscale //lower cd to 25 if it is above 25
|
||||
if (m.energy < 0.05) {
|
||||
m.fireCDcycle = m.cycle + 120; //fire cooldown
|
||||
} else if (m.cycle + 25 * b.fireCDscale < m.fireCDcycle) {
|
||||
m.fireCDcycle = m.cycle + 35 * 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), (input.down ? 0.00015 : 0.0003))
|
||||
player.force.x += momentum.x
|
||||
@@ -1488,31 +1495,31 @@ const b = {
|
||||
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 + 20 // cool down
|
||||
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 {
|
||||
//snap rope if not enough energy
|
||||
if (m.energy < 0.05) {
|
||||
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;
|
||||
}
|
||||
this.dropCaughtPowerUp()
|
||||
} 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
|
||||
}
|
||||
//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
|
||||
// }
|
||||
}
|
||||
//grappling hook
|
||||
if (input.fire && Matter.Query.collides(this, map).length) {
|
||||
@@ -1562,12 +1569,13 @@ const b = {
|
||||
m.immuneCycle = m.cycle + 10;
|
||||
if (m.energy > 0.001) {
|
||||
m.energy -= 0.001
|
||||
} else {
|
||||
} 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
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -1697,7 +1705,12 @@ const b = {
|
||||
returnToPlayer() {
|
||||
if (Vector.magnitude(Vector.sub(this.position, m.pos)) < returnRadius) { //near player
|
||||
this.endCycle = 0;
|
||||
if (m.cycle + 25 * b.fireCDscale < m.fireCDcycle) m.fireCDcycle = m.cycle + 35 * b.fireCDscale //lower cd to 25 if it is above 25
|
||||
|
||||
if (m.energy < 0.05) {
|
||||
m.fireCDcycle = m.cycle + 120; //fire cooldown
|
||||
} else if (m.cycle + 25 * b.fireCDscale < m.fireCDcycle) {
|
||||
m.fireCDcycle = m.cycle + 35 * b.fireCDscale //lower cd to 25 if it is above 25
|
||||
}
|
||||
//recoil on catching
|
||||
const momentum = Vector.mult(Vector.sub(this.velocity, player.velocity), (input.down ? 0.00015 : 0.0003))
|
||||
player.force.x += momentum.x
|
||||
@@ -1749,24 +1762,13 @@ const b = {
|
||||
this.cycle++
|
||||
if (isReturn || target) {
|
||||
if (isReturn) {
|
||||
if (this.cycle > totalCycles) {
|
||||
//snap rope if not enough energy
|
||||
if (m.energy < 0.05) {
|
||||
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;
|
||||
}
|
||||
this.dropCaughtPowerUp()
|
||||
} else {
|
||||
//return to player
|
||||
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
|
||||
}
|
||||
if (this.cycle > totalCycles || m.energy < 0.05) { //return to player
|
||||
this.do = this.returnToPlayer
|
||||
if (this.angularSpeed < 0.5) this.torque += this.inertia * 0.001 * (Math.random() - 0.5) //(Math.round(Math.random()) ? 1 : -1)
|
||||
Matter.Sleeping.set(this, false)
|
||||
this.collisionFilter.category = 0
|
||||
this.collisionFilter.mask = 0
|
||||
this.endCycle = simulation.cycle + 60
|
||||
} else {
|
||||
this.grabPowerUp()
|
||||
}
|
||||
@@ -5307,6 +5309,9 @@ const b = {
|
||||
have: false,
|
||||
// num: 5,
|
||||
do() {},
|
||||
foamBall() {
|
||||
|
||||
},
|
||||
fireOne() {
|
||||
const SPEED = input.down ? 43 : 36
|
||||
m.fireCDcycle = m.cycle + Math.floor((input.down ? 23 : 15) * b.fireCDscale); // cool down
|
||||
@@ -5332,6 +5337,15 @@ const b = {
|
||||
b.explosion(this.position, this.mass * 280); //makes bullet do explosive damage at end
|
||||
this.endCycle = 0
|
||||
}
|
||||
if (tech.isFoamBall) {
|
||||
const radius = 5 + 8 * Math.random()
|
||||
const velocity = { x: Math.max(2, 10 - radius * 0.25), y: 0 }
|
||||
for (let i = 0, len = 6 * this.mass; i < len; i++) {
|
||||
b.foam(this.position, Vector.rotate(velocity, 6.28 * Math.random()), radius)
|
||||
}
|
||||
this.endCycle = 0
|
||||
// this.mass = 0 //prevent damage
|
||||
}
|
||||
};
|
||||
},
|
||||
fireMulti() {
|
||||
@@ -5362,26 +5376,35 @@ const b = {
|
||||
b.explosion(this.position, this.mass * 320 + 70 * Math.random()); //makes bullet do explosive damage at end
|
||||
this.endCycle = 0
|
||||
}
|
||||
if (tech.isFoamBall) {
|
||||
const radius = 5 + 8 * Math.random()
|
||||
const velocity = { x: Math.max(2, 10 - radius * 0.25), y: 0 }
|
||||
for (let i = 0, len = 6 * this.mass; i < len; i++) {
|
||||
b.foam(this.position, Vector.rotate(velocity, 6.28 * Math.random()), radius)
|
||||
}
|
||||
this.endCycle = 0
|
||||
// this.mass = 0 //prevent damage
|
||||
}
|
||||
};
|
||||
dir += SPREAD;
|
||||
}
|
||||
},
|
||||
fireQueue() {
|
||||
// const dir = m.angle
|
||||
// const x = m.pos.x
|
||||
// const y = m.pos.y
|
||||
const SPEED = input.down ? 43 : 36
|
||||
const dir = m.angle
|
||||
const x = m.pos.x
|
||||
const y = m.pos.y
|
||||
const num = 3 + Math.floor(tech.extraSuperBalls * Math.random())
|
||||
const num = 1 + 3 + Math.floor(tech.extraSuperBalls * Math.random()) //1 extra
|
||||
const delay = Math.floor((input.down ? 18 : 12) * b.fireCDscale)
|
||||
m.fireCDcycle = m.cycle + delay; // cool down
|
||||
|
||||
const fireBall = () => {
|
||||
const me = bullet.length;
|
||||
bullet[me] = Bodies.polygon(x, y, 12, 11 * tech.bulletSize, b.fireAttributes(dir, false));
|
||||
bullet[me] = Bodies.polygon(m.pos.x, m.pos.y, 12, 11 * tech.bulletSize, b.fireAttributes(m.angle, false));
|
||||
Composite.add(engine.world, bullet[me]); //add bullet to world
|
||||
Matter.Body.setVelocity(bullet[me], {
|
||||
x: SPEED * Math.cos(dir),
|
||||
y: SPEED * Math.sin(dir)
|
||||
x: SPEED * Math.cos(m.angle),
|
||||
y: SPEED * Math.sin(m.angle)
|
||||
});
|
||||
bullet[me].endCycle = simulation.cycle + Math.floor(330 * tech.isBulletsLastLonger);
|
||||
bullet[me].minDmgSpeed = 0;
|
||||
@@ -5395,16 +5418,28 @@ const b = {
|
||||
b.explosion(this.position, this.mass * 320 + 70 * Math.random()); //makes bullet do explosive damage at end
|
||||
this.endCycle = 0
|
||||
}
|
||||
if (tech.isFoamBall) {
|
||||
const radius = 5 + 8 * Math.random()
|
||||
const velocity = { x: Math.max(2, 10 - radius * 0.25), y: 0 }
|
||||
for (let i = 0, len = 6 * this.mass; i < len; i++) {
|
||||
b.foam(this.position, Vector.rotate(velocity, 6.28 * Math.random()), radius)
|
||||
}
|
||||
this.endCycle = 0
|
||||
// this.mass = 0 //prevent damage
|
||||
}
|
||||
};
|
||||
m.fireCDcycle = m.cycle + delay; // cool down
|
||||
}
|
||||
|
||||
function cycle() {
|
||||
if (simulation.paused || m.isBodiesAsleep) { requestAnimationFrame(cycle) } else {
|
||||
count++
|
||||
if (count % 2) fireBall()
|
||||
if (count < num * 2 && m.alive) requestAnimationFrame(cycle);
|
||||
}
|
||||
// if (simulation.paused || m.isBodiesAsleep) {
|
||||
// requestAnimationFrame(cycle)
|
||||
// } else {
|
||||
count++
|
||||
// if (count % 2)
|
||||
fireBall()
|
||||
if (count < num && m.alive) requestAnimationFrame(cycle);
|
||||
// }
|
||||
}
|
||||
let count = 0
|
||||
requestAnimationFrame(cycle);
|
||||
@@ -5449,79 +5484,81 @@ const b = {
|
||||
},
|
||||
do() {},
|
||||
do360Longitudinal() {
|
||||
ctx.strokeStyle = "rgba(0,0,0,0.6)" //"000";
|
||||
ctx.lineWidth = 2 * tech.wavePacketDamage
|
||||
ctx.beginPath();
|
||||
const end = 700 * Math.sqrt(tech.isBulletsLastLonger) / Math.sqrt(tech.waveReflections * 0.5) //should equal about 1060
|
||||
const damage = 2 * m.dmgScale * tech.wavePacketDamage * tech.waveBeamDamage * (tech.isBulletTeleport ? 1.43 : 1) //damage is lower for large radius mobs, since they feel the waves longer
|
||||
if (!m.isBodiesAsleep) {
|
||||
ctx.strokeStyle = "rgba(0,0,0,0.6)" //"000";
|
||||
ctx.lineWidth = 2 * tech.wavePacketDamage
|
||||
ctx.beginPath();
|
||||
const end = 700 * Math.sqrt(tech.isBulletsLastLonger) / Math.sqrt(tech.waveReflections * 0.5) //should equal about 1060
|
||||
const damage = 2 * m.dmgScale * tech.wavePacketDamage * tech.waveBeamDamage * (tech.isBulletTeleport ? 1.43 : 1) //damage is lower for large radius mobs, since they feel the waves longer
|
||||
|
||||
for (let i = this.waves.length - 1; i > -1; i--) {
|
||||
//draw wave
|
||||
ctx.moveTo(this.waves[i].position.x + this.waves[i].radius, this.waves[i].position.y)
|
||||
ctx.arc(this.waves[i].position.x, this.waves[i].position.y, this.waves[i].radius, 0, 2 * Math.PI);
|
||||
// collisions
|
||||
if (tech.isBulletTeleport && Math.random() < 0.04) {
|
||||
const scale = 400 * Math.random()
|
||||
this.waves[i].position = Vector.add(this.waves[i].position, { x: scale * (Math.random() - 0.5), y: scale * (Math.random() - 0.5) })
|
||||
}
|
||||
for (let j = 0, len = mob.length; j < len; j++) {
|
||||
const dist = Vector.magnitude(Vector.sub(this.waves[i].position, mob[j].position))
|
||||
const r = mob[j].radius + 30
|
||||
if (dist + r > this.waves[i].radius && dist - r < this.waves[i].radius) {
|
||||
//make them shake around
|
||||
if (!mob[j].isBadTarget) {
|
||||
mob[j].force.x += 0.01 * (Math.random() - 0.5) * mob[j].mass
|
||||
mob[j].force.y += 0.01 * (Math.random() - 0.5) * mob[j].mass
|
||||
for (let i = this.waves.length - 1; i > -1; i--) {
|
||||
//draw wave
|
||||
ctx.moveTo(this.waves[i].position.x + this.waves[i].radius, this.waves[i].position.y)
|
||||
ctx.arc(this.waves[i].position.x, this.waves[i].position.y, this.waves[i].radius, 0, 2 * Math.PI);
|
||||
// collisions
|
||||
if (tech.isBulletTeleport && Math.random() < 0.04) {
|
||||
const scale = 400 * Math.random()
|
||||
this.waves[i].position = Vector.add(this.waves[i].position, { x: scale * (Math.random() - 0.5), y: scale * (Math.random() - 0.5) })
|
||||
}
|
||||
for (let j = 0, len = mob.length; j < len; j++) {
|
||||
const dist = Vector.magnitude(Vector.sub(this.waves[i].position, mob[j].position))
|
||||
const r = mob[j].radius + 30
|
||||
if (dist + r > this.waves[i].radius && dist - r < this.waves[i].radius) {
|
||||
//make them shake around
|
||||
if (!mob[j].isBadTarget) {
|
||||
mob[j].force.x += 0.01 * (Math.random() - 0.5) * mob[j].mass
|
||||
mob[j].force.y += 0.01 * (Math.random() - 0.5) * mob[j].mass
|
||||
}
|
||||
if (!mob[j].isShielded) {
|
||||
Matter.Body.setVelocity(mob[j], { //friction
|
||||
x: mob[j].velocity.x * 0.95,
|
||||
y: mob[j].velocity.y * 0.95
|
||||
});
|
||||
//draw vibes
|
||||
let vertices = mob[j].vertices;
|
||||
const vibe = 50 + mob[j].radius * 0.15
|
||||
ctx.moveTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
|
||||
for (let k = 1; k < vertices.length; k++) {
|
||||
ctx.lineTo(vertices[k].x + vibe * (Math.random() - 0.5), vertices[k].y + vibe * (Math.random() - 0.5));
|
||||
}
|
||||
ctx.lineTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
|
||||
//damage
|
||||
mob[j].locatePlayer();
|
||||
mob[j].damage(damage / Math.sqrt(mob[j].radius));
|
||||
}
|
||||
}
|
||||
if (!mob[j].isShielded) {
|
||||
Matter.Body.setVelocity(mob[j], { //friction
|
||||
x: mob[j].velocity.x * 0.95,
|
||||
y: mob[j].velocity.y * 0.95
|
||||
});
|
||||
}
|
||||
for (let j = 0, len = body.length; j < len; j++) {
|
||||
const dist = Vector.magnitude(Vector.sub(this.waves[i].position, body[j].position))
|
||||
const r = 20
|
||||
if (dist + r > this.waves[i].radius && dist - r < this.waves[i].radius) {
|
||||
//make them shake around
|
||||
body[j].force.x += 0.01 * (Math.random() - 0.5) * body[j].mass
|
||||
body[j].force.y += (0.01 * (Math.random() - 0.5) - simulation.g * 0.25) * body[j].mass //remove force of gravity
|
||||
//draw vibes
|
||||
let vertices = mob[j].vertices;
|
||||
const vibe = 50 + mob[j].radius * 0.15
|
||||
let vertices = body[j].vertices;
|
||||
const vibe = 25
|
||||
ctx.moveTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
|
||||
for (let k = 1; k < vertices.length; k++) {
|
||||
ctx.lineTo(vertices[k].x + vibe * (Math.random() - 0.5), vertices[k].y + vibe * (Math.random() - 0.5));
|
||||
}
|
||||
ctx.lineTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
|
||||
//damage
|
||||
mob[j].locatePlayer();
|
||||
mob[j].damage(damage / Math.sqrt(mob[j].radius));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (let j = 0, len = body.length; j < len; j++) {
|
||||
const dist = Vector.magnitude(Vector.sub(this.waves[i].position, body[j].position))
|
||||
const r = 20
|
||||
if (dist + r > this.waves[i].radius && dist - r < this.waves[i].radius) {
|
||||
//make them shake around
|
||||
body[j].force.x += 0.01 * (Math.random() - 0.5) * body[j].mass
|
||||
body[j].force.y += (0.01 * (Math.random() - 0.5) - simulation.g * 0.25) * body[j].mass //remove force of gravity
|
||||
//draw vibes
|
||||
let vertices = body[j].vertices;
|
||||
const vibe = 25
|
||||
ctx.moveTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
|
||||
for (let k = 1; k < vertices.length; k++) {
|
||||
ctx.lineTo(vertices[k].x + vibe * (Math.random() - 0.5), vertices[k].y + vibe * (Math.random() - 0.5));
|
||||
}
|
||||
ctx.lineTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
|
||||
this.waves[i].radius += tech.waveBeamSpeed * this.waves[i].expanding //expand / move
|
||||
// if (this.waves[i].radius > end) this.waves.splice(i, 1) //end
|
||||
if (this.waves[i].radius > end) {
|
||||
this.waves[i].expanding = -1
|
||||
this.waves[i].reflection--
|
||||
if (this.waves[i].reflection < 1) this.waves.splice(i, 1) //end
|
||||
} else if (this.waves[i].radius < 25) {
|
||||
this.waves[i].expanding = 1
|
||||
this.waves[i].reflection--
|
||||
if (this.waves[i].reflection < 1) this.waves.splice(i, 1) //end
|
||||
}
|
||||
}
|
||||
this.waves[i].radius += tech.waveBeamSpeed * this.waves[i].expanding //expand / move
|
||||
// if (this.waves[i].radius > end) this.waves.splice(i, 1) //end
|
||||
if (this.waves[i].radius > end) {
|
||||
this.waves[i].expanding = -1
|
||||
this.waves[i].reflection--
|
||||
if (this.waves[i].reflection < 1) this.waves.splice(i, 1) //end
|
||||
} else if (this.waves[i].radius < 25) {
|
||||
this.waves[i].expanding = 1
|
||||
this.waves[i].reflection--
|
||||
if (this.waves[i].reflection < 1) this.waves.splice(i, 1) //end
|
||||
}
|
||||
ctx.stroke();
|
||||
}
|
||||
ctx.stroke();
|
||||
},
|
||||
fire360Longitudinal() {
|
||||
m.fireCDcycle = m.cycle + Math.floor((input.down ? 3 : 8) * b.fireCDscale); // cool down
|
||||
@@ -5533,87 +5570,89 @@ const b = {
|
||||
})
|
||||
},
|
||||
doLongitudinal() {
|
||||
ctx.strokeStyle = "rgba(0,0,0,0.6)" //"000";
|
||||
ctx.lineWidth = 2 * tech.wavePacketDamage
|
||||
ctx.beginPath();
|
||||
const end = 1100 * tech.isBulletsLastLonger / Math.sqrt(tech.waveReflections * 0.5) //should equal about 1767
|
||||
const damage = 2 * m.dmgScale * tech.wavePacketDamage * tech.waveBeamDamage * (tech.isBulletTeleport ? 1.43 : 1) //damage is lower for large radius mobs, since they feel the waves longer
|
||||
if (!m.isBodiesAsleep) {
|
||||
ctx.strokeStyle = "rgba(0,0,0,0.6)" //"000";
|
||||
ctx.lineWidth = 2 * tech.wavePacketDamage
|
||||
ctx.beginPath();
|
||||
const end = 1100 * tech.isBulletsLastLonger / Math.sqrt(tech.waveReflections * 0.5) //should equal about 1767
|
||||
const damage = 2 * m.dmgScale * tech.wavePacketDamage * tech.waveBeamDamage * (tech.isBulletTeleport ? 1.43 : 1) //damage is lower for large radius mobs, since they feel the waves longer
|
||||
|
||||
for (let i = this.waves.length - 1; i > -1; i--) {
|
||||
const v1 = Vector.add(this.waves[i].position, Vector.mult(this.waves[i].unit1, this.waves[i].radius))
|
||||
const v2 = Vector.add(this.waves[i].position, Vector.mult(this.waves[i].unit2, this.waves[i].radius))
|
||||
//draw wave
|
||||
ctx.moveTo(v1.x, v1.y)
|
||||
ctx.arc(this.waves[i].position.x, this.waves[i].position.y, this.waves[i].radius, this.waves[i].angle, this.waves[i].angle + this.waves[i].arc);
|
||||
// collisions
|
||||
//using small angle linear approximation of circle arc, this will not work if the arc gets large // https://stackoverflow.com/questions/13652518/efficiently-find-points-inside-a-circle-sector
|
||||
if (tech.isBulletTeleport && Math.random() < 0.05) {
|
||||
if (Math.random() < 0.5) {
|
||||
// const scale = 500 * Math.random()
|
||||
// this.waves[i].position = Vector.add(this.waves[i].position, { x: scale * (Math.random() - 0.5), y: scale * (Math.random() - 0.5) })
|
||||
} else {
|
||||
this.waves[i].arc *= 1 + 1 * (Math.random() - 0.5)
|
||||
const halfArc = this.waves[i].arc / 2
|
||||
const angle = m.angle + 0.5 * (Math.random() - 0.5)
|
||||
this.waves[i].angle = angle - halfArc
|
||||
this.waves[i].unit1 = { x: Math.cos(angle - halfArc), y: Math.sin(angle - halfArc) }
|
||||
this.waves[i].unit2 = { x: Math.cos(angle + halfArc), y: Math.sin(angle + halfArc) }
|
||||
for (let i = this.waves.length - 1; i > -1; i--) {
|
||||
const v1 = Vector.add(this.waves[i].position, Vector.mult(this.waves[i].unit1, this.waves[i].radius))
|
||||
const v2 = Vector.add(this.waves[i].position, Vector.mult(this.waves[i].unit2, this.waves[i].radius))
|
||||
//draw wave
|
||||
ctx.moveTo(v1.x, v1.y)
|
||||
ctx.arc(this.waves[i].position.x, this.waves[i].position.y, this.waves[i].radius, this.waves[i].angle, this.waves[i].angle + this.waves[i].arc);
|
||||
// collisions
|
||||
//using small angle linear approximation of circle arc, this will not work if the arc gets large // https://stackoverflow.com/questions/13652518/efficiently-find-points-inside-a-circle-sector
|
||||
if (tech.isBulletTeleport && Math.random() < 0.05) {
|
||||
if (Math.random() < 0.5) {
|
||||
// const scale = 500 * Math.random()
|
||||
// this.waves[i].position = Vector.add(this.waves[i].position, { x: scale * (Math.random() - 0.5), y: scale * (Math.random() - 0.5) })
|
||||
} else {
|
||||
this.waves[i].arc *= 1 + 1 * (Math.random() - 0.5)
|
||||
const halfArc = this.waves[i].arc / 2
|
||||
const angle = m.angle + 0.5 * (Math.random() - 0.5)
|
||||
this.waves[i].angle = angle - halfArc
|
||||
this.waves[i].unit1 = { x: Math.cos(angle - halfArc), y: Math.sin(angle - halfArc) }
|
||||
this.waves[i].unit2 = { x: Math.cos(angle + halfArc), y: Math.sin(angle + halfArc) }
|
||||
}
|
||||
}
|
||||
}
|
||||
let hits = Matter.Query.ray(mob, v1, v2, 50) //Matter.Query.ray(bodies, startPoint, endPoint, [rayWidth])
|
||||
for (let j = 0; j < hits.length; j++) {
|
||||
const who = hits[j].body
|
||||
//make them shake around
|
||||
if (!who.isBadTarget) {
|
||||
let hits = Matter.Query.ray(mob, v1, v2, 50) //Matter.Query.ray(bodies, startPoint, endPoint, [rayWidth])
|
||||
for (let j = 0; j < hits.length; j++) {
|
||||
const who = hits[j].body
|
||||
//make them shake around
|
||||
if (!who.isBadTarget) {
|
||||
who.force.x += 0.01 * (Math.random() - 0.5) * who.mass
|
||||
who.force.y += 0.01 * (Math.random() - 0.5) * who.mass
|
||||
}
|
||||
if (!who.isShielded) {
|
||||
Matter.Body.setVelocity(who, { //friction
|
||||
x: who.velocity.x * 0.95,
|
||||
y: who.velocity.y * 0.95
|
||||
});
|
||||
let vertices = who.vertices;
|
||||
const vibe = 50 + who.radius * 0.15
|
||||
ctx.moveTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
|
||||
for (let j = 1; j < vertices.length; j++) {
|
||||
ctx.lineTo(vertices[j].x + vibe * (Math.random() - 0.5), vertices[j].y + vibe * (Math.random() - 0.5));
|
||||
}
|
||||
ctx.lineTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
|
||||
who.locatePlayer();
|
||||
who.damage(damage / Math.sqrt(who.radius));
|
||||
}
|
||||
}
|
||||
|
||||
hits = Matter.Query.ray(body, v1, v2, 50) //Matter.Query.ray(bodies, startPoint, endPoint, [rayWidth])
|
||||
for (let j = 0; j < hits.length; j++) {
|
||||
const who = hits[j].body
|
||||
//make them shake around
|
||||
who.force.x += 0.01 * (Math.random() - 0.5) * who.mass
|
||||
who.force.y += 0.01 * (Math.random() - 0.5) * who.mass
|
||||
}
|
||||
if (!who.isShielded) {
|
||||
Matter.Body.setVelocity(who, { //friction
|
||||
x: who.velocity.x * 0.95,
|
||||
y: who.velocity.y * 0.95
|
||||
});
|
||||
who.force.y += (0.01 * (Math.random() - 0.5) - simulation.g * 0.25) * who.mass //remove force of gravity
|
||||
|
||||
let vertices = who.vertices;
|
||||
const vibe = 50 + who.radius * 0.15
|
||||
const vibe = 25
|
||||
ctx.moveTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
|
||||
for (let j = 1; j < vertices.length; j++) {
|
||||
ctx.lineTo(vertices[j].x + vibe * (Math.random() - 0.5), vertices[j].y + vibe * (Math.random() - 0.5));
|
||||
}
|
||||
ctx.lineTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
|
||||
who.locatePlayer();
|
||||
who.damage(damage / Math.sqrt(who.radius));
|
||||
}
|
||||
// ctx.stroke(); //draw vibes
|
||||
|
||||
this.waves[i].radius += tech.waveBeamSpeed * 2 * this.waves[i].expanding //expand / move
|
||||
if (this.waves[i].radius > end) {
|
||||
this.waves[i].expanding = -1
|
||||
this.waves[i].reflection--
|
||||
if (this.waves[i].reflection < 1) this.waves.splice(i, 1) //end
|
||||
} else if (this.waves[i].radius < 25) {
|
||||
this.waves[i].expanding = 1
|
||||
this.waves[i].reflection--
|
||||
if (this.waves[i].reflection < 1) this.waves.splice(i, 1) //end
|
||||
}
|
||||
}
|
||||
|
||||
hits = Matter.Query.ray(body, v1, v2, 50) //Matter.Query.ray(bodies, startPoint, endPoint, [rayWidth])
|
||||
for (let j = 0; j < hits.length; j++) {
|
||||
const who = hits[j].body
|
||||
//make them shake around
|
||||
who.force.x += 0.01 * (Math.random() - 0.5) * who.mass
|
||||
who.force.y += (0.01 * (Math.random() - 0.5) - simulation.g * 0.25) * who.mass //remove force of gravity
|
||||
|
||||
let vertices = who.vertices;
|
||||
const vibe = 25
|
||||
ctx.moveTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
|
||||
for (let j = 1; j < vertices.length; j++) {
|
||||
ctx.lineTo(vertices[j].x + vibe * (Math.random() - 0.5), vertices[j].y + vibe * (Math.random() - 0.5));
|
||||
}
|
||||
ctx.lineTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5));
|
||||
}
|
||||
// ctx.stroke(); //draw vibes
|
||||
|
||||
this.waves[i].radius += tech.waveBeamSpeed * 2 * this.waves[i].expanding //expand / move
|
||||
if (this.waves[i].radius > end) {
|
||||
this.waves[i].expanding = -1
|
||||
this.waves[i].reflection--
|
||||
if (this.waves[i].reflection < 1) this.waves.splice(i, 1) //end
|
||||
} else if (this.waves[i].radius < 25) {
|
||||
this.waves[i].expanding = 1
|
||||
this.waves[i].reflection--
|
||||
if (this.waves[i].reflection < 1) this.waves.splice(i, 1) //end
|
||||
}
|
||||
ctx.stroke();
|
||||
}
|
||||
ctx.stroke();
|
||||
},
|
||||
fireLongitudinal() {
|
||||
m.fireCDcycle = m.cycle + Math.floor((input.down ? 3 : 8) * b.fireCDscale); // cool down
|
||||
|
||||
@@ -904,7 +904,7 @@ window.addEventListener("keydown", function(event) {
|
||||
// level.levelAnnounce();
|
||||
document.body.style.cursor = "none";
|
||||
requestAnimationFrame(cycle);
|
||||
} else {
|
||||
} else if (!tech.isNoDraftPause) {
|
||||
simulation.paused = true;
|
||||
build.pauseGrid()
|
||||
document.body.style.cursor = "auto";
|
||||
|
||||
316
js/level.js
316
js/level.js
@@ -16,12 +16,12 @@ const level = {
|
||||
start() {
|
||||
if (level.levelsCleared === 0) { //this code only runs on the first level
|
||||
// simulation.isHorizontalFlipped = true
|
||||
// m.setField("standing wave")
|
||||
// b.giveGuns("laser")
|
||||
// tech.giveTech("scrap-bot manufacturing")
|
||||
// m.setField("time dilation")
|
||||
// b.giveGuns("matter wave")
|
||||
// tech.giveTech("phonon")
|
||||
// tech.giveTech("eternalism")
|
||||
// tech.giveTech("options exchange")
|
||||
// tech.giveTech("ICBM")
|
||||
// tech.giveTech("isotropic radiator")
|
||||
// tech.giveTech("polyurethane balls")
|
||||
// tech.giveTech("grappling hook")
|
||||
// tech.giveTech("paradigm shift")
|
||||
// for (let i = 0; i < 1; i++) powerUps.directSpawn(450, -50, "tech");
|
||||
@@ -37,7 +37,7 @@ const level = {
|
||||
// m.immuneCycle = Infinity //you can't take damage
|
||||
// level.difficultyIncrease(15) //30 is near max on hard //60 is near max on why
|
||||
// simulation.enableConstructMode() //used to build maps in testing mode
|
||||
// level.testChamber();
|
||||
// level.labs();
|
||||
// level.testing(); //not in rotation, used for testing
|
||||
if (simulation.isTraining) { level.walk(); } else { level.intro(); } //normal starting level ************************************************
|
||||
// powerUps.research.changeRerolls(3000)
|
||||
@@ -972,19 +972,19 @@ const level = {
|
||||
}
|
||||
}
|
||||
//delete any overlapping mobs
|
||||
const mobsHits = Matter.Query.collides(this, mob)
|
||||
for (let i = 0; i < mobsHits.length; i++) {
|
||||
if (mobsHits[i].bodyB !== this && mobsHits[i].bodyB !== m.holdingTarget) { //dont' delete yourself <----- bug here maybe...
|
||||
Matter.Composite.remove(engine.world, mobsHits[i].bodyB);
|
||||
mobsHits[i].bodyB.isRemoveMeNow = true
|
||||
for (let i = 1; i < mob.length; i++) { //find which index in body array it is and remove from array
|
||||
if (mob[i].isRemoveMeNow) {
|
||||
mob.splice(i, 1);
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// const mobsHits = Matter.Query.collides(this, mob)
|
||||
// for (let i = 0; i < mobsHits.length; i++) {
|
||||
// if (mobsHits[i].bodyB !== this && mobsHits[i].bodyB !== m.holdingTarget) { //dont' delete yourself <----- bug here maybe...
|
||||
// Matter.Composite.remove(engine.world, mobsHits[i].bodyB);
|
||||
// mobsHits[i].bodyB.isRemoveMeNow = true
|
||||
// for (let i = 1; i < mob.length; i++) { //find which index in body array it is and remove from array
|
||||
// if (mob[i].isRemoveMeNow) {
|
||||
// mob.splice(i, 1);
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1444,15 +1444,15 @@ const level = {
|
||||
spawn.bodyRect(x + 1460, y - 900, 30, 150); //entrance door
|
||||
spawn.mapRect(x + 1600, y - 350, 500, 100); //toggle shelf
|
||||
const toggle = level.toggle(x + 1650, y - 350, true) //(x,y,isOn,isLockOn = true/false)
|
||||
let hazard
|
||||
let hazard1
|
||||
if (Math.random() > 0.5) {
|
||||
spawn.mapRect(x + 550, y - 750, 1500, 50); //entrance shelf
|
||||
hazard = level.hazard(x + 850, y - 920, 600, 10, 0.4) //laser
|
||||
hazard1 = level.hazard(x + 850, y - 920, 600, 10, 0.4) //laser
|
||||
spawn.mapRect(x + 860, y - 925, 10, 20); //laser nose
|
||||
spawn.mapRect(x + 660, y - 975, 200, 120); //laser body
|
||||
} else {
|
||||
spawn.mapRect(x + 1350, y - 750, 700, 50); //entrance shelf
|
||||
hazard = level.hazard(x + 1040, y - 660, 1000, 10, 0.4) //laser
|
||||
hazard1 = level.hazard(x + 1040, y - 660, 1000, 10, 0.4) //laser
|
||||
spawn.mapRect(x + 1050, y - 665, 10, 20); //laser nose
|
||||
spawn.mapRect(x + 650, y - 705, 400, 100); //laser body
|
||||
}
|
||||
@@ -1476,14 +1476,17 @@ const level = {
|
||||
doCustomTopLayer.push(
|
||||
() => {
|
||||
toggle.query();
|
||||
hazard.isOn = toggle.isOn
|
||||
hazard1.isOn = toggle.isOn
|
||||
hazard2.isOn = toggle.isOn
|
||||
hazard3.isOn = toggle.isOn
|
||||
hazard4.isOn = toggle.isOn
|
||||
hazard.opticalQuery();
|
||||
hazard2.opticalQuery();
|
||||
hazard3.opticalQuery();
|
||||
hazard4.opticalQuery();
|
||||
if ((simulation.cycle % 120) > 60) {
|
||||
hazard1.opticalQuery();
|
||||
hazard2.opticalQuery();
|
||||
} else {
|
||||
hazard3.opticalQuery();
|
||||
hazard4.opticalQuery();
|
||||
}
|
||||
// if (!isSpawnedMobs && !toggle.isOn) {
|
||||
// isSpawnedMobs = true
|
||||
// spawn.randomMob(x + 150, y + -1100, mobSpawnChance);
|
||||
@@ -2173,89 +2176,102 @@ const level = {
|
||||
|
||||
// },
|
||||
(x = offset.x, y = offset.y) => {
|
||||
const toggle = level.toggle(x + 950, y + 0, false, true) // toggle(x, y, isOn = false, isLockOn = false) {
|
||||
toggle.isAddedElements = false
|
||||
// const toggle = level.toggle(x + 950, y + 0, false, true) // toggle(x, y, isOn = false, isLockOn = false) {
|
||||
// toggle.isAddedElements = false
|
||||
|
||||
const button = level.button(x + 950, y + 0)
|
||||
button.isUp = true
|
||||
|
||||
|
||||
spawn.mapVertex(x + 5, y + -1318, "0 0 0 -250 125 -250"); //left ledges
|
||||
spawn.mapVertex(x + 1995, y + -1318, "0 0 0 -250 -125 -250"); // right ledges
|
||||
doCustomTopLayer.push(
|
||||
() => {
|
||||
toggle.query();
|
||||
if (toggle.isOn && !toggle.isAddedElements) { //this code runs once after the toggle is triggered
|
||||
toggle.isAddedElements = true //only do this once
|
||||
addMapToLevelInProgress = (who) => { //adds new map elements to the level while the level is already running //don't forget to run simulation.draw.setPaths() after you all the the elements so they show up visually
|
||||
who.collisionFilter.category = cat.map;
|
||||
who.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet;
|
||||
Matter.Body.setStatic(who, true); //make static
|
||||
Composite.add(engine.world, who); //add to world
|
||||
button.draw();
|
||||
if (button.isUp) {
|
||||
button.query();
|
||||
if (!button.isUp) {
|
||||
// toggle.isAddedElements = true //only do this once
|
||||
addMapToLevelInProgress = (who) => { //adds new map elements to the level while the level is already running //don't forget to run simulation.draw.setPaths() after you all the the elements so they show up visually
|
||||
who.collisionFilter.category = cat.map;
|
||||
who.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet;
|
||||
Matter.Body.setStatic(who, true); //make static
|
||||
Composite.add(engine.world, who); //add to world
|
||||
}
|
||||
let r = 150
|
||||
let hexagon = `${r} 0 ${r * Math.cos(5.236)} ${r * Math.sin(5.236)} ${r * Math.cos(4.189)} ${r * Math.sin(4.189)} ${-r} 0 ${r * Math.cos(2.0944)} ${r * Math.sin(2.0944)} ${r * Math.cos(1.0472)} ${r * Math.sin(1.0472)} `
|
||||
//450 horizontal spread // -130-130-130 = 390 vertical
|
||||
if (Math.random() < 0.5) {
|
||||
spawn.mapVertex(x + 775, y + -260, hexagon);
|
||||
spawn.mapVertex(x + 1225, y + -260, hexagon);
|
||||
|
||||
spawn.mapVertex(x + 550, y + -650, hexagon);
|
||||
spawn.mapVertex(x + 1000, y + -650, hexagon);
|
||||
spawn.mapVertex(x + 1450, y + -650, hexagon);
|
||||
|
||||
spawn.mapVertex(x + 325, y + -1040, hexagon);
|
||||
spawn.mapVertex(x + 775, y + -1040, hexagon);
|
||||
spawn.mapVertex(x + 1225, y + -1040, hexagon);
|
||||
spawn.mapVertex(x + 1675, y + -1040, hexagon);
|
||||
|
||||
spawn.mapVertex(x + 550, y + -1430, hexagon);
|
||||
spawn.mapVertex(x + 1000, y + -1430, hexagon);
|
||||
spawn.mapVertex(x + 1450, y + -1430, hexagon);
|
||||
|
||||
const numberOfMapElementsAdded = 12
|
||||
for (let i = 0; i < numberOfMapElementsAdded; i++) addMapToLevelInProgress(map[map.length - 1 - i])
|
||||
spawn.randomMob(x + 225, y + -1775, mobSpawnChance);
|
||||
spawn.randomMob(x + 700, y + -1750, mobSpawnChance);
|
||||
spawn.randomMob(x + 1175, y + -1725, mobSpawnChance);
|
||||
spawn.randomMob(x + 1700, y + -1700, mobSpawnChance);
|
||||
spawn.randomMob(x + 1750, y + -250, mobSpawnChance);
|
||||
spawn.randomMob(x + 125, y + -250, mobSpawnChance);
|
||||
} else {
|
||||
spawn.mapVertex(x + 775, y + -260, hexagon);
|
||||
spawn.mapVertex(x + 1225, y + -260, hexagon);
|
||||
|
||||
spawn.mapVertex(x + 550, y + -650, hexagon);
|
||||
spawn.mapVertex(x + 1000, y + -650, hexagon);
|
||||
spawn.mapVertex(x + 1450, y + -650, hexagon);
|
||||
|
||||
spawn.mapVertex(x + 775, y + -1040, hexagon);
|
||||
spawn.mapVertex(x + 1225, y + -1040, hexagon);
|
||||
|
||||
spawn.mapVertex(x + 550, y + -1430, hexagon);
|
||||
spawn.mapVertex(x + 1000, y + -1430, hexagon);
|
||||
spawn.mapVertex(x + 1450, y + -1430, hexagon);
|
||||
|
||||
spawn.mapVertex(x + 775, y + -1820, hexagon);
|
||||
spawn.mapVertex(x + 1225, y + -1820, hexagon);
|
||||
const numberOfMapElementsAdded = 12
|
||||
for (let i = 0; i < numberOfMapElementsAdded; i++) addMapToLevelInProgress(map[map.length - 1 - i])
|
||||
|
||||
spawn.randomMob(x + 225, y + -1025, mobSpawnChance);
|
||||
spawn.randomMob(x + 200, y + -675, mobSpawnChance);
|
||||
spawn.randomMob(x + 225, y + -200, mobSpawnChance);
|
||||
spawn.randomMob(x + 1750, y + -1075, mobSpawnChance);
|
||||
spawn.randomMob(x + 1700, y + -650, mobSpawnChance);
|
||||
spawn.randomMob(x + 1675, y + -175, mobSpawnChance);
|
||||
}
|
||||
simulation.draw.setPaths() //update map graphics
|
||||
spawn.randomGroup(x + 300, y + -2200);
|
||||
spawn.randomGroup(x + 1625, y + -2200);
|
||||
spawn.randomLevelBoss(x + 700, y + -2300);
|
||||
spawn.secondaryBossChance(x + 1250, y + -2300)
|
||||
}
|
||||
let r = 150
|
||||
let hexagon = `${r} 0 ${r * Math.cos(5.236)} ${r * Math.sin(5.236)} ${r * Math.cos(4.189)} ${r * Math.sin(4.189)} ${-r} 0 ${r * Math.cos(2.0944)} ${r * Math.sin(2.0944)} ${r * Math.cos(1.0472)} ${r * Math.sin(1.0472)} `
|
||||
//450 horizontal spread // -130-130-130 = 390 vertical
|
||||
if (Math.random() < 0.5) {
|
||||
spawn.mapVertex(x + 775, y + -260, hexagon);
|
||||
spawn.mapVertex(x + 1225, y + -260, hexagon);
|
||||
|
||||
spawn.mapVertex(x + 550, y + -650, hexagon);
|
||||
spawn.mapVertex(x + 1000, y + -650, hexagon);
|
||||
spawn.mapVertex(x + 1450, y + -650, hexagon);
|
||||
|
||||
spawn.mapVertex(x + 325, y + -1040, hexagon);
|
||||
spawn.mapVertex(x + 775, y + -1040, hexagon);
|
||||
spawn.mapVertex(x + 1225, y + -1040, hexagon);
|
||||
spawn.mapVertex(x + 1675, y + -1040, hexagon);
|
||||
|
||||
spawn.mapVertex(x + 550, y + -1430, hexagon);
|
||||
spawn.mapVertex(x + 1000, y + -1430, hexagon);
|
||||
spawn.mapVertex(x + 1450, y + -1430, hexagon);
|
||||
|
||||
const numberOfMapElementsAdded = 12
|
||||
for (let i = 0; i < numberOfMapElementsAdded; i++) addMapToLevelInProgress(map[map.length - 1 - i])
|
||||
spawn.randomMob(x + 225, y + -1775, mobSpawnChance);
|
||||
spawn.randomMob(x + 700, y + -1750, mobSpawnChance);
|
||||
spawn.randomMob(x + 1175, y + -1725, mobSpawnChance);
|
||||
spawn.randomMob(x + 1700, y + -1700, mobSpawnChance);
|
||||
spawn.randomMob(x + 1750, y + -250, mobSpawnChance);
|
||||
spawn.randomMob(x + 125, y + -250, mobSpawnChance);
|
||||
} else {
|
||||
spawn.mapVertex(x + 775, y + -260, hexagon);
|
||||
spawn.mapVertex(x + 1225, y + -260, hexagon);
|
||||
|
||||
spawn.mapVertex(x + 550, y + -650, hexagon);
|
||||
spawn.mapVertex(x + 1000, y + -650, hexagon);
|
||||
spawn.mapVertex(x + 1450, y + -650, hexagon);
|
||||
|
||||
spawn.mapVertex(x + 775, y + -1040, hexagon);
|
||||
spawn.mapVertex(x + 1225, y + -1040, hexagon);
|
||||
|
||||
spawn.mapVertex(x + 550, y + -1430, hexagon);
|
||||
spawn.mapVertex(x + 1000, y + -1430, hexagon);
|
||||
spawn.mapVertex(x + 1450, y + -1430, hexagon);
|
||||
|
||||
spawn.mapVertex(x + 775, y + -1820, hexagon);
|
||||
spawn.mapVertex(x + 1225, y + -1820, hexagon);
|
||||
const numberOfMapElementsAdded = 12
|
||||
for (let i = 0; i < numberOfMapElementsAdded; i++) addMapToLevelInProgress(map[map.length - 1 - i])
|
||||
|
||||
spawn.randomMob(x + 225, y + -1025, mobSpawnChance);
|
||||
spawn.randomMob(x + 200, y + -675, mobSpawnChance);
|
||||
spawn.randomMob(x + 225, y + -200, mobSpawnChance);
|
||||
spawn.randomMob(x + 1750, y + -1075, mobSpawnChance);
|
||||
spawn.randomMob(x + 1700, y + -650, mobSpawnChance);
|
||||
spawn.randomMob(x + 1675, y + -175, mobSpawnChance);
|
||||
}
|
||||
simulation.draw.setPaths() //update map graphics
|
||||
spawn.randomGroup(x + 300, y + -2200);
|
||||
spawn.randomGroup(x + 1625, y + -2200);
|
||||
spawn.randomLevelBoss(x + 700, y + -2300);
|
||||
spawn.secondaryBossChance(x + 1250, y + -2300)
|
||||
}
|
||||
// toggle.query();
|
||||
// if (toggle.isOn && !toggle.isAddedElements) { //this code runs once after the toggle is triggered
|
||||
|
||||
// }
|
||||
}
|
||||
)
|
||||
},
|
||||
(x = offset.x, y = offset.y) => {
|
||||
const toggle = level.toggle(x + 950, y + 0, false, true) // toggle(x, y, isOn = false, isLockOn = false) {
|
||||
toggle.isAddedElements = false
|
||||
|
||||
// const toggle = level.toggle(x + 950, y + 0, false, true) // toggle(x, y, isOn = false, isLockOn = false) {
|
||||
// toggle.isAddedElements = false
|
||||
const button = level.button(x + 950, y + 0)
|
||||
button.isUp = true
|
||||
//left ledges
|
||||
spawn.mapVertex(x + 5, y + -1868, "0 0 0 -250 125 -250");
|
||||
spawn.mapVertex(x + 5, y + -1318, "0 0 0 -250 125 -250"); //door
|
||||
@@ -2267,55 +2283,57 @@ const level = {
|
||||
|
||||
doCustomTopLayer.push(
|
||||
() => {
|
||||
toggle.query();
|
||||
if (toggle.isOn && !toggle.isAddedElements) { //this code runs once after the toggle is triggered
|
||||
toggle.isAddedElements = true //only do this once
|
||||
addMapToLevelInProgress = (who) => { //adds new map elements to the level while the level is already running //don't forget to run simulation.draw.setPaths() after you all the the elements so they show up visually
|
||||
who.collisionFilter.category = cat.map;
|
||||
who.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet;
|
||||
Matter.Body.setStatic(who, true); //make static
|
||||
Composite.add(engine.world, who); //add to world
|
||||
button.draw();
|
||||
if (button.isUp) {
|
||||
button.query();
|
||||
if (!button.isUp) {
|
||||
addMapToLevelInProgress = (who) => { //adds new map elements to the level while the level is already running //don't forget to run simulation.draw.setPaths() after you all the the elements so they show up visually
|
||||
who.collisionFilter.category = cat.map;
|
||||
who.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet;
|
||||
Matter.Body.setStatic(who, true); //make static
|
||||
Composite.add(engine.world, who); //add to world
|
||||
}
|
||||
//right side hexagons
|
||||
let r = 300
|
||||
let hexagon = `${r} 0 ${r * Math.cos(5.236)} ${r * Math.sin(5.236)} ${r * Math.cos(4.189)} ${r * Math.sin(4.189)} ${-r} 0 ${r * Math.cos(2.0944)} ${r * Math.sin(2.0944)} ${r * Math.cos(1.0472)} ${r * Math.sin(1.0472)} `
|
||||
spawn.mapVertex(x + 1640, y + -365, hexagon);
|
||||
// r = 275
|
||||
// let hexagonHalf = `${r} 0 ${r*Math.cos(5.236)} ${r*Math.sin(5.236)} ${r*Math.cos(4.189)} ${r*Math.sin(4.189)} ${-r} 0 `
|
||||
// spawn.mapVertex(x + 2300, y + -75, hexagonHalf);
|
||||
r = 150
|
||||
const hexagon150 = `${r} 0 ${r * Math.cos(5.236)} ${r * Math.sin(5.236)} ${r * Math.cos(4.189)} ${r * Math.sin(4.189)} ${-r} 0 ${r * Math.cos(2.0944)} ${r * Math.sin(2.0944)} ${r * Math.cos(1.0472)} ${r * Math.sin(1.0472)} `
|
||||
// spawn.mapVertex(x + 1750, y + -550, hexagon150);
|
||||
spawn.mapVertex(x + 1750, y + -1100, hexagon150);
|
||||
spawn.mapVertex(x + 1750, y + -1650, hexagon150);
|
||||
spawn.mapVertex(x + 1750, y + -2200, hexagon150);
|
||||
|
||||
//left side
|
||||
r = 350
|
||||
let hexagonHalf = `${r} 0 ${r * Math.cos(5.236)} ${r * Math.sin(5.236)} ${r * Math.cos(4.189)} ${r * Math.sin(4.189)} ${-r} 0 `
|
||||
spawn.mapVertex(x + 425, y + -90, hexagonHalf);
|
||||
|
||||
spawn.mapVertex(x + 850, y + -500, hexagon150);
|
||||
spawn.mapVertex(x + 550, y + -850, hexagon150);
|
||||
spawn.mapVertex(x + 250, y + -1200, hexagon150);
|
||||
spawn.mapVertex(x + 250, y + -1700, hexagon150);
|
||||
spawn.mapVertex(x + 725, y + -1950, hexagon150);
|
||||
spawn.mapVertex(x + 1200, y + -2200, hexagon150);
|
||||
const numberOfMapElementsAdded = 11
|
||||
for (let i = 0; i < numberOfMapElementsAdded; i++) addMapToLevelInProgress(map[map.length - 1 - i])
|
||||
|
||||
spawn.randomMob(x + 1075, y + -1500, mobSpawnChance);
|
||||
spawn.randomMob(x + 325, y + -550, mobSpawnChance);
|
||||
spawn.randomMob(x + 800, y + -925, mobSpawnChance);
|
||||
spawn.randomMob(x + 1400, y + -1250, mobSpawnChance);
|
||||
spawn.randomMob(x + 1350, y + -1725, mobSpawnChance);
|
||||
spawn.randomMob(x + 575, y + -1375, mobSpawnChance);
|
||||
spawn.randomMob(x + 225, y + -2275, mobSpawnChance);
|
||||
spawn.randomMob(x + 875, y + -2450, mobSpawnChance);
|
||||
spawn.randomMob(x + 1550, y + -2525, mobSpawnChance);
|
||||
spawn.randomLevelBoss(x + 1075, y + -1500);
|
||||
spawn.secondaryBossChance(x + 1200, y + -1000)
|
||||
simulation.draw.setPaths() //update map graphics
|
||||
}
|
||||
//right side hexagons
|
||||
let r = 300
|
||||
let hexagon = `${r} 0 ${r * Math.cos(5.236)} ${r * Math.sin(5.236)} ${r * Math.cos(4.189)} ${r * Math.sin(4.189)} ${-r} 0 ${r * Math.cos(2.0944)} ${r * Math.sin(2.0944)} ${r * Math.cos(1.0472)} ${r * Math.sin(1.0472)} `
|
||||
spawn.mapVertex(x + 1640, y + -365, hexagon);
|
||||
// r = 275
|
||||
// let hexagonHalf = `${r} 0 ${r*Math.cos(5.236)} ${r*Math.sin(5.236)} ${r*Math.cos(4.189)} ${r*Math.sin(4.189)} ${-r} 0 `
|
||||
// spawn.mapVertex(x + 2300, y + -75, hexagonHalf);
|
||||
r = 150
|
||||
const hexagon150 = `${r} 0 ${r * Math.cos(5.236)} ${r * Math.sin(5.236)} ${r * Math.cos(4.189)} ${r * Math.sin(4.189)} ${-r} 0 ${r * Math.cos(2.0944)} ${r * Math.sin(2.0944)} ${r * Math.cos(1.0472)} ${r * Math.sin(1.0472)} `
|
||||
// spawn.mapVertex(x + 1750, y + -550, hexagon150);
|
||||
spawn.mapVertex(x + 1750, y + -1100, hexagon150);
|
||||
spawn.mapVertex(x + 1750, y + -1650, hexagon150);
|
||||
spawn.mapVertex(x + 1750, y + -2200, hexagon150);
|
||||
|
||||
//left side
|
||||
r = 350
|
||||
let hexagonHalf = `${r} 0 ${r * Math.cos(5.236)} ${r * Math.sin(5.236)} ${r * Math.cos(4.189)} ${r * Math.sin(4.189)} ${-r} 0 `
|
||||
spawn.mapVertex(x + 425, y + -90, hexagonHalf);
|
||||
|
||||
spawn.mapVertex(x + 850, y + -500, hexagon150);
|
||||
spawn.mapVertex(x + 550, y + -850, hexagon150);
|
||||
spawn.mapVertex(x + 250, y + -1200, hexagon150);
|
||||
spawn.mapVertex(x + 250, y + -1700, hexagon150);
|
||||
spawn.mapVertex(x + 725, y + -1950, hexagon150);
|
||||
spawn.mapVertex(x + 1200, y + -2200, hexagon150);
|
||||
const numberOfMapElementsAdded = 11
|
||||
for (let i = 0; i < numberOfMapElementsAdded; i++) addMapToLevelInProgress(map[map.length - 1 - i])
|
||||
|
||||
spawn.randomMob(x + 1075, y + -1500, mobSpawnChance);
|
||||
spawn.randomMob(x + 325, y + -550, mobSpawnChance);
|
||||
spawn.randomMob(x + 800, y + -925, mobSpawnChance);
|
||||
spawn.randomMob(x + 1400, y + -1250, mobSpawnChance);
|
||||
spawn.randomMob(x + 1350, y + -1725, mobSpawnChance);
|
||||
spawn.randomMob(x + 575, y + -1375, mobSpawnChance);
|
||||
spawn.randomMob(x + 225, y + -2275, mobSpawnChance);
|
||||
spawn.randomMob(x + 875, y + -2450, mobSpawnChance);
|
||||
spawn.randomMob(x + 1550, y + -2525, mobSpawnChance);
|
||||
spawn.randomLevelBoss(x + 1075, y + -1500);
|
||||
spawn.secondaryBossChance(x + 1200, y + -1000)
|
||||
simulation.draw.setPaths() //update map graphics
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -2654,7 +2672,7 @@ const level = {
|
||||
// spawn.shieldingBoss(1700, -500)
|
||||
|
||||
// for (let i = 0; i < 10; ++i) spawn.bodyRect(1600 + 5, -500, 30, 40);
|
||||
for (let i = 0; i < 1; i++) spawn.stabber(1900, -500)
|
||||
for (let i = 0; i < 4; i++) spawn.starter(1900, -500)
|
||||
// spawn.pulsar(1900, -500)
|
||||
// spawn.shield(mob[mob.length - 1], 1900, -500, 1);
|
||||
// mob[mob.length - 1].isShielded = true
|
||||
|
||||
255
js/player.js
255
js/player.js
@@ -522,7 +522,7 @@ const m = {
|
||||
if (tech.isAddBlockMass && m.isHolding) dmg *= 0.15
|
||||
if (tech.isSpeedHarm) dmg *= 1 - Math.min(player.speed * 0.0165, 0.66)
|
||||
if (tech.isSlowFPS) dmg *= 0.8
|
||||
if (tech.isHarmReduce && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.34
|
||||
if (tech.isHarmReduce && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.25
|
||||
if (tech.isNeutronium && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.1
|
||||
if (tech.isBotArmor) dmg *= 0.94 ** b.totalBots()
|
||||
if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.33;
|
||||
@@ -1501,8 +1501,9 @@ const m = {
|
||||
},
|
||||
fieldUpgrades: [{
|
||||
name: "field emitter",
|
||||
description: "regen <strong>6</strong> <strong class='color-f'>energy</strong> per second<br>use it to <strong>deflect</strong> mobs and <strong>throw</strong> <strong class='color-block'>blocks</strong><br><strong class='color-f'>energy</strong> regen disabled if immune to <strong class='color-harm'>harm</strong>",
|
||||
// description: "use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs,<br><strong>grab</strong> power ups, and <strong>throw</strong> <strong class='color-block'>blocks</strong><br>regen <strong>6</strong> <strong class='color-f'>energy</strong>/s, when not immune to <strong class='color-harm'>harm</strong>",
|
||||
//<br><strong class='color-f'>energy</strong> regen disabled if immune to <strong class='color-harm'>harm</strong>
|
||||
description: "use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs<br>store up to <strong>100</strong> <strong class='color-f'>energy</strong><br>generate <strong>6</strong> <strong class='color-f'>energy</strong>/second",
|
||||
// description: "use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs,<br><strong>grab</strong> power ups, and <strong>throw</strong> <strong class='color-block'>blocks</strong><br>generate <strong>6</strong> <strong class='color-f'>energy</strong>/s, when not immune to <strong class='color-harm'>harm</strong>",
|
||||
effect: () => {
|
||||
m.hold = function() {
|
||||
if (m.isHolding) {
|
||||
@@ -1527,7 +1528,8 @@ const m = {
|
||||
},
|
||||
{
|
||||
name: "standing wave",
|
||||
description: "<strong>3</strong> oscillating <strong>shields</strong> are permanently active<br><strong>deflecting</strong> protects you in every <strong>direction</strong><br>increase your <strong>max</strong> <strong class='color-f'>energy</strong> by <strong>60</strong>", //drains <strong class='color-f'>energy</strong> //<strong>deflecting</strong> has <strong>50%</strong> less <strong>recoil</strong>
|
||||
//<strong>deflecting</strong> protects you in every <strong>direction</strong>
|
||||
description: "<strong>3</strong> oscillating <strong>shields</strong> are permanently active<br>increase your <strong>max</strong> <strong class='color-f'>energy</strong> by <strong>60</strong><br>generate <strong>6</strong> <strong class='color-f'>energy</strong>/second", //drains <strong class='color-f'>energy</strong> //<strong>deflecting</strong> has <strong>50%</strong> less <strong>recoil</strong>
|
||||
drainCD: 0,
|
||||
effect: () => {
|
||||
m.fieldBlockCD = 0;
|
||||
@@ -1540,7 +1542,7 @@ const m = {
|
||||
const fieldRange2 = (0.68 + 0.37 * Math.sin(m.cycle / 37)) * m.fieldRange * m.harmonicRadius
|
||||
const fieldRange3 = (0.7 + 0.35 * Math.sin(m.cycle / 47)) * m.fieldRange * m.harmonicRadius
|
||||
const netfieldRange = Math.max(fieldRange1, fieldRange2, fieldRange3)
|
||||
ctx.fillStyle = "rgba(110,170,200," + Math.min(0.65, (0.04 + m.energy * (0.11 + 0.13 * Math.random()))) + ")";
|
||||
ctx.fillStyle = "rgba(110,170,200," + Math.min(0.6, (0.04 + m.energy * (0.1 + 0.11 * Math.random()))) + ")";
|
||||
ctx.beginPath();
|
||||
ctx.arc(m.pos.x, m.pos.y, fieldRange1, 0, 2 * Math.PI);
|
||||
ctx.fill();
|
||||
@@ -1571,7 +1573,7 @@ const m = {
|
||||
const radius = m.fieldRange * m.harmonicRadius
|
||||
ctx.lineWidth = 1;
|
||||
ctx.strokeStyle = "rgba(110,170,200,0.8)"
|
||||
ctx.fillStyle = "rgba(110,170,200," + Math.min(0.65, m.energy * (0.13 + 0.1 * Math.random()) * (3 / tech.harmonics)) + ")";
|
||||
ctx.fillStyle = "rgba(110,170,200," + Math.min(0.6, m.energy * (0.11 + 0.1 * Math.random()) * (3 / tech.harmonics)) + ")";
|
||||
// ctx.fillStyle = "rgba(110,170,200," + Math.min(0.7, m.energy * (0.22 - 0.01 * tech.harmonics) * (0.5 + 0.5 * Math.random())) + ")";
|
||||
for (let i = 0; i < tech.harmonics; i++) {
|
||||
ctx.beginPath();
|
||||
@@ -1628,7 +1630,8 @@ const m = {
|
||||
},
|
||||
{
|
||||
name: "perfect diamagnetism",
|
||||
description: "<strong>attract</strong> power ups from <strong>far away</strong><br><strong>deflecting</strong> does not drain <strong class='color-f'>energy</strong><br>maintains <strong>functionality</strong> while <strong>inactive</strong>",
|
||||
description: "<strong>deflecting</strong> does not drain <strong class='color-f'>energy</strong><br>maintains <strong>functionality</strong> while <strong>inactive</strong><br>generate <strong>6</strong> <strong class='color-f'>energy</strong>/second",
|
||||
// <br><strong>attract</strong> power ups from <strong>far away</strong>
|
||||
// description: "<strong>attract</strong> power ups from <strong>far away</strong><br><strong>deflecting</strong> doesn't drain <strong class='color-f'>energy</strong><br>thrown <strong class='color-block'>blocks</strong> have",
|
||||
// description: "gain <strong class='color-f'>energy</strong> when <strong>blocking</strong><br>no <strong>recoil</strong> when <strong>blocking</strong>",
|
||||
effect: () => {
|
||||
@@ -1810,7 +1813,8 @@ const m = {
|
||||
},
|
||||
{
|
||||
name: "negative mass",
|
||||
description: "use <strong class='color-f'>energy</strong> to nullify <strong style='letter-spacing: 7px;'>gravity</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>55%</strong><br>hold <strong class='color-block'>blocks</strong> as if they have a lower <strong>mass</strong>",
|
||||
//<br>hold <strong class='color-block'>blocks</strong> as if they have a lower <strong>mass</strong>
|
||||
description: "use <strong class='color-f'>energy</strong> to nullify <strong style='letter-spacing: 7px;'>gravity</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>55%</strong><br>generate <strong>6</strong> <strong class='color-f'>energy</strong>/second",
|
||||
fieldDrawRadius: 0,
|
||||
effect: () => {
|
||||
m.fieldFire = true;
|
||||
@@ -1960,7 +1964,8 @@ const m = {
|
||||
},
|
||||
{
|
||||
name: "molecular assembler",
|
||||
description: "excess <strong class='color-f'>energy</strong> used to build <strong>drones</strong><br>use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs<br><strong>double</strong> your default <strong class='color-f'>energy</strong> regeneration",
|
||||
description: "excess <strong class='color-f'>energy</strong> used to build <strong>drones</strong><br>use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs<br>generate <strong>12</strong> <strong class='color-f'>energy</strong>/second",
|
||||
//<strong>double</strong> your default <strong class='color-f'>energy</strong> regeneration
|
||||
effect: () => {
|
||||
// m.fieldMeterColor = "#0c5"
|
||||
// m.eyeFillColor = m.fieldMeterColor
|
||||
@@ -2095,7 +2100,7 @@ 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",
|
||||
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>6</strong> <strong class='color-f'>energy</strong>/second",
|
||||
set() {
|
||||
b.isExtruderOn = false
|
||||
if (m.plasmaBall) {
|
||||
@@ -2472,7 +2477,7 @@ const m = {
|
||||
{
|
||||
name: "time dilation",
|
||||
// description: "use <strong class='color-f'>energy</strong> to <strong style='letter-spacing: 1px;'>stop time</strong><br>while time is stopped you can <strong>move</strong> and <strong>fire</strong><br>and <strong>collisions</strong> do <strong>50%</strong> less <strong class='color-harm'>harm</strong>",
|
||||
description: "use <strong class='color-f'>energy</strong> to <strong style='letter-spacing: 1px;'>stop time</strong><br><strong>move</strong> and <strong>fire</strong> while time is stopped<br>but, <strong>collisions</strong> still do <strong class='color-harm'>harm</strong>",
|
||||
description: "use <strong class='color-f'>energy</strong> to <strong style='letter-spacing: 2px;'>stop time</strong><br>for everything except you<br>generate <strong>12</strong> <strong class='color-f'>energy</strong>/second",
|
||||
set() {
|
||||
if (tech.isRewindField) {
|
||||
this.rewindCount = 0
|
||||
@@ -2488,7 +2493,7 @@ const m = {
|
||||
|
||||
if (!m.holdingTarget) {
|
||||
this.rewindCount += 6;
|
||||
const DRAIN = 0.001
|
||||
const DRAIN = 0.003
|
||||
let history = m.history[(m.cycle - this.rewindCount) % 600]
|
||||
if (this.rewindCount > 599 || m.energy < DRAIN) {
|
||||
this.rewindCount = 0;
|
||||
@@ -2538,34 +2543,10 @@ const m = {
|
||||
bullet[bullet.length - 1].endCycle = simulation.cycle + 480 + Math.floor(120 * Math.random()) //8-9 seconds
|
||||
}
|
||||
}
|
||||
|
||||
if (tech.isRewindGrenade) {
|
||||
b.grenade(m.pos, this.rewindCount) //Math.PI / 2
|
||||
const who = bullet[bullet.length - 1]
|
||||
// Matter.Body.setVelocity(who, {
|
||||
// x: 0,
|
||||
// y: 0
|
||||
// });
|
||||
who.endCycle = simulation.cycle + 60
|
||||
// if (tech.isVacuumBomb) {
|
||||
// Matter.Body.setVelocity(who, {
|
||||
// x: who.velocity.x * 0.5,
|
||||
// y: who.velocity.y * 0.5
|
||||
// });
|
||||
// } else if (tech.isRPG) {
|
||||
// who.endCycle = simulation.cycle + 10
|
||||
// } else if (tech.isNeutronBomb) {
|
||||
// Matter.Body.setVelocity(who, {
|
||||
// x: who.velocity.x * 0.3,
|
||||
// y: who.velocity.y * 0.3
|
||||
// });
|
||||
// } else {
|
||||
// Matter.Body.setVelocity(who, {
|
||||
// x: who.velocity.x * 0.5,
|
||||
// y: who.velocity.y * 0.5
|
||||
// });
|
||||
// who.endCycle = simulation.cycle + 30
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
@@ -2579,74 +2560,13 @@ const m = {
|
||||
m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
|
||||
this.rewindCount = 0;
|
||||
}
|
||||
m.drawFieldMeter()
|
||||
|
||||
|
||||
|
||||
|
||||
// // console.log(this.rewindCount)
|
||||
// if (input.field && m.fieldCDcycle < m.cycle) { //button has been held down
|
||||
// if (m.isHolding) {
|
||||
// m.drawHold(m.holdingTarget);
|
||||
// m.holding();
|
||||
// m.throwBlock();
|
||||
// } else {
|
||||
// m.grabPowerUp();
|
||||
// m.lookForPickUp();
|
||||
// if (!m.holdingTarget) {
|
||||
// this.rewindCount += 8;
|
||||
// const DRAIN = 0.001
|
||||
// let history = m.history[(m.cycle - this.rewindCount) % 600]
|
||||
// if (this.rewindCount > 599 || m.energy < DRAIN) {
|
||||
// this.rewindCount = 0;
|
||||
// m.resetHistory();
|
||||
// } else {
|
||||
// // m.grabPowerUp(); //a second grab power up to make the power ups easier to grab, and they more fast which matches the time theme
|
||||
// m.energy -= DRAIN
|
||||
// if (m.immuneCycle < m.cycle + 30) m.immuneCycle = m.cycle + 30; //player is immune to damage for 30 cycles
|
||||
// Matter.Body.setPosition(player, history.position);
|
||||
// Matter.Body.setVelocity(player, { x: history.velocity.x, y: history.velocity.y });
|
||||
// if (m.health < history.health) {
|
||||
// m.health = history.health
|
||||
// m.displayHealth();
|
||||
// }
|
||||
// m.yOff = history.yOff
|
||||
// if (m.yOff < 48) {
|
||||
// m.doCrouch()
|
||||
// } else {
|
||||
// m.undoCrouch()
|
||||
// }
|
||||
// //grab power ups
|
||||
// for (let i = 0, len = powerUp.length; i < len; ++i) {
|
||||
// if (
|
||||
// Vector.magnitudeSquared(Vector.sub(m.pos, powerUp[i].position)) < 100000 &&
|
||||
// !simulation.isChoosing &&
|
||||
// (powerUp[i].name !== "heal" || m.health !== m.maxHealth || tech.isOverHeal)
|
||||
// ) {
|
||||
// powerUps.onPickUp(powerUp[i]);
|
||||
// powerUp[i].effect();
|
||||
// Matter.Composite.remove(engine.world, powerUp[i]);
|
||||
// powerUp.splice(i, 1);
|
||||
// break; //because the array order is messed up after splice
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } else { //button is held the first time
|
||||
// this.rewindCount = 0;
|
||||
// if (m.holdingTarget && m.fieldCDcycle < m.cycle) {
|
||||
// m.pickUp();
|
||||
// } else {
|
||||
// m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
|
||||
// }
|
||||
// }
|
||||
|
||||
if (m.energy < m.maxEnergy) m.regenEnergy(); //extra energy regen
|
||||
m.drawFieldMeter() // this calls m.regenEnergy(); also
|
||||
}
|
||||
} else {
|
||||
m.fieldFire = true;
|
||||
m.isBodiesAsleep = false;
|
||||
m.drain = 0.0003
|
||||
m.drain = 0.003
|
||||
m.hold = function() {
|
||||
if (m.isHolding) {
|
||||
m.wakeCheck();
|
||||
@@ -2656,8 +2576,6 @@ const m = {
|
||||
} else if (input.field && m.fieldCDcycle < m.cycle) {
|
||||
m.grabPowerUp();
|
||||
m.lookForPickUp();
|
||||
|
||||
m.drain += 0.000002 //also increases inside tech.isTimeSkip
|
||||
if (m.energy > m.drain) {
|
||||
m.energy -= m.drain;
|
||||
if (m.energy < m.drain) {
|
||||
@@ -2665,6 +2583,7 @@ const m = {
|
||||
m.energy = 0;
|
||||
m.wakeCheck();
|
||||
}
|
||||
m.immuneCycle = m.cycle + 10; //immune to harm while time is stopped, this also disables regen
|
||||
//draw field everywhere
|
||||
ctx.globalCompositeOperation = "saturation"
|
||||
ctx.fillStyle = "#ccc";
|
||||
@@ -2687,26 +2606,26 @@ const m = {
|
||||
sleep(bullet);
|
||||
|
||||
simulation.cycle--; //pause all functions that depend on game cycle increasing
|
||||
if (tech.isTimeSkip) {
|
||||
m.immuneCycle = 0;
|
||||
m.drain += 0.0000025
|
||||
m.regenEnergy(); //immunity disables normal regen, so turn off immunity for just this function
|
||||
m.immuneCycle = m.cycle + 10;
|
||||
simulation.isTimeSkipping = true;
|
||||
m.cycle++;
|
||||
simulation.gravity();
|
||||
if (tech.isFireMoveLock && input.fire) {
|
||||
player.force.x = 0
|
||||
player.force.y = 0
|
||||
}
|
||||
Engine.update(engine, simulation.delta);
|
||||
m.move();
|
||||
simulation.checks();
|
||||
m.walk_cycle += m.flipLegs * m.Vx;
|
||||
b.fire();
|
||||
b.bulletDo();
|
||||
simulation.isTimeSkipping = false;
|
||||
}
|
||||
// if (tech.isTimeSkip) {
|
||||
// m.immuneCycle = 0;
|
||||
// m.drain += 0.0000025
|
||||
// m.regenEnergy(); //immunity disables normal regen, so turn off immunity for just this function
|
||||
// m.immuneCycle = m.cycle + 10;
|
||||
// simulation.isTimeSkipping = true;
|
||||
// m.cycle++;
|
||||
// simulation.gravity();
|
||||
// if (tech.isFireMoveLock && input.fire) {
|
||||
// player.force.x = 0
|
||||
// player.force.y = 0
|
||||
// }
|
||||
// Engine.update(engine, simulation.delta);
|
||||
// m.move();
|
||||
// simulation.checks();
|
||||
// m.walk_cycle += m.flipLegs * m.Vx;
|
||||
// b.fire();
|
||||
// b.bulletDo();
|
||||
// simulation.isTimeSkipping = false;
|
||||
// }
|
||||
} else { //holding, but field button is released
|
||||
m.wakeCheck();
|
||||
}
|
||||
@@ -2714,23 +2633,96 @@ const m = {
|
||||
m.wakeCheck();
|
||||
m.pickUp();
|
||||
} else {
|
||||
if (m.drain > 0.0005) m.drain -= 0.000005 //return drain to base level
|
||||
m.wakeCheck();
|
||||
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)
|
||||
}
|
||||
// console.log(m.drain.toFixed(6))
|
||||
if (m.energy < m.maxEnergy) m.regenEnergy(); //extra energy regen
|
||||
m.drawFieldMeter()
|
||||
}
|
||||
}
|
||||
// } else {
|
||||
// m.fieldFire = true;
|
||||
// m.isBodiesAsleep = false;
|
||||
// m.isTimeStopped = false;
|
||||
// m.drain = 0.005
|
||||
// let isFieldInputDown = false;
|
||||
// m.hold = function() {
|
||||
// if (m.isHolding) {
|
||||
// m.drawHold(m.holdingTarget);
|
||||
// m.holding();
|
||||
// m.throwBlock();
|
||||
// isFieldInputDown = false
|
||||
// } else if (input.field && m.fieldCDcycle < m.cycle) { //not hold but field button is pressed
|
||||
// if (!m.holdingTarget) isFieldInputDown = true;
|
||||
// m.grabPowerUp();
|
||||
// m.lookForPickUp();
|
||||
// // if (m.energy > 0.05) { //deflecting
|
||||
// // m.drawField();
|
||||
// // m.pushMobsFacing();
|
||||
// // }
|
||||
// } else if (m.holdingTarget && m.fieldCDcycle < m.cycle) { //holding, but field button is released
|
||||
// m.pickUp();
|
||||
// } else {
|
||||
// m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
|
||||
// }
|
||||
|
||||
// if (isFieldInputDown && !input.field && !m.holdingTarget && !m.isHolding) {
|
||||
// isFieldInputDown = false;
|
||||
// m.isTimeStopped = true;
|
||||
// }
|
||||
// m.drawFieldMeter()
|
||||
// if (m.energy < m.maxEnergy) { //extra energy regen
|
||||
// m.regenEnergy();
|
||||
// m.regenEnergy();
|
||||
// }
|
||||
// if (m.isTimeStopped) {
|
||||
// if (m.energy > m.drain) {
|
||||
// // if (player.speed > 0.01 || input.fire)
|
||||
// m.energy -= m.drain;
|
||||
// m.immuneCycle = m.cycle + 10; //immune to harm while time is stopped, this also disables regen
|
||||
// simulation.cycle--; //pause all functions that depend on game cycle increasing
|
||||
// m.isBodiesAsleep = true;
|
||||
// ctx.globalCompositeOperation = "saturation" //draw field everywhere
|
||||
// ctx.fillStyle = "#ccc";
|
||||
// ctx.fillRect(-100000, -100000, 200000, 200000)
|
||||
// ctx.globalCompositeOperation = "source-over"
|
||||
|
||||
// function sleep(who) {
|
||||
// for (let i = 0, len = who.length; i < len; ++i) {
|
||||
// if (!who[i].isSleeping) {
|
||||
// who[i].storeVelocity = who[i].velocity
|
||||
// who[i].storeAngularVelocity = who[i].angularVelocity
|
||||
// }
|
||||
// Matter.Sleeping.set(who[i], true)
|
||||
// }
|
||||
// }
|
||||
// sleep(mob);
|
||||
// sleep(body);
|
||||
// sleep(bullet);
|
||||
// } else { //restart time
|
||||
// m.fieldCDcycle = m.cycle + 60;
|
||||
// m.energy = 0;
|
||||
// m.isTimeStopped = false
|
||||
// m.wakeCheck();
|
||||
// }
|
||||
// if (simulation.isChoosing) {
|
||||
// // m.fieldCDcycle = m.cycle + 60;
|
||||
// m.isTimeStopped = false
|
||||
// m.wakeCheck();
|
||||
// }
|
||||
// }
|
||||
|
||||
// }
|
||||
// }
|
||||
},
|
||||
effect() {
|
||||
// m.fieldMeterColor = "#000"
|
||||
this.set();
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "metamaterial cloaking", //"weak photonic coupling" "electromagnetically induced transparency" "optical non-coupling" "slow light field" "electro-optic transparency"
|
||||
description: "when not firing activate a <strong class='color-cloaked'>cloaking</strong> effect<br><strong>+333%</strong> <strong class='color-d'>damage</strong> if a mob hasn't recently <strong>died</strong><br><strong>collisions</strong> do <strong>50%</strong> less <strong class='color-harm'>harm</strong> when <strong class='color-cloaked'>cloaked</strong>",
|
||||
//<br><strong>collisions</strong> do <strong>50%</strong> less <strong class='color-harm'>harm</strong> when <strong class='color-cloaked'>cloaked</strong>
|
||||
description: "when not firing activate <strong class='color-cloaked'>cloaking</strong><br><span style = 'font-size:95%;'><strong>+333%</strong> <strong class='color-d'>damage</strong> if no mob has <strong>died</strong> in <strong>4</strong> seconds</span><br>generate <strong>6</strong> <strong class='color-f'>energy</strong>/second",
|
||||
effect: () => {
|
||||
m.fieldFire = true;
|
||||
m.fieldMeterColor = "#333";
|
||||
@@ -3028,7 +3020,9 @@ const m = {
|
||||
// },
|
||||
{
|
||||
name: "pilot wave",
|
||||
description: "use <strong class='color-f'>energy</strong> to push <strong class='color-block'>blocks</strong> with your mouse<br><strong class='color-block'>blocks</strong> can't <strong>collide</strong> with <strong>intangible</strong> mobs<br>field <strong>radius</strong> decreases out of <strong>line of sight</strong>",
|
||||
//<br><strong class='color-block'>blocks</strong> can't <strong>collide</strong> with <strong>intangible</strong> mobs
|
||||
//field <strong>radius</strong> decreases out of <strong>line of sight</strong>
|
||||
description: "use <strong class='color-f'>energy</strong> to guide <strong class='color-block'>blocks</strong><br><strong>unlock</strong> <strong class='color-m'>tech</strong> from other <strong class='color-f'>fields</strong><br>generate <strong>6</strong> <strong class='color-f'>energy</strong>/second",
|
||||
effect: () => {
|
||||
m.fieldPhase = 0;
|
||||
m.fieldPosition = {
|
||||
@@ -3223,7 +3217,8 @@ const m = {
|
||||
},
|
||||
{
|
||||
name: "wormhole",
|
||||
description: "use <strong class='color-f'>energy</strong> to <strong>tunnel</strong> through a <strong class='color-worm'>wormhole</strong><br><strong class='color-worm'>wormholes</strong> attract <strong class='color-block'>blocks</strong> and power ups<br><strong>5%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong>", //<br>bullets may also traverse <strong class='color-worm'>wormholes</strong>
|
||||
//<strong class='color-worm'>wormholes</strong> attract <strong class='color-block'>blocks</strong> and power ups<br>
|
||||
description: "use <strong class='color-f'>energy</strong> to <strong>tunnel</strong> through a <strong class='color-worm'>wormhole</strong><br><strong>5%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>generate <strong>6</strong> <strong class='color-f'>energy</strong>/second", //<br>bullets may also traverse <strong class='color-worm'>wormholes</strong>
|
||||
drain: 0,
|
||||
effect: function() {
|
||||
m.duplicateChance = 0.05
|
||||
@@ -3641,10 +3636,6 @@ const m = {
|
||||
// } else {
|
||||
// m.hole.isReady = true;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
|
||||
m.drawFieldMeter()
|
||||
}
|
||||
},
|
||||
|
||||
@@ -280,7 +280,7 @@ const powerUps = {
|
||||
|
||||
if (!simulation.paused) {
|
||||
if (tech.isNoDraftPause) {
|
||||
powerUps.spawn(m.pos.x, m.pos.y, "ammo");
|
||||
// powerUps.spawn(m.pos.x, m.pos.y, "ammo");
|
||||
document.getElementById("choose-grid").style.opacity = "0.7"
|
||||
} else {
|
||||
simulation.paused = true;
|
||||
|
||||
@@ -3929,7 +3929,7 @@ const spawn = {
|
||||
me.lockedOn = null;
|
||||
|
||||
me.torqueMagnitude = 0.00024 * me.inertia * (Math.random() > 0.5 ? -1 : 1);
|
||||
me.delay = 120 * simulation.CDScale;
|
||||
me.delay = 60 + 60 * simulation.CDScale;
|
||||
me.cd = 0;
|
||||
me.swordRadius = 0;
|
||||
me.swordVertex = 1
|
||||
|
||||
146
js/tech.js
146
js/tech.js
@@ -221,6 +221,7 @@ const tech = {
|
||||
},
|
||||
damageFromTech() {
|
||||
let dmg = 1 //m.fieldDamage
|
||||
if (tech.isNoDraftPause) dmg *= 1.5
|
||||
if (tech.isTechDebt) dmg *= Math.max(41 / (tech.totalCount + 21), 4 - 0.15 * tech.totalCount)
|
||||
if (tech.isAxion && tech.isHarmMACHO) dmg *= 1 + 0.75 * (1 - m.harmReduction())
|
||||
if (tech.OccamDamage) dmg *= tech.OccamDamage
|
||||
@@ -593,25 +594,6 @@ const tech = {
|
||||
tech.isAmmoFromHealth = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "eternalism",
|
||||
description: `choosing a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong> spawns ${powerUps.orb.ammo()}<br><strong>time</strong> doesn't <strong>pause</strong> while choosing`, //${powerUps.orb.heal()} or
|
||||
// description: "increase <strong class='color-d'>damage</strong> by <strong>50%</strong>, but <strong>time</strong> continues<br>while choosing a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return true
|
||||
},
|
||||
requires: "",
|
||||
effect() {
|
||||
tech.isNoDraftPause = true
|
||||
},
|
||||
remove() {
|
||||
tech.isNoDraftPause = false
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "exciton",
|
||||
description: `increase <strong class='color-d'>damage</strong> by <strong>88%</strong>, but<br>${powerUps.orb.ammo()} will no longer <strong>spawn</strong>`,
|
||||
@@ -3154,9 +3136,9 @@ const tech = {
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return !tech.isSuperDeterminism
|
||||
return !tech.isSuperDeterminism && !tech.isNoDraftPause
|
||||
},
|
||||
requires: "not superdeterminism",
|
||||
requires: "not superdeterminism, eternalism",
|
||||
effect() {
|
||||
tech.isPauseSwitchField = true;
|
||||
for (let i = 0, len = tech.tech.length; i < len; i++) {
|
||||
@@ -3195,8 +3177,10 @@ const tech = {
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() { return true },
|
||||
requires: "",
|
||||
allowed() {
|
||||
return !tech.isSuperDeterminism && !tech.isNoDraftPause
|
||||
},
|
||||
requires: "not superdeterminism, eternalism",
|
||||
effect() {
|
||||
tech.isPauseEjectTech = true;
|
||||
},
|
||||
@@ -3204,6 +3188,25 @@ const tech = {
|
||||
tech.isPauseEjectTech = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "eternalism",
|
||||
// description: `increase <strong class='color-d'>damage</strong> by <strong>60%</strong>, but <strong>time</strong> doesn't <strong>pause</strong><br>while choosing a choosing a <strong class='color-f'>field</strong>, <strong class='color-m'>tech</strong>, or <strong class='color-g'>gun</strong>`, //${powerUps.orb.heal()} or
|
||||
description: "increase <strong class='color-d'>damage</strong> by <strong>50%</strong>, but<br><strong>time</strong> can't be <strong>paused</strong> <em>(time dilation still works)</em>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return !tech.isPauseSwitchField && !tech.isPauseEjectTech && !tech.isWormHolePause
|
||||
},
|
||||
requires: "not unified field theory, paradigm shift, invariant",
|
||||
effect() {
|
||||
tech.isNoDraftPause = true
|
||||
},
|
||||
remove() {
|
||||
tech.isNoDraftPause = false
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "technical debt", // overengineering
|
||||
// description: `increase <strong class='color-d'>damage</strong> by <strong>300%</strong> minus <strong>10%</strong> for <strong class='color-m'>tech</strong> you have learned(${4 - 0.1 * tech.totalCount})`,
|
||||
@@ -3505,7 +3508,7 @@ const tech = {
|
||||
allowed() {
|
||||
return tech.duplicationChance() > 0.6
|
||||
},
|
||||
requires: "duplication chance above 70%",
|
||||
requires: "NOT EXPERIMENT MODE, duplication chance above 60%",
|
||||
effect() {
|
||||
tech.is111Duplicate = true;
|
||||
tech.maxDuplicationEvent()
|
||||
@@ -4289,9 +4292,9 @@ const tech = {
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return (tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIceShot && !tech.isRivets && !tech.isFoamShot && !tech.isSporeWorm && !tech.isNeedles) || tech.haveGunCheck("super balls") || (tech.isRivets && !tech.isNailCrit) || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && !(tech.isDroneTeleport || tech.isDroneRadioactive || tech.isSporeField || tech.isMissileField || tech.isIceField)) || (tech.haveGunCheck("drones") && !tech.isForeverDrones && !tech.isDroneRadioactive && !tech.isDroneTeleport)
|
||||
return (tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIceShot && !tech.isRivets && !tech.isFoamShot && !tech.isSporeWorm && !tech.isNeedles) || (tech.haveGunCheck("super balls") && !tech.isFoamBall) || (tech.isRivets && !tech.isNailCrit) || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && !(tech.isDroneTeleport || tech.isDroneRadioactive || tech.isSporeField || tech.isMissileField || tech.isIceField)) || (tech.haveGunCheck("drones") && !tech.isForeverDrones && !tech.isDroneRadioactive && !tech.isDroneTeleport)
|
||||
},
|
||||
requires: "shotgun, super balls, rivets, drones, not irradiated drones or burst drones",
|
||||
requires: "shotgun, super balls, rivets, drones, not irradiated drones, burst drones, polyurethane",
|
||||
effect() {
|
||||
tech.isIncendiary = true
|
||||
},
|
||||
@@ -4300,9 +4303,8 @@ const tech = {
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "supertemporal",
|
||||
link: `<a target="_blank" href='https://en.wikipedia.org/wiki/Temporal_paradox' class="link">supertemporal</a>`,
|
||||
description: "fire <strong>super ball</strong> from the same point in <strong>space</strong><br> but separated by <strong>0.1</strong> seconds in <strong>time</strong>",
|
||||
name: "autocannon",
|
||||
description: "fire <strong>+1</strong> extra <strong>super ball</strong><br><strong>balls</strong> are quickly released in same direction",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -4373,6 +4375,26 @@ const tech = {
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "polyurethane foam",
|
||||
description: "<strong>super balls</strong> colliding with <strong>mobs</strong> catalyzes<br>a reaction that yields <strong>foam</strong> bubbles",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("super balls")
|
||||
},
|
||||
requires: "super balls",
|
||||
effect() {
|
||||
tech.isFoamBall = true;
|
||||
},
|
||||
remove() {
|
||||
tech.isFoamBall = false;
|
||||
}
|
||||
},
|
||||
//
|
||||
{
|
||||
name: "phase velocity",
|
||||
description: "matter wave <strong>propagates</strong> faster through <strong>solids</strong><br>increase matter wave <strong class='color-d'>damage</strong> by <strong>15%</strong>",
|
||||
@@ -5218,7 +5240,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || tech.haveGunCheck("spores") || tech.haveGunCheck("drones") || tech.haveGunCheck("missiles") || tech.haveGunCheck("foam") || tech.haveGunCheck("matter wave") || tech.isNeutronBomb || tech.isIceField || tech.isIceShot || tech.relayIce || tech.isNeedleIce || tech.blockingIce > 1 || tech.isSporeWorm || tech.foamBotCount > 1
|
||||
return m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || tech.haveGunCheck("spores") || tech.haveGunCheck("drones") || tech.haveGunCheck("missiles") || tech.haveGunCheck("foam") || tech.haveGunCheck("matter wave") || tech.isNeutronBomb || tech.isIceField || tech.isIceShot || tech.relayIce || tech.isNeedleIce || tech.blockingIce > 1 || tech.isSporeWorm || tech.foamBotCount > 1 || tech.isFoamBall
|
||||
},
|
||||
requires: "drones, spores, missiles, foam, matter wave, neutron bomb, ice IX",
|
||||
effect() {
|
||||
@@ -5489,7 +5511,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return !tech.isBulletTeleport && (tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot)
|
||||
return !tech.isBulletTeleport && (tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot || tech.isFoamBall)
|
||||
},
|
||||
requires: "foam, not uncertainty",
|
||||
effect() {
|
||||
@@ -5508,7 +5530,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return (!tech.isFoamAttract && (tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot)) || (tech.haveGunCheck("matter wave") && !tech.isLongitudinal)
|
||||
return (!tech.isFoamAttract && (tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot || tech.isFoamBall)) || (tech.haveGunCheck("matter wave") && !tech.isLongitudinal)
|
||||
},
|
||||
requires: "foam, not electrostatic induction, matter wave, not phonon",
|
||||
effect() {
|
||||
@@ -5527,7 +5549,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot || tech.isSporeWorm
|
||||
return tech.haveGunCheck("foam") || tech.isFoamBall || tech.foamBotCount > 1 || tech.isFoamShot || tech.isSporeWorm
|
||||
},
|
||||
requires: "foam, worms",
|
||||
effect() {
|
||||
@@ -5546,7 +5568,7 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot
|
||||
return tech.haveGunCheck("foam") || tech.foamBotCount > 1 || tech.isFoamShot || tech.isFoamBall
|
||||
},
|
||||
requires: "foam",
|
||||
effect() {
|
||||
@@ -6213,9 +6235,9 @@ const tech = {
|
||||
frequency: 3,
|
||||
frequencyDefault: 3,
|
||||
allowed() {
|
||||
return (m.fieldUpgrades[m.fieldMode].name === "standing wave" || m.fieldUpgrades[m.fieldMode].name === "pilot wave") && (build.isExperimentSelection || powerUps.research.count > 1)
|
||||
return (m.fieldUpgrades[m.fieldMode].name === "standing wave" || m.fieldUpgrades[m.fieldMode].name === "pilot wave" || m.fieldUpgrades[m.fieldMode].name === "time dilation") && (build.isExperimentSelection || powerUps.research.count > 1)
|
||||
},
|
||||
requires: "standing wave or pilot wave",
|
||||
requires: "standing wave, pilot wave, time dilation",
|
||||
effect() {
|
||||
tech.harmonicEnergy = 1
|
||||
m.setMaxEnergy()
|
||||
@@ -6747,7 +6769,7 @@ const tech = {
|
||||
// },
|
||||
{
|
||||
name: "degenerate matter",
|
||||
description: "reduce <strong class='color-harm'>harm</strong> by <strong>66%</strong> while your <strong class='color-f'>field</strong> is active",
|
||||
description: "reduce <strong class='color-harm'>harm</strong> by <strong>75%</strong> while your <strong class='color-f'>field</strong> is active",
|
||||
isFieldTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -6949,25 +6971,25 @@ const tech = {
|
||||
if (this.count) m.fieldUpgrades[m.fieldMode].set()
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "timelike",
|
||||
description: "<strong>time dilation</strong> doubles your relative time <strong>rate</strong><br>and makes you immune to <strong class='color-harm'>harm</strong>",
|
||||
isFieldTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return m.fieldUpgrades[m.fieldMode].name === "time dilation" && !m.isShipMode && !tech.isRewindField
|
||||
},
|
||||
requires: "time dilation, not retrocausality",
|
||||
effect() {
|
||||
tech.isTimeSkip = true;
|
||||
},
|
||||
remove() {
|
||||
tech.isTimeSkip = false;
|
||||
}
|
||||
},
|
||||
// {
|
||||
// name: "timelike",
|
||||
// description: "<strong>time dilation</strong> doubles your relative time <strong>rate</strong><br>and makes you immune to <strong class='color-harm'>harm</strong>",
|
||||
// isFieldTech: true,
|
||||
// maxCount: 1,
|
||||
// count: 0,
|
||||
// frequency: 2,
|
||||
// frequencyDefault: 2,
|
||||
// allowed() {
|
||||
// return m.fieldUpgrades[m.fieldMode].name === "time dilation" && !m.isShipMode && !tech.isRewindField
|
||||
// },
|
||||
// requires: "time dilation, not retrocausality",
|
||||
// effect() {
|
||||
// tech.isTimeSkip = true;
|
||||
// },
|
||||
// remove() {
|
||||
// tech.isTimeSkip = false;
|
||||
// }
|
||||
// },
|
||||
{
|
||||
name: "Lorentz transformation",
|
||||
description: `use ${powerUps.orb.research(3)}to increase your time rate<br><strong>move</strong>, <strong>jump</strong>, and <strong>shoot</strong> <strong>50%</strong> faster`,
|
||||
@@ -6997,7 +7019,7 @@ const tech = {
|
||||
},
|
||||
{
|
||||
name: "time crystals",
|
||||
description: "<strong>quadruple</strong> your default <strong class='color-f'>energy</strong> regeneration",
|
||||
description: "<strong>quadruple</strong> your base <strong class='color-f'>energy</strong> regeneration",
|
||||
isFieldTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -7241,7 +7263,7 @@ const tech = {
|
||||
effect: () => {
|
||||
tech.wimpCount++
|
||||
spawn.WIMP()
|
||||
for (let j = 0, len = 1 + 5 * Math.random(); j < len; j++) powerUps.spawn(level.exit.x + 100 * (Math.random() - 0.5), level.exit.y - 100 + 100 * (Math.random() - 0.5), "research", false)
|
||||
for (let j = 0, len = 5; j < len; j++) powerUps.spawn(level.exit.x + 100 * (Math.random() - 0.5), level.exit.y - 100 + 100 * (Math.random() - 0.5), "research", false)
|
||||
},
|
||||
remove() {
|
||||
tech.wimpCount = 0
|
||||
@@ -7368,9 +7390,9 @@ const tech = {
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
allowed() {
|
||||
return m.fieldUpgrades[m.fieldMode].name === "wormhole"
|
||||
return m.fieldUpgrades[m.fieldMode].name === "wormhole" && !tech.isNoDraftPause
|
||||
},
|
||||
requires: "wormhole",
|
||||
requires: "wormhole, not eternalism",
|
||||
effect() {
|
||||
tech.isWormHolePause = true
|
||||
},
|
||||
@@ -7822,7 +7844,7 @@ const tech = {
|
||||
remove() {}
|
||||
},
|
||||
{
|
||||
name: "opacity",
|
||||
name: " ",
|
||||
description: "",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -9895,4 +9917,6 @@ const tech = {
|
||||
coyoteTime: null,
|
||||
missileFireCD: null,
|
||||
isBotField: null,
|
||||
isFoamBall: null,
|
||||
isNoDraftPause: null
|
||||
}
|
||||
45
todo.txt
45
todo.txt
@@ -1,34 +1,45 @@
|
||||
******************************************************** NEXT PATCH **************************************************
|
||||
|
||||
tech: eternalism - tech,gun,field gives an ammo but, time doesn't pause while choosing
|
||||
I might change the ammo to something else, not sure, maybe just damage
|
||||
JUNK tech: panpsychism - awaken blocks, blocks can drop power ups
|
||||
time dilation field rework
|
||||
2x energy regen, but pausing time now uses much more energy
|
||||
you are immune to harm while time is paused
|
||||
but this stops energy regen
|
||||
tech timelike is removed
|
||||
|
||||
cache gives 14->16x ammo
|
||||
1st ionization energy gives 8->10% max energy on heal
|
||||
eternalism gives 50% damage instead of ammo
|
||||
also disables the pause button, and other pause effects
|
||||
|
||||
powerUpBossBaby immunity phase is a bit shorter
|
||||
tech: polyurethane foam - super balls turn into foam after hitting a mob
|
||||
supertemporal renamed autocannon
|
||||
now gives +1 ball, and has a shorter delay between balls
|
||||
|
||||
harpoon and grapple no longer lose ammo when you run out of energy
|
||||
they just trigger a 2 second fire CD
|
||||
slashBoss doesn't slash as often at higher difficulty levels
|
||||
field descriptions rewritten
|
||||
|
||||
bug fixes
|
||||
|
||||
******************************************************** TODO ********************************************************
|
||||
|
||||
tech: - don't pause time during draft
|
||||
tech: eternalism - don't pause time during draft
|
||||
bugs
|
||||
requirements change after draft is generated
|
||||
disable effects that change requirements
|
||||
when simulation.isChoosing you can't: eject tech,
|
||||
check for requirements onclick and give random tech if not met?
|
||||
|
||||
make lasers on labs flash on and off
|
||||
make switch a button that stays down
|
||||
check for requirements onclick and give random tech if not met?
|
||||
|
||||
tech expansion: should also make other fields do things
|
||||
perfect diamagnetism moves forward when you hold down the shield
|
||||
maybe only with crouch?
|
||||
time dilation drains 1/2 as much energy when paused
|
||||
grow plasma torch as you hold it down
|
||||
negative mass effects much more space
|
||||
needs more benefit
|
||||
reduces the cloaking vision effect?
|
||||
needs more benefit
|
||||
|
||||
nonrefundable tech don't display, this is confusing
|
||||
maybe they can show up but greyed out or something
|
||||
|
||||
make your power up list scrollable while in power up selection pause menu
|
||||
|
||||
Tech could probably be indexed, something like running
|
||||
tech.index = new Map();
|
||||
for (let i = 0; i < tech.tech.length; i++) {
|
||||
@@ -45,10 +56,6 @@ if (queriedTech) {
|
||||
guntech fire a bullet that fires nail fragments after 1s in the same direction as the original bullet
|
||||
like overwatch roadhog
|
||||
|
||||
make mol fab field do something cool when it blocks
|
||||
generate energy?
|
||||
reset lifespan of: drone,spore,worm, iceIX
|
||||
|
||||
bring back:
|
||||
the old phase decoherence field
|
||||
make cloak only active on input.field down
|
||||
|
||||
Reference in New Issue
Block a user