From c6afd8982c1cd4b8c77ed52941fbe7e01cb4d066 Mon Sep 17 00:00:00 2001 From: landgreen Date: Sun, 12 Jan 2020 11:05:47 -0800 Subject: [PATCH] mines are even more sticky, fixed quantum immortality --- js/bullets.js | 292 +++++++++++++++++++++++++------------------------- js/engine.js | 2 +- js/index.js | 7 -- js/level.js | 14 ++- js/player.js | 5 +- 5 files changed, 161 insertions(+), 159 deletions(-) diff --git a/js/bullets.js b/js/bullets.js index 2930f15..d88ab5a 100644 --- a/js/bullets.js +++ b/js/bullets.js @@ -31,7 +31,7 @@ const b = { modNailBotCount: null, modCollisionImmuneCycles: null, modBlockDmg: null, - modPiezo: null, + isModPiezo: null, setModDefaults() { b.modCount = 0; b.modFireRate = 1; @@ -60,7 +60,7 @@ const b = { b.modNailBotCount = 0; b.modCollisionImmuneCycles = 30; b.modBlockDmg = 0; - b.modPiezo = 0; + b.isModPiezo = false; mech.Fx = 0.015; mech.jumpForce = 0.38; mech.maxHealth = 1; @@ -262,11 +262,12 @@ const b = { }, { name: "piezoelectricity", //17 - description: "after colliding with enemies gain 50% energy", + description: "colliding with enemies fills your energy", maxCount: 1, count: 0, effect() { - b.modPiezo = 0.50 + b.isModPiezo = true; + mech.fieldMeter = mech.fieldEnergyMax; } }, { @@ -355,6 +356,7 @@ const b = { powerUps.spawn(mech.pos.x, mech.pos.y, "mod"); } b.setModDefaults(); // remove all mods + //have state is checked in mech.death() } }, { @@ -714,8 +716,134 @@ const b = { } } } + }, + mine(where, velocity, angle = 0) { + const bIndex = bullet.length; + bullet[bIndex] = Bodies.rectangle(where.x, where.y, 45 * b.modBulletSize, 16 * b.modBulletSize, { + angle: angle, + friction: 1, + frictionAir: 0, + restitution: 0, + dmg: 0, //damage done in addition to the damage from momentum + classType: "bullet", + collisionFilter: { + category: cat.bullet, + mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield | cat.bullet + }, + minDmgSpeed: 5, + stillCount: 0, + isArmed: false, + endCycle: game.cycle + 2000 + 360 * Math.random(), + lookFrequency: 41 + Math.floor(23 * Math.random()), + range: 700, + onDmg() {}, + do() { + this.force.y += this.mass * 0.002; //extra gravity + let collide = Matter.Query.collides(this, map) //check if collides with map + if (collide.length > 0) { + for (let i = 0; i < collide.length; i++) { + if (collide[i].bodyA.collisionFilter.category === cat.map || collide[i].bodyB.collisionFilter.category === cat.map) { + // console.log(collide) + const angle = Matter.Vector.angle(collide[i].normal, { + x: 1, + y: 0 + }) + if (angle > -0.2 || angle < -1.5) { //don't stick to level ground + Matter.Body.setAngle(this, Math.atan2(collide[i].tangent.y, collide[i].tangent.x)) + //move until touching map again after rotation + for (let j = 0; j < 10; j++) { + if (Matter.Query.collides(this, map).length > 0) { + Matter.Body.setStatic(this, true) //don't set to static if not touching map + this.arm(); - // Vector.magnitudeSquared(Vector.sub(bullet[me].position, mob[i].position)) + //sometimes the mine can't attach to map and it just needs to explode + const that = this + setTimeout(function () { + if (Matter.Query.collides(that, map).length === 0) { + that.endCycle = 0 // if not touching map explode + that.isArmed = false + b.mine(that.position, that.velocity, that.angle) + } + }, 100, that); + break + } + //move until you are touching the wall + Matter.Body.setPosition(this, Vector.add(this.position, Vector.mult(collide[i].normal, 2))) + } + } else if (this.speed < 1 && this.angularSpeed < 0.01 && !mech.isBodiesAsleep) { + this.stillCount += 2 + } + } + } + } else { + if (this.speed < 1 && this.angularSpeed < 0.01 && !mech.isBodiesAsleep) { + this.stillCount++ + } + } + if (this.stillCount > 35) this.arm(); + }, + arm() { + this.isArmed = true + game.drawList.push({ + //add dmg to draw queue + x: this.position.x, + y: this.position.y, + radius: 10, + color: "#f00", + time: 4 + }); + + this.do = function () { //overwrite the do method for this bullet + this.force.y += this.mass * 0.002; //extra gravity + if (!(game.cycle % this.lookFrequency)) { //find mob targets + for (let i = 0, len = mob.length; i < len; ++i) { + if (Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)) < 500000 && + mob[i].dropPowerUp && + Matter.Query.ray(map, this.position, mob[i].position).length === 0 && + Matter.Query.ray(body, this.position, mob[i].position).length === 0) { + this.endCycle = 0 //end life if mob is near and visible + } + } + } + } + }, + onEnd() { + if (this.isArmed) { + const targets = [] //target nearby mobs + for (let i = 0, len = mob.length; i < len; i++) { + if (mob[i].dropPowerUp) { + const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)); + if (dist < 1440000 && //1200*1200 + Matter.Query.ray(map, this.position, mob[i].position).length === 0 && + Matter.Query.ray(body, this.position, mob[i].position).length === 0) { + targets.push(Vector.add(mob[i].position, Vector.mult(mob[i].velocity, Math.sqrt(dist) / 60))) //predict where the mob will be in a few cycles + } + } + } + for (let i = 0; i < 16; i++) { + const speed = 53 + 10 * Math.random() + if (targets.length > 0) { // aim near a random target in array + const index = Math.floor(Math.random() * targets.length) + const SPREAD = 150 / targets.length + const WHERE = { + x: targets[index].x + SPREAD * (Math.random() - 0.5), + y: targets[index].y + SPREAD * (Math.random() - 0.5) + } + b.nail(this.position, Vector.mult(Vector.normalise(Vector.sub(WHERE, this.position)), speed), 1) + } else { // aim in random direction + const ANGLE = 2 * Math.PI * Math.random() + b.nail(this.position, { + x: speed * Math.cos(ANGLE), + y: speed * Math.sin(ANGLE) + }) + } + } + } + } + }); + bullet[bIndex].torque += bullet[bIndex].inertia * 0.0001 * (0.5 - Math.random()) + Matter.Body.setVelocity(bullet[bIndex], velocity); + World.add(engine.world, bullet[bIndex]); //add bullet to world }, spore(who) { //used with the mod upgrade in mob.death() const bIndex = bullet.length; @@ -1730,153 +1858,21 @@ const b = { } }, { name: "mine", //10 - description: "drop a proximity mine that sticks to walls
fires nails at enemies within range", + description: "toss a proximity mine that sticks to walls
fires nails at enemies within range", ammo: 0, - ammoPack: 4, + ammoPack: 3, have: false, isStarterGun: false, fire() { - const me = bullet.length; - const dir = mech.angle; - if (mech.crouch) { - bullet[me] = Bodies.rectangle(mech.pos.x + 35 * Math.cos(mech.angle), mech.pos.y + 35 * Math.sin(mech.angle), 45 * b.modBulletSize, 16 * b.modBulletSize, { - angle: 0, - friction: 1, - frictionAir: 0, - dmg: 0, //damage done in addition to the damage from momentum - classType: "bullet", - collisionFilter: { - category: cat.bullet, - mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield | cat.bullet - }, - minDmgSpeed: 5, - onDmg() {}, - onEnd() {} - }); - mech.fireCDcycle = mech.cycle + Math.floor(35 * b.modFireRate); // cool down - Matter.Body.setVelocity(bullet[me], { - x: mech.Vx / 2 + 26 * Math.cos(dir), - y: mech.Vy / 2 + 26 * Math.sin(dir) - }); - bullet[me].torque += bullet[me].inertia * 0.0001 * (0.5 - Math.random()) - } else { - bullet[me] = Bodies.rectangle(mech.pos.x, mech.pos.y + 25, 45 * b.modBulletSize, 16 * b.modBulletSize, { - angle: 0, - friction: 1, - frictionAir: 0, - dmg: 0, //damage done in addition to the damage from momentum - classType: "bullet", - collisionFilter: { - category: cat.bullet, - mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield | cat.bullet - }, - minDmgSpeed: 5, - onDmg() {}, - onEnd() {} - }); - mech.fireCDcycle = mech.cycle + Math.floor(20 * b.modFireRate); // cool down - Matter.Body.setVelocity(bullet[me], { - x: mech.Vx, - y: mech.Vy - }); - } - World.add(engine.world, bullet[me]); //add bullet to world - bullet[me].endCycle = game.cycle + 2000 + 360 * Math.random(); - bullet[me].restitution = 0; - bullet[me].lookFrequency = 41 + Math.floor(23 * Math.random()) - bullet[me].range = 700 - - bullet[me].arm = function () { - this.do = function () { //overwrite the do method for this bullet - this.force.y += this.mass * 0.002; //extra gravity - if (!(game.cycle % this.lookFrequency)) { //find mob targets - for (let i = 0, len = mob.length; i < len; ++i) { - if (Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)) < 500000 && - mob[i].dropPowerUp && - Matter.Query.ray(map, this.position, mob[i].position).length === 0 && - Matter.Query.ray(body, this.position, mob[i].position).length === 0) { - this.endCycle = 0 //end life if mob is near and visible - } - } - } - } - } - bullet[me].do = function () { - this.force.y += this.mass * 0.002; //extra gravity - let collide = Matter.Query.collides(this, map) //check if collides with map - if (collide.length > 0) { - for (let i = 0; i < collide.length; i++) { - if (collide[i].bodyA.collisionFilter.category === cat.map || collide[i].bodyB.collisionFilter.category === cat.map) { - // console.log(collide) - const angle = Matter.Vector.angle(collide[i].normal, { - x: 1, - y: 0 - }) - if (angle > -0.2 || angle < -1.5) { //don't stick to level ground - Matter.Body.setAngle(this, Math.atan2(collide[i].tangent.y, collide[i].tangent.x)) - //move until touching map again after rotation - for (let j = 0; j < 10; j++) { - if (Matter.Query.collides(this, map).length > 0) { - Matter.Body.setStatic(this, true) //don't set to static if not touching map - this.arm(); - - //sometimes the mine can't attach to map and it just needs to explode - const who = this - setTimeout(function () { - if (Matter.Query.collides(who, map).length === 0) who.endCycle = 0 // if not touching map explode - }, 100, who); - break - } - //move until you are touching the wall - Matter.Body.setPosition(this, Vector.add(this.position, Vector.mult(collide[i].normal, 2))) - } - } else if (this.speed < 1) { - this.arm(); - } - } - } - } else if (this.speed < 1) { //check if collides with a body - collide = Matter.Query.collides(this, body) - if (collide.length > 0) { - for (let i = 0; i < collide.length; i++) { - if (collide[i].bodyA.collisionFilter.category === cat.body || collide[i].bodyB.collisionFilter.category === cat.body) { - this.arm(); - } - } - } - } - } - bullet[me].onEnd = function () { - const targets = [] //target nearby mobs - for (let i = 0, len = mob.length; i < len; i++) { - if (mob[i].dropPowerUp) { - const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)); - if (dist < 1440000 && //1200*1200 - Matter.Query.ray(map, this.position, mob[i].position).length === 0 && - Matter.Query.ray(body, this.position, mob[i].position).length === 0) { - targets.push(Vector.add(mob[i].position, Vector.mult(mob[i].velocity, Math.sqrt(dist) / 60))) //predict where the mob will be in a few cycles - } - } - } - for (let i = 0; i < 16; i++) { - const speed = 53 + 10 * Math.random() - if (targets.length > 0) { // aim near a random target in array - const index = Math.floor(Math.random() * targets.length) - const SPREAD = 150 / targets.length - const WHERE = { - x: targets[index].x + SPREAD * (Math.random() - 0.5), - y: targets[index].y + SPREAD * (Math.random() - 0.5) - } - b.nail(this.position, Vector.mult(Vector.normalise(Vector.sub(WHERE, this.position)), speed), 0.8) - } else { // aim in random direction - const ANGLE = 2 * Math.PI * Math.random() - b.nail(this.position, { - x: speed * Math.cos(ANGLE), - y: speed * Math.sin(ANGLE) - }) - } - } - } + const speed = mech.crouch ? 34 : 20 + b.mine({ + x: mech.pos.x + 30 * Math.cos(mech.angle), + y: mech.pos.y + 30 * Math.sin(mech.angle) + }, { + x: speed * Math.cos(mech.angle), + y: speed * Math.sin(mech.angle) + }) + mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 60 : 40) * b.modFireRate); // cool down } }, { diff --git a/js/engine.js b/js/engine.js index f28f3eb..008aff5 100644 --- a/js/engine.js +++ b/js/engine.js @@ -138,7 +138,7 @@ function collisionChecks(event) { let dmg = Math.min(Math.max(0.025 * Math.sqrt(mob[k].mass), 0.05), 0.3) * game.dmgScale; //player damage is capped at 0.3*dmgScale of 1.0 mech.damage(dmg); if (mob[k].onHit) mob[k].onHit(k); - mech.fieldMeter += b.modPiezo + if (b.isModPiezo) mech.fieldMeter = mech.fieldEnergyMax; if (b.isModAnnihilation && mob[k].dropPowerUp && !mob[k].isShielded) { mob[k].death(); game.drawList.push({ diff --git a/js/index.js b/js/index.js index 3f70747..e73d928 100644 --- a/js/index.js +++ b/js/index.js @@ -4,13 +4,6 @@ add setting for random drops instead of choosing -mines: move targeting position to be perpendicular to stuck wall -mines change shape of mine (maybe a octagon?) -mines: collide with bots - probably don't have to fix... -mines: add high friction, like vacuum bomb and trigger static mode after not moving for a bit - no need to watch collisions - rework custom mode custom mode grey out mods that are bad, like selection based mods enable recursive mods diff --git a/js/level.js b/js/level.js index 802de2b..94afde4 100644 --- a/js/level.js +++ b/js/level.js @@ -14,7 +14,7 @@ const level = { start() { if (level.levelsCleared === 0) { // game.difficulty = 6; //for testing to simulate possible mobs spawns - b.giveGuns(10) + // b.giveGuns(10) // mech.setField(3) // b.giveMod(3); @@ -1569,7 +1569,17 @@ const level = { } }, levelAnnounce() { - document.title = "n-gon: L" + (level.levelsCleared) + " " + level.levels[level.onLevel]; + let mode = document.getElementById("difficulty-select").value + if (mode === "0") { + mode = "(easy)" + } else if (mode === "1") { + mode = "(normal)" + } else if (mode === "2") { + mode = "(hard)" + } else if (mode === "6") { + mode = "(why)" + } + document.title = "n-gon: L" + (level.levelsCleared) + " " + level.levels[level.onLevel] + " " + mode; // game.makeTextLog(`
level ${game.difficulty}
${level.levels[level.onLevel]}
`, 300); // if (game.difficulty === 0) text = ""; // text = "Level " + (game.difficulty + 1) + ": " + spawn.pickList[0] + "s + " + spawn.pickList[1] + "s"; diff --git a/js/player.js b/js/player.js index 26bc956..83052b0 100644 --- a/js/player.js +++ b/js/player.js @@ -307,13 +307,16 @@ const mech = { function randomizeMods() { b.setModDefaults(); //remove all mods + //remove all bullets + for (let i = 0; i < bullet.length; ++i) Matter.World.remove(engine.world, bullet[i]); + bullet = []; for (let i = 0; i < totalMods; i++) { //find what mods I don't have let options = []; for (let i = 0, len = b.mods.length; i < len; i++) { //can't get quantum immortality or multiverse if (b.mods[i].name !== "quantum immortality" && - b.mods[i].name !== "level II multiverse" && + b.mods[i].name !== "Born rule" && b.mods[i].count < b.mods[i].maxCount) options.push(i); } //add a new mod