diff --git a/.DS_Store b/.DS_Store index 2c071c3..d106e0e 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/js/bullet.js b/js/bullet.js index 09ced4f..1266d0b 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -1272,66 +1272,64 @@ const b = { } }, do() { - if (!m.isBodiesAsleep) { - this.cycle++ - // if (this.cycle > 40) { - // this.frictionAir = 0.003 - // this.do = this.doNoTargeting - // } - // if (closest.target) { //rotate towards the target - const face = { x: Math.cos(this.angle), y: Math.sin(this.angle) }; - const vectorGoal = Vector.normalise(Vector.sub(this.position, closest.position)); - const cross = Vector.cross(vectorGoal, face) - if (cross > 0.01) { - Matter.Body.rotate(this, this.turnRate * Math.sqrt(cross)); - } else if (cross < 0.01) { - Matter.Body.rotate(this, -this.turnRate * Math.sqrt(Math.abs(cross))); - } - this.force.x += this.thrustMag * this.mass * Math.cos(this.angle); - this.force.y += this.thrustMag * this.mass * Math.sin(this.angle); - // } - if (Matter.Query.collides(this, map).length) { //stick in walls - this.collisionFilter.mask = 0; - Matter.Body.setAngularVelocity(this, 0) - Matter.Body.setVelocity(this, { - x: 0, - y: 0 - }); - this.do = this.doNoTargeting - } - // else if (!(this.cycle % 2)) { //look for a target if you don't have one - // simulation.drawList.push({ //add dmg to draw queue - // x: this.position.x, - // y: this.position.y, - // radius: 10, - // color: simulation.mobDmgColor, - // time: simulation.drawTime - // }); - // let closest = { - // distance: 2000, - // target: null - // } - // const dir = Vector.normalise(this.velocity) //make a vector for direction of length 1 - // for (let i = 0, len = mob.length; i < len; ++i) { - // if ( - // mob[i].alive && !mob[i].isBadTarget && - // Matter.Query.ray(map, this.position, mob[i].position).length === 0 && //check for map in Line of sight - // Vector.dot(dir, Vector.normalise(Vector.sub(mob[i].position, this.position))) > 0.55 //the dot product of diff and dir will return how much over lap between the vectors - // ) { - // const dist = Vector.magnitude(Vector.sub(this.position, mob[i].position)) - // if (dist < closest.distance) { - // closest.distance = dist - // closest.target = mob[i] - // } - // } - // } - // if (closest.target) { - // target = closest.target - // this.turnRate = 0.05 - // this.frictionAir = 0.8 - // } - // } + this.cycle++ + // if (this.cycle > 40) { + // this.frictionAir = 0.003 + // this.do = this.doNoTargeting + // } + // if (closest.target) { //rotate towards the target + const face = { x: Math.cos(this.angle), y: Math.sin(this.angle) }; + const vectorGoal = Vector.normalise(Vector.sub(this.position, closest.position)); + const cross = Vector.cross(vectorGoal, face) + if (cross > 0.01) { + Matter.Body.rotate(this, this.turnRate * Math.sqrt(cross)); + } else if (cross < 0.01) { + Matter.Body.rotate(this, -this.turnRate * Math.sqrt(Math.abs(cross))); } + this.force.x += this.thrustMag * this.mass * Math.cos(this.angle); + this.force.y += this.thrustMag * this.mass * Math.sin(this.angle); + // } + if (Matter.Query.collides(this, map).length) { //stick in walls + this.collisionFilter.mask = 0; + Matter.Body.setAngularVelocity(this, 0) + Matter.Body.setVelocity(this, { + x: 0, + y: 0 + }); + this.do = this.doNoTargeting + } + // else if (!(this.cycle % 2)) { //look for a target if you don't have one + // simulation.drawList.push({ //add dmg to draw queue + // x: this.position.x, + // y: this.position.y, + // radius: 10, + // color: simulation.mobDmgColor, + // time: simulation.drawTime + // }); + // let closest = { + // distance: 2000, + // target: null + // } + // const dir = Vector.normalise(this.velocity) //make a vector for direction of length 1 + // for (let i = 0, len = mob.length; i < len; ++i) { + // if ( + // mob[i].alive && !mob[i].isBadTarget && + // Matter.Query.ray(map, this.position, mob[i].position).length === 0 && //check for map in Line of sight + // Vector.dot(dir, Vector.normalise(Vector.sub(mob[i].position, this.position))) > 0.55 //the dot product of diff and dir will return how much over lap between the vectors + // ) { + // const dist = Vector.magnitude(Vector.sub(this.position, mob[i].position)) + // if (dist < closest.distance) { + // closest.distance = dist + // closest.target = mob[i] + // } + // } + // } + // if (closest.target) { + // target = closest.target + // this.turnRate = 0.05 + // this.frictionAir = 0.8 + // } + // } }, }); Matter.Body.setVelocity(bullet[me], { @@ -1470,7 +1468,7 @@ const b = { } } } else { - if (m.energy > 0.005 && !m.isBodiesAsleep) m.energy -= 0.005 + if (m.energy > 0.005) m.energy -= 0.005 const sub = Vector.sub(this.position, m.pos) const rangeScale = 1 + 0.000001 * Vector.magnitude(sub) * Vector.magnitude(sub) //return faster when far from player const returnForce = Vector.mult(Vector.normalise(sub), rangeScale * this.thrustMag * this.mass) @@ -1503,80 +1501,78 @@ const b = { } }, do() { - if (!m.isBodiesAsleep) { - this.cycle++ - if (isReturn) { - if (this.cycle > totalCycles) { - if (m.energy < 0.05) { //snap rope if not enough energy - const returnForce = Vector.mult(Vector.normalise(Vector.sub(this.position, m.pos)), 3 * this.thrustMag * this.mass) - this.force.x -= returnForce.x - this.force.y -= returnForce.y - this.frictionAir = 0.002 - this.do = () => { this.force.y += this.mass * 0.001; } - this.dropCaughtPowerUp() - } else { //return to player - this.do = this.returnToPlayer - Matter.Body.setDensity(this, 0.0005); //reduce density on return - if (this.angularSpeed < 0.5) this.torque += this.inertia * 0.001 * (Math.random() - 0.5) //(Math.round(Math.random()) ? 1 : -1) - this.collisionFilter.mask = cat.map | cat.mob | cat.mobBullet | cat.mobShield // | cat.body - } - } else { - this.grabPowerUp() + this.cycle++ + if (isReturn) { + if (this.cycle > totalCycles) { + if (m.energy < 0.05) { //snap rope if not enough energy + const returnForce = Vector.mult(Vector.normalise(Vector.sub(this.position, m.pos)), 3 * this.thrustMag * this.mass) + this.force.x -= returnForce.x + this.force.y -= returnForce.y + this.frictionAir = 0.002 + this.do = () => { this.force.y += this.mass * 0.001; } + this.dropCaughtPowerUp() + } else { //return to player + this.do = this.returnToPlayer + Matter.Body.setDensity(this, 0.0005); //reduce density on return + if (this.angularSpeed < 0.5) this.torque += this.inertia * 0.001 * (Math.random() - 0.5) //(Math.round(Math.random()) ? 1 : -1) + this.collisionFilter.mask = cat.map | cat.mob | cat.mobBullet | cat.mobShield // | cat.body } - } else if (this.cycle > 30) { - this.frictionAir = 0.003 - this.do = () => { this.force.y += this.mass * 0.003; } + } else { + this.grabPowerUp() } - - if (target) { //rotate towards the target - const face = { - x: Math.cos(this.angle), - y: Math.sin(this.angle) - }; - const vectorGoal = Vector.normalise(Vector.sub(this.position, target.position)); - if (Vector.cross(vectorGoal, face) > 0) { - Matter.Body.rotate(this, this.turnRate); - } else { - Matter.Body.rotate(this, -this.turnRate); - } - } - if (isReturn || target) { - this.force.x += this.thrustMag * this.mass * Math.cos(this.angle); - this.force.y += this.thrustMag * this.mass * Math.sin(this.angle); - } - // else if (!(this.cycle % 2)) { //look for a target if you don't have one - // simulation.drawList.push({ //add dmg to draw queue - // x: this.position.x, - // y: this.position.y, - // radius: 10, - // color: simulation.mobDmgColor, - // time: simulation.drawTime - // }); - // let closest = { - // distance: 2000, - // target: null - // } - // const dir = Vector.normalise(this.velocity) //make a vector for direction of length 1 - // for (let i = 0, len = mob.length; i < len; ++i) { - // if ( - // mob[i].alive && !mob[i].isBadTarget && - // Matter.Query.ray(map, this.position, mob[i].position).length === 0 && //check for map in Line of sight - // Vector.dot(dir, Vector.normalise(Vector.sub(mob[i].position, this.position))) > 0.55 //the dot product of diff and dir will return how much over lap between the vectors - // ) { - // const dist = Vector.magnitude(Vector.sub(this.position, mob[i].position)) - // if (dist < closest.distance) { - // closest.distance = dist - // closest.target = mob[i] - // } - // } - // } - // if (closest.target) { - // target = closest.target - // this.turnRate = 0.05 - // this.frictionAir = 0.8 - // } - // } + } else if (this.cycle > 30) { + this.frictionAir = 0.003 + this.do = () => { this.force.y += this.mass * 0.003; } } + + if (target) { //rotate towards the target + const face = { + x: Math.cos(this.angle), + y: Math.sin(this.angle) + }; + const vectorGoal = Vector.normalise(Vector.sub(this.position, target.position)); + if (Vector.cross(vectorGoal, face) > 0) { + Matter.Body.rotate(this, this.turnRate); + } else { + Matter.Body.rotate(this, -this.turnRate); + } + } + if (isReturn || target) { + this.force.x += this.thrustMag * this.mass * Math.cos(this.angle); + this.force.y += this.thrustMag * this.mass * Math.sin(this.angle); + } + // else if (!(this.cycle % 2)) { //look for a target if you don't have one + // simulation.drawList.push({ //add dmg to draw queue + // x: this.position.x, + // y: this.position.y, + // radius: 10, + // color: simulation.mobDmgColor, + // time: simulation.drawTime + // }); + // let closest = { + // distance: 2000, + // target: null + // } + // const dir = Vector.normalise(this.velocity) //make a vector for direction of length 1 + // for (let i = 0, len = mob.length; i < len; ++i) { + // if ( + // mob[i].alive && !mob[i].isBadTarget && + // Matter.Query.ray(map, this.position, mob[i].position).length === 0 && //check for map in Line of sight + // Vector.dot(dir, Vector.normalise(Vector.sub(mob[i].position, this.position))) > 0.55 //the dot product of diff and dir will return how much over lap between the vectors + // ) { + // const dist = Vector.magnitude(Vector.sub(this.position, mob[i].position)) + // if (dist < closest.distance) { + // closest.distance = dist + // closest.target = mob[i] + // } + // } + // } + // if (closest.target) { + // target = closest.target + // this.turnRate = 0.05 + // this.frictionAir = 0.8 + // } + // } this.draw() }, }); @@ -1608,48 +1604,6 @@ const b = { } } Composite.add(engine.world, bullet[me]); //add bullet to world - - /* todo - despawn - when player gets far away? - set time - release mouse? - - */ - // if (true && input.down) { - // Matter.Body.setVelocity(bullet[me], { - // x: m.Vx / 2 + 70 * Math.cos(bullet[me].angle), - // y: m.Vy / 2 + 70 * Math.sin(bullet[me].angle) - // }); - // bullet[me].frictionAir = 0.0011 - // bullet[me].endCycle = simulation.cycle + Infinity - // bullet[me].do = function() { - // if (!m.isBodiesAsleep) { - // this.cycle++ - // if (Matter.Query.collides(this, map).length) { - // // this.collisionFilter.mask = 0; //non collide with everything - // this.collisionFilter.category = cat.map - // this.collisionFilter.mask = cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet; - - // Matter.Body.setPosition(this, Vector.add(this.position, Vector.mult(Vector.normalise(this.lastVelocity), 30))) //move a bit into the wall - // Matter.Body.setVelocity(this, { x: 0, y: 0 }); - // Matter.Body.setStatic(this, true) //don't set to static if not touching map - - // Matter.Body.setAngularVelocity(this, 0) - // const unit = Vector.normalise(Vector.sub({ x: this.position.x, y: this.position.y - 150 }, player.position)) - // const push = Vector.mult(unit, 1) - // player.force.x += push.x - // player.force.y += push.y - // //pull player back in - // this.do = () => { - - // } - // } - // this.lastVelocity = { x: this.velocity.x, y: this.velocity.y } - // } - // this.drawString() - // } - // } }, missile(where, angle, speed, size = 1) { if (tech.missileSize) size *= 1.5 @@ -1709,43 +1663,33 @@ const b = { } }, do() { - if (!m.isBodiesAsleep) { - if (!(m.cycle % this.lookFrequency)) this.tryToLockOn(); - if (this.lockedOn) { //rotate missile towards the target - const face = { - x: Math.cos(this.angle), - y: Math.sin(this.angle) - }; - const target = Vector.normalise(Vector.sub(this.position, this.lockedOn.position)); - const dot = Vector.dot(target, face) - const aim = Math.min(0.08, (1 + dot) * 1) - if (Vector.cross(target, face) > 0) { - Matter.Body.rotate(this, aim); - } else { - Matter.Body.rotate(this, -aim); - } - this.frictionAir = Math.min(0.1, Math.max(0.04, 1 + dot)) //0.08; //extra friction if turning + if (!(m.cycle % this.lookFrequency)) this.tryToLockOn(); + if (this.lockedOn) { //rotate missile towards the target + const face = { + x: Math.cos(this.angle), + y: Math.sin(this.angle) + }; + const target = Vector.normalise(Vector.sub(this.position, this.lockedOn.position)); + const dot = Vector.dot(target, face) + const aim = Math.min(0.08, (1 + dot) * 1) + if (Vector.cross(target, face) > 0) { + Matter.Body.rotate(this, aim); + } else { + Matter.Body.rotate(this, -aim); } - //accelerate in direction bullet is facing - const dir = this.angle; - this.force.x += thrust * Math.cos(dir); - this.force.y += thrust * Math.sin(dir); - - ctx.beginPath(); //draw rocket - ctx.arc(this.position.x - Math.cos(this.angle) * (25 * size - 3) + (Math.random() - 0.5) * 4, - this.position.y - Math.sin(this.angle) * (25 * size - 3) + (Math.random() - 0.5) * 4, - 11 * size, 0, 2 * Math.PI); - ctx.fillStyle = "rgba(255,155,0,0.5)"; - ctx.fill(); - } else { - //draw rocket with time stop - ctx.beginPath(); - ctx.arc(this.position.x - Math.cos(this.angle) * (30 * size - 3) + (Math.random() - 0.5) * 4, - this.position.y - Math.sin(this.angle) * (30 * size - 3) + (Math.random() - 0.5) * 4, - 2 + 9 * size, 0, 2 * Math.PI); - ctx.fillStyle = "rgba(255,155,0,0.5)"; - ctx.fill(); + this.frictionAir = Math.min(0.1, Math.max(0.04, 1 + dot)) //0.08; //extra friction if turning } + //accelerate in direction bullet is facing + const dir = this.angle; + this.force.x += thrust * Math.cos(dir); + this.force.y += thrust * Math.sin(dir); + + ctx.beginPath(); //draw rocket + ctx.arc(this.position.x - Math.cos(this.angle) * (25 * size - 3) + (Math.random() - 0.5) * 4, + this.position.y - Math.sin(this.angle) * (25 * size - 3) + (Math.random() - 0.5) * 4, + 11 * size, 0, 2 * Math.PI); + ctx.fillStyle = "rgba(255,155,0,0.5)"; + ctx.fill(); }, }); const thrust = 0.0066 * bullet[me].mass * (tech.missileSize ? 0.6 : 1); @@ -1793,30 +1737,28 @@ const b = { beforeDmg() {}, onEnd() {}, do() { - if (!m.isBodiesAsleep) { - if (this.endCycle < simulation.cycle + 1) this.isWave = false - if (Matter.Query.point(map, this.position).length) { //check if inside map - this.isBranch = true; - this.do = () => { if (this.endCycle < simulation.cycle + 1) this.isWave = false } - } else { //check if inside a body - for (let i = 0, len = mob.length; i < len; i++) { - const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)) - const radius = mob[i].radius + tech.extruderRange / 2 - if (dist < radius * radius) { - Matter.Body.setVelocity(mob[i], { x: mob[i].velocity.x * 0.25, y: mob[i].velocity.y * 0.25 }); - Matter.Body.setPosition(this, Vector.add(this.position, mob[i].velocity)) //move with the medium - let dmg = this.dmg / Math.min(10, mob[i].mass) - mob[i].damage(dmg); - if (mob[i].alive) mob[i].foundPlayer(); - } + if (this.endCycle < simulation.cycle + 1) this.isWave = false + if (Matter.Query.point(map, this.position).length) { //check if inside map + this.isBranch = true; + this.do = () => { if (this.endCycle < simulation.cycle + 1) this.isWave = false } + } else { //check if inside a body + for (let i = 0, len = mob.length; i < len; i++) { + const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)) + const radius = mob[i].radius + tech.extruderRange / 2 + if (dist < radius * radius) { + Matter.Body.setVelocity(mob[i], { x: mob[i].velocity.x * 0.25, y: mob[i].velocity.y * 0.25 }); + Matter.Body.setPosition(this, Vector.add(this.position, mob[i].velocity)) //move with the medium + let dmg = this.dmg / Math.min(10, mob[i].mass) + mob[i].damage(dmg); + if (mob[i].alive) mob[i].foundPlayer(); } } - this.cycle++ - const wiggleMag = (input.down ? 6 : 12) * Math.cos(simulation.cycle * 0.09) - const wiggle = Vector.mult(transverse, wiggleMag * Math.cos(this.cycle * 0.36)) //+ wiggleMag * Math.cos(simulation.cycle * 0.3)) - const velocity = Vector.mult(player.velocity, 0.4) //move with player - Matter.Body.setPosition(this, Vector.add(velocity, Vector.add(this.position, wiggle))) } + this.cycle++ + const wiggleMag = (input.down ? 6 : 12) * Math.cos(simulation.cycle * 0.09) + const wiggle = Vector.mult(transverse, wiggleMag * Math.cos(this.cycle * 0.36)) //+ wiggleMag * Math.cos(simulation.cycle * 0.3)) + const velocity = Vector.mult(player.velocity, 0.4) //move with player + Matter.Body.setPosition(this, Vector.add(velocity, Vector.add(this.position, wiggle))) } }); Composite.add(engine.world, bullet[me]); //add bullet to world @@ -2290,7 +2232,7 @@ const b = { } } } else { - if (this.speed < 1 && this.angularSpeed < 0.01 && !m.isBodiesAsleep) this.stillCount++ + if (this.speed < 1 && this.angularSpeed < 0.01) this.stillCount++ } if (this.stillCount > 25) this.arm(); }, @@ -2326,7 +2268,7 @@ const b = { this.endCycle = simulation.cycle + 1020 this.do = function() { //overwrite the do method for this bullet this.force.y += this.mass * 0.002; //extra gravity - if (!(simulation.cycle % this.lookFrequency) && !m.isBodiesAsleep) { //find mob targets + if (!(simulation.cycle % this.lookFrequency)) { //find mob targets b.targetedNail(this.position, 1, 45 + 5 * Math.random(), 1100, false, 2.3) //targetedNail(position, num = 1, speed = 40 + 10 * Math.random(), range = 1200, isRandomAim = true, damage = 1.4) { if (!(simulation.cycle % (this.lookFrequency * 6))) { simulation.drawList.push({ @@ -3136,104 +3078,102 @@ const b = { }, onEnd() {}, do() { - if (!m.isBodiesAsleep) { //if time dilation isn't active - if (this.count < 20) { - this.count++ - //grow - const SCALE = 1.06 + if (this.count < 20) { + this.count++ + //grow + const SCALE = 1.06 + Matter.Body.scale(this, SCALE, SCALE); + this.radius *= SCALE; + } else { + //shrink + Matter.Body.scale(this, this.scale, this.scale); + this.radius *= this.scale; + if (this.radius < 8) this.endCycle = 0; + } + if (this.target && this.target.alive) { //if stuck to a target + const rotate = Vector.rotate(this.targetRelativePosition, this.target.angle) //add in the mob's new angle to the relative position vector + if (this.target.isVerticesChange) { + Matter.Body.setPosition(this, this.target.vertices[this.targetVertex]) + } else { + Matter.Body.setPosition(this, Vector.add(Vector.add(rotate, this.target.velocity), this.target.position)) + } + Matter.Body.setVelocity(this.target, Vector.mult(this.target.velocity, 0.9)) + Matter.Body.setAngularVelocity(this.target, this.target.angularVelocity * 0.9); + // Matter.Body.setAngularVelocity(this.target, this.target.angularVelocity * 0.9) + if (this.target.isShielded) { + this.target.damage(b.dmgScale * this.damage, true); //shield damage bypass + const SCALE = 1 - 0.004 / tech.isBulletsLastLonger //shrink if mob is shielded Matter.Body.scale(this, SCALE, SCALE); this.radius *= SCALE; } else { - //shrink - Matter.Body.scale(this, this.scale, this.scale); - this.radius *= this.scale; - if (this.radius < 8) this.endCycle = 0; + this.target.damage(b.dmgScale * this.damage); } - if (this.target && this.target.alive) { //if stuck to a target - const rotate = Vector.rotate(this.targetRelativePosition, this.target.angle) //add in the mob's new angle to the relative position vector - if (this.target.isVerticesChange) { - Matter.Body.setPosition(this, this.target.vertices[this.targetVertex]) - } else { - Matter.Body.setPosition(this, Vector.add(Vector.add(rotate, this.target.velocity), this.target.position)) + } else if (this.target !== null) { //look for a new target + this.target = null + this.collisionFilter.category = cat.bullet; + this.collisionFilter.mask = cat.mob //| cat.mobShield //cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield + if (tech.isFoamGrowOnDeath && bullet.length < 180) { + let targets = [] + for (let i = 0, len = mob.length; i < len; i++) { + const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)); + if (dist < 1000000) targets.push(mob[i]) } - Matter.Body.setVelocity(this.target, Vector.mult(this.target.velocity, 0.9)) - Matter.Body.setAngularVelocity(this.target, this.target.angularVelocity * 0.9); - // Matter.Body.setAngularVelocity(this.target, this.target.angularVelocity * 0.9) - if (this.target.isShielded) { - this.target.damage(b.dmgScale * this.damage, true); //shield damage bypass - const SCALE = 1 - 0.004 / tech.isBulletsLastLonger //shrink if mob is shielded - Matter.Body.scale(this, SCALE, SCALE); - this.radius *= SCALE; - } else { - this.target.damage(b.dmgScale * this.damage); - } - } else if (this.target !== null) { //look for a new target - this.target = null - this.collisionFilter.category = cat.bullet; - this.collisionFilter.mask = cat.mob //| cat.mobShield //cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield - if (tech.isFoamGrowOnDeath && bullet.length < 180) { - let targets = [] - for (let i = 0, len = mob.length; i < len; i++) { - const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)); - if (dist < 1000000) targets.push(mob[i]) - } - const radius = Math.min(this.radius * 0.5, 9) - const len = bullet.length < 80 ? 2 : 1 - for (let i = 0; i < len; i++) { - if (targets.length - i > 0) { - const index = Math.floor(Math.random() * targets.length) - const speed = 6 + 6 * Math.random() - const velocity = Vector.mult(Vector.normalise(Vector.sub(targets[index].position, this.position)), speed) - b.foam(this.position, Vector.rotate(velocity, 0.5 * (Math.random() - 0.5)), radius) - } else { - b.foam(this.position, Vector.rotate({ - x: 15 + 10 * Math.random(), - y: 0 - }, 2 * Math.PI * Math.random()), radius) - } - } - } - } else if (Matter.Query.point(map, this.position).length > 0) { //slow when touching map or blocks - const slow = 0.85 - Matter.Body.setVelocity(this, { - x: this.velocity.x * slow, - y: this.velocity.y * slow - }); - const SCALE = 0.96 - Matter.Body.scale(this, SCALE, SCALE); - this.radius *= SCALE; - // } else if (Matter.Query.collides(this, body).length > 0) { - } else if (Matter.Query.point(body, this.position).length > 0) { - const slow = 0.9 - Matter.Body.setVelocity(this, { - x: this.velocity.x * slow, - y: this.velocity.y * slow - }); - const SCALE = 0.96 - Matter.Body.scale(this, SCALE, SCALE); - this.radius *= SCALE; - } else { - this.force.y += this.mass * tech.foamGravity; //gravity - if (tech.isFoamAttract) { - for (let i = 0, len = mob.length; i < len; i++) { - if (!mob[i].isBadTarget && Vector.magnitude(Vector.sub(mob[i].position, this.position)) < 375 && mob[i].alive && Matter.Query.ray(map, this.position, mob[i].position).length === 0) { - this.force = Vector.mult(Vector.normalise(Vector.sub(mob[i].position, this.position)), this.mass * 0.004) - const slow = 0.9 - Matter.Body.setVelocity(this, { - x: this.velocity.x * slow, - y: this.velocity.y * slow - }); - break - } + const radius = Math.min(this.radius * 0.5, 9) + const len = bullet.length < 80 ? 2 : 1 + for (let i = 0; i < len; i++) { + if (targets.length - i > 0) { + const index = Math.floor(Math.random() * targets.length) + const speed = 6 + 6 * Math.random() + const velocity = Vector.mult(Vector.normalise(Vector.sub(targets[index].position, this.position)), speed) + b.foam(this.position, Vector.rotate(velocity, 0.5 * (Math.random() - 0.5)), radius) + } else { + b.foam(this.position, Vector.rotate({ + x: 15 + 10 * Math.random(), + y: 0 + }, 2 * Math.PI * Math.random()), radius) } } } - if (this.nextPortCycle < simulation.cycle) { //teleport around if you have tech.isBulletTeleport - this.nextPortCycle = simulation.cycle + this.portFrequency - const range = 15 * Math.sqrt(this.radius) * Math.random() - Matter.Body.setPosition(this, Vector.add(this.position, Vector.rotate({ x: range, y: 0 }, 2 * Math.PI * Math.random()))) + } else if (Matter.Query.point(map, this.position).length > 0) { //slow when touching map or blocks + const slow = 0.85 + Matter.Body.setVelocity(this, { + x: this.velocity.x * slow, + y: this.velocity.y * slow + }); + const SCALE = 0.96 + Matter.Body.scale(this, SCALE, SCALE); + this.radius *= SCALE; + // } else if (Matter.Query.collides(this, body).length > 0) { + } else if (Matter.Query.point(body, this.position).length > 0) { + const slow = 0.9 + Matter.Body.setVelocity(this, { + x: this.velocity.x * slow, + y: this.velocity.y * slow + }); + const SCALE = 0.96 + Matter.Body.scale(this, SCALE, SCALE); + this.radius *= SCALE; + } else { + this.force.y += this.mass * tech.foamGravity; //gravity + if (tech.isFoamAttract) { + for (let i = 0, len = mob.length; i < len; i++) { + if (!mob[i].isBadTarget && Vector.magnitude(Vector.sub(mob[i].position, this.position)) < 375 && mob[i].alive && Matter.Query.ray(map, this.position, mob[i].position).length === 0) { + this.force = Vector.mult(Vector.normalise(Vector.sub(mob[i].position, this.position)), this.mass * 0.004) + const slow = 0.9 + Matter.Body.setVelocity(this, { + x: this.velocity.x * slow, + y: this.velocity.y * slow + }); + break + } + } } } + if (this.nextPortCycle < simulation.cycle) { //teleport around if you have tech.isBulletTeleport + this.nextPortCycle = simulation.cycle + this.portFrequency + const range = 15 * Math.sqrt(this.radius) * Math.random() + Matter.Body.setPosition(this, Vector.add(this.position, Vector.rotate({ x: range, y: 0 }, 2 * Math.PI * Math.random()))) + } } }); if (tech.isBulletTeleport) bullet[me].nextPortCycle = simulation.cycle + bullet[me].portFrequency @@ -3318,57 +3258,55 @@ const b = { // bullet[me].turnRate = 0.005 * (Math.random() - 0.5) bullet[me].isInMap = false bullet[me].do = function() { - if (!m.isBodiesAsleep) { - const whom = Matter.Query.collides(this, mob) - if (whom.length && this.speed > 20) { //if touching a mob - for (let i = 0, len = whom.length; i < len; i++) { - who = whom[i].bodyA - if (who && who.mob) { - let immune = false - for (let i = 0; i < this.immuneList.length; i++) { //check if this needle has hit this mob already - if (this.immuneList[i] === who.id) { - immune = true - break - } + const whom = Matter.Query.collides(this, mob) + if (whom.length && this.speed > 20) { //if touching a mob + for (let i = 0, len = whom.length; i < len; i++) { + who = whom[i].bodyA + if (who && who.mob) { + let immune = false + for (let i = 0; i < this.immuneList.length; i++) { //check if this needle has hit this mob already + if (this.immuneList[i] === who.id) { + immune = true + break } - if (!immune) { - if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.94) { - b.explosion(this.position, 220 * tech.nailSize + 50 * Math.random()); //makes bullet do explosive damage at end - } - this.immuneList.push(who.id) //remember that this needle has hit this mob once already - let dmg = this.dmg * tech.nailSize * b.dmgScale - if (tech.isNailRadiation) { - mobs.statusDoT(who, (tech.isFastRadiation ? 6 : 2) * tech.nailSize, tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles - dmg *= 0.25 - } - if (tech.isCrit && who.isStunned) dmg *= 4 - who.damage(dmg, tech.isShieldPierce); - if (who.alive) who.foundPlayer(); - if (who.damageReduction) { - simulation.drawList.push({ //add dmg to draw queue - x: this.position.x, - y: this.position.y, - radius: Math.log(dmg + 1.1) * 40 * who.damageReduction + 3, - color: simulation.playerDmgColor, - time: simulation.drawTime - }); - } + } + if (!immune) { + if (tech.isNailCrit && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.94) { + b.explosion(this.position, 220 * tech.nailSize + 50 * Math.random()); //makes bullet do explosive damage at end + } + this.immuneList.push(who.id) //remember that this needle has hit this mob once already + let dmg = this.dmg * tech.nailSize * b.dmgScale + if (tech.isNailRadiation) { + mobs.statusDoT(who, (tech.isFastRadiation ? 6 : 2) * tech.nailSize, tech.isSlowRadiation ? 360 : (tech.isFastRadiation ? 60 : 180)) // one tick every 30 cycles + dmg *= 0.25 + } + if (tech.isCrit && who.isStunned) dmg *= 4 + who.damage(dmg, tech.isShieldPierce); + if (who.alive) who.foundPlayer(); + if (who.damageReduction) { + simulation.drawList.push({ //add dmg to draw queue + x: this.position.x, + y: this.position.y, + radius: Math.log(dmg + 1.1) * 40 * who.damageReduction + 3, + color: simulation.playerDmgColor, + time: simulation.drawTime + }); } } } - } else if (Matter.Query.collides(this, map).length) { //penetrate walls - if (!this.isInMap) { //turn after entering the map, but only turn once - this.isInMap = true - Matter.Body.setVelocity(this, Vector.rotate(this.velocity, 0.25 * (Math.random() - 0.5))); - Matter.Body.setAngle(this, Math.atan2(this.velocity.y, this.velocity.x)) - } - Matter.Body.setPosition(this, Vector.add(this.position, Vector.mult(this.velocity, -0.98))) //move back 1/2 your velocity = moving at 1/2 speed - } else if (Matter.Query.collides(this, body).length) { //penetrate blocks - Matter.Body.setAngularVelocity(this, 0) - Matter.Body.setPosition(this, Vector.add(this.position, Vector.mult(this.velocity, -0.94))) //move back 1/2 your velocity = moving at 1/2 speed - } else if (this.speed < 30) { - this.force.y += this.mass * 0.001; //no gravity until it slows down to improve aiming } + } else if (Matter.Query.collides(this, map).length) { //penetrate walls + if (!this.isInMap) { //turn after entering the map, but only turn once + this.isInMap = true + Matter.Body.setVelocity(this, Vector.rotate(this.velocity, 0.25 * (Math.random() - 0.5))); + Matter.Body.setAngle(this, Math.atan2(this.velocity.y, this.velocity.x)) + } + Matter.Body.setPosition(this, Vector.add(this.position, Vector.mult(this.velocity, -0.98))) //move back 1/2 your velocity = moving at 1/2 speed + } else if (Matter.Query.collides(this, body).length) { //penetrate blocks + Matter.Body.setAngularVelocity(this, 0) + Matter.Body.setPosition(this, Vector.add(this.position, Vector.mult(this.velocity, -0.94))) //move back 1/2 your velocity = moving at 1/2 speed + } else if (this.speed < 30) { + this.force.y += this.mass * 0.001; //no gravity until it slows down to improve aiming } }; } else { @@ -3630,68 +3568,66 @@ const b = { // } //check for damage - if (!m.isBodiesAsleep) { - if (m.immuneCycle < m.cycle && !((m.cycle + this.phase) % 30)) { //twice a second - if (Vector.magnitude(Vector.sub(this.position, player.position)) < 250 && m.immuneCycle < m.cycle) { //give energy - Matter.Body.setAngularVelocity(this, this.spin) - if (this.isUpgraded) { - m.energy += 0.115 - simulation.drawList.push({ //add dmg to draw queue - x: this.position.x, - y: this.position.y, - radius: 10, - color: m.fieldMeterColor, - time: simulation.drawTime - }); - } else { - m.energy += 0.035 - simulation.drawList.push({ //add dmg to draw queue - x: this.position.x, - y: this.position.y, - radius: 5, - color: m.fieldMeterColor, - time: simulation.drawTime - }); - } + if (m.immuneCycle < m.cycle && !((m.cycle + this.phase) % 30)) { //twice a second + if (Vector.magnitude(Vector.sub(this.position, player.position)) < 250 && m.immuneCycle < m.cycle) { //give energy + Matter.Body.setAngularVelocity(this, this.spin) + if (this.isUpgraded) { + m.energy += 0.115 + simulation.drawList.push({ //add dmg to draw queue + x: this.position.x, + y: this.position.y, + radius: 10, + color: m.fieldMeterColor, + time: simulation.drawTime + }); + } else { + m.energy += 0.035 + simulation.drawList.push({ //add dmg to draw queue + x: this.position.x, + y: this.position.y, + radius: 5, + color: m.fieldMeterColor, + time: simulation.drawTime + }); } } - - if (!m.isCloak) { //if time dilation isn't active - const size = 33 - q = Matter.Query.region(mob, { - min: { - x: this.position.x - size, - y: this.position.y - size - }, - max: { - x: this.position.x + size, - y: this.position.y + size - } - }) - for (let i = 0; i < q.length; i++) { - if (!q[i].isShielded) { - Matter.Body.setAngularVelocity(this, this.spin) - // mobs.statusStun(q[i], 180) - // const dmg = 0.5 * b.dmgScale * (this.isUpgraded ? 2.5 : 1) - const dmg = 0.5 * b.dmgScale - q[i].damage(dmg); - if (q[i].alive) q[i].foundPlayer(); - if (q[i].damageReduction) { - simulation.drawList.push({ //add dmg to draw queue - x: this.position.x, - y: this.position.y, - // radius: 600 * dmg * q[i].damageReduction, - radius: Math.sqrt(2000 * dmg * q[i].damageReduction) + 2, - color: 'rgba(0,0,0,0.4)', - time: simulation.drawTime - }); - } - } - } - } - let history = m.history[(m.cycle - this.followDelay) % 600] - Matter.Body.setPosition(this, { x: history.position.x, y: history.position.y - history.yOff + 24.2859 }) //bullets move with player } + + if (!m.isCloak) { //if time dilation isn't active + const size = 33 + q = Matter.Query.region(mob, { + min: { + x: this.position.x - size, + y: this.position.y - size + }, + max: { + x: this.position.x + size, + y: this.position.y + size + } + }) + for (let i = 0; i < q.length; i++) { + if (!q[i].isShielded) { + Matter.Body.setAngularVelocity(this, this.spin) + // mobs.statusStun(q[i], 180) + // const dmg = 0.5 * b.dmgScale * (this.isUpgraded ? 2.5 : 1) + const dmg = 0.5 * b.dmgScale + q[i].damage(dmg); + if (q[i].alive) q[i].foundPlayer(); + if (q[i].damageReduction) { + simulation.drawList.push({ //add dmg to draw queue + x: this.position.x, + y: this.position.y, + // radius: 600 * dmg * q[i].damageReduction, + radius: Math.sqrt(2000 * dmg * q[i].damageReduction) + 2, + color: 'rgba(0,0,0,0.4)', + time: simulation.drawTime + }); + } + } + } + } + let history = m.history[(m.cycle - this.followDelay) % 600] + Matter.Body.setPosition(this, { x: history.position.x, y: history.position.y - history.yOff + 24.2859 }) //bullets move with player } }) Composite.add(engine.world, bullet[me]); //add bullet to world @@ -4317,7 +4253,7 @@ const b = { orbitalSpeed: 0, phase: 2 * Math.PI * Math.random(), do() { - if (!m.isCloak && !m.isBodiesAsleep) { //if time dilation isn't active + if (!m.isCloak) { //if time dilation isn't active const size = 33 q = Matter.Query.region(mob, { min: { x: this.position.x - size, y: this.position.y - size }, @@ -4850,10 +4786,8 @@ const b = { // bullet[me].restitution = 0.4 bullet[me].frictionAir = 0.034; bullet[me].do = function() { - if (!m.isBodiesAsleep) { - const scale = 1 - 0.034 / tech.isBulletsLastLonger - Matter.Body.scale(this, scale, scale); - } + const scale = 1 - 0.034 / tech.isBulletsLastLonger + Matter.Body.scale(this, scale, scale); }; } } @@ -5016,62 +4950,56 @@ const b = { 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 (!m.isBodiesAsleep) { - - - 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)); - } - 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.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 } - } - for (let j = 0, len = 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) { - //make them shake around - body[j].force.x += 0.01 * (Math.random() - 0.5) * body[j].mass - body[j].force.y += (0.01 * (Math.random() - 0.5) - simulation.g * 0.25) * body[j].mass //remove force of gravity + 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 = body[j].vertices; - const vibe = 25 + 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)); } } - this.waves[i].radius += tech.waveBeamSpeed * this.waves[i].expanding //expand / move } + for (let j = 0, len = 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) { + //make them shake around + body[j].force.x += 0.01 * (Math.random() - 0.5) * body[j].mass + body[j].force.y += (0.01 * (Math.random() - 0.5) - simulation.g * 0.25) * body[j].mass //remove force of gravity + //draw vibes + let vertices = body[j].vertices; + const vibe = 25 + 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)); + } + } + this.waves[i].radius += 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) { this.waves[i].expanding = -1 @@ -5109,64 +5037,62 @@ const b = { 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 (!m.isBodiesAsleep) { - 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) } - } + 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) { - 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 - }); - 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)); - } - 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)); - } - } - - hits = Matter.Query.ray(body, 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 + } + 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) { who.force.x += 0.01 * (Math.random() - 0.5) * who.mass - who.force.y += (0.01 * (Math.random() - 0.5) - simulation.g * 0.25) * who.mass //remove force of gravity - + 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 + }); let vertices = who.vertices; - const vibe = 25 + 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)); } 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)); } - // ctx.stroke(); //draw vibes - - this.waves[i].radius += tech.waveBeamSpeed * 2 * this.waves[i].expanding //expand / move } + + hits = Matter.Query.ray(body, 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 + who.force.x += 0.01 * (Math.random() - 0.5) * who.mass + who.force.y += (0.01 * (Math.random() - 0.5) - simulation.g * 0.25) * who.mass //remove force of gravity + + let vertices = who.vertices; + const vibe = 25 + 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)); + } + ctx.lineTo(vertices[0].x + vibe * (Math.random() - 0.5), vertices[0].y + vibe * (Math.random() - 0.5)); + } + // ctx.stroke(); //draw vibes + + this.waves[i].radius += tech.waveBeamSpeed * 2 * this.waves[i].expanding //expand / move if (this.waves[i].radius > end) { this.waves[i].expanding = -1 this.waves[i].reflection-- @@ -5291,22 +5217,18 @@ const b = { if (tech.waveReflections) { bullet[me].reflectCycle = totalCycles / tech.waveReflections //tech.waveLengthRange bullet[me].do = function() { - if (!m.isBodiesAsleep) { - this.query() - if (this.cycle > this.reflectCycle) { - this.reflectCycle += totalCycles / tech.waveReflections - Matter.Body.setVelocity(this, Vector.mult(this.velocity, -1)); - // if (this.reflectCycle > tech.waveLengthRange * (1 + tech.waveReflections)) this.endCycle = 0; - } - this.wiggle() + this.query() + if (this.cycle > this.reflectCycle) { + this.reflectCycle += totalCycles / tech.waveReflections + Matter.Body.setVelocity(this, Vector.mult(this.velocity, -1)); + // if (this.reflectCycle > tech.waveLengthRange * (1 + tech.waveReflections)) this.endCycle = 0; } + this.wiggle() } } else { bullet[me].do = function() { - if (!m.isBodiesAsleep) { - this.query() - this.wiggle(); - } + this.query() + this.wiggle(); } } Composite.add(engine.world, bullet[me]); //add bullet to world @@ -5502,30 +5424,26 @@ const b = { ctx.arc(this.position.x, this.position.y, this.maxRadius, 0, 2 * Math.PI); ctx.fill(); } - bullet[me].grow = function() { this.stuck(); //runs different code based on what the bullet is stuck to - if (!m.isBodiesAsleep) { - let scale = 1.01 - if (tech.isSporeGrowth && !(simulation.cycle % 40)) { //release a spore - if (tech.isSporeWorm) { - if (!(simulation.cycle % 80)) b.worm(this.position) - } else { - b.spore(this.position) - } - // this.totalSpores-- - scale = 0.96 - if (this.stuckTo && this.stuckTo.alive) scale = 0.9 - Matter.Body.scale(this, scale, scale); - this.radius *= scale + let scale = 1.01 + if (tech.isSporeGrowth && !(simulation.cycle % 40)) { //release a spore + if (tech.isSporeWorm) { + if (!(simulation.cycle % 80)) b.worm(this.position) } else { - if (this.stuckTo && this.stuckTo.alive) scale = 1.03 - Matter.Body.scale(this, scale, scale); - this.radius *= scale - if (this.radius > this.maxRadius) this.endCycle = 0; + b.spore(this.position) } + // this.totalSpores-- + scale = 0.96 + if (this.stuckTo && this.stuckTo.alive) scale = 0.9 + Matter.Body.scale(this, scale, scale); + this.radius *= scale + } else { + if (this.stuckTo && this.stuckTo.alive) scale = 1.03 + Matter.Body.scale(this, scale, scale); + this.radius *= scale + if (this.radius > this.maxRadius) this.endCycle = 0; } - // this.force.y += this.mass * 0.00045; //draw green glow diff --git a/js/mob.js b/js/mob.js index 9f0583c..7b2ab66 100644 --- a/js/mob.js +++ b/js/mob.js @@ -59,7 +59,7 @@ const mobs = { } function applySlow(whom) { - if (!whom.shield && !whom.isShielded && !m.isBodiesAsleep) { + if (!whom.shield && !whom.isShielded) { if (whom.isBoss) cycles = Math.floor(cycles * 0.25) let i = whom.status.length while (i--) { @@ -98,7 +98,7 @@ const mobs = { } }, statusStun(who, cycles = 180) { - if (!who.shield && !who.isShielded && !m.isBodiesAsleep) { + if (!who.shield && !who.isShielded) { Matter.Body.setVelocity(who, { x: who.velocity.x * 0.8, y: who.velocity.y * 0.8 @@ -153,7 +153,7 @@ const mobs = { if (!who.isShielded && who.alive && who.damageReduction > 0) { who.status.push({ effect() { - if ((simulation.cycle - this.startCycle) % 30 === 0 && !m.isBodiesAsleep) { + if ((simulation.cycle - this.startCycle) % 30 === 0) { let dmg = b.dmgScale * this.dmg who.damage(dmg); if (who.damageReduction) { @@ -822,27 +822,25 @@ const mobs = { } }, grow() { - if (!m.isBodiesAsleep) { - if (this.seePlayer.recall) { - if (this.radius < 80) { - const scale = 1.01; - Matter.Body.scale(this, scale, scale); - this.radius *= scale; - // this.torque = -0.00002 * this.inertia; - this.fill = `hsl(144, ${this.radius}%, 50%)`; - if (this.isShielded) { //remove shield if shielded when growing - this.isShielded = false; - this.removeConsBB(); - } - } - } else { - if (this.radius > 15) { - const scale = 0.99; - Matter.Body.scale(this, scale, scale); - this.radius *= scale; - this.fill = `hsl(144, ${this.radius}%, 50%)`; + if (this.seePlayer.recall) { + if (this.radius < 80) { + const scale = 1.01; + Matter.Body.scale(this, scale, scale); + this.radius *= scale; + // this.torque = -0.00002 * this.inertia; + this.fill = `hsl(144, ${this.radius}%, 50%)`; + if (this.isShielded) { //remove shield if shielded when growing + this.isShielded = false; + this.removeConsBB(); } } + } else { + if (this.radius > 15) { + const scale = 0.99; + Matter.Body.scale(this, scale, scale); + this.radius *= scale; + this.fill = `hsl(144, ${this.radius}%, 50%)`; + } } }, search() { @@ -943,55 +941,53 @@ const mobs = { } }, fire() { - if (!m.isBodiesAsleep) { - const setNoseShape = () => { - const mag = this.radius + this.radius * this.noseLength; - this.vertices[1].x = this.position.x + Math.cos(this.angle) * mag; - this.vertices[1].y = this.position.y + Math.sin(this.angle) * mag; - }; - //throw a mob/bullet at player - 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)); - this.fireDir.y -= Math.abs(this.seePlayer.position.x - this.position.x) / 2500; //gives the bullet an arc //was / 1600 - } - //rotate towards fireAngle - const angle = this.angle + Math.PI / 2; - const dot = Vector.dot({ - x: Math.cos(angle), - y: Math.sin(angle) - }, this.fireDir) - // c = Math.cos(angle) * this.fireDir.x + Math.sin(angle) * this.fireDir.y; - const threshold = 0.1; - if (dot > threshold) { - this.torque += 0.000004 * this.inertia; - } else if (dot < -threshold) { - this.torque -= 0.000004 * this.inertia; - } else if (this.noseLength > 1.5 && dot > -0.2 && dot < 0.2) { - //fire - spawn.bullet(this.vertices[1].x, this.vertices[1].y, 9 + Math.ceil(this.radius / 15)); - const v = 15; - Matter.Body.setVelocity(mob[mob.length - 1], { - x: this.velocity.x + this.fireDir.x * v + 3 * Math.random(), - y: this.velocity.y + this.fireDir.y * v + 3 * Math.random() - }); - this.noseLength = 0; - // recoil - this.force.x -= 0.005 * this.fireDir.x * this.mass; - this.force.y -= 0.005 * this.fireDir.y * this.mass; - } - if (this.noseLength < 1.5) this.noseLength += this.fireFreq; - setNoseShape(); - } else if (this.noseLength > 0.1) { - this.noseLength -= this.fireFreq / 2; - setNoseShape(); + const setNoseShape = () => { + const mag = this.radius + this.radius * this.noseLength; + this.vertices[1].x = this.position.x + Math.cos(this.angle) * mag; + this.vertices[1].y = this.position.y + Math.sin(this.angle) * mag; + }; + //throw a mob/bullet at player + 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)); + this.fireDir.y -= Math.abs(this.seePlayer.position.x - this.position.x) / 2500; //gives the bullet an arc //was / 1600 } - // else if (this.noseLength < -0.1) { - // this.noseLength += this.fireFreq / 4; - // setNoseShape(); - // } + //rotate towards fireAngle + const angle = this.angle + Math.PI / 2; + const dot = Vector.dot({ + x: Math.cos(angle), + y: Math.sin(angle) + }, this.fireDir) + // c = Math.cos(angle) * this.fireDir.x + Math.sin(angle) * this.fireDir.y; + const threshold = 0.1; + if (dot > threshold) { + this.torque += 0.000004 * this.inertia; + } else if (dot < -threshold) { + this.torque -= 0.000004 * this.inertia; + } else if (this.noseLength > 1.5 && dot > -0.2 && dot < 0.2) { + //fire + spawn.bullet(this.vertices[1].x, this.vertices[1].y, 9 + Math.ceil(this.radius / 15)); + const v = 15; + Matter.Body.setVelocity(mob[mob.length - 1], { + x: this.velocity.x + this.fireDir.x * v + 3 * Math.random(), + y: this.velocity.y + this.fireDir.y * v + 3 * Math.random() + }); + this.noseLength = 0; + // recoil + this.force.x -= 0.005 * this.fireDir.x * this.mass; + this.force.y -= 0.005 * this.fireDir.y * this.mass; + } + if (this.noseLength < 1.5) this.noseLength += this.fireFreq; + setNoseShape(); + } else if (this.noseLength > 0.1) { + this.noseLength -= this.fireFreq / 2; + setNoseShape(); } + // else if (this.noseLength < -0.1) { + // this.noseLength += this.fireFreq / 4; + // setNoseShape(); + // } }, // launch() { // if (this.seePlayer.recall) { @@ -1038,12 +1034,10 @@ const mobs = { } }, timeLimit() { - if (!m.isBodiesAsleep) { - this.timeLeft--; - if (this.timeLeft < 0) { - this.isDropPowerUp = false; - this.death(); //death with no power up - } + this.timeLeft--; + if (this.timeLeft < 0) { + this.isDropPowerUp = false; + this.death(); //death with no power up } }, healthBar() { //draw health by mob //most health bars are drawn in mobs.healthbar(); diff --git a/js/simulation.js b/js/simulation.js index f80918b..1024889 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -14,14 +14,16 @@ const simulation = { } m.move(); m.look(); - simulation.checks(); simulation.camera(); level.custom(); powerUps.do(); mobs.draw(); simulation.draw.cons(); simulation.draw.body(); - if (!m.isBodiesAsleep) mobs.loop(); + if (!m.isBodiesAsleep) { + simulation.checks(); + mobs.loop(); + } mobs.healthBar(); m.draw(); m.hold(); @@ -873,7 +875,7 @@ const simulation = { // } // }, checks() { - if (!(simulation.cycle % 60) && !m.isBodiesAsleep) { //once a second + if (!(simulation.cycle % 60)) { //once a second //energy overfill if (m.energy > m.maxEnergy) m.energy = m.maxEnergy + (m.energy - m.maxEnergy) * tech.overfillDrain //every second energy above max energy loses 25% if (tech.isFlipFlopEnergy && m.immuneCycle < m.cycle) { diff --git a/js/spawn.js b/js/spawn.js index 82b552d..1024726 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -431,9 +431,8 @@ const spawn = { // }); this.modeDo(); //this does different things based on the mode this.checkStatus(); - if (!m.isBodiesAsleep) this.cycle++; //switch modes÷ if time isn't paused + this.cycle++; //switch modes÷ if time isn't paused this.totalCycles++; - // if (!m.isBodiesAsleep) { if (this.health > 0.25) { if (this.cycle > this.endCycle) { this.cycle = 0; @@ -491,7 +490,7 @@ const spawn = { } me.spawnInterval = 395 me.modeSpawns = function() { - if (!(this.cycle % this.spawnInterval) && !m.isBodiesAsleep && mob.length < 40) { + if (!(this.cycle % this.spawnInterval) && mob.length < 40) { if (this.mode !== 3) Matter.Body.setAngularVelocity(this, 0.1) //fire a bullet from each vertex const whoSpawn = spawn.fullPickList[Math.floor(Math.random() * spawn.fullPickList.length)]; @@ -504,7 +503,7 @@ const spawn = { y: this.velocity.y + velocity.y }); } - if (!(this.cycle % 2 * this.spawnInterval) && !m.isBodiesAsleep && mob.length < 40) { + if (!(this.cycle % 2 * this.spawnInterval) && mob.length < 40) { const len = (this.totalCycles / 600 + simulation.difficulty / 2 - 30) / 15 for (let i = 0; i < len; i++) { spawn.randomLevelBoss(3000 * (simulation.isHorizontalFlipped ? -1 : 1) + 2000 * (Math.random() - 0.5), -1100 + 200 * (Math.random() - 0.5)) @@ -650,7 +649,7 @@ const spawn = { ctx.lineTo(best.x, best.y); } me.modeLasers = function() { - if (!m.isBodiesAsleep && !this.isStunned) { + if (!this.isStunned) { let slowed = false //check if slowed for (let i = 0; i < this.status.length; i++) { if (this.status[i].type === "slow") { @@ -795,7 +794,7 @@ const spawn = { this.force.y += force.y; } - if (!(simulation.cycle % 30) && !m.isBodiesAsleep) { + if (!(simulation.cycle % 30)) { //find blocks to turn into mobs for (let i = 0; i < body.length; i++) { if (Vector.magnitude(Vector.sub(this.position, body[i].position)) < 700 && !body[i].isNotHoldable) { // check distance for each block @@ -899,17 +898,14 @@ const spawn = { me.do = function() { //grow phase only occurs for growCycles this.checkStatus(); this.seePlayerCheck(); - - if (!m.isBodiesAsleep) { - this.cycle++ - if (this.cycle > growCycles) { - this.damageReduction = 1.8 //take extra damage - this.do = this.normalDo - } else { - const scale = 1.04; //if 120 use 1.02 - Matter.Body.scale(this, scale, scale); - this.radius *= scale; - } + this.cycle++ + if (this.cycle > growCycles) { + this.damageReduction = 1.8 //take extra damage + this.do = this.normalDo + } else { + const scale = 1.04; //if 120 use 1.02 + Matter.Body.scale(this, scale, scale); + this.radius *= scale; } } me.normalDo = function() { @@ -957,29 +953,26 @@ const spawn = { } me.damageReduction = 0.17 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1); //me.damageReductionGoal me.do = function() { - // // this.armor(); - if (!m.isBodiesAsleep) { - this.seePlayerByDistOrLOS(); - this.checkStatus(); - this.attraction(); + this.seePlayerByDistOrLOS(); + this.checkStatus(); + this.attraction(); - if (this.seePlayer.recall && this.mass < this.cellMassMax) { //grow cell radius - const scale = 1 + 0.0002 * this.cellMassMax / this.mass; - Matter.Body.scale(this, scale, scale); - this.radius = Math.sqrt(this.mass * k / Math.PI) - } - if (!(simulation.cycle % this.seePlayerFreq)) { //move away from other mobs - const repelRange = 150 - const attractRange = 700 - for (let i = 0, len = mob.length; i < len; i++) { - if (mob[i].isCell && mob[i].id !== this.id) { - const sub = Vector.sub(this.position, mob[i].position) - const dist = Vector.magnitude(sub) - if (dist < repelRange) { - this.force = Vector.mult(Vector.normalise(sub), this.mass * 0.002) - } else if (dist > attractRange) { - this.force = Vector.mult(Vector.normalise(sub), -this.mass * 0.003) - } + if (this.seePlayer.recall && this.mass < this.cellMassMax) { //grow cell radius + const scale = 1 + 0.0002 * this.cellMassMax / this.mass; + Matter.Body.scale(this, scale, scale); + this.radius = Math.sqrt(this.mass * k / Math.PI) + } + if (!(simulation.cycle % this.seePlayerFreq)) { //move away from other mobs + const repelRange = 150 + const attractRange = 700 + for (let i = 0, len = mob.length; i < len; i++) { + if (mob[i].isCell && mob[i].id !== this.id) { + const sub = Vector.sub(this.position, mob[i].position) + const dist = Vector.magnitude(sub) + if (dist < repelRange) { + this.force = Vector.mult(Vector.normalise(sub), this.mass * 0.002) + } else if (dist > attractRange) { + this.force = Vector.mult(Vector.normalise(sub), -this.mass * 0.003) } } } @@ -1030,24 +1023,21 @@ const spawn = { }; me.damageReduction = 0.2 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1); me.doAwake = function() { - if (!m.isBodiesAsleep) { - // this.armor(); - this.alwaysSeePlayer(); - this.checkStatus(); - this.attraction(); + this.alwaysSeePlayer(); + this.checkStatus(); + this.attraction(); - if (!(simulation.cycle % this.seePlayerFreq)) { //move away from other mobs - const repelRange = 40 - const attractRange = 240 - for (let i = 0, len = mob.length; i < len; i++) { - if (mob[i].isSpawnBoss && mob[i].id !== this.id) { - const sub = Vector.sub(this.position, mob[i].position) - const dist = Vector.magnitude(sub) - if (dist < repelRange) { - this.force = Vector.mult(Vector.normalise(sub), this.mass * 0.002) - } else if (dist > attractRange) { - this.force = Vector.mult(Vector.normalise(sub), -this.mass * 0.002) - } + if (!(simulation.cycle % this.seePlayerFreq)) { //move away from other mobs + const repelRange = 40 + const attractRange = 240 + for (let i = 0, len = mob.length; i < len; i++) { + if (mob[i].isSpawnBoss && mob[i].id !== this.id) { + const sub = Vector.sub(this.position, mob[i].position) + const dist = Vector.magnitude(sub) + if (dist < repelRange) { + this.force = Vector.mult(Vector.normalise(sub), this.mass * 0.002) + } else if (dist > attractRange) { + this.force = Vector.mult(Vector.normalise(sub), -this.mass * 0.002) } } } @@ -1153,7 +1143,7 @@ const spawn = { me.do = function() { if (this.isInvulnerable) { if (this.invulnerabilityCountDown > 0) { - if (!m.isBodiesAsleep) this.invulnerabilityCountDown-- + this.invulnerabilityCountDown-- ctx.beginPath(); let vertices = this.vertices; ctx.moveTo(vertices[0].x, vertices[0].y); @@ -1234,7 +1224,7 @@ const spawn = { me.do = function() { if (this.isInvulnerable) { if (this.invulnerabilityCountDown > 0) { - if (!m.isBodiesAsleep) this.invulnerabilityCountDown-- + this.invulnerabilityCountDown-- ctx.beginPath(); let vertices = this.vertices; ctx.moveTo(vertices[0].x, vertices[0].y); @@ -1745,7 +1735,7 @@ const spawn = { this.checkStatus(); if (this.seePlayer.recall) { //throw large seekers - if (!(simulation.cycle % 240) && !m.isBodiesAsleep) { + if (!(simulation.cycle % 240)) { spawn.seeker(this.position.x, this.position.y, 15 * (0.7 + 0.5 * Math.random()), 7); //give the bullet a rotational velocity as if they were attached to a vertex const who = mob[mob.length - 1] Matter.Body.setDensity(who, 0.00001); //normal is 0.001 @@ -1982,7 +1972,7 @@ const spawn = { ctx.strokeStyle = "rgba(255,255,255,0.7)"; ctx.stroke(); } else if (this.invulnerabilityCountDown > 0) { - if (!m.isBodiesAsleep) this.invulnerabilityCountDown-- + this.invulnerabilityCountDown-- } else { this.isInvulnerable = true if (this.damageReduction) this.startingDamageReduction = this.damageReduction @@ -2369,7 +2359,7 @@ const spawn = { // ctx.setLineDash([]); // ctx.fillStyle = "rgba(150,0,255,0.03)"; // ctx.fill(); - if (!m.isBodiesAsleep && !this.isStunned && !this.isSlowed) { + if (!this.isStunned && !this.isSlowed) { if (this.followDelay > this.delayLimit) this.followDelay -= 0.15; let history = m.history[(m.cycle - Math.floor(this.followDelay)) % 600] Matter.Body.setPosition(this, { x: history.position.x, y: history.position.y - history.yOff + 24.2859 }) //bullets move with player @@ -2403,53 +2393,51 @@ const spawn = { }; spawn.shield(me, x, y); me.do = function() { - if (!m.isBodiesAsleep) { - this.seePlayerByLookingAt(); - this.checkStatus(); - this.attraction(); - const dist2 = this.distanceToPlayer2(); - //laser Tracking - if (this.seePlayer.yes && dist2 < 4000000) { - const rangeWidth = 2000; //this is sqrt of 4000000 from above if() - //targeting laser will slowly move from the mob to the player's position - this.laserPos = Vector.add(this.laserPos, Vector.mult(Vector.sub(player.position, this.laserPos), 0.1)); - let targetDist = Vector.magnitude(Vector.sub(this.laserPos, m.pos)); - const r = 12; - ctx.beginPath(); - ctx.moveTo(this.position.x, this.position.y); - if (targetDist < r + 16) { - targetDist = r + 10; - //charge at player - const forceMag = this.accelMag * 40 * this.mass; - const angle = Math.atan2(this.seePlayer.position.y - this.position.y, this.seePlayer.position.x - this.position.x); - this.force.x += forceMag * Math.cos(angle); - this.force.y += forceMag * Math.sin(angle); - } - // else { - //high friction if can't lock onto player - // Matter.Body.setVelocity(this, { - // x: this.velocity.x * 0.98, - // y: this.velocity.y * 0.98 - // }); - // } - if (dist2 > 80000) { - const laserWidth = 0.002; - let laserOffR = Vector.rotateAbout(this.laserPos, (targetDist - r) * laserWidth, this.position); - let sub = Vector.normalise(Vector.sub(laserOffR, this.position)); - laserOffR = Vector.add(laserOffR, Vector.mult(sub, rangeWidth)); - ctx.lineTo(laserOffR.x, laserOffR.y); - - let laserOffL = Vector.rotateAbout(this.laserPos, (targetDist - r) * -laserWidth, this.position); - sub = Vector.normalise(Vector.sub(laserOffL, this.position)); - laserOffL = Vector.add(laserOffL, Vector.mult(sub, rangeWidth)); - ctx.lineTo(laserOffL.x, laserOffL.y); - ctx.fillStyle = `rgba(0,0,255,${Math.max(0, 0.3 * r / targetDist)})` - ctx.fill(); - } - } else { - this.laserPos = this.position; + this.seePlayerByLookingAt(); + this.checkStatus(); + this.attraction(); + const dist2 = this.distanceToPlayer2(); + //laser Tracking + if (this.seePlayer.yes && dist2 < 4000000) { + const rangeWidth = 2000; //this is sqrt of 4000000 from above if() + //targeting laser will slowly move from the mob to the player's position + this.laserPos = Vector.add(this.laserPos, Vector.mult(Vector.sub(player.position, this.laserPos), 0.1)); + let targetDist = Vector.magnitude(Vector.sub(this.laserPos, m.pos)); + const r = 12; + ctx.beginPath(); + ctx.moveTo(this.position.x, this.position.y); + if (targetDist < r + 16) { + targetDist = r + 10; + //charge at player + const forceMag = this.accelMag * 40 * this.mass; + const angle = Math.atan2(this.seePlayer.position.y - this.position.y, this.seePlayer.position.x - this.position.x); + this.force.x += forceMag * Math.cos(angle); + this.force.y += forceMag * Math.sin(angle); } - }; + // else { + //high friction if can't lock onto player + // Matter.Body.setVelocity(this, { + // x: this.velocity.x * 0.98, + // y: this.velocity.y * 0.98 + // }); + // } + if (dist2 > 80000) { + const laserWidth = 0.002; + let laserOffR = Vector.rotateAbout(this.laserPos, (targetDist - r) * laserWidth, this.position); + let sub = Vector.normalise(Vector.sub(laserOffR, this.position)); + laserOffR = Vector.add(laserOffR, Vector.mult(sub, rangeWidth)); + ctx.lineTo(laserOffR.x, laserOffR.y); + + let laserOffL = Vector.rotateAbout(this.laserPos, (targetDist - r) * -laserWidth, this.position); + sub = Vector.normalise(Vector.sub(laserOffL, this.position)); + laserOffL = Vector.add(laserOffL, Vector.mult(sub, rangeWidth)); + ctx.lineTo(laserOffL.x, laserOffL.y); + ctx.fillStyle = `rgba(0,0,255,${Math.max(0, 0.3 * r / targetDist)})` + ctx.fill(); + } + } else { + this.laserPos = this.position; + } } }, laserTargetingBoss(x, y, radius = 80) { @@ -2850,85 +2838,83 @@ const spawn = { me.fire = function() { // this.armor(); this.checkStatus(); - if (!m.isBodiesAsleep) { - if (!m.isCloak && !this.isStunned) { - if (this.isFiring) { - if (this.fireCycle > this.fireDelay) { //fire - this.isFiring = false - this.fireCycle = 0 - this.torque += (0.00008 + 0.00007 * Math.random()) * this.inertia * (Math.round(Math.random()) * 2 - 1) //randomly spin around after firing - //is player in beam path - if (Matter.Query.ray([player], this.fireTarget, this.position).length) { - unit = Vector.mult(Vector.normalise(Vector.sub(this.vertices[1], this.position)), this.distanceToPlayer() - 100) - this.fireTarget = Vector.add(this.vertices[1], unit) - } - //damage player if in range - if (Vector.magnitude(Vector.sub(player.position, this.fireTarget)) < this.pulseRadius && m.immuneCycle < m.cycle) { - m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage - m.damage(0.045 * simulation.dmgScale); - } - simulation.drawList.push({ //add dmg to draw queue - x: this.fireTarget.x, - y: this.fireTarget.y, - radius: this.pulseRadius, - color: "rgba(120,0,255,0.6)", - time: simulation.drawTime - }); - ctx.beginPath(); - ctx.moveTo(this.vertices[1].x, this.vertices[1].y) - ctx.lineTo(this.fireTarget.x, this.fireTarget.y) - ctx.lineWidth = 20; - ctx.strokeStyle = "rgba(120,0,255,0.3)"; - ctx.stroke(); - ctx.lineWidth = 5; - ctx.strokeStyle = "rgba(120,0,255,1)"; - ctx.stroke(); - } else { //delay before firing - this.fireCycle++ - //draw explosion outline - ctx.beginPath(); - ctx.arc(this.fireTarget.x, this.fireTarget.y, this.pulseRadius, 0, 2 * Math.PI); //* this.fireCycle / this.fireDelay - ctx.fillStyle = "rgba(120,0,255,0.07)"; - ctx.fill(); - //draw path from mob to explosion - ctx.beginPath(); - ctx.moveTo(this.vertices[1].x, this.vertices[1].y) - ctx.lineTo(this.fireTarget.x, this.fireTarget.y) - ctx.setLineDash([40 * Math.random(), 200 * Math.random()]); - ctx.lineWidth = 2; - ctx.strokeStyle = "rgba(120,0,255,0.3)"; - ctx.stroke(); - ctx.setLineDash([]); - } - } else { //aim at player - this.fireCycle++ - this.fireDir = Vector.normalise(Vector.sub(m.pos, this.position)); //set direction to turn to fire - //rotate towards fireAngle - const angle = this.angle + Math.PI / 2; - const c = Math.cos(angle) * this.fireDir.x + Math.sin(angle) * this.fireDir.y; - const threshold = 0.04; - if (c > threshold) { - this.torque += 0.0000015 * this.inertia; - } else if (c < -threshold) { - this.torque -= 0.0000015 * this.inertia; - } else if (this.fireCycle > 45) { //fire + if (!m.isCloak && !this.isStunned) { + if (this.isFiring) { + if (this.fireCycle > this.fireDelay) { //fire + this.isFiring = false + this.fireCycle = 0 + this.torque += (0.00008 + 0.00007 * Math.random()) * this.inertia * (Math.round(Math.random()) * 2 - 1) //randomly spin around after firing + //is player in beam path + if (Matter.Query.ray([player], this.fireTarget, this.position).length) { unit = Vector.mult(Vector.normalise(Vector.sub(this.vertices[1], this.position)), this.distanceToPlayer() - 100) this.fireTarget = Vector.add(this.vertices[1], unit) - if (Vector.magnitude(Vector.sub(m.pos, this.fireTarget)) < 1000) { //if's possible for this to be facing 180 degrees away from the player, this makes sure that doesn't occur - Matter.Body.setAngularVelocity(this, 0) - this.fireLockCount = 0 - this.isFiring = true - this.fireCycle = 0 - } + } + //damage player if in range + if (Vector.magnitude(Vector.sub(player.position, this.fireTarget)) < this.pulseRadius && m.immuneCycle < m.cycle) { + m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage + m.damage(0.045 * simulation.dmgScale); + } + simulation.drawList.push({ //add dmg to draw queue + x: this.fireTarget.x, + y: this.fireTarget.y, + radius: this.pulseRadius, + color: "rgba(120,0,255,0.6)", + time: simulation.drawTime + }); + ctx.beginPath(); + ctx.moveTo(this.vertices[1].x, this.vertices[1].y) + ctx.lineTo(this.fireTarget.x, this.fireTarget.y) + ctx.lineWidth = 20; + ctx.strokeStyle = "rgba(120,0,255,0.3)"; + ctx.stroke(); + ctx.lineWidth = 5; + ctx.strokeStyle = "rgba(120,0,255,1)"; + ctx.stroke(); + } else { //delay before firing + this.fireCycle++ + //draw explosion outline + ctx.beginPath(); + ctx.arc(this.fireTarget.x, this.fireTarget.y, this.pulseRadius, 0, 2 * Math.PI); //* this.fireCycle / this.fireDelay + ctx.fillStyle = "rgba(120,0,255,0.07)"; + ctx.fill(); + //draw path from mob to explosion + ctx.beginPath(); + ctx.moveTo(this.vertices[1].x, this.vertices[1].y) + ctx.lineTo(this.fireTarget.x, this.fireTarget.y) + ctx.setLineDash([40 * Math.random(), 200 * Math.random()]); + ctx.lineWidth = 2; + ctx.strokeStyle = "rgba(120,0,255,0.3)"; + ctx.stroke(); + ctx.setLineDash([]); + } + } else { //aim at player + this.fireCycle++ + this.fireDir = Vector.normalise(Vector.sub(m.pos, this.position)); //set direction to turn to fire + //rotate towards fireAngle + const angle = this.angle + Math.PI / 2; + const c = Math.cos(angle) * this.fireDir.x + Math.sin(angle) * this.fireDir.y; + const threshold = 0.04; + if (c > threshold) { + this.torque += 0.0000015 * this.inertia; + } else if (c < -threshold) { + this.torque -= 0.0000015 * this.inertia; + } else if (this.fireCycle > 45) { //fire + unit = Vector.mult(Vector.normalise(Vector.sub(this.vertices[1], this.position)), this.distanceToPlayer() - 100) + this.fireTarget = Vector.add(this.vertices[1], unit) + if (Vector.magnitude(Vector.sub(m.pos, this.fireTarget)) < 1000) { //if's possible for this to be facing 180 degrees away from the player, this makes sure that doesn't occur + Matter.Body.setAngularVelocity(this, 0) + this.fireLockCount = 0 + this.isFiring = true + this.fireCycle = 0 } } - //gently return to starting location - // const sub = Vector.sub(this.homePosition, this.position) - // const dist = Vector.magnitude(sub) - // if (dist > 250) this.force = Vector.mult(Vector.normalise(sub), this.mass * 0.0002) - } else { - this.isFiring = false } + //gently return to starting location + // const sub = Vector.sub(this.homePosition, this.position) + // const dist = Vector.magnitude(sub) + // if (dist > 250) this.force = Vector.mult(Vector.normalise(sub), this.mass * 0.0002) + } else { + this.isFiring = false } }; }, @@ -2971,90 +2957,88 @@ const spawn = { me.do = function() { this.seePlayerByLookingAt(); this.checkStatus(); - if (!m.isBodiesAsleep) { - if (this.seePlayer.recall) { - if (this.isFiring) { - if (this.fireCycle > this.fireDelay) { //fire - if (!this.canSeeTarget()) return - this.isFiring = false - this.fireCycle = 0 - this.torque += (0.00002 + 0.0002 * Math.random()) * this.inertia * (Math.round(Math.random()) * 2 - 1) //randomly spin around after firing - //is player in beam path - if (Matter.Query.ray([player], this.fireTarget, this.position).length) { - unit = Vector.mult(Vector.normalise(Vector.sub(this.vertices[1], this.position)), this.distanceToPlayer() - 100) - this.fireTarget = Vector.add(this.vertices[1], unit) - } - //damage player if in range - if (Vector.magnitude(Vector.sub(player.position, this.fireTarget)) < this.pulseRadius && m.immuneCycle < m.cycle) { - m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage - m.damage(0.03 * simulation.dmgScale); - } - simulation.drawList.push({ //add dmg to draw queue - x: this.fireTarget.x, - y: this.fireTarget.y, - radius: this.pulseRadius, - color: "rgba(255,0,100,0.6)", - time: simulation.drawTime - }); - ctx.beginPath(); - ctx.moveTo(this.vertices[1].x, this.vertices[1].y) - ctx.lineTo(this.fireTarget.x, this.fireTarget.y) - ctx.lineWidth = 20; - ctx.strokeStyle = "rgba(255,0,100,0.3)"; - ctx.stroke(); - ctx.lineWidth = 5; - ctx.strokeStyle = "rgba(255,0,100,1)"; - ctx.stroke(); - } else { //delay before firing - this.fireCycle++ - if (!(simulation.cycle % 3)) { - if (!this.canSeeTarget()) return //if can't see stop firing - } - //draw explosion outline - ctx.beginPath(); - ctx.arc(this.fireTarget.x, this.fireTarget.y, this.pulseRadius, 0, 2 * Math.PI); //* this.fireCycle / this.fireDelay - ctx.fillStyle = "rgba(255,0,100,0.07)"; - ctx.fill(); - //draw path from mob to explosion - ctx.beginPath(); - ctx.moveTo(this.vertices[1].x, this.vertices[1].y) - ctx.lineTo(this.fireTarget.x, this.fireTarget.y) - ctx.setLineDash([40 * Math.random(), 200 * Math.random()]); - ctx.lineWidth = 2; - ctx.strokeStyle = "rgba(255,0,100,0.3)"; - ctx.stroke(); - ctx.setLineDash([]); - } - } else { //aim at player - this.fireCycle++ - // this.fireDir = ; //set direction to turn to fire - const angle = this.angle + Math.PI / 2; - const dot = Vector.dot({ - x: Math.cos(angle), - y: Math.sin(angle) - }, Vector.normalise(Vector.sub(this.seePlayer.position, this.position))) - const threshold = 0.04; - if (dot > threshold) { //rotate towards fireAngle - this.torque += 0.0000015 * this.inertia; - } else if (dot < -threshold) { - this.torque -= 0.0000015 * this.inertia; - } else if (this.fireCycle > 60) { // aim + if (this.seePlayer.recall) { + if (this.isFiring) { + if (this.fireCycle > this.fireDelay) { //fire + if (!this.canSeeTarget()) return + this.isFiring = false + this.fireCycle = 0 + this.torque += (0.00002 + 0.0002 * Math.random()) * this.inertia * (Math.round(Math.random()) * 2 - 1) //randomly spin around after firing + //is player in beam path + if (Matter.Query.ray([player], this.fireTarget, this.position).length) { unit = Vector.mult(Vector.normalise(Vector.sub(this.vertices[1], this.position)), this.distanceToPlayer() - 100) this.fireTarget = Vector.add(this.vertices[1], unit) - if (!this.canSeeTarget()) return - Matter.Body.setAngularVelocity(this, 0) - this.fireLockCount = 0 - this.isFiring = true - this.fireCycle = 0 } + //damage player if in range + if (Vector.magnitude(Vector.sub(player.position, this.fireTarget)) < this.pulseRadius && m.immuneCycle < m.cycle) { + m.immuneCycle = m.cycle + tech.collisionImmuneCycles; //player is immune to damage + m.damage(0.03 * simulation.dmgScale); + } + simulation.drawList.push({ //add dmg to draw queue + x: this.fireTarget.x, + y: this.fireTarget.y, + radius: this.pulseRadius, + color: "rgba(255,0,100,0.6)", + time: simulation.drawTime + }); + ctx.beginPath(); + ctx.moveTo(this.vertices[1].x, this.vertices[1].y) + ctx.lineTo(this.fireTarget.x, this.fireTarget.y) + ctx.lineWidth = 20; + ctx.strokeStyle = "rgba(255,0,100,0.3)"; + ctx.stroke(); + ctx.lineWidth = 5; + ctx.strokeStyle = "rgba(255,0,100,1)"; + ctx.stroke(); + } else { //delay before firing + this.fireCycle++ + if (!(simulation.cycle % 3)) { + if (!this.canSeeTarget()) return //if can't see stop firing + } + //draw explosion outline + ctx.beginPath(); + ctx.arc(this.fireTarget.x, this.fireTarget.y, this.pulseRadius, 0, 2 * Math.PI); //* this.fireCycle / this.fireDelay + ctx.fillStyle = "rgba(255,0,100,0.07)"; + ctx.fill(); + //draw path from mob to explosion + ctx.beginPath(); + ctx.moveTo(this.vertices[1].x, this.vertices[1].y) + ctx.lineTo(this.fireTarget.x, this.fireTarget.y) + ctx.setLineDash([40 * Math.random(), 200 * Math.random()]); + ctx.lineWidth = 2; + ctx.strokeStyle = "rgba(255,0,100,0.3)"; + ctx.stroke(); + ctx.setLineDash([]); + } + } else { //aim at player + this.fireCycle++ + // this.fireDir = ; //set direction to turn to fire + const angle = this.angle + Math.PI / 2; + const dot = Vector.dot({ + x: Math.cos(angle), + y: Math.sin(angle) + }, Vector.normalise(Vector.sub(this.seePlayer.position, this.position))) + const threshold = 0.04; + if (dot > threshold) { //rotate towards fireAngle + this.torque += 0.0000015 * this.inertia; + } else if (dot < -threshold) { + this.torque -= 0.0000015 * this.inertia; + } else if (this.fireCycle > 60) { // aim + unit = Vector.mult(Vector.normalise(Vector.sub(this.vertices[1], this.position)), this.distanceToPlayer() - 100) + this.fireTarget = Vector.add(this.vertices[1], unit) + if (!this.canSeeTarget()) return + Matter.Body.setAngularVelocity(this, 0) + this.fireLockCount = 0 + this.isFiring = true + this.fireCycle = 0 } - //gently return to starting location - // const sub = Vector.sub(this.homePosition, this.position) - // const dist = Vector.magnitude(sub) - // if (dist > 350) this.force = Vector.mult(Vector.normalise(sub), this.mass * 0.0002) - } else { - this.isFiring = false } + //gently return to starting location + // const sub = Vector.sub(this.homePosition, this.position) + // const dist = Vector.magnitude(sub) + // if (dist > 350) this.force = Vector.mult(Vector.normalise(sub), this.mass * 0.0002) + } else { + this.isFiring = false } }; }, @@ -3092,12 +3076,6 @@ const spawn = { }); Composite.add(engine.world, me.constraint); }, 2000); //add in a delay in case the level gets flipped left right - - - // me.startingPosition = { - // x: x, - // y: y - // } me.count = 0; me.frictionAir = 0.03; // me.torque -= me.inertia * 0.002 @@ -3105,12 +3083,10 @@ const spawn = { Matter.Body.setDensity(me, 0.03); //extra dense //normal is 0.001 //makes effective life much larger me.damageReduction = 0.25 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) me.isBoss = true; - // spawn.shield(me, x, y, 1); //not working, not sure why me.onDeath = function() { powerUps.spawnBossPowerUp(this.position.x, this.position.y) }; - me.rotateVelocity = Math.min(0.0045, 0.0015 * simulation.accelScale * simulation.accelScale) * (level.levelsCleared > 8 ? 1 : -1) * (simulation.isHorizontalFlipped ? -1 : 1) me.do = function() { // this.armor(); @@ -3118,21 +3094,20 @@ const spawn = { this.checkStatus(); if (!this.isStunned) { - if (!m.isBodiesAsleep) { - //check if slowed - let slowed = false - for (let i = 0; i < this.status.length; i++) { - if (this.status[i].type === "slow") { - slowed = true - break - } - } - if (!slowed) { - this.count++ - Matter.Body.setAngle(this, this.count * this.rotateVelocity) - Matter.Body.setAngularVelocity(this, 0) + //check if slowed + let slowed = false + for (let i = 0; i < this.status.length; i++) { + if (this.status[i].type === "slow") { + slowed = true + break } } + if (!slowed) { + this.count++ + Matter.Body.setAngle(this, this.count * this.rotateVelocity) + Matter.Body.setAngularVelocity(this, 0) + } + ctx.beginPath(); this.lasers(this.vertices[0], this.angle + Math.PI / 3); this.lasers(this.vertices[1], this.angle + Math.PI); @@ -3254,56 +3229,52 @@ const spawn = { } }; me.do = function() { - if (!m.isBodiesAsleep) { - // this.gravity(); - this.seePlayerByLookingAt(); - this.checkStatus(); - this.attraction(); - - if (this.isSpikeReset) { - if (this.seePlayer.recall) { - const dist = Vector.sub(this.seePlayer.position, this.position); - const distMag = Vector.magnitude(dist); - if (distMag < this.radius * 7) { - //find nearest vertex - let nearestDistance = Infinity - for (let i = 0, len = this.vertices.length; i < len; i++) { - //find distance to player for each vertex - const dist = Vector.sub(this.seePlayer.position, this.vertices[i]); - const distMag = Vector.magnitude(dist); - //save the closest distance - if (distMag < nearestDistance) { - this.spikeVertex = i - nearestDistance = distMag - } + this.seePlayerByLookingAt(); + this.checkStatus(); + this.attraction(); + if (this.isSpikeReset) { + if (this.seePlayer.recall) { + const dist = Vector.sub(this.seePlayer.position, this.position); + const distMag = Vector.magnitude(dist); + if (distMag < this.radius * 7) { + //find nearest vertex + let nearestDistance = Infinity + for (let i = 0, len = this.vertices.length; i < len; i++) { + //find distance to player for each vertex + const dist = Vector.sub(this.seePlayer.position, this.vertices[i]); + const distMag = Vector.magnitude(dist); + //save the closest distance + if (distMag < nearestDistance) { + this.spikeVertex = i + nearestDistance = distMag } - this.spikeLength = 1 - this.isSpikeGrowing = true; - this.isSpikeReset = false; - Matter.Body.setAngularVelocity(this, 0) } + this.spikeLength = 1 + this.isSpikeGrowing = true; + this.isSpikeReset = false; + Matter.Body.setAngularVelocity(this, 0) + } + } + } else { + if (this.isSpikeGrowing) { + this.spikeLength += 1 + if (this.spikeLength > spikeMax) { + this.isSpikeGrowing = false; } } else { - if (this.isSpikeGrowing) { - this.spikeLength += 1 - if (this.spikeLength > spikeMax) { - this.isSpikeGrowing = false; - } - } else { - //reduce rotation - Matter.Body.setAngularVelocity(this, this.angularVelocity * 0.8) + //reduce rotation + Matter.Body.setAngularVelocity(this, this.angularVelocity * 0.8) - this.spikeLength -= 0.2 - if (this.spikeLength < 1) { - this.spikeLength = 1 - this.isSpikeReset = true - } + this.spikeLength -= 0.2 + if (this.spikeLength < 1) { + this.spikeLength = 1 + this.isSpikeReset = true } - const spike = Vector.mult(Vector.normalise(Vector.sub(this.vertices[this.spikeVertex], this.position)), this.radius * this.spikeLength) - this.vertices[this.spikeVertex].x = this.position.x + spike.x - this.vertices[this.spikeVertex].y = this.position.y + spike.y } + const spike = Vector.mult(Vector.normalise(Vector.sub(this.vertices[this.spikeVertex], this.position)), this.radius * this.spikeLength) + this.vertices[this.spikeVertex].x = this.position.x + spike.x + this.vertices[this.spikeVertex].y = this.position.y + spike.y } }; }, @@ -3385,7 +3356,6 @@ const spawn = { powerUps.spawnBossPowerUp(this.position.x, this.position.y) }; - //invulnerability every 1/4 fraction of life lost //required setup for invulnerable me.isInvulnerable = false @@ -3401,7 +3371,7 @@ const spawn = { } if (this.isInvulnerable) { if (this.invulnerabilityCountDown > 0) { - if (!m.isBodiesAsleep) this.invulnerabilityCountDown-- + this.invulnerabilityCountDown-- //graphics //draw a super shield? ctx.beginPath(); let vertices = this.vertices; @@ -3452,7 +3422,7 @@ const spawn = { this.seePlayerByHistory(60); this.attraction(); //traveling laser - if (!m.isBodiesAsleep) this.laserAngle += this.isInvulnerable ? 0.06 : 0.015 + this.laserAngle += this.isInvulnerable ? 0.06 : 0.015 for (let i = 0, len = this.vertices.length; i < len; i++) { // this.laserSword(this.vertices[1], this.angle + laserAngle); const bend = bendFactor * Math.cos(this.laserAngle + 2 * Math.PI * i / len) @@ -3551,7 +3521,7 @@ const spawn = { this.seePlayerByHistory(); this.attraction(); this.checkStatus(); - if (!m.isBodiesAsleep) this.sword() //does various things depending on what stage of the sword swing + this.sword() //does various things depending on what stage of the sword swing // ctx.beginPath(); //hide map // ctx.arc(this.position.x, this.position.y, 3000, 0, 2 * Math.PI); //* this.fireCycle / this.fireDelay @@ -3703,7 +3673,7 @@ const spawn = { this.checkStatus(); this.seePlayerByHistory(15); this.attraction(); - if (!m.isBodiesAsleep) this.sword() //does various things depending on what stage of the sword swing + this.sword() //does various things depending on what stage of the sword swing }; me.swordWaiting = function() { if ( @@ -3822,12 +3792,10 @@ const spawn = { this.checkStatus(); this.attraction(); //draw - if (!m.isBodiesAsleep) { - if (this.seePlayer.recall) { - if (this.alpha < 1) this.alpha += 0.003 + 0.003 / simulation.CDScale; - } else { - if (this.alpha > 0) this.alpha -= 0.03; - } + if (this.seePlayer.recall) { + if (this.alpha < 1) this.alpha += 0.003 + 0.003 / simulation.CDScale; + } else { + if (this.alpha > 0) this.alpha -= 0.03; } if (this.alpha > 0) { if (this.alpha > 0.7) { @@ -3880,12 +3848,10 @@ const spawn = { this.attraction(); this.search(); //draw - if (!m.isBodiesAsleep) { - if (this.distanceToPlayer2() < this.seeAtDistance2) { - if (this.alpha < 1) this.alpha += 0.005 * simulation.CDScale; //near player go solid - } else { - if (this.alpha > 0) this.alpha -= 0.05; ///away from player, hide - } + if (this.distanceToPlayer2() < this.seeAtDistance2) { + if (this.alpha < 1) this.alpha += 0.005 * simulation.CDScale; //near player go solid + } else { + if (this.alpha > 0) this.alpha -= 0.05; ///away from player, hide } if (this.alpha > 0) { if (this.alpha > 0.8 && this.seePlayer.recall) { @@ -4200,61 +4166,59 @@ const spawn = { this.seePlayerCheck(); this.checkStatus(); - if (!m.isBodiesAsleep) { - const setNoseShape = () => { - const mag = this.radius + this.radius * this.noseLength; - this.vertices[1].x = this.position.x + Math.cos(this.angle) * mag; - this.vertices[1].y = this.position.y + Math.sin(this.angle) * mag; - }; - //throw a mob/bullet at player - 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)); - // this.fireDir.y -= Math.abs(this.seePlayer.position.x - this.position.x) / 1600; //gives the bullet an arc - } - //rotate towards fireAngle - const angle = this.angle + Math.PI / 2; - // c = Math.cos(angle) * this.fireDir.x + Math.sin(angle) * this.fireDir.y; - //rotate towards fireAngle - const dot = Vector.dot({ - x: Math.cos(angle), - y: Math.sin(angle) - }, this.fireDir) - const threshold = 0.03; - if (dot > threshold) { - this.torque += 0.000004 * this.inertia; - } else if (dot < -threshold) { - this.torque -= 0.000004 * this.inertia; - } 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 = 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() - }); - this.noseLength = 0; - // recoil - this.force.x -= 0.005 * this.fireDir.x * this.mass; - this.force.y -= 0.005 * this.fireDir.y * this.mass; - } - if (this.noseLength < 1.5) this.noseLength += this.fireFreq; - setNoseShape(); - } else if (this.noseLength > 0.1) { - this.noseLength -= this.fireFreq / 2; - setNoseShape(); + const setNoseShape = () => { + const mag = this.radius + this.radius * this.noseLength; + this.vertices[1].x = this.position.x + Math.cos(this.angle) * mag; + this.vertices[1].y = this.position.y + Math.sin(this.angle) * mag; + }; + //throw a mob/bullet at player + 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)); + // this.fireDir.y -= Math.abs(this.seePlayer.position.x - this.position.x) / 1600; //gives the bullet an arc } - // else if (this.noseLength < -0.1) { - // this.noseLength += this.fireFreq / 4; - // setNoseShape(); - // } + //rotate towards fireAngle + const angle = this.angle + Math.PI / 2; + // c = Math.cos(angle) * this.fireDir.x + Math.sin(angle) * this.fireDir.y; + //rotate towards fireAngle + const dot = Vector.dot({ + x: Math.cos(angle), + y: Math.sin(angle) + }, this.fireDir) + const threshold = 0.03; + if (dot > threshold) { + this.torque += 0.000004 * this.inertia; + } else if (dot < -threshold) { + this.torque -= 0.000004 * this.inertia; + } 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 = 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() + }); + this.noseLength = 0; + // recoil + this.force.x -= 0.005 * this.fireDir.x * this.mass; + this.force.y -= 0.005 * this.fireDir.y * this.mass; + } + if (this.noseLength < 1.5) this.noseLength += this.fireFreq; + setNoseShape(); + } else if (this.noseLength > 0.1) { + this.noseLength -= this.fireFreq / 2; + setNoseShape(); + } + // else if (this.noseLength < -0.1) { + // this.noseLength += this.fireFreq / 4; + // setNoseShape(); + // } - if (this.seePlayer.recall) { - if (this.alpha < 1) this.alpha += 0.01; - } else { - if (this.alpha > 0) this.alpha -= 0.03; - } + if (this.seePlayer.recall) { + if (this.alpha < 1) this.alpha += 0.01; + } else { + if (this.alpha > 0) this.alpha -= 0.03; } //draw if (this.alpha > 0) { @@ -4324,7 +4288,7 @@ const spawn = { this.seePlayerCheck(); this.checkStatus(); this.attraction(); - if (this.seePlayer.recall && !(simulation.cycle % this.fireFreq) && !m.isBodiesAsleep) { + if (this.seePlayer.recall && !(simulation.cycle % this.fireFreq)) { Matter.Body.setAngularVelocity(this, 0.14) spawn.seeker(this.vertices[0].x, this.vertices[0].y, 20, 9); //give the bullet a rotational velocity as if they were attached to a vertex const who = mob[mob.length - 1] @@ -4354,7 +4318,7 @@ const spawn = { this.seePlayerCheck(); this.checkStatus(); this.attraction(); - if (this.seePlayer.recall && !(simulation.cycle % this.fireFreq) && !m.isBodiesAsleep) { + if (this.seePlayer.recall && !(simulation.cycle % this.fireFreq)) { Matter.Body.setAngularVelocity(this, 0.14) //fire a bullet from each vertex for (let i = 0, len = this.vertices.length; i < len; i++) { @@ -4397,7 +4361,7 @@ const spawn = { this.checkStatus(); this.attraction(); this.repulsion(); - if (this.seePlayer.recall && !(simulation.cycle % this.fireFreq) && !m.isBodiesAsleep) { + if (this.seePlayer.recall && !(simulation.cycle % this.fireFreq)) { Matter.Body.setAngularVelocity(this, 0.11) //fire a bullet from each vertex for (let i = 0, len = this.vertices.length; i < len; i++) { @@ -4494,51 +4458,49 @@ const spawn = { this.seePlayerCheck(); this.checkStatus(); - if (!m.isBodiesAsleep) { - const setNoseShape = () => { - const mag = this.radius + this.radius * this.noseLength; - this.vertices[1].x = this.position.x + Math.cos(this.angle) * mag; - this.vertices[1].y = this.position.y + Math.sin(this.angle) * mag; - }; - //throw a mob/bullet at player - 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)); - // this.fireDir.y -= Math.abs(this.seePlayer.position.x - this.position.x) / 1600; //gives the bullet an arc - } - //rotate towards fireAngle - const angle = this.angle + Math.PI / 2; - // c = Math.cos(angle) * this.fireDir.x + Math.sin(angle) * this.fireDir.y; - //rotate towards fireAngle - const dot = Vector.dot({ - x: Math.cos(angle), - y: Math.sin(angle) - }, this.fireDir) - const threshold = 0.03; - if (dot > threshold) { - this.torque += 0.000004 * this.inertia; - } else if (dot < -threshold) { - this.torque -= 0.000004 * this.inertia; - } else if (this.noseLength > 1.5 && dot > -0.2 && dot < 0.2) { - //fire - spawn.grenade(this.vertices[1].x, this.vertices[1].y); - const v = 5 * 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() - }); - this.noseLength = 0; - // recoil - this.force.x -= 0.005 * this.fireDir.x * this.mass; - this.force.y -= 0.005 * this.fireDir.y * this.mass; - } - if (this.noseLength < 1.5) this.noseLength += this.fireFreq; - setNoseShape(); - } else if (this.noseLength > 0.1) { - this.noseLength -= this.fireFreq / 2; - setNoseShape(); + const setNoseShape = () => { + const mag = this.radius + this.radius * this.noseLength; + this.vertices[1].x = this.position.x + Math.cos(this.angle) * mag; + this.vertices[1].y = this.position.y + Math.sin(this.angle) * mag; + }; + //throw a mob/bullet at player + 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)); + // this.fireDir.y -= Math.abs(this.seePlayer.position.x - this.position.x) / 1600; //gives the bullet an arc } + //rotate towards fireAngle + const angle = this.angle + Math.PI / 2; + // c = Math.cos(angle) * this.fireDir.x + Math.sin(angle) * this.fireDir.y; + //rotate towards fireAngle + const dot = Vector.dot({ + x: Math.cos(angle), + y: Math.sin(angle) + }, this.fireDir) + const threshold = 0.03; + if (dot > threshold) { + this.torque += 0.000004 * this.inertia; + } else if (dot < -threshold) { + this.torque -= 0.000004 * this.inertia; + } else if (this.noseLength > 1.5 && dot > -0.2 && dot < 0.2) { + //fire + spawn.grenade(this.vertices[1].x, this.vertices[1].y); + const v = 5 * 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() + }); + this.noseLength = 0; + // recoil + this.force.x -= 0.005 * this.fireDir.x * this.mass; + this.force.y -= 0.005 * this.fireDir.y * this.mass; + } + if (this.noseLength < 1.5) this.noseLength += this.fireFreq; + setNoseShape(); + } else if (this.noseLength > 0.1) { + this.noseLength -= this.fireFreq / 2; + setNoseShape(); } }; }, @@ -4637,25 +4599,23 @@ const spawn = { ctx.strokeStyle = "rgb(255,255,255)" ctx.stroke(); - if (!m.isBodiesAsleep) { - this.cycle++ - if (this.cycle > this.maxCycles) { - this.cycle = 0 - ctx.beginPath(); - for (let i = 0; i < mob.length; i++) { - if (!mob[i].isShielded && !mob[i].shield && mob[i].isDropPowerUp && mob[i].alive && !mob[i].isBoss) { - ctx.moveTo(this.position.x, this.position.y) - ctx.lineTo(mob[i].position.x, mob[i].position.y) - spawn.shield(mob[i], mob[i].position.x, mob[i].position.y, 1, true); - // me.damageReduction = 0.075 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) - mob[mob.length - 1].damageReduction = 0.5 * 0.075 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) //shields are extra strong - } + this.cycle++ + if (this.cycle > this.maxCycles) { + this.cycle = 0 + ctx.beginPath(); + for (let i = 0; i < mob.length; i++) { + if (!mob[i].isShielded && !mob[i].shield && mob[i].isDropPowerUp && mob[i].alive && !mob[i].isBoss) { + ctx.moveTo(this.position.x, this.position.y) + ctx.lineTo(mob[i].position.x, mob[i].position.y) + spawn.shield(mob[i], mob[i].position.x, mob[i].position.y, 1, true); + // me.damageReduction = 0.075 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) + mob[mob.length - 1].damageReduction = 0.5 * 0.075 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) //shields are extra strong } - if (!this.isShielded && this.alive) spawn.shield(this, this.position.x, this.position.y, 1, true); - ctx.lineWidth = 20 - ctx.strokeStyle = "rgb(200,200,255)" - ctx.stroke(); } + if (!this.isShielded && this.alive) spawn.shield(this, this.position.x, this.position.y, 1, true); + ctx.lineWidth = 20 + ctx.strokeStyle = "rgb(200,200,255)" + ctx.stroke(); } }; }, @@ -4693,7 +4653,7 @@ const spawn = { this.repulsion(); this.cycle++ - if (this.seePlayer.recall && ((this.cycle % 15) === 0) && !m.isBodiesAsleep) { + if (this.seePlayer.recall && ((this.cycle % 15) === 0)) { if (this.canFire) { if (this.cycle > 120) { this.cycle = 0 @@ -4910,7 +4870,7 @@ const spawn = { this.checkStatus(); this.attraction(); this.cycle++ - if (this.seePlayer.recall && ((this.cycle % 10) === 0) && !m.isBodiesAsleep) { + if (this.seePlayer.recall && ((this.cycle % 10) === 0)) { if (this.canFire) { if (this.cycle > 120) { this.cycle = 0 diff --git a/todo.txt b/todo.txt index c769f6b..a9f7d42 100644 --- a/todo.txt +++ b/todo.txt @@ -1,16 +1,7 @@ ******************************************************** NEXT PATCH ************************************************** -exit door has a 1 second delay and animation - -reservoir map now has a flipped horizontal chance -map ruins renamed -> pavilion - -all the individual !m.isBodiesAsleep are replaced with ones in the main game loop - this needs extensive bug testing? - should behave similarly to testing mode, which doesn't have issues - todo remove the checks from bullets and mobs, do this after update so it can be easy to revert - -bug fixes +removed about 80 !m.isBodiesAsleep + this could cause some bugs for bullets or mobs when time is dilated ******************************************************** TODO ********************************************************