diff --git a/js/bullets.js b/js/bullets.js index 0b1bfc1..1928669 100644 --- a/js/bullets.js +++ b/js/bullets.js @@ -926,7 +926,7 @@ const b = { }, { name: "super ball", - description: "fire one large super ball
that stuns mobs for 2 second", + description: "fire one large super ball
that stuns mobs for 3 second", maxCount: 1, count: 0, allowed() { @@ -1338,7 +1338,7 @@ const b = { }, { name: "renormalization", - description: "phase decoherence field has 3x visibility
and 1/3 energy drain when firing", + description: "phase decoherence field has 3x visibility
and 3x less energy drain when firing", maxCount: 1, count: 0, allowed() { @@ -1353,8 +1353,9 @@ const b = { } }, { - name: "quantum dissipation", - description: "phase decoherence field uses energy to
damage unshielded mobs that you overlap", + name: "superposition", + // description: "phase decoherence field applies a stun
to unshielded mobs for 2 seconds", + description: "apply a 4 second stun to unshielded mobs
that overlap with phase decoherence field", maxCount: 1, count: 0, allowed() { @@ -1362,10 +1363,10 @@ const b = { }, requires: "phase decoherence field", effect() { - b.isModPhaseFieldDamage = true; + b.superposition = true; }, remove() { - b.isModPhaseFieldDamage = false; + b.superposition = false; } }, ], @@ -2478,7 +2479,7 @@ const b = { this.force.y += this.mass * 0.001; }; bullet[me].onDmg = function (who) { - mobs.statusStun(who, 120) // (2.3) * 2 / 14 ticks (2x damage over 7 seconds) + mobs.statusStun(who, 180) // (2.3) * 2 / 14 ticks (2x damage over 7 seconds) }; } else { b.muzzleFlash(20); diff --git a/js/game.js b/js/game.js index b773138..f14563d 100644 --- a/js/game.js +++ b/js/game.js @@ -601,7 +601,7 @@ const game = { if (game.isCommunityMaps) level.levels.push("stronghold"); level.levels = shuffle(level.levels); //shuffles order of maps level.levels.unshift("bosses"); //add bosses level to the end of the randomized levels list - console.log(level.levels) + // console.log(level.levels) } game.reset(); game.firstRun = false; diff --git a/js/index.js b/js/index.js index a40ab83..2ae60fa 100644 --- a/js/index.js +++ b/js/index.js @@ -1,6 +1,6 @@ "use strict"; //collision groups -// cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet | cat.mobShield +// cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet | cat.mobShield | cat.phased const cat = { player: 0x1, map: 0x10, @@ -10,6 +10,7 @@ const cat = { mob: 0x100000, mobBullet: 0x1000000, mobShield: 0x10000000, + phased: 0x100000000, } //example https://landgreen.github.io/sidescroller/index.html? diff --git a/js/level.js b/js/level.js index 85083a1..7c2f692 100644 --- a/js/level.js +++ b/js/level.js @@ -147,8 +147,8 @@ const level = { spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump // spawn.laserBoss(2900, -500) - // spawn.exploder(3200, -500) - spawn.timeSkipBoss(2900, -500) + spawn.springer(3200, -500) + // spawn.timeSkipBoss(2900, -500) // spawn.randomMob(3200, -500) }, diff --git a/js/mobs.js b/js/mobs.js index a73e967..ee16ba8 100644 --- a/js/mobs.js +++ b/js/mobs.js @@ -485,10 +485,10 @@ const mobs = { } }, searchSpring() { + //draw the two dots on the end of the springs ctx.beginPath(); ctx.arc(this.cons.pointA.x, this.cons.pointA.y, 6, 0, 2 * Math.PI); ctx.arc(this.cons2.pointA.x, this.cons2.pointA.y, 6, 0, 2 * Math.PI); - // ctx.arc(this.cons.bodyB.position.x, this.cons.bodyB.position.y,6,0,2*Math.PI); ctx.fillStyle = "#222"; ctx.fill(); @@ -501,25 +501,28 @@ const mobs = { !mech.isStealth ) { this.foundPlayer(); - if (!(game.cycle % (this.seePlayerFreq * 2))) { - this.springTarget.x = this.seePlayer.position.x; - this.springTarget.y = this.seePlayer.position.y; - this.cons.length = -200; - this.cons2.length = 100 + 1.5 * this.radius; - } else { - this.springTarget2.x = this.seePlayer.position.x; - this.springTarget2.y = this.seePlayer.position.y; - this.cons.length = 100 + 1.5 * this.radius; - this.cons2.length = -200; - } } else if (this.seePlayer.recall) { this.lostPlayer(); } } - //if you don't recall player location rotate and draw to show where you are looking - if (!this.seePlayer.recall) { + }, + springAttack() { + // set new values of the ends of the spring constraints + if (this.seePlayer.recall) { + if (!(game.cycle % (this.seePlayerFreq * 2))) { + this.springTarget.x = this.seePlayer.position.x; + this.springTarget.y = this.seePlayer.position.y; + this.cons.length = -200; + this.cons2.length = 100 + 1.5 * this.radius; + } else { + this.springTarget2.x = this.seePlayer.position.x; + this.springTarget2.y = this.seePlayer.position.y; + this.cons.length = 100 + 1.5 * this.radius; + this.cons2.length = -200; + } + } else { this.torque = this.lookTorque * this.inertia; - //draw + //draw looking around arcs const range = Math.PI * this.lookRange; ctx.beginPath(); ctx.arc(this.position.x, this.position.y, this.radius * 2.5, this.angle - range, this.angle + range); @@ -567,8 +570,8 @@ const mobs = { } } }; - const seeRange = 3000; - if (!(game.cycle % (this.seePlayerFreq * 10))) { + //move to a random location + if (!(game.cycle % (this.seePlayerFreq * 5))) { best = { x: null, y: null, @@ -577,6 +580,7 @@ const mobs = { v1: null, v2: null }; + const seeRange = 3000; const look = { x: this.position.x + seeRange * Math.cos(this.angle), y: this.position.y + seeRange * Math.sin(this.angle) @@ -589,27 +593,6 @@ const mobs = { this.cons2.length = 100 + 1.5 * this.radius; } } - if (!((game.cycle + this.seePlayerFreq * 5) % (this.seePlayerFreq * 10))) { - best = { - x: null, - y: null, - dist2: Infinity, - who: null, - v1: null, - v2: null - }; - const look = { - x: this.position.x + seeRange * Math.cos(this.angle), - y: this.position.y + seeRange * Math.sin(this.angle) - }; - vertexCollision(this.position, look, map); - if (best.dist2 != Infinity) { - this.springTarget2.x = best.x; - this.springTarget2.y = best.y; - this.cons.length = 100 + 1.5 * this.radius; - this.cons2.length = 100 + 1.5 * this.radius; - } - } } }, alertNearByMobs() { @@ -805,6 +788,7 @@ const mobs = { if (this.seePlayer.recall && this.cd < game.cycle) { const dist = Vector.sub(this.seePlayer.position, this.position); const distMag = Vector.magnitude(dist); + console.log(this.seePlayer.recall) if (distMag < 400) { this.cd = game.cycle + this.delay; ctx.beginPath(); diff --git a/js/player.js b/js/player.js index ccef669..b129cf4 100644 --- a/js/player.js +++ b/js/player.js @@ -1787,7 +1787,7 @@ const mech = { mech.grabPowerUp(); mech.lookForPickUp(); - const DRAIN = (0.0005 + 0.0001 * player.speed) * (mech.fireCDcycle > mech.cycle ? 10 / b.modRenormalization : 1) //game.mouseDown + const DRAIN = (0.0005 + 0.0001 * player.speed) * (mech.fireCDcycle > mech.cycle ? 9 / b.modRenormalization : 1) //game.mouseDown if (mech.energy > DRAIN) { mech.energy -= DRAIN; if (mech.energy < 0.001) { @@ -1805,14 +1805,15 @@ const mech = { if (inPlayer.length > 0) { for (let i = 0; i < inPlayer.length; i++) { if (inPlayer[i].shield) { - mech.energy -= 0.005; //shields drain player energy + mech.energy -= 0.01; //shields drain player energy //draw outline of shield ctx.fillStyle = `rgba(0, 204, 255,0.6)` ctx.fill() - } else if (b.isModPhaseFieldDamage && mech.energy > 0.006 && inPlayer[i].dropPowerUp && !inPlayer[i].isShielded) { - inPlayer[i].damage(0.4 * b.dmgScale); //damage mobs inside the player - mech.energy -= 0.002; + } else if (b.superposition && inPlayer[i].dropPowerUp) { + // inPlayer[i].damage(0.4 * b.dmgScale); //damage mobs inside the player + // mech.energy += 0.005; + mobs.statusStun(inPlayer[i], 240) //draw outline of mob in a few random locations to show blurriness const vertices = inPlayer[i].vertices; const off = 30 @@ -1825,11 +1826,8 @@ const mech = { ctx.lineTo(xOff + vertices[j].x, yOff + vertices[j].y); } ctx.lineTo(xOff + vertices[0].x, yOff + vertices[0].y); - ctx.fillStyle = "rgba(0,0,0,0.3)" + ctx.fillStyle = "rgba(0,0,0,0.1)" ctx.fill() - // ctx.strokeStyle = "#000" - // ctx.lineWidth = 1 - // ctx.stroke() } break; } diff --git a/js/spawn.js b/js/spawn.js index 7a92ac5..d5a3af9 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -182,6 +182,7 @@ const spawn = { me.do = function () { if (!mech.isBodiesAsleep) { this.seePlayerByDistOrLOS(); + this.checkStatus(); this.attraction(); if (this.seePlayer.recall && this.mass < this.cellMassMax) { //grow cell radius @@ -205,7 +206,6 @@ const spawn = { } } } - this.checkStatus() }; me.onDeath = function () { let count = 0 //count other cells @@ -318,8 +318,8 @@ const spawn = { me.do = function () { this.gravity(); this.seePlayerCheck(); - this.attraction(); this.checkStatus(); + this.attraction(); }; }, grower(x, y, radius = 15) { @@ -329,9 +329,9 @@ const spawn = { me.accelMag = 0.00045 * game.accelScale; me.do = function () { this.seePlayerByLookingAt(); + this.checkStatus(); this.attraction(); this.grow(); - this.checkStatus(); }; }, springer(x, y, radius = 20 + Math.ceil(Math.random() * 35)) { @@ -381,6 +381,8 @@ const spawn = { this.gravity(); this.searchSpring(); this.checkStatus(); + this.springAttack(); + //not properly effected by stun, if looking at player while stun will still attack... }; }, hopper(x, y, radius = 30 + Math.ceil(Math.random() * 30)) { @@ -397,6 +399,7 @@ const spawn = { me.do = function () { this.gravity(); this.seePlayerCheck(); + this.checkStatus(); this.hop(); //randomly hob if not aware of player if (this.randomHopCD < game.cycle && this.speed < 1 && !this.seePlayer.recall) { @@ -408,7 +411,6 @@ const spawn = { this.force.x += forceMag * Math.cos(angle); this.force.y += forceMag * Math.sin(angle) - 0.04 * this.mass; //antigravity } - this.checkStatus(); }; }, spinner(x, y, radius = 30 + Math.ceil(Math.random() * 35)) { @@ -430,6 +432,7 @@ const spawn = { spawn.shield(me, x, y); me.do = function () { this.seePlayerByLookingAt(); + this.checkStatus(); //accelerate towards the player after a delay if (this.seePlayer.recall) { if (this.cdBurst2 < game.cycle && this.angularSpeed < 0.01) { @@ -463,7 +466,6 @@ const spawn = { } else { this.cdBurst2 = 0; } - this.checkStatus(); }; }, sucker(x, y, radius = 30 + Math.ceil(Math.random() * 70)) { @@ -486,6 +488,7 @@ const spawn = { }); } this.seePlayerByDistOrLOS(); + this.checkStatus(); if (this.seePlayer.recall) { //eventHorizon waves in and out eventHorizon = this.eventHorizon * (0.93 + 0.17 * Math.sin(game.cycle * 0.011)) @@ -533,7 +536,6 @@ const spawn = { ctx.fill(); } } - this.checkStatus(); } }, suckerBoss(x, y, radius = 25) { @@ -575,6 +577,7 @@ const spawn = { }); } this.seePlayerByDistOrLOS(); + this.checkStatus(); if (this.seePlayer.recall) { //accelerate towards the player const forceMag = this.accelMag * this.mass; @@ -633,7 +636,6 @@ const spawn = { } this.curl(eventHorizon); } - this.checkStatus(); } }, timeSkipBoss(x, y, radius = 80) { @@ -654,6 +656,7 @@ const spawn = { me.do = function () { //keep it slow, to stop issues from explosion knock backs this.seePlayerCheck(); + this.checkStatus(); this.attraction() if (!game.isTimeSkipping) { const compress = 3 @@ -704,8 +707,6 @@ const spawn = { ctx.fill(); } } - - this.checkStatus(); } }, beamer(x, y, radius = 15 + Math.ceil(Math.random() * 15)) { @@ -719,11 +720,11 @@ const spawn = { spawn.shield(me, x, y); me.do = function () { this.seePlayerByLookingAt(); + this.checkStatus(); this.attraction(); this.repulsion(); //laser beam this.laserBeam(); - this.checkStatus(); }; }, focuser(x, y, radius = 30 + Math.ceil(Math.random() * 10)) { @@ -744,6 +745,7 @@ const spawn = { me.do = function () { if (!mech.isBodiesAsleep) { this.seePlayerByLookingAt(); + this.checkStatus(); const dist2 = this.distanceToPlayer2(); //laser Tracking if (this.seePlayer.yes && dist2 < 4000000 && !mech.isStealth) { @@ -787,7 +789,6 @@ const spawn = { this.laserPos = this.position; } }; - this.checkStatus(); } }, laser(x, y, radius = 30) { @@ -802,9 +803,9 @@ const spawn = { }; me.do = function () { this.seePlayerByLookingAt(); + this.checkStatus(); this.attraction(); this.laser(); - this.checkStatus(); }; }, laserBoss(x, y, radius = 30) { @@ -937,11 +938,11 @@ const spawn = { this.cd = game.cycle + this.delay; }; me.do = function () { - this.seePlayerCheck(); - this.attraction(); this.gravity(); - this.strike(); + this.seePlayerCheck(); this.checkStatus(); + this.attraction(); + this.strike(); }; }, sneaker(x, y, radius = 15 + Math.ceil(Math.random() * 25)) { @@ -958,9 +959,10 @@ const spawn = { me.showHealthBar = false; // me.memory = 420; me.do = function () { - this.seePlayerCheck(); - this.attraction(); this.gravity(); + this.seePlayerCheck(); + this.checkStatus(); + this.attraction(); //draw if (!mech.isBodiesAsleep) { if (this.seePlayer.yes) { @@ -991,7 +993,6 @@ const spawn = { this.canTouchPlayer = false; this.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob //can't touch player } - this.checkStatus(); }; }, ghoster(x, y, radius = 40 + Math.ceil(Math.random() * 100)) { @@ -1018,6 +1019,7 @@ const spawn = { }); } this.seePlayerCheckByDistance(); + this.checkStatus(); this.attraction(); this.search(); //draw @@ -1049,7 +1051,6 @@ const spawn = { this.canTouchPlayer = false; this.collisionFilter.mask = cat.bullet; //can't touch player or walls } - this.checkStatus(); }; }, // blinker(x, y, radius = 45 + Math.ceil(Math.random() * 70)) { @@ -1122,10 +1123,12 @@ const spawn = { }; me.do = function () { this.seePlayerCheckByDistance(); - this.hoverOverPlayer(); - this.bomb(); - this.search(); this.checkStatus(); + if (this.seePlayer.recall) { + this.hoverOverPlayer(); + this.bomb(); + this.search(); + } }; }, shooter(x, y, radius = 25 + Math.ceil(Math.random() * 50)) { @@ -1146,8 +1149,8 @@ const spawn = { // spawn.shield(me, x, y); me.do = function () { this.seePlayerByLookingAt(); - this.fire(); this.checkStatus(); + this.fire(); }; }, shooterBoss(x, y, radius = 130) { @@ -1176,12 +1179,12 @@ const spawn = { }; me.do = function () { this.seePlayerByLookingAt(); + this.checkStatus(); this.fire(); //gently return to starting location const sub = Vector.sub(this.homePosition, this.position) const dist = Vector.magnitude(sub) if (dist > 50) this.force = Vector.mult(Vector.normalise(sub), this.mass * 0.0002) - this.checkStatus(); }; }, bullet(x, y, radius = 6, sides = 0) { @@ -1226,8 +1229,8 @@ const spawn = { me.do = function () { this.gravity(); this.seePlayerCheck(); - this.attraction(); this.checkStatus(); + this.attraction(); }; }, spawns(x, y, radius = 15 + Math.ceil(Math.random() * 5)) { @@ -1246,8 +1249,8 @@ const spawn = { me.do = function () { this.gravity(); this.seePlayerCheck(); - this.attraction(); this.checkStatus(); + this.attraction(); }; }, exploder(x, y, radius = 25 + Math.ceil(Math.random() * 50)) { @@ -1261,8 +1264,8 @@ const spawn = { me.do = function () { this.gravity(); this.seePlayerCheck(); - this.attraction(); this.checkStatus(); + this.attraction(); }; }, snakeBoss(x, y, radius = 80) { @@ -1279,9 +1282,9 @@ const spawn = { }; me.do = function () { this.seePlayerCheck(); + this.checkStatus(); this.attraction(); this.laserBeam(); - this.checkStatus(); }; //snake tail @@ -1322,8 +1325,8 @@ const spawn = { me.do = function () { this.gravity(); this.seePlayerCheck(); - this.attraction(); this.checkStatus(); + this.attraction(); }; }, shield(target, x, y, chance = Math.min(0.02 + game.difficulty * 0.005, 0.2)) { diff --git a/todo.txt b/todo.txt index ee0d005..f23f278 100644 --- a/todo.txt +++ b/todo.txt @@ -1,5 +1,10 @@ ************** TODO - n-gon ************** +boss mob - just a faster and larger version of a springer mob + could have a more frequent random walk + always shielded + consider combining with time skipper field? + pulse and time dilation only ones left with no dedicated mod lore - a robot (the player) gains self awareness