diff --git a/img/1st ionization energy.webp b/img/1st ionization energy.webp index 95e17b1..5f13a56 100644 Binary files a/img/1st ionization energy.webp and b/img/1st ionization energy.webp differ diff --git a/img/Gibbs free energy.webp b/img/Gibbs free energy.webp index 321c317..b4b03d3 100644 Binary files a/img/Gibbs free energy.webp and b/img/Gibbs free energy.webp differ diff --git a/img/ceramics.webp b/img/ceramics.webp index 6cdd6e6..ca6c177 100644 Binary files a/img/ceramics.webp and b/img/ceramics.webp differ diff --git a/img/electronegativity.webp b/img/electronegativity.webp index 99c0822..4df69cd 100644 Binary files a/img/electronegativity.webp and b/img/electronegativity.webp differ diff --git a/img/energy conservation.webp b/img/energy conservation.webp index 9b52335..e825adb 100644 Binary files a/img/energy conservation.webp and b/img/energy conservation.webp differ diff --git a/img/exothermic process.webp b/img/exothermic process.webp index a75216f..3d79008 100644 Binary files a/img/exothermic process.webp and b/img/exothermic process.webp differ diff --git a/img/heat engine.webp b/img/heat engine.webp index 7394708..df299f8 100644 Binary files a/img/heat engine.webp and b/img/heat engine.webp differ diff --git a/img/homeostasis.webp b/img/homeostasis.webp index 9d107d3..862ae53 100644 Binary files a/img/homeostasis.webp and b/img/homeostasis.webp differ diff --git a/img/inductive charging.webp b/img/inductive charging.webp index e3765ea..55643bd 100644 Binary files a/img/inductive charging.webp and b/img/inductive charging.webp differ diff --git a/img/mass-energy equivalence.webp b/img/mass-energy equivalence.webp index b00a85b..78906ed 100644 Binary files a/img/mass-energy equivalence.webp and b/img/mass-energy equivalence.webp differ diff --git a/img/nail-bot upgrade.webp b/img/nail-bot upgrade.webp index fc3518a..e92c7fb 100644 Binary files a/img/nail-bot upgrade.webp and b/img/nail-bot upgrade.webp differ diff --git a/img/nail-bot.webp b/img/nail-bot.webp index 1b0da80..58bdd6e 100644 Binary files a/img/nail-bot.webp and b/img/nail-bot.webp differ diff --git a/img/orbital-bot upgrade.webp b/img/orbital-bot upgrade.webp index 010f6e1..46ff538 100644 Binary files a/img/orbital-bot upgrade.webp and b/img/orbital-bot upgrade.webp differ diff --git a/img/orbital-bot.webp b/img/orbital-bot.webp index 003029a..1ab8298 100644 Binary files a/img/orbital-bot.webp and b/img/orbital-bot.webp differ diff --git a/img/overcharge.webp b/img/overcharge.webp index 69f5712..7c20edb 100644 Binary files a/img/overcharge.webp and b/img/overcharge.webp differ diff --git a/img/parasitism.webp b/img/parasitism.webp index dbab55b..3db9826 100644 Binary files a/img/parasitism.webp and b/img/parasitism.webp differ diff --git a/img/piezoelectricity.webp b/img/piezoelectricity.webp index 25ec3fc..455fd7c 100644 Binary files a/img/piezoelectricity.webp and b/img/piezoelectricity.webp differ diff --git a/img/repeater.webp b/img/repeater.webp new file mode 100644 index 0000000..1be7058 Binary files /dev/null and b/img/repeater.webp differ diff --git a/index.html b/index.html index afe321a..ce4e267 100644 --- a/index.html +++ b/index.html @@ -140,8 +140,7 @@ controls
To change controls click a box -
- and press an unused key. +
and press an unused key.

