diff --git a/.DS_Store b/.DS_Store index 3a8ed2b..904cd0a 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/js/bullet.js b/js/bullet.js index 48f4efc..fefa9e2 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -957,23 +957,16 @@ const b = { bullet[me].beforeDmg = function() {}; bullet[me].stuck = function() {}; bullet[me].do = function() { - function onCollide(that) { - that.collisionFilter.mask = 0; //non collide with everything - Matter.Body.setVelocity(that, { - x: 0, - y: 0 - }); - if (tech.isRPG) that.thrust = { - x: 0, - y: 0 - } - that.do = that.radiationMode; - // if (collides(that, map).length || Matter.Query.collides(that, body).length || Matter.Query.collides(that, mob).length) { + const onCollide = () => { + this.collisionFilter.mask = 0; //non collide with everything + Matter.Body.setVelocity(this, { x: 0, y: 0 }); + if (tech.isRPG) this.thrust = { x: 0, y: 0 } + this.do = this.radiationMode; } const mobCollisions = Matter.Query.collides(this, mob) if (mobCollisions.length) { - onCollide(this) + onCollide() this.stuckTo = mobCollisions[0].bodyA mobs.statusDoT(this.stuckTo, 0.5, 360) //apply radiation damage status effect on direct hits @@ -1002,7 +995,7 @@ const b = { const bodyCollisions = Matter.Query.collides(this, body) if (bodyCollisions.length) { if (!bodyCollisions[0].bodyA.isNotHoldable) { - onCollide(this) + onCollide() this.stuckTo = bodyCollisions[0].bodyA //find the relative position for when the mob is at angle zero by undoing the mobs rotation this.stuckToRelativePosition = Vector.rotate(Vector.sub(this.position, this.stuckTo.position), -this.stuckTo.angle) @@ -1020,7 +1013,7 @@ const b = { } } else { if (Matter.Query.collides(this, map).length) { - onCollide(this) + onCollide() } else if (tech.isRPG) { //if colliding with nothing this.force.x += this.thrust.x; this.force.y += this.thrust.y; @@ -1142,7 +1135,7 @@ const b = { // const futurePos = this.lockedOn ? :Vector.add(this.position, Vector.mult(this.velocity, 50)) for (let i = 0, len = mob.length; i < len; ++i) { if ( - mob[i].alive && !mob[i].isBadTarget && !mob[i].isBadTarget && + mob[i].alive && !mob[i].isBadTarget && Matter.Query.ray(map, this.position, mob[i].position).length === 0 // && Matter.Query.ray(body, this.position, mob[i].position).length === 0 ) { @@ -1525,7 +1518,8 @@ const b = { }); if (tech.isLaserPush) { //push mobs away const index = path.length - 1 - const force = Vector.mult(Vector.normalise(Vector.sub(path[index], path[Math.max(0, index - 1)])), 0.0035 * push * Math.min(6, best.who.mass)) + Matter.Body.setVelocity(best.who, { x: best.who.velocity.x * 0.94, y: best.who.velocity.y * 0.94 }); + const force = Vector.mult(Vector.normalise(Vector.sub(path[index], path[Math.max(0, index - 1)])), 0.006 * push * Math.min(6, best.who.mass)) Matter.Body.applyForce(best.who, path[index], force) } } @@ -3123,7 +3117,11 @@ const b = { if (this.cd < simulation.cycle && !(simulation.cycle % this.lookFrequency) && !m.isCloak) { for (let i = 0, len = mob.length; i < len; i++) { const dist2 = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)); - if (Matter.Query.ray(map, this.position, mob[i].position).length === 0 && dist2 > 250000) { + if ( + mob[i].alive && !mob[i].isBadTarget && + dist2 > 250000 && + Matter.Query.ray(map, this.position, mob[i].position).length === 0 + ) { this.cd = simulation.cycle + this.delay; const angle = Vector.angle(this.position, mob[i].position) Matter.Body.setAngle(this, angle) @@ -4750,48 +4748,30 @@ const b = { name: "drones", description: "deploy drones that crash into mobs
crashes reduce their lifespan by 1 second", ammo: 0, - ammoPack: 14, - defaultAmmoPack: 14, + ammoPack: 14.5, + defaultAmmoPack: 14.5, have: false, do() {}, fire() { if (tech.isDroneRadioactive) { if (m.crouch) { b.droneRadioactive({ x: m.pos.x + 30 * Math.cos(m.angle) + 10 * (Math.random() - 0.5), y: m.pos.y + 30 * Math.sin(m.angle) + 10 * (Math.random() - 0.5) }, 45) - m.fireCDcycle = m.cycle + Math.floor(5 * 13 * b.fireCDscale); // cool down + m.fireCDcycle = m.cycle + Math.floor(50 * b.fireCDscale); // cool down } else { b.droneRadioactive({ x: m.pos.x + 30 * Math.cos(m.angle) + 10 * (Math.random() - 0.5), y: m.pos.y + 30 * Math.sin(m.angle) + 10 * (Math.random() - 0.5) }, 10) - m.fireCDcycle = m.cycle + Math.floor(5 * 6 * b.fireCDscale); // cool down + m.fireCDcycle = m.cycle + Math.floor(25 * b.fireCDscale); // cool down } } else { if (m.crouch) { - b.drone({ x: m.pos.x + 30 * Math.cos(m.angle) + 10 * (Math.random() - 0.5), y: m.pos.y + 30 * Math.sin(m.angle) + 10 * (Math.random() - 0.5) }, 45) - m.fireCDcycle = m.cycle + Math.floor(13 * b.fireCDscale); // cool down + b.drone({ x: m.pos.x + 30 * Math.cos(m.angle) + 10 * (Math.random() - 0.5), y: m.pos.y + 30 * Math.sin(m.angle) + 10 * (Math.random() - 0.5) }, 55) + m.fireCDcycle = m.cycle + Math.floor(10 * b.fireCDscale); // cool down } else { - b.drone() - m.fireCDcycle = m.cycle + Math.floor(6 * b.fireCDscale); // cool down + b.drone({ x: m.pos.x + 30 * Math.cos(m.angle) + 10 * (Math.random() - 0.5), y: m.pos.y + 30 * Math.sin(m.angle) + 10 * (Math.random() - 0.5) }, 20) + m.fireCDcycle = m.cycle + Math.floor(5 * b.fireCDscale); // cool down } } } }, - // { - // name: "ice IX", - // description: "synthesize short-lived ice crystals
crystals seek out and freeze mobs", - // ammo: 0, - // ammoPack: 64, - // have: false, - // do() {}, - // fire() { - // if (m.crouch) { - // b.iceIX(10, 0.3) - // m.fireCDcycle = m.cycle + Math.floor(8 * b.fireCDscale); // cool down - // } else { - // b.iceIX(2) - // m.fireCDcycle = m.cycle + Math.floor(3 * b.fireCDscale); // cool down - // } - - // } - // }, { name: "foam", description: "spray bubbly foam that sticks to mobs
slows mobs and does damage over time", @@ -4812,7 +4792,36 @@ const b = { if (this.isDischarge) { this.charge-- - this.fireFoam() + const spread = (m.crouch ? 0.05 : 0.6) * (Math.random() - 0.5) + const radius = 5 + 8 * Math.random() + (tech.isAmmoFoamSize && this.ammo < 300) * 12 + const SPEED = 18 - radius * 0.4; + const dir = m.angle + 0.15 * (Math.random() - 0.5) + const velocity = { + x: SPEED * Math.cos(dir), + y: SPEED * Math.sin(dir) + } + const position = { + x: m.pos.x + 30 * Math.cos(m.angle), + y: m.pos.y + 30 * Math.sin(m.angle) + } + if (tech.foamFutureFire) { + simulation.drawList.push({ //add dmg to draw queue + x: position.x, + y: position.y, + radius: 5, + color: "rgba(0,50,50,0.3)", + time: 15 * tech.foamFutureFire + }); + setTimeout(() => { + if (!simulation.paused) { + b.foam(position, Vector.rotate(velocity, spread), radius) + // (tech.isFastFoam ? 0.044 : 0.011) * (tech.isFoamTeleport ? 1.60 : 1) + bullet[bullet.length - 1].damage *= (1 + 0.75 * tech.foamFutureFire) + } + }, 250 * tech.foamFutureFire); + } else { + b.foam(position, Vector.rotate(velocity, spread), radius) + } m.fireCDcycle = m.cycle + 1; //disable firing and adding more charge } else if (!input.fire) { this.isDischarge = true; @@ -4825,38 +4834,6 @@ const b = { this.charge++ m.fireCDcycle = m.cycle + Math.floor((1 + 0.35 * this.charge) * b.fireCDscale); }, - fireFoam() { - const spread = (m.crouch ? 0.05 : 0.6) * (Math.random() - 0.5) - const radius = 5 + 8 * Math.random() + (tech.isAmmoFoamSize && this.ammo < 300) * 12 - const SPEED = 18 - radius * 0.4; - const dir = m.angle + 0.15 * (Math.random() - 0.5) - const velocity = { - x: SPEED * Math.cos(dir), - y: SPEED * Math.sin(dir) - } - const position = { - x: m.pos.x + 30 * Math.cos(m.angle), - y: m.pos.y + 30 * Math.sin(m.angle) - } - if (tech.foamFutureFire) { - simulation.drawList.push({ //add dmg to draw queue - x: position.x, - y: position.y, - radius: 5, - color: "rgba(0,50,50,0.3)", - time: 15 * tech.foamFutureFire - }); - setTimeout(() => { - if (!simulation.paused) { - b.foam(position, Vector.rotate(velocity, spread), radius) - // (tech.isFastFoam ? 0.044 : 0.011) * (tech.isFoamTeleport ? 1.60 : 1) - bullet[bullet.length - 1].damage *= (1 + 0.75 * tech.foamFutureFire) - } - }, 250 * tech.foamFutureFire); - } else { - b.foam(position, Vector.rotate(velocity, spread), radius) - } - } }, { name: "rail gun", description: "use energy to launch a high-speed dense rod
hold left mouse to charge, release to fire", diff --git a/js/level.js b/js/level.js index d862f56..628f13e 100644 --- a/js/level.js +++ b/js/level.js @@ -12,7 +12,7 @@ const level = { start() { if (level.levelsCleared === 0) { //this code only runs on the first level // localSettings.levelsClearedLastGame = 10 - // level.difficultyIncrease(10) //30 is near max on hard //60 is near max on why + // level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why // simulation.isHorizontalFlipped = true // tech.isFieldFree = true // m.setField("perfect diamagnetism") @@ -2267,12 +2267,16 @@ const level = { spawn.mapRect(5050, -100, 50, 150); spawn.mapRect(4850, -275, 50, 175); // level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why - // spawn.starter(1900, -500, 200) //big boy + spawn.starter(1900, -500, 200) //big boy + // spawn.spiderBoss(1900, -500) + // spawn.laserBombingBoss(1900, -500) + // for (let i = 0; i < 5; i++) spawn.focuser(1900, -500) + // spawn.growBossCulture(1900, -500) - spawn.laserBombingBoss(1900, -500) - // spawn.snakeSpitBoss(1900, -500) - // spawn.growBossCulture(1900, -500) - // spawn.sneaker(1900, -500) + spawn.sneaker(1900, -500) + spawn.sneaker(1900, -500) + spawn.shield(mob[mob.length - 1], 1900, -500, 1); + // mob[mob.length - 1].isShielded = true // spawn.historyBoss(1200, -500) // spawn.laserTargetingBoss(1600, -400) // spawn.focuser(1600, -500) @@ -2284,7 +2288,6 @@ const level = { // spawn.cellBossCulture(1600, -500) // spawn.laserTargetingBoss(1600, -500) // spawn.grenadierBoss(1200, -500) - // spawn.shield(mob[mob.length - 1], 1800, -120, 1); // spawn.nodeGroup(1200, -500, "grenadier") // spawn.snakeBoss(1200, -500) diff --git a/js/lore.js b/js/lore.js index d02b2c6..388f0e8 100644 --- a/js/lore.js +++ b/js/lore.js @@ -305,7 +305,7 @@ const lore = { lore.talkingColor = "#dff" level.isHazardRise = true //remove all bullets, so they can't get endless energy - for (let i = 0; i < bullet.length; ++i) Matter.Composite.remove(engine.world, bullet[i]); + for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]); bullet = []; setTimeout(() => { lore.anand.text("I'm actually surprised you haven't been attacked by the adversarial network this time.") }, 500); }, diff --git a/js/player.js b/js/player.js index 95797e1..7584699 100644 --- a/js/player.js +++ b/js/player.js @@ -1332,12 +1332,13 @@ const m = { for (let i = 0, len = mob.length; i < len; ++i) { if ( Vector.magnitude(Vector.sub(mob[i].position, m.pos)) - mob[i].radius < m.fieldRange && - !mob[i].isShielded && m.lookingAt(mob[i]) && + !mob[i].isUnblockable && Matter.Query.ray(map, mob[i].position, m.pos).length === 0 ) { mob[i].locatePlayer(); m.pushMass(mob[i]); + if (mob[i].isShielded) m.fieldCDcycle = m.cycle + 60 } } }, @@ -1499,7 +1500,7 @@ const m = { ctx.fill(); //360 block for (let i = 0, len = mob.length; i < len; ++i) { - if (Vector.magnitude(Vector.sub(mob[i].position, m.pos)) - mob[i].radius < netfieldRange && !mob[i].isShielded) { // && Matter.Query.ray(map, mob[i].position, m.pos).length === 0 + if (Vector.magnitude(Vector.sub(mob[i].position, m.pos)) - mob[i].radius < netfieldRange && !mob[i].isUnblockable) { // && Matter.Query.ray(map, mob[i].position, m.pos).length === 0 mob[i].locatePlayer(); if (this.drainCD > m.cycle) { m.pushMass(mob[i], 0); @@ -1507,6 +1508,7 @@ const m = { m.pushMass(mob[i]); this.drainCD = m.cycle + 10 } + if (mob[i].isShielded) m.fieldCDcycle = m.cycle + 45 } } } @@ -1527,7 +1529,7 @@ const m = { } //360 block for (let i = 0, len = mob.length; i < len; ++i) { - if (Vector.magnitude(Vector.sub(mob[i].position, m.pos)) - mob[i].radius < radius && !mob[i].isShielded) { // && Matter.Query.ray(map, mob[i].position, m.pos).length === 0 + if (Vector.magnitude(Vector.sub(mob[i].position, m.pos)) - mob[i].radius < radius && !mob[i].isUnblockable) { // && Matter.Query.ray(map, mob[i].position, m.pos).length === 0 mob[i].locatePlayer(); if (this.drainCD > m.cycle) { m.pushMass(mob[i], 0); @@ -1535,6 +1537,7 @@ const m = { m.pushMass(mob[i]); this.drainCD = m.cycle + 10 } + if (mob[i].isShielded) m.fieldCDcycle = m.cycle + 45 } } } @@ -1584,27 +1587,25 @@ const m = { m.fieldPosition = { x: m.pos.x, y: m.pos.y } m.fieldAngle = m.angle m.perfectPush = (isFree = false) => { - for (let i = 0, len = mob.length; i < len; ++i) { - if ( - Vector.magnitude(Vector.sub(mob[i].position, m.fieldPosition)) - mob[i].radius < m.fieldRange && - !mob[i].isShielded && - Vector.dot({ x: Math.cos(m.fieldAngle), y: Math.sin(m.fieldAngle) }, Vector.normalise(Vector.sub(mob[i].position, m.fieldPosition))) > m.fieldThreshold && - Matter.Query.ray(map, mob[i].position, m.fieldPosition).length === 0 - ) { - mob[i].locatePlayer(); - - const unit = Vector.normalise(Vector.sub(m.fieldPosition, mob[i].position)) - if (m.fieldCDcycle < m.cycle) { - m.fieldCDcycle = m.cycle + m.fieldBlockCD; + if (m.fieldCDcycle < m.cycle) { + for (let i = 0, len = mob.length; i < len; ++i) { + if ( + Vector.magnitude(Vector.sub(mob[i].position, m.fieldPosition)) - mob[i].radius < m.fieldRange && + !mob[i].isUnblockable && + Vector.dot({ x: Math.cos(m.fieldAngle), y: Math.sin(m.fieldAngle) }, Vector.normalise(Vector.sub(mob[i].position, m.fieldPosition))) > m.fieldThreshold && + Matter.Query.ray(map, mob[i].position, m.fieldPosition).length === 0 + ) { + mob[i].locatePlayer(); + const unit = Vector.normalise(Vector.sub(m.fieldPosition, mob[i].position)) + m.fieldCDcycle = m.cycle + m.fieldBlockCD + (mob[i].isShielded ? 15 : 0); if (tech.blockingIce) { for (let i = 0; i < tech.blockingIce; i++) { const angle = m.fieldAngle + 1.55 * (Math.random() - 0.5) b.iceIX(10, angle, Vector.add(m.fieldPosition, { x: m.fieldRange * Math.cos(angle), y: m.fieldRange * Math.sin(angle) })) } } - if (tech.blockDmg) { + if (tech.blockDmg) { //electricity mob[i].damage(tech.blockDmg * b.dmgScale) - //draw electricity const step = 40 ctx.beginPath(); for (let i = 0, len = 1.5 * tech.blockDmg; i < len; i++) { @@ -1622,32 +1623,9 @@ const m = { ctx.stroke(); } else if (isFree) { //when blocking draw this graphic - // const len = mob[i].vertices.length - 1; ctx.fillStyle = "rgba(110,170,200," + (0.2 + 0.4 * Math.random()) + ")"; ctx.lineWidth = 2; ctx.strokeStyle = "#000"; - // const angleOff = m.fieldAngle + 2 * m.fieldArc * (Math.random() - 0.5) - // const off = { - // x: m.fieldRange * Math.cos(angleOff), - // y: m.fieldRange * Math.sin(angleOff), - // } - // const where = Vector.add(m.fieldPosition, off) - // ctx.beginPath(); - // ctx.moveTo(where.x, where.y); - // ctx.lineTo(mob[i].vertices[len].x, mob[i].vertices[len].y); - // ctx.lineTo(mob[i].vertices[0].x, mob[i].vertices[0].y); - // ctx.fill(); - // ctx.stroke(); - // for (let j = 0; j < len; j++) { - // ctx.beginPath(); - // ctx.moveTo(where.x, where.y); - // ctx.lineTo(mob[i].vertices[j].x, mob[i].vertices[j].y); - // ctx.lineTo(mob[i].vertices[j + 1].x, mob[i].vertices[j + 1].y); - // ctx.fill(); - // ctx.stroke(); - // } - - const len = mob[i].vertices.length - 1; const mag = mob[i].radius ctx.beginPath(); @@ -1681,31 +1659,26 @@ const m = { } } if (tech.isStunField) mobs.statusStun(mob[i], tech.isStunField) - //knock backs - const massRoot = Math.sqrt(Math.max(0.15, mob[i].mass)); + //mob knock backs + const massRoot = Math.sqrt(Math.max(1, mob[i].mass)); Matter.Body.setVelocity(mob[i], { - x: player.velocity.x - (20 * unit.x) / massRoot, - y: player.velocity.y - (20 * unit.y) / massRoot + x: player.velocity.x - (30 * unit.x) / massRoot, + y: player.velocity.y - (30 * unit.y) / massRoot }); if (mob[i].isOrbital) Matter.Body.setVelocity(mob[i], { x: 0, y: 0 }); - } - - if (isFree) { - - } else { - if (mob[i].isDropPowerUp && player.speed < 12) { - const massRootCap = Math.sqrt(Math.min(10, Math.max(0.2, mob[i].mass))); - Matter.Body.setVelocity(player, { - x: 0.9 * player.velocity.x + 0.6 * unit.x * massRootCap, - y: 0.9 * player.velocity.y + 0.6 * unit.y * massRootCap - }); + if (!isFree) { //player knock backs + if (mob[i].isDropPowerUp && player.speed < 12) { + const massRootCap = Math.sqrt(Math.min(10, Math.max(0.2, mob[i].mass))); + Matter.Body.setVelocity(player, { + x: 0.9 * player.velocity.x + 0.6 * unit.x * massRootCap, + y: 0.9 * player.velocity.y + 0.6 * unit.y * massRootCap + }); + } } } - } } } - m.hold = function() { const wave = Math.sin(m.cycle * 0.022); m.fieldRange = 190 + 12 * wave @@ -1744,13 +1717,12 @@ const m = { cp1y = m.pos.y + curve * m.fieldRange * Math.sin(a) ctx.quadraticCurveTo(cp1x, cp1y, m.pos.x + 1 * m.fieldRange * Math.cos(m.angle - Math.PI * m.fieldArc), m.pos.y + 1 * m.fieldRange * Math.sin(m.angle - Math.PI * m.fieldArc)) ctx.fill(); - // m.pushMobsFacing(); m.perfectPush(); } else if (m.holdingTarget && m.fieldCDcycle < m.cycle) { //holding, but field button is released m.pickUp(); } else { m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists) - if (tech.isFieldFree && !input.field) { + if (!input.field) { //tech.isFieldFre //draw field free of player ctx.fillStyle = "rgba(110,170,200," + (0.27 + 0.2 * Math.random() - 0.1 * wave) + ")"; ctx.strokeStyle = "rgba(110, 200, 235, " + (0.4 + 0.5 * Math.random()) + ")" @@ -1769,7 +1741,7 @@ const m = { } m.drawFieldMeter() if (tech.isPerfectBrake) { //cap mob speed around player - const range = 160 + 140 * wave + 200 * m.energy + const range = 200 + 140 * wave + 150 * m.energy for (let i = 0; i < mob.length; i++) { const distance = Vector.magnitude(Vector.sub(m.pos, mob[i].position)) if (distance < range) { @@ -2705,6 +2677,26 @@ const m = { y: powerUp[i].velocity.y * 0.05 }); if (dist2 < 1000 && !simulation.isChoosing) { //use power up if it is close enough + + // if (true) { //AoE radiation effect + // const range = 800 + + // for (let i = 0, len = mob.length; i < len; ++i) { + // if (mob[i].alive && !mob[i].isShielded) { + // dist = Vector.magnitude(Vector.sub(powerUp[i].position, mob[i].position)) - mob[i].radius; + // if (dist < range) mobs.statusDoT(mob[i], 0.5) //apply radiation damage status effect on direct hits + // } + // } + + // simulation.drawList.push({ + // x: powerUp[i].position.x, + // y: powerUp[i].position.y, + // radius: range, + // color: "rgba(0,150,200,0.3)", + // time: 4 + // }); + // } + m.fieldRange *= 0.8 powerUps.onPickUp(powerUp[i]); powerUp[i].effect(); @@ -2846,19 +2838,19 @@ const m = { ) { const sub = Vector.sub(simulation.mouseInGame, m.pos) const mag = Vector.magnitude(sub) - const drain = 0.03 + 0.005 * Math.sqrt(mag) + const drain = 0.06 + 0.006 * Math.sqrt(mag) if (m.energy > drain && mag > 300) { m.energy -= drain m.hole.isReady = false; m.fieldRange = 0 Matter.Body.setPosition(player, simulation.mouseInGame); m.buttonCD_jump = 0 //this might fix a bug with jumping - const velocity = Vector.mult(Vector.normalise(sub), 18) + const velocity = Vector.mult(Vector.normalise(sub), 20) Matter.Body.setVelocity(player, { x: velocity.x, y: velocity.y - 4 //an extra vertical kick so the player hangs in place longer }); - if (m.immuneCycle < m.cycle + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage + if (m.immuneCycle < m.cycle + 15) m.immuneCycle = m.cycle + 15; //player is immune to damage for 1/4 seconds // move bots to player for (let i = 0; i < bullet.length; i++) { if (bullet[i].botType) { diff --git a/js/simulation.js b/js/simulation.js index e1c572e..25cbf5c 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -812,13 +812,13 @@ const simulation = { if (tech.isFlipFlopOn) { if (m.immuneCycle < m.cycle) m.energy += 0.22; } else { - m.energy -= 0.041; + m.energy -= 0.022; if (m.energy < 0) m.energy = 0 } } if (tech.relayIce && tech.isFlipFlopOn) { for (let j = 0; j < tech.relayIce; j++) { - for (let i = 0, len = Math.ceil(8 * Math.random()); i < len; i++) b.iceIX(2) + for (let i = 0, len = Math.ceil(9 * Math.random()); i < len; i++) b.iceIX(2) } } diff --git a/js/spawn.js b/js/spawn.js index e4fadf7..af38da7 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -110,6 +110,7 @@ const spawn = { me.isShielded = true; //makes it immune to damage me.leaveBody = false; me.isBadTarget = true; + me.isUnblockable = true; me.isDropPowerUp = false; me.showHealthBar = false; me.collisionFilter.category = 0; @@ -166,6 +167,7 @@ const spawn = { me.isShielded = true; //makes it immune to damage me.leaveBody = false; me.isBadTarget = true; + me.isUnblockable = true; me.isDropPowerUp = false; me.showHealthBar = false; me.collisionFilter.category = 0; @@ -1998,19 +2000,19 @@ const spawn = { 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.0005 * Math.sqrt(simulation.accelScale); + me.accelMag = 0.00055 * Math.sqrt(simulation.accelScale); me.seePlayerFreq = Math.floor(30 * simulation.lookFreqScale); me.memory = 420; me.restitution = 1; me.frictionAir = 0.05; me.frictionStatic = 0; me.friction = 0; - me.lookTorque = 0.000005 * (Math.random() > 0.5 ? -1 : 1); + me.lookTorque = 0.0000055 * (Math.random() > 0.5 ? -1 : 1) * (1 + 0.1 * Math.sqrt(simulation.difficulty)) me.fireDir = { x: 0, y: 0 } - Matter.Body.setDensity(me, 0.008); //extra dense //normal is 0.001 //makes effective life much larger + Matter.Body.setDensity(me, 0.01); //extra dense //normal is 0.001 //makes effective life much larger spawn.shield(me, x, y, 1); spawn.spawnOrbitals(me, radius + 200 + 300 * Math.random()) me.onHit = function() {}; @@ -2019,7 +2021,7 @@ const spawn = { }; me.damageReduction = 0.25 me.targetingCount = 0; - me.targetingTime = 60 - Math.min(55, 2 * simulation.difficulty) + me.targetingTime = 60 - Math.min(58, 3 * simulation.difficulty) me.do = function() { // this.armor(); this.seePlayerByLookingAt(); @@ -2103,7 +2105,7 @@ const spawn = { this.targetingCount -= 10; const sub = Vector.sub(player.position, this.position) const dist = Vector.magnitude(sub) - const speed = 30 + const speed = Math.min(55, 5 + 20 * simulation.accelScale) const velocity = Vector.mult(Vector.normalise(sub), speed) spawn.grenade(this.vertices[1].x, this.vertices[1].y, dist / speed, Math.min(550, 250 + simulation.difficulty * 3), 6); // grenade(x, y, lifeSpan = 90 + Math.ceil(60 / simulation.accelScale), pulseRadius = Math.min(550, 250 + simulation.difficulty * 3), size = 4) { Matter.Body.setVelocity(mob[mob.length - 1], velocity); @@ -2125,15 +2127,15 @@ const spawn = { ctx.moveTo(this.vertices[1].x, this.vertices[1].y); ctx.lineTo(best.x, best.y); ctx.strokeStyle = "rgba(0,235,255,1)"; - ctx.lineWidth = 2 + ctx.lineWidth = 3 ctx.stroke(); if (this.targetingCount / this.targetingTime > 0.33) { - ctx.strokeStyle = "rgba(0,235,255,0.4)"; - ctx.lineWidth = 8 + ctx.strokeStyle = "rgba(0,235,255,0.45)"; + ctx.lineWidth = 10 ctx.stroke(); if (this.targetingCount / this.targetingTime > 0.66) { - ctx.strokeStyle = "rgba(0,235,255,0.2)"; - ctx.lineWidth = 25 + ctx.strokeStyle = "rgba(0,235,255,0.25)"; + ctx.lineWidth = 30 ctx.stroke(); } } @@ -2144,20 +2146,20 @@ const spawn = { }; }, blinkBoss(x, y) { - mobs.spawn(x, y, 5, 50, "rgb(215,80,190)"); //"rgb(221,102,119)" + mobs.spawn(x, y, 5, 50, "rgb(0,235,255)"); //"rgb(221,102,119)" let me = mob[mob.length - 1]; Matter.Body.rotate(me, Math.PI * 0.1); - Matter.Body.setDensity(me, 0.02); //extra dense //normal is 0.001 //makes effective life much larger + Matter.Body.setDensity(me, 0.018); //extra dense //normal is 0.001 //makes effective life much larger me.isBoss = true; me.frictionStatic = 0; me.friction = 0; me.memory = 240 me.seePlayerFreq = 60 - me.delay = 20 + 30 * simulation.CDScale; + me.delay = 25 + 30 * simulation.CDScale; me.nextBlinkCycle = me.delay; me.blinkRange = 235 - me.grenadeDelay = 30 + 60 * simulation.CDScale + me.grenadeDelay = 35 + 60 * simulation.CDScale me.pulseRadius = 2 * Math.min(550, 220 + simulation.difficulty * 4) spawn.shield(me, x, y, 1); me.onDamage = function() { @@ -3185,7 +3187,7 @@ const spawn = { } else if (this.noseLength > 1.5 && dot > -0.2 && dot < 0.2) { //fire spawn.sniperBullet(this.vertices[1].x, this.vertices[1].y, 7 + Math.ceil(this.radius / 15), 4); - const v = 20 * simulation.accelScale; + const v = 10 + 15 * simulation.accelScale; Matter.Body.setVelocity(mob[mob.length - 1], { x: this.velocity.x + this.fireDir.x * v + Math.random(), y: this.velocity.y + this.fireDir.y * v + Math.random() @@ -3246,8 +3248,8 @@ const spawn = { this.explode(this.mass * 20); }; Matter.Body.setDensity(me, 0.00005); //normal is 0.001 - me.timeLeft = 240; - me.g = 0.0005; //required if using 'gravity' + me.timeLeft = 120; + // me.g = 0.0005; //required if using 'gravity' me.frictionAir = 0; me.restitution = 0; me.leaveBody = false; @@ -3258,7 +3260,7 @@ const spawn = { me.collisionFilter.category = cat.mobBullet; me.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet; me.do = function() { - this.gravity(); + // this.gravity(); this.timeLimit(); if (Matter.Query.collides(this, map).length > 0 || Matter.Query.collides(this, body).length > 0 && this.speed < 3) { this.isDropPowerUp = false; @@ -3339,7 +3341,7 @@ const spawn = { }; }, grenadierBoss(x, y, radius = 95) { - mobs.spawn(x, y, 6, radius, "rgb(215,80,190)"); + mobs.spawn(x, y, 6, radius, "rgb(0,235,255)"); let me = mob[mob.length - 1]; me.isBoss = true; @@ -3391,7 +3393,7 @@ const spawn = { }; }, grenadier(x, y, radius = 35 + Math.ceil(Math.random() * 20)) { - mobs.spawn(x, y, 3, radius, "rgb(215,80,190)"); //rgb(255,100,200) + mobs.spawn(x, y, 3, radius, "rgb(0,235,255)"); //rgb(255,100,200) 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 me.isVerticesChange = true @@ -4063,6 +4065,7 @@ const spawn = { Matter.Body.setDensity(me, 0.00001) //very low density to not mess with the original mob's motion me.shield = true; me.damageReduction = 0.075 + me.isUnblockable = true me.isExtraShield = isExtraShield //this prevents spamming with tech.isShieldAmmo me.collisionFilter.category = cat.mobShield me.collisionFilter.mask = cat.bullet; @@ -4162,6 +4165,7 @@ const spawn = { me.leaveBody = false; me.isDropPowerUp = false; me.isBadTarget = true; + me.isUnblockable = true; me.showHealthBar = false; me.isOrbital = true; // me.isShielded = true @@ -4393,6 +4397,7 @@ const spawn = { me.isDropPowerUp = false; me.showHealthBar = false; me.isBadTarget = true; + me.isUnblockable = true; me.do = function() { let wireX = -50; @@ -4461,6 +4466,7 @@ const spawn = { me.isDropPowerUp = false; me.showHealthBar = false; me.isBadTarget = true; + me.isUnblockable = true; me.do = function() { let wireX = -50 - 20; @@ -4512,6 +4518,7 @@ const spawn = { me.isDropPowerUp = false; me.showHealthBar = false; me.isBadTarget = true; + me.isUnblockable = true; me.do = function() { let wireX = -50 - 35; @@ -4562,6 +4569,7 @@ const spawn = { me.isDropPowerUp = false; me.showHealthBar = false; me.isBadTarget = true; + me.isUnblockable = true; me.do = function() { let wireX = -50 + 16; @@ -4612,6 +4620,7 @@ const spawn = { me.isDropPowerUp = false; me.showHealthBar = false; me.isBadTarget = true; + me.isUnblockable = true; me.do = function() { let wireX = -50 + 26; diff --git a/js/tech.js b/js/tech.js index 8d80184..f380abb 100644 --- a/js/tech.js +++ b/js/tech.js @@ -168,7 +168,7 @@ damageFromTech() { let dmg = 1 //m.fieldDamage if (tech.isCloakingDamage) dmg *= 1.35 - if (tech.isFlipFlopDamage && tech.isFlipFlopOn) dmg *= 1.45 + if (tech.isFlipFlopDamage && tech.isFlipFlopOn) dmg *= 1.5 if (tech.isAnthropicDamage && tech.isDeathAvoidedThisLevel) dmg *= 2.3703599 if (tech.isDamageAfterKill) dmg *= (m.lastKillCycle + 300 > m.cycle) ? 2 : 0.66 if (m.isSneakAttack && m.cycle > m.lastKillCycle + 240) dmg *= tech.sneakAttackDmg @@ -1805,7 +1805,7 @@ }, { name: "thermocouple", - description: "if relay switch is in the ON state
condense 1-7 ice IX crystals every second", + description: "if relay switch is in the ON state
condense 1-9 ice IX crystals every second", maxCount: 9, count: 0, frequency: 4, @@ -1823,7 +1823,7 @@ }, { name: "NAND gate", - description: "if in the ON state
do 45% more damage", + description: "if in the ON state
do 50% more damage", maxCount: 1, count: 0, frequency: 4, @@ -1841,7 +1841,7 @@ }, { name: "transistor", - description: "if ON regen 22 energy per second
if OFF drain 4.1 energy per second", + description: "if ON regen 22 energy per second
if OFF drain 2.2 energy per second", maxCount: 1, count: 0, frequency: 4, @@ -7536,7 +7536,8 @@ description: `this`, maxCount: 1, count: 0, - frequency: 2, + frequency: 3, + frequencyDefault: 3, isLore: true, // isNonRefundable: true, isExperimentHide: true, diff --git a/todo.txt b/todo.txt index eafe9ad..2f63a7f 100644 --- a/todo.txt +++ b/todo.txt @@ -1,28 +1,16 @@ ******************************************************** NEXT PATCH ******************************************************** -new laserBombingBoss - I didn't do any difficulty testing, so maybe let me know if it's too easy +relativistic momentum: laser pushes harder and slows mobs a bit to give a more predictable effect +laserBombingBoss targets faster at higher levels +you can now block shielded mobs, but your shield gets disabled for a bit -laser and plasma bots will target mobs bullets -non updating health bar bug fix +fixed bug that made perfect diamagnetism have trouble blocking too many things at once +and more small bug fixes, of course ******************************************************** TODO ******************************************************** mob: spawning seekers on death -"Lazer pulser Boss" -Basically the blue lazer boss, but it has another color -Instead of shooting one current stream of lasers, the laser is completely harmless -If the boss focused the Lazer on the player for a certain amount of time, it'll glow brightly and send a fast, explosive pulse down the Lazer beam -The harmless lazer beam serves like a sniper's lazer scope - -laser damage seems low based on 2 runs - history is low damage - -buff laser push tech - push like plasma? - push harder - drones can combine with other drones to get bigger? drones that grab powers ups can grab more then one and get even bigger each time