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

@@ -91,18 +91,18 @@
<option value="pavilion">
<option value="labs">
<option value="______">
<option value="biohazard">
<option value="islands">
<option value="tunnel">
<option value="coliseum">
<option value="dripp">
<option value="perplex">
<option value="n-gon">
<option value="vats">
<option value="basement">
<option value="stronghold">
<option value="crossfire">
<option value="house">
<option value="dripp">
<option value="crossfire">
<option value="temple">
<option value="run">
</datalist>

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,19 +5870,20 @@ 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++) {
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) {
@@ -5913,9 +5909,21 @@ const b = {
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,
})
}
}
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,14 +7064,12 @@ 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) {
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) {
const len = 1 + tech.historyLaser
const spacing = Math.ceil(30 - 2 * 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({

View File

@@ -160,7 +160,64 @@ function collisionChecks(event) {
simulation.makeTextLog(`simulation.amplitude <span class='color-symbol'>=</span> ${Math.random()}`);
}
if (tech.isPiezo) m.energy += 20.48;
if (tech.isCouplingNoHit) m.couplingChange(-0.5)
if (tech.isCouplingNoHit && m.coupling > 0) {
m.couplingChange(-0.5)
const unit = Vector.rotate({ x: 1, y: 0 }, 6.28 * Math.random())
let where = Vector.add(m.pos, Vector.mult(unit, 17))
simulation.drawList.push({ //add dmg to draw queue
x: where.x,
y: where.y,
radius: 22,
color: 'rgba(0, 171, 238, 0.33)',
time: 8
});
where = Vector.add(m.pos, Vector.mult(unit, 60))
simulation.drawList.push({ //add dmg to draw queue
x: where.x,
y: where.y,
radius: 18,
color: 'rgba(0, 171, 238, 0.5)',
time: 16
});
where = Vector.add(m.pos, Vector.mult(unit, 100))
simulation.drawList.push({ //add dmg to draw queue
x: where.x,
y: where.y,
radius: 14,
color: 'rgba(0, 171, 238, 0.6)',
time: 24
});
where = Vector.add(m.pos, Vector.mult(unit, 135))
simulation.drawList.push({ //add dmg to draw queue
x: where.x,
y: where.y,
radius: 10,
color: 'rgba(0, 171, 238, 0.7)',
time: 32
});
// simulation.drawList.push({ //add dmg to draw queue
// x: m.pos.x,
// y: m.pos.y,
// radius: 150,
// color: 'rgba(0, 171, 238, 0.33)',
// time: 6
// });
// simulation.drawList.push({ //add dmg to draw queue
// x: m.pos.x,
// y: m.pos.y,
// radius: 75,
// color: 'rgba(0, 171, 238, 0.5)',
// time: 16
// });
// simulation.drawList.push({ //add dmg to draw queue
// x: m.pos.x,
// y: m.pos.y,
// radius: 25,
// color: 'rgba(0, 171, 238, 0.75)',
// time: 25
// });
}
if (tech.isStimulatedEmission) powerUps.ejectTech()
if (mob[k].onHit) mob[k].onHit();
if (m.immuneCycle < m.cycle + m.collisionImmuneCycles) m.immuneCycle = m.cycle + m.collisionImmuneCycles; //player is immune to damage for 30 cycles

View File

@@ -226,7 +226,6 @@ for (let i = 0, len = tech.tech.length; i < len; i++) {
}
const build = {
pauseGrid() {
//used for junk estimation
let junkCount = 0
let totalCount = 1 //start at one to avoid NaN issues
@@ -255,7 +254,7 @@ const build = {
text += `
<br><strong class='color-d'>damage</strong>: ${((tech.damageFromTech())).toPrecision(3)} &nbsp; &nbsp; difficulty: ${((m.dmgScale)).toPrecision(3)}
<br><strong class='color-defense'>defense</strong>: ${(1-m.harmReduction()).toPrecision(3)} &nbsp; &nbsp; difficulty: ${(1/simulation.dmgScale).toPrecision(3)}
${b.fireCDscale < 1 ? `<br><strong><em>fire rate</em></strong>: ${((1-b.fireCDscale)*100).toFixed(b.fireCDscale < 0.1 ? 2 : 0)}%`: ""}
<br><strong><em>fire rate</em></strong>: ${((1-b.fireCDscale)*100).toFixed(b.fireCDscale < 0.1 ? 2 : 0)}%
${tech.duplicationChance() ? `<br><strong class='color-dup'>duplication</strong>: ${(tech.duplicationChance()*100).toFixed(0)}%`: ""}
${m.coupling ? `<br><strong class='color-coupling'>coupling</strong>: ${(m.coupling).toFixed(2)} &nbsp; <span style = 'font-size:90%;'>`+m.couplingDescription()+"</span>": ""}
${botText}
@@ -431,7 +430,7 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>": ""}
//update tech text //disable not allowed tech
for (let i = 0, len = tech.tech.length; i < len; i++) {
const techID = document.getElementById("tech-" + i)
if (!tech.tech[i].isExperimentHide && !tech.tech[i].isNonRefundable && (!tech.tech[i].isJunk || localSettings.isJunkExperiment)) {
if ((!tech.tech[i].isJunk || localSettings.isJunkExperiment)) { //!tech.tech[i].isNonRefundable && //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! does removing this cause problems????
if (tech.tech[i].allowed() || isAllowed || tech.tech[i].count > 0) {
const techCountText = tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : "";
// <div class="circle-grid-small research" style="position:absolute; top:13px; left:30px;opacity:0.85;"></div>
@@ -529,7 +528,7 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>": ""}
text += `<div id = "gun-${i}" class="experiment-grid-module" onclick="build.choosePowerUp(this,${i},'gun')"><div class="grid-title"><div class="circle-grid gun"></div> &nbsp; ${build.nameLink(b.guns[i].name)}</div> ${b.guns[i].description}</div>`
}
for (let i = 0, len = tech.tech.length; i < len; i++) {
if (!tech.tech[i].isExperimentHide && (!tech.tech[i].isJunk || localSettings.isJunkExperiment)) { //&& (!tech.tech[i].isNonRefundable)) {
if (!tech.tech[i].isJunk || localSettings.isJunkExperiment) {
if (tech.tech[i].allowed() && (!tech.tech[i].isNonRefundable || localSettings.isJunkExperiment)) { // || tech.tech[i].name === "+1 cardinality") { //|| tech.tech[i].name === "leveraged investment"
if (tech.tech[i].isJunk) {
text += `<div id="tech-${i}" class="experiment-grid-module" onclick="build.choosePowerUp(this,${i},'tech')"><div class="grid-title"><div class="circle-grid junk"></div> &nbsp; ${tech.tech[i].link}</div> ${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}</div>`
@@ -595,7 +594,7 @@ ${simulation.isCheating ? "<br><br><em>lore disabled</em>": ""}
count = 0;
for (let i = 0; i < tech.tech.length; i++) {
for (let j = 0; j < tech.tech[i].count; j++) {
if (!tech.tech[i].isLore && !tech.tech[i].isJunk && !tech.tech[i].isNonRefundable && !tech.tech[i].isExperimentHide) {
if (!tech.tech[i].isLore && !tech.tech[i].isJunk && !tech.tech[i].isNonRefundable) {
url += `&tech${count}=${encodeURIComponent(tech.tech[i].name.trim())}`
count++
}

View File

@@ -16,7 +16,7 @@ const level = {
start() {
if (level.levelsCleared === 0) { //this code only runs on the first level
// simulation.enableConstructMode() //used to build maps in testing mode
// level.difficultyIncrease(10 * 4) //30 is near max on hard //60 is near max on why
// level.difficultyIncrease(24 * 4) //30 is near max on hard //60 is near max on why
// simulation.isHorizontalFlipped = true
// m.maxHealth = m.health = 100
// tech.isRerollDamage = true
@@ -24,23 +24,24 @@ const level = {
// m.immuneCycle = Infinity //you can't take damage
// tech.tech[297].frequency = 100
// m.setField("time dilation") //molecular assembler standing wave time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass
// b.giveGuns("laser") //0 nail gun 1 shotgun 2 super balls 3 matter wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.guns[0].ammo = 1000000
// tech.giveTech("fine-structure constant")
// for (let i = 0; i < 1; ++i) tech.giveTech("relay switch")
// for (let i = 0; i < 1; ++i) tech.giveTech("decoupling")
// m.damage(0.1);
// tech.giveTech("lens")
// for (let i = 0; i < 9; i++) tech.giveTech("compound lens")
// b.giveGuns("wave") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser
// b.guns[3].ammo = 1000000
// tech.giveTech("phonon")
// for (let i = 0; i < 4; ++i) tech.giveTech("bound state")
// for (let i = 0; i < 1; ++i) tech.giveTech("isotropic")
// tech.giveTech("sympathetic resonance")
// for (let i = 0; i < 1; i++) tech.giveTech("uncertainty principle")
// for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "tech");
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "boost");
// for (let i = 0; i < 10; i++) powerUps.directSpawn(1750, -500, "coupling");
// spawn.starter(1900, -500, 200)
// spawn.starter(1900, -500)
// spawn.beetleBoss(2538, -1950)
// for (let i = 0; i < 15; ++i) spawn.shooter(1900 + 300 * Math.random(), -500 + 300 * Math.random())
// for (let i = 0; i < 33; ++i) spawn.shooter(1000 + 5000 * Math.random(), -500 + 300 * Math.random())
// tech.addJunkTechToPool(2)
// tech.tech[321].frequency = 100
// tech.tech[322].frequency = 100
// level.testing();
// spawn.blowSuckBoss(1900, -500)
// for (let i = 0; i < 13; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "research");
@@ -11665,7 +11666,7 @@ const level = {
},
biohazard() {
// MAP BY INOOBBOI AND THESHWARMA
simulation.makeTextLog(`<strong>dripp</strong> by <span class='color-var'>INOOBBOI</span> and <span class='color-var'>THESHWARMA</span>`);
simulation.makeTextLog(`<strong>biohazard</strong> by <span class='color-var'>INOOBBOI</span> and <span class='color-var'>THESHWARMA</span>`);
// set here for the cutscene later
level.setPosToSpawn(-2800, -150)
@@ -13674,7 +13675,7 @@ const level = {
spawn.mapRect(1550, 12, 50, 25);
spawn.mapRect(1600, -400, 50, 225); //exit room left upper wall
},
matterWave() { //fire matter wave through the map to kill mosb
matterWave() { //fire wave through the map to kill mosb
level.difficultyIncrease(1) //difficulty on training mode resets to zero with each new level
level.setPosToSpawn(60, -50); //normal spawn
spawn.mapRect(10, -10, 100, 20); //small platform for player
@@ -13686,17 +13687,17 @@ const level = {
simulation.zoomTransition(level.defaultZoom, 1)
document.body.style.backgroundColor = level.trainingBackgroundColor
b.removeAllGuns();
b.giveGuns("matter wave")
b.giveGuns("wave")
// b.guns[b.activeGun].ammo = 0
// simulation.updateGunHUD();
const door = level.door(1612.5, -175, 25, 190, 185, 3)
let instruction = 0
level.trainingText(`use <strong class='color-g'>matter wave</strong> to clear the room of mobs`)
level.trainingText(`use <strong class='color-g'>wave</strong> to clear the room of mobs`)
level.custom = () => {
if (instruction === 0 && mob.length === 0) {
instruction++
level.trainingText(`<s>use <strong class='color-g'>matter wave</strong> to clear the room of mobs</s>`)
level.trainingText(`<s>use <strong class='color-g'>wave</strong> to clear the room of mobs</s>`)
}
//spawn ammo if you run out
let isAmmo = false

View File

@@ -237,7 +237,7 @@ const mobs = {
// },
mobSpawnWithHealth: 1,
setMobSpawnHealth() {
mobs.mobSpawnWithHealth = 0.87 ** (tech.mobSpawnWithHealth) //+ (m.fieldMode === 0 || m.fieldMode === 7) * m.coupling
mobs.mobSpawnWithHealth = 0.88 ** (tech.mobSpawnWithHealth) //+ (m.fieldMode === 0 || m.fieldMode === 7) * m.coupling
},
//**********************************************************************************************
//**********************************************************************************************

View File

@@ -1582,7 +1582,7 @@ const m = {
case 5: //plasma
return `<strong>+${(15*couple).toFixed(0)}%</strong> <strong class='color-d'>damage</strong>`
case 6: //time dilation
return `<strong>+${(25*couple).toFixed(0)}%</strong> longer <strong style='letter-spacing: 2px;'>stopped time</strong>` //<strong>movement</strong>, <strong>jumping</strong>, and
return `<strong>+${(30*couple).toFixed(0)}%</strong> longer <strong style='letter-spacing: 2px;'>stopped time</strong>` //<strong>movement</strong>, <strong>jumping</strong>, and
case 7: //cloaking
return `<strong>+${(33*couple).toFixed(0)}%</strong> ambush <strong class='color-d'>damage</strong>`
case 8: //pilot wave
@@ -2685,14 +2685,14 @@ const m = {
},
{
name: "time dilation",
description: "use <strong class='color-f'>energy</strong> to <strong style='letter-spacing: 2px;'>stop time</strong><br><strong>+25%</strong> movement, jumping, and <strong><em>fire rate</em></strong><br>generate <strong>18</strong> <strong class='color-f'>energy</strong> per second",
description: "use <strong class='color-f'>energy</strong> to <strong style='letter-spacing: 2px;'>stop time</strong><br><strong>+25%</strong> movement and <strong><em>fire rate</em></strong><br>generate <strong>18</strong> <strong class='color-f'>energy</strong> per second",
set() {
// m.fieldMeterColor = "#0fc"
// m.fieldMeterColor = "#ff0"
m.fieldMeterColor = "#3fe"
m.eyeFillColor = m.fieldMeterColor
m.fieldFx = 1.2
m.fieldJump = 1.09
m.fieldFx = 1.3
// m.fieldJump = 1.09
m.setMovement();
const timeStop = () => {
@@ -2745,7 +2745,7 @@ const m = {
m.throwBlock();
m.wakeCheck();
} else if (input.field && m.fieldCDcycle < m.cycle) { //not hold but field button is pressed
const drain = 0.002 / (1 + 0.25 * m.coupling)
const drain = 0.002 / (1 + 0.3 * m.coupling)
if (m.energy > drain) m.energy -= drain
m.grabPowerUp();
@@ -2822,7 +2822,7 @@ const m = {
m.holding();
m.throwBlock();
} else if (input.field && m.fieldCDcycle < m.cycle) {
const drain = 0.0026 / (1 + 0.25 * m.coupling)
const drain = 0.0026 / (1 + 0.3 * m.coupling)
if (m.energy > drain) m.energy -= drain
m.grabPowerUp();
m.lookForPickUp(); //this drains energy 0.001

View File

@@ -1094,7 +1094,7 @@ const powerUps = {
},
onPickUp(who) {
powerUps.research.currentRerollCount = 0
if (tech.isTechDamage && who.name === "tech") m.damage(0.11 + 0.11 * tech.isEnergyHealth)
if (tech.isTechDamage && who.name === "tech") m.damage(0.12 + 0.12 * tech.isEnergyHealth)
if (tech.isMassEnergy) m.energy += 2;
if (tech.isMineDrop && bullet.length < 150 && Math.random() < 0.6) {
if (tech.isLaserMine && input.down) {

View File

@@ -449,9 +449,9 @@ const simulation = {
}
},
switchGun() {
if (tech.isLongitudinal && b.guns[b.activeGun].name === "matter wave") {
if (tech.isLongitudinal && b.guns[b.activeGun].name === "wave") {
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "matter wave") {
if (b.guns[i].name === "wave") {
b.guns[i].waves = []; //empty array of wave bullets
break;
}
@@ -870,7 +870,7 @@ const simulation = {
if (m.alive) {
if (tech.isLongitudinal) {
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "matter wave") {
if (b.guns[i].name === "wave") {
b.guns[i].waves = []; //empty array of wave bullets
break;
}

View File

@@ -3594,21 +3594,116 @@ const spawn = {
};
},
laser(x, y, radius = 30) {
mobs.spawn(x, y, 3, radius, "#f00");
const color = "#f00"
mobs.spawn(x, y, 3, radius, color);
let me = mob[mob.length - 1];
me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front
Matter.Body.rotate(me, Math.random() * Math.PI * 2);
me.accelMag = 0.0001 * simulation.accelScale;
me.laserInterval = 100
me.onHit = function() {
//run this function on hitting player
this.explode();
};
me.do = function() {
this.torque = this.lookTorque * this.inertia * 0.5;
this.seePlayerByLookingAt();
this.checkStatus();
this.attraction();
this.laser();
this.torque = this.lookTorque * this.inertia * 0.5;
if (this.seePlayer.recall) {
//set direction to turn to fire
if (!(simulation.cycle % this.seePlayerFreq)) this.fireDir = Vector.normalise(Vector.sub(this.seePlayer.position, this.position));
if (simulation.cycle % this.laserInterval > this.laserInterval / 2) {
const vertexCollision = function(v1, v1End, domain) {
for (let i = 0; i < domain.length; ++i) {
let vertices = domain[i].vertices;
const len = vertices.length - 1;
for (let j = 0; j < len; j++) {
results = simulation.checkLineIntersection(v1, v1End, vertices[j], vertices[j + 1]);
if (results.onLine1 && results.onLine2) {
const dx = v1.x - results.x;
const dy = v1.y - results.y;
const dist2 = dx * dx + dy * dy;
if (dist2 < best.dist2 && (!domain[i].mob || domain[i].alive)) {
best = {
x: results.x,
y: results.y,
dist2: dist2,
who: domain[i],
v1: vertices[j],
v2: vertices[j + 1]
};
}
}
}
results = simulation.checkLineIntersection(v1, v1End, vertices[0], vertices[len]);
if (results.onLine1 && results.onLine2) {
const dx = v1.x - results.x;
const dy = v1.y - results.y;
const dist2 = dx * dx + dy * dy;
if (dist2 < best.dist2) {
best = {
x: results.x,
y: results.y,
dist2: dist2,
who: domain[i],
v1: vertices[0],
v2: vertices[len]
};
}
}
}
};
const seeRange = 8000;
best = {
x: null,
y: null,
dist2: Infinity,
who: null,
v1: null,
v2: null
};
const look = {
x: this.position.x + seeRange * Math.cos(this.angle),
y: this.position.y + seeRange * Math.sin(this.angle)
};
vertexCollision(this.position, look, map);
vertexCollision(this.position, look, body);
if (!m.isCloak) vertexCollision(this.position, look, [playerBody, playerHead]);
// hitting player
if ((best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) {
const dmg = 0.003 * simulation.dmgScale;
m.damage(dmg);
//draw damage
ctx.fillStyle = color;
ctx.beginPath();
ctx.arc(best.x, best.y, dmg * 1500, 0, 2 * Math.PI);
ctx.fill();
}
//draw beam
if (best.dist2 === Infinity) best = look;
ctx.beginPath();
ctx.moveTo(this.vertices[1].x, this.vertices[1].y);
ctx.lineTo(best.x, best.y);
ctx.strokeStyle = color;
ctx.lineWidth = 3;
ctx.setLineDash([50 + 120 * Math.random(), 50 * Math.random()]);
ctx.stroke();
ctx.setLineDash([]);
ctx.beginPath();
ctx.arc(this.vertices[1].x, this.vertices[1].y, 1 + 0.3 * (this.laserInterval - simulation.cycle % this.laserInterval), 0, 2 * Math.PI); //* this.fireCycle / this.fireDelay
ctx.fillStyle = color;
ctx.fill();
} else {
ctx.beginPath();
ctx.arc(this.vertices[1].x, this.vertices[1].y, 1 + 0.3 * (simulation.cycle % this.laserInterval), 0, 2 * Math.PI); //* this.fireCycle / this.fireDelay
ctx.fillStyle = color;
ctx.fill();
}
}
};
},
laserBoss(x, y, radius = 30) {

View File

@@ -293,7 +293,6 @@ const tech = {
frequency: 1,
frequencyDefault: 1,
isNonRefundable: true,
// isExperimentHide: true,
isBadRandomOption: true,
allowed: () => true,
requires: "",
@@ -572,16 +571,16 @@ const tech = {
},
{
name: "non-renewables",
description: `<strong>+88%</strong> <strong class='color-d'>damage</strong><br>${powerUps.orb.ammo()} can't <strong>spawn</strong>`,
description: `<strong>+67%</strong> <strong class='color-d'>damage</strong><br>${powerUps.orb.ammo()} can't <strong>spawn</strong>`,
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
allowed() {
return !tech.isAmmoFromHealth
return !tech.isAmmoFromHealth && !tech.isBoostReplaceAmmo
},
requires: "not catabolism",
damage: 1.88,
requires: "not catabolism, quasiparticles",
damage: 1.67,
effect() {
tech.damage *= this.damage
tech.isEnergyNoAmmo = true;
@@ -950,7 +949,7 @@ const tech = {
},
{
name: "reaction inhibitor",
description: "<strong>-13%</strong> maximum mob <strong>health</strong>", //<strong class='color-h'>health</strong>
description: "<strong>-12%</strong> maximum mob <strong>health</strong>", //<strong class='color-h'>health</strong>
maxCount: 3,
count: 0,
frequency: 1,
@@ -2680,7 +2679,7 @@ const tech = {
// },
{
name: "antiscience",
description: "<strong>+90%</strong> <strong class='color-d'>damage</strong><br><strong>11</strong> <strong class='color-h'>health</strong> after picking up a <strong class='color-m'>tech</strong>",
description: "<strong>+90%</strong> <strong class='color-d'>damage</strong><br><strong>12</strong> <strong class='color-h'>health</strong> after picking up a <strong class='color-m'>tech</strong>",
maxCount: 1,
count: 0,
frequency: 1,
@@ -3483,21 +3482,21 @@ const tech = {
{
name: "quintessence",
descriptionFunction() {
let converted = powerUps.research.count * this.couplingToResearch
if (this.count) converted = this.researchUsed * this.couplingToResearch
let converted = powerUps.research.count * this.couplingToResearch * 10
if (this.count) converted = this.researchUsed * this.couplingToResearch * 10
let orbText
if (converted > 20) {
if (converted > 15) {
orbText = `${converted} ${powerUps.orb.coupling()}`
} else {
orbText = powerUps.orb.coupling(converted)
}
return `use all your ${powerUps.orb.research(1)} to spawn <strong>${orbText}<br></strong>that each give <strong>+0.1</strong> <strong class='color-coupling'>coupling</strong><br>${ m.couplingDescription(1)} ${m.fieldMode === 0 ? "" : "per <strong class='color-coupling'>coupling</strong>"}`
return `use all your ${powerUps.orb.research(1)} to spawn <strong>${orbText}</strong><br>that each give <strong>+0.1</strong> <strong class='color-coupling'>coupling</strong><br>${ m.couplingDescription(1)} ${m.fieldMode === 0 ? "" : "per <strong class='color-coupling'>coupling</strong>"}`
},
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 100,
frequencyDefault: 1,
allowed() {
return powerUps.research.count > 3
},
@@ -3508,10 +3507,10 @@ const tech = {
let count = 0
while (powerUps.research.count > 0) {
powerUps.research.changeRerolls(-1)
count += 10
count += 2.5
this.researchUsed++
}
powerUps.spawnDelay("coupling", count)
powerUps.spawnDelay("coupling", Math.floor(count))
},
remove() {
if (this.count) {
@@ -3542,18 +3541,18 @@ const tech = {
{
name: "fine-structure constant",
descriptionFunction() {
return `spawn ${this.value} ${powerUps.orb.coupling(1)} that each give <strong>+0.1</strong> <strong class='color-coupling'>coupling</strong>
<br><strong>-0.5</strong> <strong class='color-coupling'>coupling</strong> after mob <strong>collisions</strong>
<br>${m.couplingDescription(1)} ${m.fieldMode === 0 ? "" : "per <strong class='color-coupling'>coupling</strong>"}`
return `spawn ${this.value} ${powerUps.orb.coupling(1)} that each give <strong>+0.1</strong> <strong class='color-coupling'>coupling</strong><br><strong>-0.5</strong> <strong class='color-coupling'>coupling</strong> after mob <strong>collisions</strong><br>${m.couplingDescription(1)} ${m.fieldMode === 0 ? "" : "per <strong class='color-coupling'>coupling</strong>"}`
},
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 100,
frequencyDefault: 1,
isNonRefundable: true,
allowed: () => true,
value: 60,
requires: "",
// allowed() { return !build.isExperimentSelection },
// requires: "NOT EXPERIMENT MODE",
value: 60,
effect() {
tech.isCouplingNoHit = true
powerUps.spawnDelay("coupling", this.value)
@@ -4091,7 +4090,7 @@ const tech = {
},
{
name: "caliber",
description: `<strong>rivets</strong>, <strong>needles</strong>, <strong>super balls</strong>, and <strong>nails</strong><br>have <strong>+25%</strong> mass and physical <strong class='color-d'>damage</strong>`,
description: `<strong>rivets</strong>, <strong>needles</strong>, <strong>super balls</strong>, and <strong>nails</strong><br>have <strong>+30%</strong> mass and physical <strong class='color-d'>damage</strong>`,
isGunTech: true,
maxCount: 9,
count: 0,
@@ -4102,7 +4101,7 @@ const tech = {
},
requires: "nails, nail gun, rivets, shotgun",
effect() {
tech.bulletSize += 0.25
tech.bulletSize = 1 + 0.25 * Math.pow(this.count + 1, 0.5)
},
remove() {
tech.bulletSize = 1;
@@ -4668,17 +4667,16 @@ const tech = {
//
{
name: "phase velocity",
description: "matter wave <strong>propagates</strong> faster through <strong>solids</strong><br><strong>+40%</strong> matter wave <strong class='color-d'>damage</strong>",
// description: "matter wave <strong>propagates</strong> faster through <strong>solids</strong><br>up by <strong>3000%</strong> in the map and <strong>760%</strong> in <strong class='color-block'>blocks</strong>",
description: "wave particles <strong>propagate</strong> faster as <strong>solids</strong><br><strong>+35%</strong> wave <strong class='color-d'>damage</strong>",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.haveGunCheck("matter wave") && !tech.isLongitudinal
return tech.haveGunCheck("wave")
},
requires: "matter wave, not phonon",
requires: "wave",
effect() {
tech.isPhaseVelocity = true;
},
@@ -4686,37 +4684,18 @@ const tech = {
tech.isPhaseVelocity = false;
}
},
{
name: "bound state",
description: "wave packets <strong>reflect</strong> backwards <strong>2</strong> times<br><strong>25%</strong> <strong>range</strong>",
isGunTech: true,
maxCount: 9,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.haveGunCheck("matter wave")
},
requires: "matter wave",
effect() {
tech.waveReflections += 2
},
remove() {
tech.waveReflections = 1
}
},
{
name: "amplitude",
description: "<strong>+37%</strong> wave <strong class='color-d'>damage</strong> and <strong>amplitude</strong>",
description: "<strong>+37%</strong> wave <strong class='color-d'>damage</strong><br><strong>+37%</strong> wave particle <strong>amplitude</strong>",
isGunTech: true,
maxCount: 3,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.haveGunCheck("matter wave")
return tech.haveGunCheck("wave")
},
requires: "matter wave",
requires: "wave",
effect() {
tech.waveFrequency *= 0.66
tech.wavePacketDamage *= 1.37
@@ -4735,92 +4714,121 @@ const tech = {
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.haveGunCheck("matter wave")
return tech.haveGunCheck("wave")
},
requires: "matter wave",
requires: "wave",
effect() {
tech.waveBeamSpeed *= 0.8;
tech.waveBeamDamage += 1.5 * 0.37 //this sets base matter wave damage
tech.waveBeamDamage += 1.55 * 0.37 //this sets base wave damage
},
remove() {
tech.waveBeamSpeed = 12;
tech.waveBeamDamage = 1.5 //this sets base matter wave damage
tech.waveBeamDamage = 1.55 //this sets base wave damage
}
},
{
name: "bound state",
description: "wave packets <strong>reflect</strong> backwards <strong>2</strong> times<br><strong>20%</strong> <strong>range</strong>",
isGunTech: true,
maxCount: 9,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.haveGunCheck("wave")
},
requires: "wave",
effect() {
tech.waveReflections += 2
},
remove() {
tech.waveReflections = 1
}
},
{
name: "frequency",
description: `<strong>wave</strong> has unlimited <strong class='color-ammo'>ammo</strong><br><strong>-50%</strong> wave <strong><em>fire rate</em></strong>`,
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 1,
frequencyDefault: 1,
allowed: () => tech.haveGunCheck("wave"),
requires: "wave",
effect() {
tech.infiniteWaveAmmo = 2
b.guns[3].savedAmmo = b.guns[3].ammo
b.guns[3].ammo = Infinity
simulation.updateGunHUD();
},
remove() {
tech.infiniteWaveAmmo = 1
b.guns[3].ammo = b.guns[3].savedAmmo
simulation.updateGunHUD();
}
},
{
name: "phonon", //longitudinal //gravitational wave?
description: "matter wave emits low <strong>frequency</strong>, high <strong class='color-d'>damage</strong><br><strong>expanding arcs</strong> that propagate through <strong>solids</strong>",
description: "waves are low <strong>frequency</strong>, high <strong class='color-d'>damage</strong><br><strong>expanding arcs</strong> that propagate through <strong>solids</strong>",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.haveGunCheck("matter wave") && !tech.isPhaseVelocity && !tech.isBulletTeleport
return tech.haveGunCheck("wave")
},
requires: "matter wave, not phase velocity, uncertainty principle",
requires: "wave",
ammoScale: 11,
effect() {
tech.isLongitudinal = true;
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "matter wave") {
b.guns[i].chooseFireMethod()
b.guns[i].ammoPack = b.guns[i].defaultAmmoPack / this.ammoScale
b.guns[i].ammo = Math.ceil(b.guns[i].ammo / this.ammoScale);
b.guns[3].chooseFireMethod()
b.guns[3].ammoPack = b.guns[3].defaultAmmoPack / this.ammoScale
if (tech.infiniteWaveAmmo === 1) {
b.guns[3].ammo = Math.ceil(b.guns[3].ammo / this.ammoScale);
} else {
b.guns[3].savedAmmo = Math.ceil(b.guns[3].savedAmmo / this.ammoScale); //used with low frequency
}
simulation.updateGunHUD();
break
}
}
},
remove() {
if (tech.isLongitudinal) {
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "matter wave") {
tech.isLongitudinal = false;
b.guns[i].chooseFireMethod()
b.guns[i].ammoPack = b.guns[i].defaultAmmoPack
b.guns[i].ammo = Math.ceil(b.guns[i].ammo * this.ammoScale);
b.guns[3].chooseFireMethod()
b.guns[3].ammoPack = b.guns[3].defaultAmmoPack
if (tech.infiniteWaveAmmo === 1) {
b.guns[3].ammo = Math.ceil(b.guns[3].ammo * this.ammoScale);
} else {
b.guns[3].savedAmmo = Math.ceil(b.guns[3].savedAmmo * this.ammoScale); //used with low frequency
}
simulation.updateGunHUD();
break
}
}
}
tech.isLongitudinal = false;
}
},
{
name: "isotropic radiator",
description: "<strong>matter wave</strong> expands in <strong>all</strong> directions<br><strong>40%</strong> <strong>range</strong> and <strong>+50%</strong> <strong class='color-d'>damage</strong>",
name: "isotropic",
description: "<strong>waves</strong> expand in <strong>all</strong> directions<br><strong>40%</strong> <strong>range</strong> and <strong>+50%</strong> <strong class='color-d'>damage</strong>",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isLongitudinal && tech.haveGunCheck("matter wave")
return tech.isLongitudinal && tech.haveGunCheck("wave") && !tech.isBulletTeleport
},
requires: "matter wave, phonon",
requires: "wave, phonon, not uncertainty principle",
effect() {
tech.is360Longitudinal = true;
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "matter wave") {
b.guns[i].chooseFireMethod()
break
}
}
b.guns[3].chooseFireMethod()
},
remove() {
tech.is360Longitudinal = false;
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
if (b.guns[i].name === "matter wave") {
b.guns[i].chooseFireMethod()
break
}
}
b.guns[3].chooseFireMethod()
}
},
{
name: "resonance",
name: "mechanical resonance",
description: "after a <strong class='color-block'>block</strong> gets vibrated by a <strong>phonon</strong><br>there is a chance it's <strong>flung</strong> at nearby mobs",
isGunTech: true,
maxCount: 1,
@@ -4828,9 +4836,9 @@ const tech = {
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isLongitudinal && tech.haveGunCheck("matter wave")
return tech.isLongitudinal && tech.haveGunCheck("wave")
},
requires: "matter wave, phonon",
requires: "wave, phonon",
effect() {
tech.isPhononBlock = true
},
@@ -4838,6 +4846,25 @@ const tech = {
tech.isPhononBlock = false
}
},
{
name: "sympathetic resonance",
description: "after a <strong>mob</strong> gets vibrated by a <strong>phonon</strong><br>a new <strong>resonance wave</strong> expands from their location",
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.isLongitudinal && tech.haveGunCheck("wave")
},
requires: "wave, phonon",
effect() {
tech.isPhononWave = true
},
remove() {
tech.isPhononWave = false
}
},
{
name: "cruise missile",
description: "<strong>+100%</strong> <strong>missile</strong> <strong class='color-e'>explosive</strong> <strong class='color-d'>damage</strong>, radius<br><strong>50%</strong> <strong>missile</strong> speed",
@@ -4953,7 +4980,7 @@ const tech = {
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.explosiveRadius === 1 && !tech.isSmallExplosion && !tech.isBlockExplode && !tech.fragments && (tech.haveGunCheck("missiles") || tech.missileBotCount || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.isPulseLaser || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && simulation.molecularMode === 1) || tech.isBoomBotUpgrade || tech.isTokamak)
return !tech.isImmuneExplosion && tech.explosiveRadius === 1 && !tech.isSmallExplosion && !tech.isBlockExplode && !tech.fragments && (tech.haveGunCheck("missiles") || tech.missileBotCount || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.isPulseLaser || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && simulation.molecularMode === 1) || tech.isBoomBotUpgrade || tech.isTokamak)
},
requires: "an explosive damage source, not ammonium nitrate, nitroglycerin, chain reaction, fragmentation",
effect() {
@@ -5875,12 +5902,12 @@ const tech = {
isGunTech: true,
maxCount: 1,
count: 0,
frequency: 2,
frequencyDefault: 2,
frequency: 1,
frequencyDefault: 1,
allowed() {
return (!tech.isFoamAttract && (tech.haveGunCheck("foam") || tech.isFoamBotUpgrade || tech.isFoamShot || tech.isFoamBall || tech.isFoamMine)) || (tech.haveGunCheck("matter wave") && !tech.isLongitudinal)
return (!tech.isFoamAttract && (tech.haveGunCheck("foam") || tech.isFoamBotUpgrade || tech.isFoamShot || tech.isFoamBall || tech.isFoamMine)) || (tech.haveGunCheck("wave") && !tech.is360Longitudinal)
},
requires: "foam, matter wave, not electrostatic induction, not phonon",
requires: "foam, wave, not isotropic, electrostatic induction",
effect() {
tech.isBulletTeleport = true
},
@@ -6274,9 +6301,9 @@ const tech = {
frequency: 2,
frequencyDefault: 2,
allowed() {
return tech.haveGunCheck("laser") || (tech.haveGunCheck("harpoon") && !tech.isRailGun) && !tech.isEnergyNoAmmo
return ((tech.haveGunCheck("wave") && tech.infiniteWaveAmmo !== 1) || tech.haveGunCheck("laser") || (tech.haveGunCheck("harpoon") && !tech.isRailGun)) && !tech.isEnergyNoAmmo
},
requires: "harpoon, laser, not railgun, non-renewables",
requires: "harpoon, laser, wave, frequency, not railgun, non-renewables",
effect() {
tech.isBoostReplaceAmmo = true
for (let i = powerUp.length - 1; i > -1; i--) {
@@ -7043,7 +7070,6 @@ const tech = {
frequencyDefault: 1,
isBotTech: true,
isNonRefundable: true,
// isExperimentHide: true,
allowed() {
return powerUps.research.count > 2 && (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || m.fieldUpgrades[m.fieldMode].name === "pilot wave")
},
@@ -8104,6 +8130,7 @@ const tech = {
count: 0,
frequency: 0,
isJunk: true,
isNonRefundable: true,
allowed() {
return !build.isExperimentSelection
},
@@ -10056,9 +10083,8 @@ const tech = {
count: 0,
frequency: 0,
isJunk: true,
allowed: () => true,
requires: "",
effect() {},
allowed() { return !build.isExperimentSelection },
requires: "NOT EXPERIMENT MODE",
remove() {},
state: [
[false, false, false, Math.random() > 0.8, false, false, false, Math.random() > 0.8, false, false, false, false, false, false, false, false, false, true, false, false, false, Math.random() > 0.8, false, false, false, Math.random() > 0.8, false, false, false, false, Math.random() > 0.8, false, Math.random() > 0.8, false, false, false, Math.random() > 0.8, false, false, false, false, false, false, false, false, false]
@@ -10118,8 +10144,8 @@ const tech = {
count: 0,
frequency: 0,
isJunk: true,
allowed: () => true,
requires: "",
allowed() { return !build.isExperimentSelection },
requires: "NOT EXPERIMENT MODE",
effect() {},
remove() {},
state: [
@@ -10340,17 +10366,15 @@ const tech = {
//**************************************************
{
name: `undefined`,
// description: `${lore.techCount+1}/${lore.techGoal}<br><em>add copies of <strong class="lore-text">this</strong> to the potential <strong class='color-m'>tech</strong> pool</em>`,
description: `<strong class="lore-text">this</strong>`,
maxCount: 1,
count: 0,
frequency: 3,
frequencyDefault: 3,
isLore: true,
// isNonRefundable: true,
isExperimentHide: true,
allowed() { return true },
requires: "",
// isExperimentHide: true,
allowed() { return !build.isExperimentSelection },
requires: "NOT EXPERIMENT MODE",
effect() {
setTimeout(() => { //a short delay, I can't remember why
lore.techCount++
@@ -10729,6 +10753,7 @@ const tech = {
isQuantumEraserDuplication: null,
quantumEraserCount: null,
isPhononBlock: null,
isPhononWave: null,
isMicroTransactions: null,
isLaserLens: null,
laserCrit: null,
@@ -10741,5 +10766,6 @@ const tech = {
isCouplingPowerUps: null,
isBoostPowerUps: null,
isBoostReplaceAmmo: null,
isFlipFlopCoupling: null
isFlipFlopCoupling: null,
infiniteWaveAmmo: null
}

View File

@@ -1,29 +1,44 @@
******************************************************** NEXT PATCH **************************************************
new level biohazard by INOOBBOI AND THESHWARMA
enable community maps in settings
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%
some coupling tech spawns power ups instead of directly giving coupling
fine-structure constant gives 60 coupling power ups, lose 0.5 coupling after mob collision
tech: decoupling: when ON: +5.00 coupling OFF: spawn a WIMP
(probably adds coupling drift bugs)
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
JUNK tech - boost - spawn a large number of boost power ups
several bug fixes
mob - flutter is no longer treated as a boss
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
*********************************************************** TODO *****************************************************
bug blocks and power ups falling through map
always foam gun (4-5 times)
might be about tech pressure vessel
happens rarely, doesn't repeat
only occurs for 3 people so far
normally after level 6
occurred once on the first level, didn't fire gun and was able to walk through a body
Tech:when relay switch/flip flop is on, turn ammo powerups into boosts, when relay swicth/flip flop is off, ammo powerups remain ammo powerups
or toggle other power ups
health/ammo
JUNK: what the golf?
trying to throw a block throws you instead
look for other tech that would benefit from a 3rd line of description text
tech for lens - you can only fire through the lens
and some buff? damage or energy?
add link to russian physics notes
suggestion: if you have both laser-mines and lens, each laser-mine is given its own lens revolving around it
hopMom fight make platforming with hop bullets harder?
complete blowSuckBoss... or don't
@@ -115,11 +130,7 @@ The tech that makes blocks that fall into a wormhole give energy should scale wi
junk suggestion: useless machine - ejects itself and removes itself from the item pool
bug blocks and power ups falling through map
always foam gun (4-5 times)
might be about tech pressure vessel
happens rarely, doesn't repeat
normally after level 6
seed isn't working right from shared URL
@@ -938,6 +949,7 @@ possible names for tech
p-hacking JUNK tech
https://en.wikipedia.org/wiki/High-entropy_alloys
https://en.wikipedia.org/wiki/Refractory_metals
https://en.wikipedia.org/wiki/Upper-atmospheric_lightning#Elves
plot script: