diff --git a/index.html b/index.html index 516b61f..fc42cc8 100644 --- a/index.html +++ b/index.html @@ -91,18 +91,18 @@ + - - + diff --git a/js/bullet.js b/js/bullet.js index 8d5bd5d..1965cf7 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -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 wave packet of oscillating particlesthat propagates through solids", 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({ diff --git a/js/engine.js b/js/engine.js index 76ad145..6fdcd87 100644 --- a/js/engine.js +++ b/js/engine.js @@ -160,7 +160,64 @@ function collisionChecks(event) { simulation.makeTextLog(`simulation.amplitude = ${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 diff --git a/js/index.js b/js/index.js index e2eb45a..cdf288b 100644 --- a/js/index.js +++ b/js/index.js @@ -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 += ` damage: ${((tech.damageFromTech())).toPrecision(3)} difficulty: ${((m.dmgScale)).toPrecision(3)} defense: ${(1-m.harmReduction()).toPrecision(3)} difficulty: ${(1/simulation.dmgScale).toPrecision(3)} -${b.fireCDscale < 1 ? `fire rate: ${((1-b.fireCDscale)*100).toFixed(b.fireCDscale < 0.1 ? 2 : 0)}%`: ""} +fire rate: ${((1-b.fireCDscale)*100).toFixed(b.fireCDscale < 0.1 ? 2 : 0)}% ${tech.duplicationChance() ? `duplication: ${(tech.duplicationChance()*100).toFixed(0)}%`: ""} ${m.coupling ? `coupling: ${(m.coupling).toFixed(2)} `+m.couplingDescription()+"": ""} ${botText} @@ -431,7 +430,7 @@ ${simulation.isCheating ? "lore disabled": ""} //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)` : ""; // @@ -529,7 +528,7 @@ ${simulation.isCheating ? "lore disabled": ""} text += ` ${build.nameLink(b.guns[i].name)} ${b.guns[i].description}` } 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 += ` ${tech.tech[i].link} ${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}` @@ -595,7 +594,7 @@ ${simulation.isCheating ? "lore disabled": ""} 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++ } diff --git a/js/level.js b/js/level.js index ee63822..eb7fedb 100644 --- a/js/level.js +++ b/js/level.js @@ -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(`dripp by INOOBBOI and THESHWARMA`); + simulation.makeTextLog(`biohazard by INOOBBOI and THESHWARMA`); // 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 matter wave to clear the room of mobs`) + level.trainingText(`use wave to clear the room of mobs`) level.custom = () => { if (instruction === 0 && mob.length === 0) { instruction++ - level.trainingText(`use matter wave to clear the room of mobs`) + level.trainingText(`use wave to clear the room of mobs`) } //spawn ammo if you run out let isAmmo = false diff --git a/js/mob.js b/js/mob.js index ab66ec0..dd8f7be 100644 --- a/js/mob.js +++ b/js/mob.js @@ -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 }, //********************************************************************************************** //********************************************************************************************** diff --git a/js/player.js b/js/player.js index 40f976d..37a1dfe 100644 --- a/js/player.js +++ b/js/player.js @@ -1582,7 +1582,7 @@ const m = { case 5: //plasma return `+${(15*couple).toFixed(0)}% damage` case 6: //time dilation - return `+${(25*couple).toFixed(0)}% longer stopped time` //movement, jumping, and + return `+${(30*couple).toFixed(0)}% longer stopped time` //movement, jumping, and case 7: //cloaking return `+${(33*couple).toFixed(0)}% ambush damage` case 8: //pilot wave @@ -2685,14 +2685,14 @@ const m = { }, { name: "time dilation", - description: "use energy to stop time+25% movement, jumping, and fire rategenerate 18 energy per second", + description: "use energy to stop time+25% movement and fire rategenerate 18 energy 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 diff --git a/js/powerup.js b/js/powerup.js index 6cbb28a..873f792 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -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) { diff --git a/js/simulation.js b/js/simulation.js index 645c294..421aa4a 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -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; } diff --git a/js/spawn.js b/js/spawn.js index 18719d1..ca033a6 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -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) { diff --git a/js/tech.js b/js/tech.js index c856c45..61b716a 100644 --- a/js/tech.js +++ b/js/tech.js @@ -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: `+88% damage${powerUps.orb.ammo()} can't spawn`, + description: `+67% damage${powerUps.orb.ammo()} can't spawn`, 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: "-13% maximum mob health", //health + description: "-12% maximum mob health", //health maxCount: 3, count: 0, frequency: 1, @@ -2680,7 +2679,7 @@ const tech = { // }, { name: "antiscience", - description: "+90% damage–11 health after picking up a tech", + description: "+90% damage–12 health after picking up a tech", 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 ${orbText}that each give +0.1 coupling${ m.couplingDescription(1)} ${m.fieldMode === 0 ? "" : "per coupling"}` + return `use all your ${powerUps.orb.research(1)} to spawn ${orbText}that each give +0.1 coupling${ m.couplingDescription(1)} ${m.fieldMode === 0 ? "" : "per coupling"}` }, 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) { @@ -3524,7 +3523,7 @@ const tech = { { name: "virtual particles", descriptionFunction() { - return `after mobs die they have a 17% chance tospawn ${powerUps.orb.coupling(1)} that each give +0.1 coupling${ m.couplingDescription(1)} ${m.fieldMode === 0 ? "" : "per coupling"}` + return `after mobs die they have a 17% chance tospawn ${powerUps.orb.coupling(1)} that each give +0.1 coupling${m.couplingDescription(1)} ${m.fieldMode === 0 ? "" : "per coupling"}` }, maxCount: 1, count: 0, @@ -3542,18 +3541,18 @@ const tech = { { name: "fine-structure constant", descriptionFunction() { - return `spawn ${this.value} ${powerUps.orb.coupling(1)} that each give +0.1 coupling - -0.5 coupling after mob collisions - ${m.couplingDescription(1)} ${m.fieldMode === 0 ? "" : "per coupling"}` + return `spawn ${this.value} ${powerUps.orb.coupling(1)} that each give +0.1 coupling-0.5 coupling after mob collisions${m.couplingDescription(1)} ${m.fieldMode === 0 ? "" : "per coupling"}` }, 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: `rivets, needles, super balls, and nailshave +25% mass and physical damage`, + description: `rivets, needles, super balls, and nailshave +30% mass and physical damage`, 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 propagates faster through solids+40% matter wave damage", - // description: "matter wave propagates faster through solidsup by 3000% in the map and 760% in blocks", + description: "wave particles propagate faster as solids+35% wave damage", 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 reflect backwards 2 times–25% range", - 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: "+37% wave damage and amplitude", + description: "+37% wave damage+37% wave particle amplitude", 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 reflect backwards 2 times–20% range", + 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: `wave has unlimited ammo-50% wave fire rate`, + 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 frequency, high damageexpanding arcs that propagate through solids", + description: "waves are low frequency, high damageexpanding arcs that propagate through solids", 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); - simulation.updateGunHUD(); - break - } + 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(); }, 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); - simulation.updateGunHUD(); - break - } + tech.isLongitudinal = false; + 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(); } tech.isLongitudinal = false; } }, { - name: "isotropic radiator", - description: "matter wave expands in all directions–40% range and +50% damage", + name: "isotropic", + description: "waves expand in all directions–40% range and +50% damage", 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 block gets vibrated by a phononthere is a chance it's flung 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 mob gets vibrated by a phonona new resonance wave 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: "+100% missile explosive damage, radius–50% missile 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}add copies of this to the potential tech pool`, description: `this`, 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 } \ No newline at end of file diff --git a/todo.txt b/todo.txt index ceb3560..6929535 100644 --- a/todo.txt +++ b/todo.txt @@ -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) - -JUNK tech - boost - spawn a large number of boost power ups +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 -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: