matter wave renamed wave
  tech: frequency - wave has unlimited ammo, but -50% wave firerate
  tech: sympathetic resonance - when phonon waves hit a mob they make a new resonance wave
    effect cooldown grows +5s with each chained resonance
  uncertainty principle works with phonon wave
  phase velocity works with all other wave tech, 40->35% damage
  boundstate reduces wave range by 25->15%

non-renewables 88% -> 67% damage
improved fine-structure constant graphic for when you lose coupling
laser mobs pulse a laser 50% of the time for 2x damage

a bunch of bug fixes
caliber does a bit more damage at 1 stack, but does less damage at 3+ stacks
  it grew mass and damage at an exponential rate before
  now it's closer to the +30% damage description
This commit is contained in:
landgreen
2022-09-11 07:10:14 -07:00
parent 9e613a281e
commit 8f702cfa4e
12 changed files with 479 additions and 259 deletions

View File

@@ -148,7 +148,7 @@ const b = {
for (let i = 0; i < b.guns.length; i++) {
b.inventory[i] = i;
b.guns[i].have = true;
b.guns[i].ammo = Math.ceil(b.guns[i].ammoPack * ammoPacks);
if (b.guns[i].ammo !== Infinity) b.guns[i].ammo = Math.ceil(b.guns[i].ammoPack * ammoPacks);
}
b.activeGun = 0;
} else {
@@ -165,11 +165,12 @@ const b = {
}
if (!b.guns[gun].have) b.inventory.push(gun);
b.guns[gun].have = true;
b.guns[gun].ammo = Math.ceil(b.guns[gun].ammoPack * ammoPacks);
if (b.guns[gun].ammo !== Infinity) b.guns[gun].ammo = Math.ceil(b.guns[gun].ammoPack * ammoPacks);
if (b.activeGun === null) {
b.activeGun = gun //if no active gun switch to new gun
if (b.guns[b.activeGun].charge) b.guns[b.activeGun].charge = 0; //set foam charge to zero if foam is a new gun
}
// if (tech.infiniteWaveAmmo === 2) b.guns[3].ammo = Infinity
}
simulation.makeGunHUD();
b.setFireCD();
@@ -280,7 +281,6 @@ const b = {
},
fireCDscale: 1,
setFireCD() {
b.fireCDscale = tech.fireRate * tech.slowFire * tech.researchHaste * tech.aimDamage
if (m.fieldMode === 6) b.fireCDscale *= 0.75
if (tech.isFastTime) b.fireCDscale *= 0.5
@@ -3731,10 +3731,7 @@ const b = {
if (!this.target && who.alive) {
this.target = who;
if (who.radius < 20) {
this.targetRelativePosition = {
x: 0,
y: 0
} //find relative position vector for zero mob rotation
this.targetRelativePosition = { x: 0, y: 0 } //find relative position vector for zero mob rotation
} else if (Matter.Query.collides(this, [who]).length > 0) {
const normal = Matter.Query.collides(this, [who])[0].normal
this.targetRelativePosition = Vector.rotate(Vector.sub(Vector.sub(this.position, who.position), Vector.mult(normal, -this.radius)), -who.angle) //find relative position vector for zero mob rotation
@@ -3754,10 +3751,7 @@ const b = {
}
}
this.targetVertex = bestVertex
Matter.Body.setVelocity(this, {
x: 0,
y: 0
});
Matter.Body.setVelocity(this, { x: 0, y: 0 });
}
},
onEnd() {},
@@ -5111,7 +5105,7 @@ const b = {
//0 nail gun
//1 shotgun
//2 super balls
//3 matter wave
//3 wave
//4 missiles
//5 grenades
//6 spores
@@ -5667,8 +5661,8 @@ const b = {
},
fireOne() {
const SPEED = input.down ? 43 : 36
m.fireCDcycle = m.cycle + Math.floor((input.down ? 23 : 15) * b.fireCDscale); // cool down
const SPEED = input.down ? 40 : 33
m.fireCDcycle = m.cycle + Math.floor((input.down ? 27 : 19) * b.fireCDscale); // cool down
let dir = m.angle
const me = bullet.length;
bullet[me] = Bodies.polygon(m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle), 12, 21 * tech.bulletSize, b.fireAttributes(dir, false));
@@ -5844,15 +5838,16 @@ const b = {
fire() {}
},
{
name: "matter wave", //3
name: "wave", //3
description: "emit a <strong>wave packet</strong> of oscillating particles<br>that propagates through <strong>solids</strong>",
ammo: 0,
ammoPack: 110,
defaultAmmoPack: 110,
ammoPack: 115,
defaultAmmoPack: 115,
have: false,
wavePacketCycle: 0,
delay: 40,
propagationRate: 20,
phononWaveCD: 0,
waves: [], //used in longitudinal mode
chooseFireMethod() { //set in simulation.startGame
this.waves = [];
@@ -5875,47 +5870,60 @@ const b = {
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 = 1.8 * m.dmgScale * tech.wavePacketDamage * tech.waveBeamDamage * (tech.isBulletTeleport ? 1.43 : 1) //damage is lower for large radius mobs, since they feel the waves longer
const end = 700 * Math.sqrt(tech.isBulletsLastLonger) * Math.pow(0.93, tech.waveReflections) // / Math.sqrt(tech.waveReflections * 0.5) //should equal about 1060
const damage = 1.9 * m.dmgScale * tech.wavePacketDamage * tech.waveBeamDamage * (tech.isBulletTeleport ? 1.43 : 1) * (tech.isPhaseVelocity ? 1.25 : 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) })
}
// 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));
if (!mob[j].isShielded) {
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 (tech.isPhononWave && this.phononWaveCD < m.cycle) {
this.phononWaveCD = m.cycle + 10 * (1 + this.waves[i].resonanceCount)
this.waves.push({
position: mob[j].position,
radius: 25,
reflection: 1,
expanding: true,
resonanceCount: this.waves[i].resonanceCount + 1,
})
}
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++) {
// for (let j = 0, len = body.length; j < len; j++) {
for (let j = 0, len = Math.min(30, 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) {
@@ -5941,7 +5949,7 @@ const b = {
}
this.waves[i].radius += 0.9 * 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) {
if (this.waves[i].radius > end - 50 * this.waves[i].resonanceCount) { //* Math.pow(0.9, this.waves[i].resonanceCount)
this.waves[i].expanding = -1
this.waves[i].reflection--
if (this.waves[i].reflection < 1) this.waves.splice(i, 1) //end
@@ -5955,12 +5963,13 @@ const b = {
}
},
fire360Longitudinal() {
m.fireCDcycle = m.cycle + Math.floor((input.down ? 3 : 8) * b.fireCDscale); // cool down
m.fireCDcycle = m.cycle + Math.floor((input.down ? 4 : 8) * b.fireCDscale * tech.infiniteWaveAmmo); // cool down
this.waves.push({
position: { x: m.pos.x, y: m.pos.y, },
radius: 25,
reflection: tech.waveReflections,
expanding: true
expanding: true,
resonanceCount: 0 //used with tech.isPhononWave
})
},
doLongitudinal() {
@@ -5968,39 +5977,22 @@ const b = {
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 = 1.8 * m.dmgScale * tech.wavePacketDamage * tech.waveBeamDamage * (tech.isBulletTeleport ? 1.43 : 1) //damage is lower for large radius mobs, since they feel the waves longer
// const end = 1100 * tech.isBulletsLastLonger / Math.sqrt(tech.waveReflections * 0.5) //should equal about 1767
const end = 1100 * tech.isBulletsLastLonger * Math.pow(0.93, tech.waveReflections) //should equal about 1767
const damage = 1.9 * m.dmgScale * tech.wavePacketDamage * tech.waveBeamDamage * (tech.isBulletTeleport ? 1.4 : 1) * (tech.isPhaseVelocity ? 1.25 : 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) }
}
}
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) {
if (!who.isShielded) {
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
@@ -6008,17 +6000,50 @@ const b = {
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));
}
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));
// if (tech.isPhononWave && (!who.alive || this.waves.length < 30 + 30 * Math.random()) && m.fireCDcycle < m.cycle) { //
if (tech.isPhononWave && this.phononWaveCD < m.cycle) {
this.phononWaveCD = m.cycle + 10 * (1 + this.waves[i].resonanceCount)
const halfArc = 0.27 //6.28 is a full circle, but these arcs needs to stay small because we are using small angle linear approximation, for collisions
let closestMob, dist
let range = end - 50 * this.waves[i].resonanceCount
for (let i = 0, len = mob.length; i < len; i++) {
if (who !== mob[i] && !mob[i].isBadTarget && !mob[i].isInvulnerable) {
dist = Vector.magnitude(Vector.sub(who.position, mob[i].position));
if (dist < range) {
closestMob = mob[i]
range = dist
}
}
}
if (closestMob) {
const dir = Vector.normalise(Vector.sub(closestMob.position, who.position))
var angle = Math.atan2(dir.y, dir.x)
} else {
var angle = 2 * Math.PI * Math.random()
}
this.waves.push({
position: who.position,
angle: angle - halfArc, //used in drawing ctx.arc
unit1: { x: Math.cos(angle - halfArc), y: Math.sin(angle - halfArc) }, //used for collision
unit2: { x: Math.cos(angle + halfArc), y: Math.sin(angle + halfArc) }, //used for collision
arc: halfArc * 2,
radius: 25,
reflection: 1,
expanding: 1,
resonanceCount: this.waves[i].resonanceCount + 1
})
}
}
}
hits = Matter.Query.ray(body, v1, v2, 50) //Matter.Query.ray(bodies, startPoint, endPoint, [rayWidth])
for (let j = 0; j < hits.length; j++) {
// for (let j = 0; j < hits.length; j++) {
for (let j = 0, len = Math.min(30, hits.length); j < len; j++) {
const who = hits[j].body
//make them shake around
who.force.x += 0.01 * (Math.random() - 0.5) * who.mass
@@ -6041,7 +6066,7 @@ const b = {
// ctx.stroke(); //draw vibes
this.waves[i].radius += tech.waveBeamSpeed * 1.8 * this.waves[i].expanding //expand / move
if (this.waves[i].radius > end) {
if (this.waves[i].radius > end - 50 * this.waves[i].resonanceCount) {
this.waves[i].expanding = -1
this.waves[i].reflection--
if (this.waves[i].reflection < 1) this.waves.splice(i, 1) //end
@@ -6055,20 +6080,26 @@ const b = {
}
},
fireLongitudinal() {
m.fireCDcycle = m.cycle + Math.floor((input.down ? 3 : 8) * b.fireCDscale); // cool down
const halfArc = input.down ? 0.0785 : 0.275 //6.28 is a full circle, but these arcs needs to stay small because we are using small angle linear approximation, for collisions
m.fireCDcycle = m.cycle + Math.floor((input.down ? 4 : 8) * b.fireCDscale * tech.infiniteWaveAmmo); // cool down
const halfArc = (input.down ? 0.0785 : 0.275) * (tech.isBulletTeleport ? 0.66 + (Math.random() - 0.5) : 1) //6.28 is a full circle, but these arcs needs to stay small because we are using small angle linear approximation, for 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) })
// }
const angle = m.angle + tech.isBulletTeleport * 0.3 * (Math.random() - 0.5)
this.waves.push({
position: {
x: m.pos.x + 25 * Math.cos(m.angle),
y: m.pos.y + 25 * Math.sin(m.angle),
},
angle: m.angle - halfArc, //used in drawing ctx.arc
unit1: { x: Math.cos(m.angle - halfArc), y: Math.sin(m.angle - halfArc) }, //used for collision
unit2: { x: Math.cos(m.angle + halfArc), y: Math.sin(m.angle + halfArc) }, //used for collision
angle: angle - halfArc, //used in drawing ctx.arc
unit1: { x: Math.cos(angle - halfArc), y: Math.sin(angle - halfArc) }, //used for collision
unit2: { x: Math.cos(angle + halfArc), y: Math.sin(angle + halfArc) }, //used for collision
arc: halfArc * 2,
radius: 25,
reflection: tech.waveReflections,
expanding: 1
expanding: 1,
resonanceCount: 0
})
},
doTransverse() {
@@ -6161,7 +6192,7 @@ const b = {
if (tech.isPhaseVelocity) {
waveSpeedMap = 3.5
waveSpeedBody = 2
bullet[me].dmg *= 1.4
bullet[me].dmg *= 1.35
}
if (tech.waveReflections) {
bullet[me].reflectCycle = totalCycles / tech.waveReflections //tech.waveLengthRange
@@ -6189,7 +6220,7 @@ const b = {
//fire a packet of bullets then delay for a while
this.wavePacketCycle++
if (this.wavePacketCycle > 35) {
m.fireCDcycle = m.cycle + Math.floor(this.delay * b.fireCDscale); // cool down
m.fireCDcycle = m.cycle + Math.floor(this.delay * b.fireCDscale * tech.infiniteWaveAmmo); // cool down
this.wavePacketCycle = 0;
}
},
@@ -6894,6 +6925,7 @@ const b = {
x: m.pos.x + 30 * Math.cos(m.angle),
y: m.pos.y + 30 * Math.sin(m.angle)
}, null, m.angle, harpoonSize, true, totalCycles)
tech.harpoonDensity = 0.004 //0.001 is normal for blocks, 0.004 is normal for harpoon, 0.004*6 when buffed
}
if (count < num * delay && m.alive) requestAnimationFrame(harpoonDelay);
}
@@ -6922,11 +6954,11 @@ const b = {
b.harpoon(where, closest.target, m.angle, harpoonSize, true, totalCycles)
}
m.fireCDcycle = m.cycle + 45 // cool down
tech.harpoonDensity = 0.004 //0.001 is normal for blocks, 0.004 is normal for harpoon, 0.004*6 when buffed
}
const recoil = Vector.mult(Vector.normalise(Vector.sub(where, m.pos)), input.down ? 0.015 : 0.035)
player.force.x -= recoil.x
player.force.y -= recoil.y
tech.harpoonDensity = 0.004 //0.001 is normal for blocks, 0.004 is normal for harpoon, 0.004*6 when buffed
},
}, {
name: "mine", //10
@@ -7032,12 +7064,10 @@ const b = {
}
if (tech.isPulseLaser) {
this.fire = () => {
const drain = 0.01 * (tech.isCapacitor ? 10 : 1) / b.fireCDscale
if (m.energy > drain) {
if (this.charge < 50 * m.maxEnergy) {
m.energy -= drain
this.charge += drain * 100
}
const drain = Math.min(0.9 * m.maxEnergy, 0.01 * (tech.isCapacitor ? 10 : 1) / b.fireCDscale)
if (m.energy > drain && this.charge < 50 * m.maxEnergy) {
m.energy -= drain
this.charge += drain * 100
}
}
if (tech.historyLaser) {
@@ -7229,7 +7259,7 @@ const b = {
} else {
m.fireCDcycle = m.cycle
m.energy -= drain
const dmg = 0.4 * tech.laserDamage / b.fireCDscale * this.lensDamage // 3.5 * 0.55 = 200% more damage
const dmg = 0.37 * tech.laserDamage / b.fireCDscale * this.lensDamage // 3.5 * 0.55 = 200% more damage
const spacing = Math.ceil(5 - 0.4 * tech.historyLaser)
ctx.beginPath();
b.laser({