@@ -185,6 +184,10 @@ + + + + @@ -197,7 +200,8 @@
E MouseWheel
GUN #Num
PAUSE P
- to default keys + +
to default keys
diff --git a/js/bullet.js b/js/bullet.js index 6c51b66..4b9ff7e 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -23,7 +23,7 @@ const b = { }, fire() {}, fireNormal() { - if (b.inventory.length) { + if (b.inventory.length && b.activeGun !== null) { if (input.fire && m.fireCDcycle < m.cycle && (!input.field || m.fieldFire)) { if (b.guns[b.activeGun].ammo > 0) { b.fireWithAmmo() @@ -36,7 +36,7 @@ const b = { } }, fireNotMove() { //added && player.speed < 0.5 && m.onGround - if (b.inventory.length) { + if (b.inventory.length && b.activeGun !== null) { if (input.fire && m.fireCDcycle < m.cycle && (!input.field || m.fieldFire) && player.speed < 2.5 && m.onGround && Math.abs(m.yOff - m.yOffGoal) < 1) { if (b.guns[b.activeGun].ammo > 0) { b.fireWithAmmo() @@ -49,7 +49,7 @@ const b = { } }, fireAlwaysFire() { //added && player.speed < 0.5 && m.onGround //removed input.fire && (!input.field || m.fieldFire) - if (b.inventory.length) { + if (b.inventory.length && b.activeGun !== null) { if (m.fireCDcycle < m.cycle && player.speed < 0.5 && m.onGround && Math.abs(m.yOff - m.yOffGoal) < 1) { if (b.guns[b.activeGun].ammo > 0) { b.fireWithAmmo() @@ -60,7 +60,7 @@ const b = { } }, fireFloat() { //added && player.speed < 0.5 && m.onGround - if (b.inventory.length) { + if (b.inventory.length && b.activeGun !== null) { if (input.fire && (!input.field || m.fieldFire)) { if (m.fireCDcycle < m.cycle) { if (b.guns[b.activeGun].ammo > 0) { @@ -125,11 +125,11 @@ const b = { simulation.updateGunHUD(); } }, - returnGunAmmo(name) { - for (i = 0, len = b.guns.length; i < len; i++) { //find which gun - if (b.guns[i].name === name) return b.guns[i].ammo - } - }, + // returnGunAmmo(name) { + // for (i = 0, len = b.guns.length; i < len; i++) { //find which gun + // if (b.guns[i].name === name) return b.guns[i].ammo + // } + // }, giveGuns(gun = "random", ammoPacks = 10) { if (tech.ammoCap) ammoPacks = 0.45 * tech.ammoCap if (tech.isOneGun) b.removeAllGuns(); @@ -173,6 +173,7 @@ const b = { // if (tech.infiniteWaveAmmo === 2) b.guns[3].ammo = Infinity } simulation.makeGunHUD(); + simulation.switchGun(); b.setFireCD(); if (tech.isOneGun && b.inventory > 0) { //count how many gun tech you have and remove them @@ -323,11 +324,19 @@ const b = { }; } }, - muzzleFlash(radius = 10) { - ctx.fillStyle = "#fb0"; - ctx.beginPath(); - ctx.arc(m.pos.x + 35 * Math.cos(m.angle), m.pos.y + 35 * Math.sin(m.angle), radius, 0, 2 * Math.PI); - ctx.fill(); + muzzleFlash(radius = 30) { + // ctx.fillStyle = "#fb0"; + // ctx.beginPath(); + // ctx.arc(m.pos.x + 35 * Math.cos(m.angle), m.pos.y + 35 * Math.sin(m.angle), radius, 0, 2 * Math.PI); + // ctx.fill(); + + simulation.drawList.push({ //add dmg to draw queue + x: m.pos.x + 35 * Math.cos(m.angle), + y: m.pos.y + 35 * Math.sin(m.angle), + radius: radius, + color: "#fb0", + time: 1 + }); }, removeConsBB(me) { for (let i = 0, len = consBB.length; i < len; ++i) { @@ -1618,13 +1627,16 @@ const b = { player.force.x += momentum.x player.force.y += momentum.y // refund ammo - for (i = 0, len = b.guns.length; i < len; i++) { //find which gun - if (b.guns[i].name === "harpoon") { - b.guns[i].ammo++; - simulation.updateGunHUD(); - break; - } - } + b.guns[9].ammo++; + simulation.updateGunHUD(); + + // for (i = 0, len = b.guns.length; i < len; i++) { //find which gun + // if (b.guns[i].name === "harpoon") { + // b.guns[i].ammo++; + // simulation.updateGunHUD(); + // break; + // } + // } } else { if (m.energy > this.drain) m.energy -= this.drain const sub = Vector.sub(this.position, m.pos) @@ -1743,13 +1755,13 @@ const b = { this.endCycle = 0; if (m.cycle + 50 < m.fireCDcycle) m.fireCDcycle = m.cycle + 50 // refund ammo - for (i = 0, len = b.guns.length; i < len; i++) { //find which gun - if (b.guns[i].name === "harpoon") { - b.guns[i].ammo++; - simulation.updateGunHUD(); - break; - } - } + b.guns[9].ammo++; + simulation.updateGunHUD(); + // for (i = 0, len = b.guns.length; i < len; i++) { //find which gun + // if (b.guns[i].name === "harpoon") { + // break; + // } + // } } } } @@ -1941,13 +1953,13 @@ const b = { player.force.y += momentum.y // refund ammo if (isReturnAmmo) { - for (i = 0, len = b.guns.length; i < len; i++) { //find which gun - if (b.guns[i].name === "harpoon") { - b.guns[i].ammo++; - simulation.updateGunHUD(); - break; - } - } + b.guns[9].ammo++; + simulation.updateGunHUD(); + // for (i = 0, len = b.guns.length; i < len; i++) { //find which gun + // if (b.guns[i].name === "harpoon") { + // break; + // } + // } } } else { const sub = Vector.sub(this.position, m.pos) @@ -2818,7 +2830,7 @@ const b = { ) { if (tech.isStun) b.AoEStunEffect(this.position, this.range + mob[i].radius + random); //AoEStunEffect(where, range, cycles = 90 + 60 * Math.random()) { if (tech.isMineSentry) { - this.lookFrequency = 15 + 10 * (tech.oneSuperBall && tech.isSuperMine) + Math.floor(3 * Math.random()) + this.lookFrequency = Math.floor(7 + 7 * b.fireCDscale + 10 * (tech.oneSuperBall && tech.isSuperMine) + Math.floor(3 * Math.random())) // this.endCycle = Infinity this.shots = tech.sentryAmmo this.do = function() { //overwrite the do method for this bullet @@ -3376,17 +3388,14 @@ const b = { } }, onEnd() { - if (tech.isDroneRespawn && b.inventory.length) { - const who = b.guns[b.activeGun] - if (who.name === "drones" && who.ammo > 0 && mob.length) { - b.drone({ - x: this.position.x, - y: this.position.y - }, 0) - if (Math.random() < 0.2) { - b.guns[b.activeGun].ammo--; - simulation.updateGunHUD(); - } + if (tech.isDroneRespawn && b.inventory.length && b.activeGun === 7 && b.guns[b.activeGun].ammo > 0 && mob.length) { + b.drone({ + x: this.position.x, + y: this.position.y + }, 0) + if (Math.random() < 0.2) { + b.guns[b.activeGun].ammo--; + simulation.updateGunHUD(); } } }, @@ -3565,17 +3574,14 @@ const b = { maxRadioRadius: 270 + Math.floor(90 * Math.random()), beforeDmg() {}, onEnd() { - if (tech.isDroneRespawn && b.inventory.length) { - const who = b.guns[b.activeGun] - if (who.name === "drones" && who.ammo > 0 && mob.length) { - b.droneRadioactive({ - x: this.position.x, - y: this.position.y - }, 0) - if (Math.random() < 0.2) { - b.guns[b.activeGun].ammo--; - simulation.updateGunHUD(); - } + if (tech.isDroneRespawn && b.inventory.length && b.activeGun === 7 && b.guns[b.activeGun].ammo > 0 && mob.length) { + b.droneRadioactive({ + x: this.position.x, + y: this.position.y + }, 0) + if (Math.random() < 0.2) { + b.guns[b.activeGun].ammo--; + simulation.updateGunHUD(); } } }, @@ -3756,15 +3762,7 @@ const b = { bullet[me].minDmgSpeed = 0; bullet[me].restitution = 1; bullet[me].friction = 0; - if (tech.isIncendiary) { - bullet[me].do = function() { - this.force.y += this.mass * 0.0012; - if (Matter.Query.collides(this, map).length) { - b.explosion(this.position, this.mass * 280); //makes bullet do explosive damage at end - this.endCycle = 0 - } - }; - } else if (tech.superHarm) { + if (tech.superHarm) { bullet[me].collidePlayerDo = function() { if (Matter.Query.collides(this, [player]).length) { this.endCycle = 0 @@ -3781,13 +3779,11 @@ const b = { } bullet[me].cycle = 0 bullet[me].do = function() { - this.cycle++ if (this.cycle > 6) this.do = this.collidePlayerDo this.force.y += this.mass * 0.0012; }; } else { bullet[me].do = function() { - this.cycle++ this.force.y += this.mass * 0.0012; }; } @@ -3801,6 +3797,10 @@ const b = { } this.endCycle = 0 } + if (tech.isIncendiary) { + b.explosion(this.position, this.mass * 280); //makes bullet do explosive damage at end + this.endCycle = 0 + } }; }, targetedBall(position, num = 1, speed = 42 + 12 * Math.random(), range = 1200, isRandomAim = true) { @@ -5818,7 +5818,7 @@ const b = { this.rotateToVelocity() }; } - b.muzzleFlash(30); + b.muzzleFlash(); //very complex recoil system if (m.onGround) { if (input.down) { @@ -5905,7 +5905,7 @@ const b = { }; } - b.muzzleFlash(30); + b.muzzleFlash(); //very complex recoil system if (m.onGround) { if (input.down) { @@ -5970,33 +5970,58 @@ const b = { ammoPack: 3.5, defaultAmmoPack: 3.5, have: false, - do() {}, + do() { + //fade cross hairs + + + + // draw loop around player head + // const left = m.fireCDcycle !== Infinity ? 0.05 * Math.max(m.fireCDcycle - m.cycle, 0) : 0 + // if (left > 0) { + // ctx.beginPath(); + // // ctx.arc(simulation.mouseInGame.x, simulation.mouseInGame.y, 30, 0, left); + // ctx.arc(m.pos.x, m.pos.y, 28, m.angle - left, m.angle); + // // ctx.fillStyle = "rgba(0,0,0,0.3)" //"#333" + // // ctx.fill(); + // ctx.strokeStyle = "#333"; + // ctx.lineWidth = 2; + // ctx.stroke(); + // } + + + //draw hip circle + // ctx.beginPath(); + // ctx.arc(m.pos.x + m.hip.x, m.pos.y + m.hip.y, 11, 0, 2 * Math.PI); + // ctx.fillStyle = "rgba(0,0,0,0.3)" //"#333" + // ctx.fill(); + }, fire() { let knock, spread - if (input.down) { - spread = 0.65 - m.fireCDcycle = m.cycle + Math.floor(73 * b.fireCDscale) // cool down - if (tech.isShotgunImmune && m.immuneCycle < m.cycle + Math.floor(60 * b.fireCDscale)) m.immuneCycle = m.cycle + Math.floor(60 * b.fireCDscale); //player is immune to damage for 30 cycles - knock = 0.01 - } else { - m.fireCDcycle = m.cycle + Math.floor(56 * b.fireCDscale) // cool down - if (tech.isShotgunImmune && m.immuneCycle < m.cycle + Math.floor(47 * b.fireCDscale)) m.immuneCycle = m.cycle + Math.floor(47 * b.fireCDscale); //player is immune to damage for 30 cycles - spread = 1.3 - knock = 0.1 - } + const coolDown = function() { + if (input.down) { + spread = 0.65 + m.fireCDcycle = m.cycle + Math.floor((73 + 36 * tech.shotgunExtraShots) * b.fireCDscale) // cool down + if (tech.isShotgunImmune && m.immuneCycle < m.cycle + Math.floor(60 * b.fireCDscale)) m.immuneCycle = m.cycle + Math.floor(60 * b.fireCDscale); //player is immune to damage for 30 cycles + knock = 0.01 + } else { + m.fireCDcycle = m.cycle + Math.floor((56 + 28 * tech.shotgunExtraShots) * b.fireCDscale) // cool down + if (tech.isShotgunImmune && m.immuneCycle < m.cycle + Math.floor(47 * b.fireCDscale)) m.immuneCycle = m.cycle + Math.floor(47 * b.fireCDscale); //player is immune to damage for 30 cycles + spread = 1.3 + knock = 0.1 + } - if (tech.isShotgunReversed) { - player.force.x += 1.6 * knock * Math.cos(m.angle) - player.force.y += 1.6 * knock * Math.sin(m.angle) - 3 * player.mass * simulation.g - } else if (tech.isShotgunRecoil) { - m.fireCDcycle -= 0.66 * (56 * b.fireCDscale) - player.force.x -= 2 * knock * Math.cos(m.angle) - player.force.y -= 2 * knock * Math.sin(m.angle) - } else { - player.force.x -= knock * Math.cos(m.angle) - player.force.y -= knock * Math.sin(m.angle) * 0.5 //reduce knock back in vertical direction to stop super jumps + if (tech.isShotgunReversed) { + player.force.x += 1.5 * knock * Math.cos(m.angle) + player.force.y += 1.5 * knock * Math.sin(m.angle) - 3 * player.mass * simulation.g + } else if (tech.isShotgunRecoil) { + m.fireCDcycle -= 0.66 * (56 * b.fireCDscale) + player.force.x -= 2 * knock * Math.cos(m.angle) + player.force.y -= 2 * knock * Math.sin(m.angle) + } else { + player.force.x -= knock * Math.cos(m.angle) + player.force.y -= knock * Math.sin(m.angle) * 0.5 //reduce knock back in vertical direction to stop super jumps + } } - const spray = (num) => { const side = 22 for (let i = 0; i < num; i++) { @@ -6020,188 +6045,210 @@ const b = { }; } } - - b.muzzleFlash(35); - - if (tech.isRivets) { - const me = bullet.length; - // const dir = m.angle + 0.02 * (Math.random() - 0.5) - bullet[me] = Bodies.rectangle(m.pos.x + 35 * Math.cos(m.angle), m.pos.y + 35 * Math.sin(m.angle), 56 * tech.bulletSize, 25 * tech.bulletSize, b.fireAttributes(m.angle)); - - Matter.Body.setDensity(bullet[me], 0.005 * (tech.isShotgunReversed ? 1.5 : 1)); - Composite.add(engine.world, bullet[me]); //add bullet to world - const SPEED = (input.down ? 50 : 43) - Matter.Body.setVelocity(bullet[me], { - x: SPEED * Math.cos(m.angle), - y: SPEED * Math.sin(m.angle) - }); - if (tech.isIncendiary) { - bullet[me].endCycle = simulation.cycle + 60 - bullet[me].onEnd = function() { - b.explosion(this.position, 360 + (Math.random() - 0.5) * 60); //makes bullet do explosive damage at end - } - bullet[me].beforeDmg = function() { - this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion - }; - } else { - bullet[me].endCycle = simulation.cycle + 180 - } - bullet[me].minDmgSpeed = 7 - // bullet[me].restitution = 0.4 - bullet[me].frictionAir = 0.004; - bullet[me].turnMag = 0.04 * Math.pow(tech.bulletSize, 3.75) - bullet[me].do = function() { - this.force.y += this.mass * 0.002 - if (this.speed > 6) { //rotates bullet to face current velocity? - const facing = { - x: Math.cos(this.angle), - y: Math.sin(this.angle) - } - if (Vector.cross(Vector.normalise(this.velocity), facing) < 0) { - this.torque += this.turnMag - } else { - this.torque -= this.turnMag - } - } - if (tech.isIncendiary && Matter.Query.collides(this, map).length) { - this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion - } - }; - bullet[me].beforeDmg = function(who) { - if (this.speed > 4) { - if (tech.fragments) { - b.targetedNail(this.position, 6 * tech.fragments * tech.bulletSize) - this.endCycle = 0 //triggers despawn - } - if (tech.isIncendiary) this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion - if (tech.isCritKill) b.crit(who, this) - } - } - spray(12); //fires normal shotgun bullets - } else if (tech.isIncendiary) { - spread *= 0.15 - const END = Math.floor(input.down ? 8 : 5); - const totalBullets = 9 - const angleStep = (input.down ? 0.3 : 0.8) / totalBullets - let dir = m.angle - angleStep * totalBullets / 2; - for (let i = 0; i < totalBullets; i++) { //5 -> 7 - dir += angleStep + const chooseBulletType = function() { + if (tech.isRivets) { const me = bullet.length; - bullet[me] = Bodies.rectangle(m.pos.x + 50 * Math.cos(m.angle), m.pos.y + 50 * Math.sin(m.angle), 17, 4, b.fireAttributes(dir)); - const end = END + Math.random() * 4 - bullet[me].endCycle = 2 * end * tech.isBulletsLastLonger + simulation.cycle - const speed = 25 * end / END - const dirOff = dir + (Math.random() - 0.5) * spread - Matter.Body.setVelocity(bullet[me], { - x: speed * Math.cos(dirOff), - y: speed * Math.sin(dirOff) - }); - bullet[me].onEnd = function() { - b.explosion(this.position, 150 * (tech.isShotgunReversed ? 1.4 : 1) + (Math.random() - 0.5) * 30); //makes bullet do explosive damage at end - } - bullet[me].beforeDmg = function() { - this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion - }; - bullet[me].do = function() { - if (Matter.Query.collides(this, map).length) this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion - } + // const dir = m.angle + 0.02 * (Math.random() - 0.5) + bullet[me] = Bodies.rectangle(m.pos.x + 35 * Math.cos(m.angle), m.pos.y + 35 * Math.sin(m.angle), 56 * tech.bulletSize, 25 * tech.bulletSize, b.fireAttributes(m.angle)); + + Matter.Body.setDensity(bullet[me], 0.005 * (tech.isShotgunReversed ? 1.5 : 1)); Composite.add(engine.world, bullet[me]); //add bullet to world - } - } else if (tech.isNailShot) { - spread *= 0.65 - const dmg = 2 * (tech.isShotgunReversed ? 1.5 : 1) - if (input.down) { - for (let i = 0; i < 17; i++) { - speed = 38 + 15 * Math.random() - const dir = m.angle + (Math.random() - 0.5) * spread - const pos = { - x: m.pos.x + 35 * Math.cos(m.angle) + 15 * (Math.random() - 0.5), - y: m.pos.y + 35 * Math.sin(m.angle) + 15 * (Math.random() - 0.5) + const SPEED = (input.down ? 50 : 43) + Matter.Body.setVelocity(bullet[me], { + x: SPEED * Math.cos(m.angle), + y: SPEED * Math.sin(m.angle) + }); + if (tech.isIncendiary) { + bullet[me].endCycle = simulation.cycle + 60 + bullet[me].onEnd = function() { + b.explosion(this.position, 360 + (Math.random() - 0.5) * 60); //makes bullet do explosive damage at end } - b.nail(pos, { - x: speed * Math.cos(dir), - y: speed * Math.sin(dir) - }, dmg) + bullet[me].beforeDmg = function() { + this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion + }; + } else { + bullet[me].endCycle = simulation.cycle + 180 + } + bullet[me].minDmgSpeed = 7 + // bullet[me].restitution = 0.4 + bullet[me].frictionAir = 0.004; + bullet[me].turnMag = 0.04 * Math.pow(tech.bulletSize, 3.75) + bullet[me].do = function() { + this.force.y += this.mass * 0.002 + if (this.speed > 6) { //rotates bullet to face current velocity? + const facing = { + x: Math.cos(this.angle), + y: Math.sin(this.angle) + } + if (Vector.cross(Vector.normalise(this.velocity), facing) < 0) { + this.torque += this.turnMag + } else { + this.torque -= this.turnMag + } + } + if (tech.isIncendiary && Matter.Query.collides(this, map).length) { + this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion + } + }; + bullet[me].beforeDmg = function(who) { + if (this.speed > 4) { + if (tech.fragments) { + b.targetedNail(this.position, 6 * tech.fragments * tech.bulletSize) + this.endCycle = 0 //triggers despawn + } + if (tech.isIncendiary) this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion + if (tech.isCritKill) b.crit(who, this) + } + } + spray(12); //fires normal shotgun bullets + } else if (tech.isIncendiary) { + spread *= 0.15 + const END = Math.floor(input.down ? 8 : 5); + const totalBullets = 9 + const angleStep = (input.down ? 0.3 : 0.8) / totalBullets + let dir = m.angle - angleStep * totalBullets / 2; + for (let i = 0; i < totalBullets; i++) { //5 -> 7 + dir += angleStep + const me = bullet.length; + bullet[me] = Bodies.rectangle(m.pos.x + 50 * Math.cos(m.angle), m.pos.y + 50 * Math.sin(m.angle), 17, 4, b.fireAttributes(dir)); + const end = END + Math.random() * 4 + bullet[me].endCycle = 2 * end * tech.isBulletsLastLonger + simulation.cycle + const speed = 25 * end / END + const dirOff = dir + (Math.random() - 0.5) * spread + Matter.Body.setVelocity(bullet[me], { + x: speed * Math.cos(dirOff), + y: speed * Math.sin(dirOff) + }); + bullet[me].onEnd = function() { + b.explosion(this.position, 150 * (tech.isShotgunReversed ? 1.4 : 1) + (Math.random() - 0.5) * 30); //makes bullet do explosive damage at end + } + bullet[me].beforeDmg = function() { + this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion + }; + bullet[me].do = function() { + if (Matter.Query.collides(this, map).length) this.endCycle = 0; //bullet ends cycle after hitting a mob and triggers explosion + } + Composite.add(engine.world, bullet[me]); //add bullet to world + } + } else if (tech.isNailShot) { + spread *= 0.65 + const dmg = 2 * (tech.isShotgunReversed ? 1.5 : 1) + if (input.down) { + for (let i = 0; i < 17; i++) { + speed = 38 + 15 * Math.random() + const dir = m.angle + (Math.random() - 0.5) * spread + const pos = { + x: m.pos.x + 35 * Math.cos(m.angle) + 15 * (Math.random() - 0.5), + y: m.pos.y + 35 * Math.sin(m.angle) + 15 * (Math.random() - 0.5) + } + b.nail(pos, { + x: speed * Math.cos(dir), + y: speed * Math.sin(dir) + }, dmg) + } + } else { + for (let i = 0; i < 17; i++) { + speed = 38 + 15 * Math.random() + const dir = m.angle + (Math.random() - 0.5) * spread + const pos = { + x: m.pos.x + 35 * Math.cos(m.angle) + 15 * (Math.random() - 0.5), + y: m.pos.y + 35 * Math.sin(m.angle) + 15 * (Math.random() - 0.5) + } + b.nail(pos, { + x: speed * Math.cos(dir), + y: speed * Math.sin(dir) + }, dmg) + } + } + } else if (tech.isSporeFlea) { + const where = { + x: m.pos.x + 35 * Math.cos(m.angle), + y: m.pos.y + 35 * Math.sin(m.angle) + } + const number = 2 * (tech.isShotgunReversed ? 1.5 : 1) + for (let i = 0; i < number; i++) { + const angle = m.angle + 0.2 * (Math.random() - 0.5) + const speed = (input.down ? 35 * (1 + 0.05 * Math.random()) : 30 * (1 + 0.15 * Math.random())) + b.flea(where, { + x: speed * Math.cos(angle), + y: speed * Math.sin(angle) + }) + bullet[bullet.length - 1].setDamage() + } + spray(10); //fires normal shotgun bullets + } else if (tech.isSporeWorm) { + const where = { + x: m.pos.x + 35 * Math.cos(m.angle), + y: m.pos.y + 35 * Math.sin(m.angle) + } + const spread = (input.down ? 0.02 : 0.07) + const number = 3 * (tech.isShotgunReversed ? 1.5 : 1) + let angle = m.angle - (number - 1) * spread * 0.5 + for (let i = 0; i < number; i++) { + b.worm(where) + const SPEED = (30 + 10 * input.down) * (1 + 0.2 * Math.random()) + Matter.Body.setVelocity(bullet[bullet.length - 1], { + x: player.velocity.x * 0.5 + SPEED * Math.cos(angle), + y: player.velocity.y * 0.5 + SPEED * Math.sin(angle) + }); + angle += spread + } + spray(7); //fires normal shotgun bullets + } else if (tech.isIceShot) { + const spread = (input.down ? 0.7 : 1.2) + for (let i = 0, len = 10 * (tech.isShotgunReversed ? 1.5 : 1); i < len; i++) { + b.iceIX(23 + 10 * Math.random(), m.angle + spread * (Math.random() - 0.5)) + } + spray(10); //fires normal shotgun bullets + } else if (tech.isFoamShot) { + const spread = (input.down ? 0.15 : 0.4) + const where = { + x: m.pos.x + 25 * Math.cos(m.angle), + y: m.pos.y + 25 * Math.sin(m.angle) + } + const number = 16 * (tech.isShotgunReversed ? 1.5 : 1) + for (let i = 0; i < number; i++) { + const SPEED = 13 + 4 * Math.random(); + const angle = m.angle + spread * (Math.random() - 0.5) + b.foam(where, { + x: SPEED * Math.cos(angle), + y: SPEED * Math.sin(angle) + }, 8 + 7 * Math.random()) + } + } else if (tech.isNeedles) { + const number = 9 * (tech.isShotgunReversed ? 1.5 : 1) + const spread = (input.down ? 0.03 : 0.05) + let angle = m.angle - (number - 1) * spread * 0.5 + for (let i = 0; i < number; i++) { + b.needle(angle) + angle += spread } } else { - for (let i = 0; i < 17; i++) { - speed = 38 + 15 * Math.random() - const dir = m.angle + (Math.random() - 0.5) * spread - const pos = { - x: m.pos.x + 35 * Math.cos(m.angle) + 15 * (Math.random() - 0.5), - y: m.pos.y + 35 * Math.sin(m.angle) + 15 * (Math.random() - 0.5) - } - b.nail(pos, { - x: speed * Math.cos(dir), - y: speed * Math.sin(dir) - }, dmg) + spray(16); //fires normal shotgun bullets + } + } + + + coolDown(); + b.muzzleFlash(35); + chooseBulletType(); + + if (tech.shotgunExtraShots) { + const delay = 7 + let count = tech.shotgunExtraShots * delay + + function cycle() { + count-- + if (!(count % delay)) { + coolDown(); + b.muzzleFlash(35); + chooseBulletType(); + } + if (count > 0) { + requestAnimationFrame(cycle); } } - } else if (tech.isSporeFlea) { - const where = { - x: m.pos.x + 35 * Math.cos(m.angle), - y: m.pos.y + 35 * Math.sin(m.angle) - } - const number = 2 * (tech.isShotgunReversed ? 1.5 : 1) - for (let i = 0; i < number; i++) { - const angle = m.angle + 0.2 * (Math.random() - 0.5) - const speed = (input.down ? 35 * (1 + 0.05 * Math.random()) : 30 * (1 + 0.15 * Math.random())) - b.flea(where, { - x: speed * Math.cos(angle), - y: speed * Math.sin(angle) - }) - bullet[bullet.length - 1].setDamage() - } - spray(10); //fires normal shotgun bullets - } else if (tech.isSporeWorm) { - const where = { - x: m.pos.x + 35 * Math.cos(m.angle), - y: m.pos.y + 35 * Math.sin(m.angle) - } - const spread = (input.down ? 0.02 : 0.07) - const number = 3 * (tech.isShotgunReversed ? 1.5 : 1) - let angle = m.angle - (number - 1) * spread * 0.5 - for (let i = 0; i < number; i++) { - b.worm(where) - const SPEED = (30 + 10 * input.down) * (1 + 0.2 * Math.random()) - Matter.Body.setVelocity(bullet[bullet.length - 1], { - x: player.velocity.x * 0.5 + SPEED * Math.cos(angle), - y: player.velocity.y * 0.5 + SPEED * Math.sin(angle) - }); - angle += spread - } - spray(7); //fires normal shotgun bullets - } else if (tech.isIceShot) { - const spread = (input.down ? 0.7 : 1.2) - for (let i = 0, len = 10 * (tech.isShotgunReversed ? 1.5 : 1); i < len; i++) { - b.iceIX(23 + 10 * Math.random(), m.angle + spread * (Math.random() - 0.5)) - } - spray(10); //fires normal shotgun bullets - } else if (tech.isFoamShot) { - const spread = (input.down ? 0.15 : 0.4) - const where = { - x: m.pos.x + 25 * Math.cos(m.angle), - y: m.pos.y + 25 * Math.sin(m.angle) - } - const number = 16 * (tech.isShotgunReversed ? 1.5 : 1) - for (let i = 0; i < number; i++) { - const SPEED = 13 + 4 * Math.random(); - const angle = m.angle + spread * (Math.random() - 0.5) - b.foam(where, { - x: SPEED * Math.cos(angle), - y: SPEED * Math.sin(angle) - }, 8 + 7 * Math.random()) - } - } else if (tech.isNeedles) { - const number = 9 * (tech.isShotgunReversed ? 1.5 : 1) - const spread = (input.down ? 0.03 : 0.05) - let angle = m.angle - (number - 1) * spread * 0.5 - for (let i = 0; i < number; i++) { - b.needle(angle) - angle += spread - } - } else { - spray(16); //fires normal shotgun bullets + requestAnimationFrame(cycle); } } }, { diff --git a/js/index.js b/js/index.js index 9ccae2f..dd5fd46 100644 --- a/js/index.js +++ b/js/index.js @@ -415,7 +415,7 @@ ${simulation.isCheating ? "

lore disabled": ""} const style = (localSettings.isHideImages || tech.tech[i].isJunk) ? `style="height:auto;"` : `style = "background-image: url('img/${tech.tech[i].name}.webp');"` const techCountText = tech.tech[i].count > 1 ? `(${tech.tech[i].count}x)` : ""; if (tech.tech[i].isNonRefundable) { - text += `
${tech.tech[i].link} ${techCountText}
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}
` + text += `
${tech.tech[i].link} ${techCountText}
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}
` // } else if (tech.tech[i].isLore) { // text += `
  ${tech.tech[i].name} ${techCountText}
${tech.tech[i].descriptionFunction ? tech.tech[i].descriptionFunction() :tech.tech[i].description}
` } else if (tech.tech[i].isFieldTech) { @@ -588,13 +588,19 @@ ${simulation.isCheating ? "

lore disabled": ""} }, populateGrid() { //background-color:var(--build-bg-color); let text = ` -
+
+
+ + +
- - - start - - + +
@@ -610,17 +616,11 @@ ${simulation.isCheating ? "

lore disabled": ""}
- - -
-
- - + + + start + +
` const hideStyle = `style="height:auto; border: none; background-color: transparent;"` @@ -905,6 +905,7 @@ const input = { document.getElementById("key-previous-gun").style.background = backgroundColor document.getElementById("key-testing").style.background = backgroundColor if (input.focus) input.focus.style.background = 'rgb(0, 200, 255)'; + document.getElementById("key-num").style.background = backgroundColor //always not highlighted }, setKeys(event) { //check for duplicate keys @@ -923,7 +924,8 @@ const input = { // event.code === "Escape" || event.code === input.key.nextGun || event.code === input.key.previousGun || - event.code === input.key.testing + event.code === input.key.testing || + event.code === "Digit1" || event.code === "Digit2" || event.code === "Digit3" || event.code === "Digit4" || event.code === "Digit5" || event.code === "Digit6" || event.code === "Digit7" || event.code === "Digit8" || event.code === "Digit9" || event.code === "Digit0" || event.code === "Minus" || event.code === "Equal" )) { switch (input.focus.id) { case "key-fire": @@ -1029,11 +1031,9 @@ window.addEventListener("keydown", function(event) { input.down = true break; case input.key.fire: - // event.preventDefault(); input.fire = true break case input.key.field: - // event.preventDefault(); input.field = true break case input.key.nextGun: @@ -1042,7 +1042,6 @@ window.addEventListener("keydown", function(event) { case input.key.previousGun: simulation.previousGun(); break - // case "Escape": case input.key.pause: if (!simulation.isChoosing && input.isPauseKeyReady && m.alive) { input.isPauseKeyReady = false @@ -1160,6 +1159,47 @@ window.addEventListener("keydown", function(event) { } break } + if (b.inventory.length > 1 && !simulation.testing) { + switch (event.code) { + case "Digit1": + simulation.switchToGunInInventory(0); + break + case "Digit2": + simulation.switchToGunInInventory(1); + break + case "Digit3": + simulation.switchToGunInInventory(2); + break + case "Digit4": + simulation.switchToGunInInventory(3); + break + case "Digit5": + simulation.switchToGunInInventory(4); + break + case "Digit6": + simulation.switchToGunInInventory(5); + break + case "Digit7": + simulation.switchToGunInInventory(6); + break + case "Digit8": + simulation.switchToGunInInventory(7); + break + case "Digit9": + simulation.switchToGunInInventory(8); + break + case "Digit0": + simulation.switchToGunInInventory(9); + break + case "Minus": + simulation.switchToGunInInventory(10); + break + case "Equal": + simulation.switchToGunInInventory(11); + break + } + } + if (simulation.testing) { if (event.key === "X") m.death(); //only uppercase switch (event.key.toLowerCase()) { diff --git a/js/level.js b/js/level.js index 964b833..1420c5e 100644 --- a/js/level.js +++ b/js/level.js @@ -28,24 +28,24 @@ const level = { // m.setField("perfect diamagnetism") //molecular assembler standing wave time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass pilot wave plasma torch // simulation.molecularMode = 2 // m.damage(0.1); - // b.giveGuns("mine") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser - // b.giveGuns("spores") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser + // b.giveGuns("shotgun") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser + // b.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[0].ammo = 10000 - // tech.giveTech("blast ball") - // tech.giveTech("elephants toothpaste") - // tech.giveTech("sentry gun") + // tech.giveTech("needle gun") + // tech.giveTech("repeater") + // tech.giveTech("ice-shot") // for (let i = 0; i < 1; ++i) tech.giveTech("super ball") // tech.isFoamBall = true - // for (let i = 0; i < 1; ++i) tech.giveTech("super ball") + // for (let i = 0; i < 3; ++i) tech.giveTech("repeater") // for (let i = 0; i < 1; i++) tech.giveTech("irradiated nails") // for (let i = 0; i < 1; i++) tech.giveTech("colony") // 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"); // level.testing(); - // spawn.shooter(1900, -500, 200) + // spawn.blinkBoss(1900, -500) // spawn.sneakBoss(1900, -500) - // spawn.starter(1900, -500, 25) + // spawn.starter(1900, -500, 200) // spawn.sneaker(1900, -500, 25) // spawn.hopper(2538, -950) // spawn.zombie(1000 + 1000 * Math.random(), -500 + 300 * Math.random(), 30, 5, "white") // zombie(x, y, radius, sides, color) diff --git a/js/player.js b/js/player.js index f43270c..ca04f10 100644 --- a/js/player.js +++ b/js/player.js @@ -697,7 +697,7 @@ const m = { } m.lastHarmCycle = m.cycle if (tech.isDroneOnDamage && bullet.length < 150) { //chance to build a drone on damage from tech - const len = Math.min((dmg - 0.06 * Math.random()) * 40, 40) / tech.droneEnergyReduction + const len = Math.min((dmg - 0.06 * Math.random()) * 40, 40) / tech.droneEnergyReduction * (tech.isEnergyHealth ? 0.5 : 1) for (let i = 0; i < len; i++) { if (Math.random() < 0.5) b.drone({ x: m.pos.x + 30 * Math.cos(m.angle) + 100 * (Math.random() - 0.5), diff --git a/js/powerup.js b/js/powerup.js index 32f6d97..88ba7f9 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -769,6 +769,9 @@ const powerUps = { } else if (parseInt(JSON.parse(elements[index + 1].getAttribute("data")).s.slice(0, -2)) < 500) { //try a different images and see if it is smaller tech.tech[choose].url = JSON.parse(elements[index + 1].getAttribute("data")).iurl document.getElementById(`junk-${choose}`).style.backgroundImage = `url('${tech.tech[choose].url}')` + } else if (parseInt(JSON.parse(elements[index + 2].getAttribute("data")).s.slice(0, -2)) < 500) { //try a different images and see if it is smaller + tech.tech[choose].url = JSON.parse(elements[index + 2].getAttribute("data")).iurl + document.getElementById(`junk-${choose}`).style.backgroundImage = `url('${tech.tech[choose].url}')` } }); } else { diff --git a/js/simulation.js b/js/simulation.js index 62e1923..0a41b58 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -297,6 +297,34 @@ const simulation = { ctx.strokeStyle = "#000"; //'rgba(0,0,0,0.4)' ctx.stroke(); // Draw it }, + drawCursorBasic() { + const size = 10; + ctx.beginPath(); + ctx.moveTo(simulation.mouse.x - size, simulation.mouse.y); + ctx.lineTo(simulation.mouse.x + size, simulation.mouse.y); + ctx.moveTo(simulation.mouse.x, simulation.mouse.y - size); + ctx.lineTo(simulation.mouse.x, simulation.mouse.y + size); + ctx.lineWidth = 2; + ctx.strokeStyle = "#000"; //'rgba(0,0,0,0.4)' + ctx.stroke(); // Draw it + }, + drawCursorCoolDown() { + const size = 10; + ctx.lineWidth = 2; + ctx.strokeStyle = "#000"; //'rgba(0,0,0,0.4)' + ctx.beginPath(); + if (m.fireCDcycle > m.cycle) { + ctx.strokeStyle = "#777"; //'rgba(0,0,0,0.4)' + ctx.arc(simulation.mouse.x, simulation.mouse.y, size + 1, 0, 2 * Math.PI); + } else { + ctx.strokeStyle = "#000"; //'rgba(0,0,0,0.4)' + } + ctx.moveTo(simulation.mouse.x - size, simulation.mouse.y); + ctx.lineTo(simulation.mouse.x + size, simulation.mouse.y); + ctx.moveTo(simulation.mouse.x, simulation.mouse.y - size); + ctx.lineTo(simulation.mouse.x, simulation.mouse.y + size); + ctx.stroke(); // Draw it + }, drawList: [], //so you can draw a first frame of explosions.. I know this is bad drawTime: 8, //how long circles are drawn. use to push into drawlist.time mobDmgColor: "rgba(255,0,0,0.7)", //color when a mob damages the player // set by mass-energy tech @@ -437,15 +465,14 @@ const simulation = { simulation.switchGun(); } }, - switchGun() { - 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 === "wave") { - b.guns[i].waves = []; //empty array of wave bullets - break; - } - } + switchToGunInInventory(num) { + if (b.inventory[num] !== undefined && b.inventoryGun !== num) { + b.inventoryGun = num + simulation.switchGun(); } + }, + switchGun() { + if (tech.isLongitudinal && b.activeGun === 3) b.guns[3].waves = []; //empty array of wave bullets if (tech.crouchAmmoCount) tech.crouchAmmoCount = 1 //this prevents hacking the tech by switching guns if (b.inventory.length > 0) { b.activeGun = b.inventory[b.inventoryGun]; @@ -453,6 +480,12 @@ const simulation = { } simulation.updateGunHUD(); simulation.boldActiveGunHUD(); + //set crosshairs + if (b.activeGun === 1) { + simulation.drawCursor = simulation.drawCursorCoolDown + } else { + simulation.drawCursor = simulation.drawCursorBasic + } }, zoom: null, zoomScale: 1000, @@ -741,6 +774,7 @@ const simulation = { input.endKeySensing(); b.removeAllGuns(); + simulation.switchGun(); tech.setupAllTech(); //sets tech to default values tech.cancelCount = 0; @@ -881,7 +915,7 @@ const simulation = { let count = 0; for (i = 0, len = bullet.length; i < len; i++) { //count mines left on map - if (bullet[i].bulletType === "mine" || bullet[i].bulletType === "laser mine") count++ + if ((bullet[i].bulletType === "mine" || bullet[i].bulletType === "laser mine") && !bullet[i].isArmed) count++ } for (i = 0, len = b.guns.length; i < len; i++) { //find which gun is mine if (b.guns[i].name === "mine") { diff --git a/js/spawn.js b/js/spawn.js index 345c000..a4b97a5 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -623,7 +623,7 @@ const spawn = { { name: "black hole", eventHorizon: 0, - eventHorizonRadius: 2100, + eventHorizonRadius: 1900, eventHorizonCycle: 0, do() { this.eventHorizonCycle++ @@ -4146,7 +4146,7 @@ const spawn = { Matter.Body.rotate(me, Math.PI * 0.1); Matter.Body.setDensity(me, 0.002); //extra dense //normal is 0.001 //makes effective life much larger me.isBoss = true; - me.damageReduction = 0.03 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) + me.damageReduction = 0.035 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) me.frictionStatic = 0; me.friction = 0; @@ -4160,7 +4160,7 @@ const spawn = { me.grenadeDelay = 100 } me.pulseRadius = 1.5 * Math.min(550, 200 + simulation.difficulty * 2) - me.delay = 35 + 35 * simulation.CDScale; + me.delay = 55 + 35 * simulation.CDScale; me.nextBlinkCycle = me.delay; spawn.shield(me, x, y, 1); me.onDamage = function() { @@ -5058,7 +5058,7 @@ const spawn = { if (this.phaseCycle > -1) { Matter.Body.rotate(this, 0.02) for (let i = 0, len = this.vertices.length; i < len; i++) { //fire a bullet from each vertex - spawn.sniperBullet(this.vertices[i].x, this.vertices[i].y, 5, 4); + spawn.sniperBullet(this.vertices[i].x, this.vertices[i].y, 3, 4); const velocity = Vector.mult(Vector.normalise(Vector.sub(this.position, this.vertices[i])), -15) Matter.Body.setVelocity(mob[mob.length - 1], { x: velocity.x, @@ -5724,7 +5724,7 @@ const spawn = { let me = mob[mob.length - 1]; Matter.Body.setDensity(me, 0.002); //extra dense //normal is 0.001 //makes effective life much larger me.isBoss = true; - me.damageReduction = 0.4 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) + me.damageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) me.accelMag = 0.0017 * Math.sqrt(simulation.accelScale); me.frictionAir = 0.01; @@ -5736,17 +5736,15 @@ const spawn = { me.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob //can't touch player me.showHealthBar = false; me.memory = 30; - me.vanishesLeft = 2 + simulation.difficultyMode + me.vanishesLeft = Math.ceil(1 + simulation.difficultyMode * 0.5) + me.onDeath = function() { + powerUps.spawnBossPowerUp(this.position.x, this.position.y) + }; me.onDamage = function() { if (this.vanishesLeft > 0 && this.health < 0.1) { //if health is below 10% teleport to a random spot on player history, heal, and cloak this.vanishesLeft-- - // const scale = 0.95; - // Matter.Body.scale(this, scale, scale); - // this.radius *= scale; - - //flash screen to hide vanish - for (let i = 0; i < 8; i++) { + for (let i = 0; i < 8; i++) { //flash screen to hide vanish simulation.drawList.push({ x: this.position.x, y: this.position.y, @@ -5761,6 +5759,7 @@ const spawn = { Matter.Body.setPosition(this, history.position) Matter.Body.setVelocity(this, { x: 0, y: 0 }); + this.damageReduction = 0 //immune to harm for the rest of this game cycle this.seePlayer.recall = 0 this.cloak(); this.health = 1; @@ -5784,6 +5783,14 @@ const spawn = { } } me.do = function() { + if (this.damageReduction === 0) { + this.damageReduction = 0.04 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) + let i = this.status.length //clear bad status effects + while (i--) { + if (this.status[i].type === "stun" || this.status[i].type === "dot") this.status.splice(i, 1); + } + this.isStunned = false; + } this.gravity(); this.seePlayerByHistory(55); this.checkStatus(); @@ -5835,6 +5842,7 @@ const spawn = { //teleport to near the end of player history Matter.Body.setPosition(this, m.history[Math.floor((m.history.length - 1) * (0.66 + 0.33 * Math.random()))].position) Matter.Body.setVelocity(this, { x: 0, y: 0 }); + this.damageReduction = 0 //immune to harm for the rest of this game cycle } }; me.cloak = function() { @@ -5846,6 +5854,14 @@ const spawn = { } } me.do = function() { + if (this.damageReduction === 0) { + this.damageReduction = 1 //stop being immune to harm immediately + let i = this.status.length //clear bad status effects + while (i--) { + if (this.status[i].type === "stun" || this.status[i].type === "dot") this.status.splice(i, 1); + } + this.isStunned = false; + } this.gravity(); this.seePlayerByHistory(25); this.checkStatus(); diff --git a/js/tech.js b/js/tech.js index f77c8eb..b943323 100644 --- a/js/tech.js +++ b/js/tech.js @@ -2382,7 +2382,7 @@ const tech = { // description: `after you collect ${powerUps.orb.heal()}
+${0.1 * tech.largerHeals} maximum energy`, // descriptionFunction: `convert current and future ${powerUps.orb.heal()} into

give +${10 * tech.largerHeals} maximum energy`, descriptionFunction() { - return `convert current and future
into

give +${8 * tech.largerHeals} maximum energy` + return `convert current and future
into

give +${8 * tech.largerHeals * (tech.isHalfHeals ? 0.5 : 1)} maximum energy` }, maxCount: 1, count: 0, @@ -2585,7 +2585,7 @@ const tech = { }, { name: "energy conservation", - description: "5% of damage done recovered as energy", + description: "4% of damage done recovered as energy", maxCount: 9, count: 0, frequency: 1, @@ -2595,7 +2595,7 @@ const tech = { }, requires: "", effect() { - tech.energySiphon += 0.05; + tech.energySiphon += 0.04; }, remove() { tech.energySiphon = 0; @@ -4151,6 +4151,25 @@ const tech = { tech.needleTunnel = false } }, + { + name: "ceramics", + description: `needles and harpoons pierce shields
directly damaging shielded mobs`, + isGunTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return (!tech.isLargeHarpoon && tech.haveGunCheck("harpoon")) || tech.isNeedles + }, + requires: "needle gun, harpoon, not Bessemer process", + effect() { + tech.isShieldPierce = true + }, + remove() { + tech.isShieldPierce = false + } + }, { name: "needle gun", description: "nail gun and shotgun fire mob piercing needles", @@ -4505,6 +4524,25 @@ const tech = { tech.isShotgunReversed = false; } }, + { + name: "repeater", + description: "shotgun immediately fires again for no ammo
-50% shotgun fire rate", + isGunTech: true, + maxCount: 9, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return (tech.haveGunCheck("shotgun")) + }, + requires: "shotgun, not Newtons 3rd law", + effect() { + tech.shotgunExtraShots++; + }, + remove() { + tech.shotgunExtraShots = 0 + } + }, { name: "nail-shot", link: `nail-shot`, @@ -5569,7 +5607,7 @@ const tech = { { name: "blast ball", descriptionFunction() { - return `instead of nails mines fire bouncy ${b.guns[10].nameString('s')}` + return `instead of nails mines fire bouncy balls` }, isGunTech: true, maxCount: 1, @@ -6386,7 +6424,7 @@ const tech = { }, { name: "railgun", - description: `harpoons can't retract, hold fire to charge
+50% harpoon density and damage`, + description: `hold fire to charge harpoon and release to launch
harpoons can't retract`, // description: `+900% harpoon ammo, but it can't retract
+50% harpoon density and damage`, isGunTech: true, maxCount: 1, @@ -6480,25 +6518,6 @@ const tech = { tech.isRailEnergy = false; } }, - { - name: "ceramics", - description: `needles and harpoons pierce shields
directly damaging shielded mobs`, - isGunTech: true, - maxCount: 1, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return (!tech.isLargeHarpoon && tech.haveGunCheck("harpoon")) || tech.isNeedles - }, - requires: "needle gun, harpoon, not Bessemer process", - effect() { - tech.isShieldPierce = true - }, - remove() { - tech.isShieldPierce = false - } - }, { name: "Bessemer process", descriptionFunction() { @@ -6535,7 +6554,7 @@ const tech = { return (tech.isRailGun ? 5 : 1) * (2 + 2 * this.count) }, allowed() { - return tech.haveGunCheck("harpoon") && b.returnGunAmmo('harpoon') >= this.removeAmmo() + return tech.haveGunCheck("harpoon") && b.guns[9].ammo >= this.removeAmmo() }, requires: "harpoon", effect() { @@ -10095,7 +10114,7 @@ const tech = { m.drawLeg("#4a4a4a"); m.calcLeg(0, 0); m.drawLeg("#333"); - ctx.rotate(m.angle - (m.fireCDcycle != Infinity ? m.flipLegs * 0.25 * Math.pow(Math.max(m.fireCDcycle - m.cycle, 0), 0.5) : 0)); + ctx.rotate(m.angle - (m.fireCDcycle !== Infinity ? m.flipLegs * 0.25 * Math.pow(Math.max(m.fireCDcycle - m.cycle, 0), 0.5) : 0)); ctx.beginPath(); ctx.arc(0, 0, 30, 0, 2 * Math.PI); @@ -10510,7 +10529,7 @@ const tech = { }, { name: "translucent", - description: "remove your guns and spawn new ones
your bullets and bots are transparent", + description: "spawn 3 gun power ups
your bullets and bots are transparent", maxCount: 1, count: 0, frequency: 0, @@ -10521,18 +10540,18 @@ const tech = { }, requires: "", effect() { - for (let i = 0; i < b.inventory.length; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "gun"); + for (let i = 0; i < 3; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "gun"); - //removes guns and ammo - b.inventory = []; - b.activeGun = null; - b.inventoryGun = 0; - for (let i = 0, len = b.guns.length; i < len; ++i) { - b.guns[i].have = false; - if (b.guns[i].ammo !== Infinity) b.guns[i].ammo = 0; - } - simulation.makeGunHUD(); //update gun HUD - b.bulletDraw = () => {}; + // //removes guns and ammo + // b.inventory = []; + // b.activeGun = null; + // b.inventoryGun = 0; + // for (let i = 0, len = b.guns.length; i < len; ++i) { + // b.guns[i].have = false; + // if (b.guns[i].ammo !== Infinity) b.guns[i].ammo = 0; + // } + // simulation.makeGunHUD(); //update gun HUD + b.bulletDraw = () => {}; //make bullets invisible }, remove() {} }, diff --git a/style.css b/style.css index 9653fee..6f56a5f 100644 --- a/style.css +++ b/style.css @@ -255,16 +255,16 @@ summary { #experiment-grid { display: flex; justify-content: center; - padding: 10px 1px; + padding: 0px; margin: 0px; border: 0px; background-color: var(--build-bg-color); display: none; grid-template-columns: repeat(auto-fit, 384px); grid-auto-flow: row; - grid-auto-rows: minmax(auto, auto); + /* grid-auto-rows: minmax(auto, auto); */ position: relative; - bottom: 0px; + /* bottom: 0px; */ z-index: 10; font-size: 1.3em; -ms-overflow-style: none; /* IE and Edge */ @@ -295,6 +295,30 @@ summary { background-color: #efeff5; } +.experiment-start-box{ + background-color: #fafcfd; + /* font-size: 1em; */ + position: sticky; + top:0; + z-index: 10; + align-self: start; + width: 195px; + line-height: 170%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + border: 2px #333 solid; + border-top: 0px; + border-radius: 10px; + border-top-left-radius: 0px; + /* border-bottom-left-radius: 0px; */ + border-top-right-radius: 0px; + padding:0.2em 0px; + height: 190px; + box-shadow: 8px 8px 7px rgba(0,0,50,0.15); +} + .card-background { height:340px; background-size: contain; @@ -325,6 +349,9 @@ summary { line-height: 160%; background-color: #fafcfd; } +.cancel-card:hover { + background-color: #efeff5; +} .research-card { font-size: 1.1em; font-weight: 100; @@ -335,6 +362,9 @@ summary { line-height: 160%; background-color: #fafcfd; } +.research-card:hover { + background-color: #efeff5; +} /* keeps 5 columns at 1440px */ diff --git a/todo.txt b/todo.txt index df9d758..d27446f 100644 --- a/todo.txt +++ b/todo.txt @@ -1,26 +1,34 @@ ******************************************************** NEXT PATCH ************************************************** -tech: cordyceps - sporangium infect mobs, making them fight for you as zombies -tech: blast ball - mines fire super balls -tech: extended magazine - sentry fires 50% more shots - sentry works with foam, nails, or super balls +tech: repeater - shotgun gets another shot, and a longer fire delay + shotgun cross hairs show when fire is on cooldown -dark patterns - stacks to 9 - 38->15% damage, 53->15% JUNK -electronegativity - stacks to 9 - 0.12->0.1% damage per energy +keys 1,2,3,4,5,6,7,8,9,0,-,= switch to a gun in your inventory +Nerfed blinkBoss health and speed +sneaker mobs are immune to harm for one cycles after vanishing +experiment button new style +new images for energy, bots bug fixes *********************************************************** TODO ***************************************************** -super-bot +tech - only allow 1,2 turrets at time? + turrets drain energy? + turrets never run out of ammo + turrets automatically use one of your mine ammos when they run out? + good with multi gun builds + conflict with booby trap -tech - shotgun triple shot, but a bit longer of a delay +tech: Bose Einstein condensate - freezes enemies in pilot wave, and drains some energy? + +super-bot tech - after standing wave runs out of energy from blocking, gain a buff buff: defense, damage? + aoe damage like railgun + push mobs away make super balls with Zectron deflectable with field but is there a simple way to do this? @@ -1157,12 +1165,8 @@ if pause is pressed while selecting power ups, display pause menu on top of sele ***major themes missing*** ***maybe redo*** dynamical systems - nail-bot - homeostasis heuristics - thermal runaway - infrared maybe? - redo the energy tech images with by Laurie Greasley - now that you can use --ar 3:2 --stylize 1000 and photo repair + negative feedback - too dark ***past style themes*** field emitter - isometric, clean white robot spherical gun turret on bird legs, blender 3d, style of artstation and behance, Disney Pixar, cute standing wave - concentric transparent blue geometric circles science