From fd67ee9aaed3da560acafe7932d9d881c5953d30 Mon Sep 17 00:00:00 2001 From: landgreen Date: Fri, 8 May 2020 09:48:35 -0700 Subject: [PATCH] sporangium sticks to things sporangium gun now sticks to things, takes longer to germinate, ammo and fire rate are increased. plasma field does 50% more damage, pushes 20% harder, but has 20% less range --- js/bullets.js | 162 ++++++++++++++++++++++++++++++++++++-------------- js/level.js | 7 ++- js/player.js | 40 +++++++++---- js/spawn.js | 28 ++++----- todo.txt | 14 ++--- 5 files changed, 167 insertions(+), 84 deletions(-) diff --git a/js/bullets.js b/js/bullets.js index c153c3c..a5bf92d 100644 --- a/js/bullets.js +++ b/js/bullets.js @@ -592,7 +592,7 @@ const b = { b.isModEntanglement = true setTimeout(function () { game.boldActiveGunHUD(); - }, 10); + }, 1000); }, remove() { @@ -1232,7 +1232,7 @@ const b = { { name: "water shielding", description: "increase neutron bomb's range by 20%
player is immune to its harmful effects", - maxCount: 3, + maxCount: 1, count: 0, allowed() { return b.haveGunCheck("neutron bomb") @@ -1605,7 +1605,7 @@ const b = { }, { name: "renormalization", - description: "phase decoherence has increased visibility
and 3x less energy drain when firing", + description: "phase decoherence has increased visibility
and 5x less energy drain when firing", maxCount: 1, count: 0, allowed() { @@ -1638,7 +1638,7 @@ const b = { }, { name: "Bose Einstein condensate", - description: "mobs in superposition with the pilot wave
are frozen for 2 second", + description: "mobs in superposition with the pilot wave
are frozen for 2 seconds", maxCount: 1, count: 0, allowed() { @@ -3312,7 +3312,7 @@ const b = { bullet[me].restitution = 0; bullet[me].minDmgSpeed = 0; bullet[me].damageRadius = 100; - bullet[me].maxDamageRadius = (450 + 150 * Math.random()) * (b.isModNeutronImmune ? 1.2 : 1) + bullet[me].maxDamageRadius = (425 + 125 * Math.random()) * (b.isModNeutronImmune ? 1.2 : 1) bullet[me].stuckTo = null; bullet[me].stuckToRelativePosition = null; bullet[me].onDmg = function () {}; @@ -3387,6 +3387,8 @@ const b = { const rotate = Vector.rotate(this.stuckToRelativePosition, this.stuckTo.angle) //add in the mob's new angle to the relative position vector Matter.Body.setPosition(this, Vector.add(Vector.add(rotate, this.stuckTo.velocity), this.stuckTo.position)) // Matter.Body.setVelocity(this, this.stuckTo.velocity); //so that it will move properly if it gets unstuck + } else { + this.force.y += this.mass * 0.001; } } } else { @@ -3404,46 +3406,46 @@ const b = { } } } - - }; + } bullet[me].radiationMode = function () { this.stuck(); //runs different code based on what the bullet is stuck to if (!mech.isBodiesAsleep) { this.damageRadius = this.damageRadius * 0.85 + 0.15 * this.maxDamageRadius //smooth radius towards max this.maxDamageRadius -= 0.8 / b.isModBulletsLastLonger //+ 0.5 * Math.sin(game.cycle * 0.1) //slowly shrink max radius - } - if (this.damageRadius < 15) { - this.endCycle = 0; - } else { - //aoe damage to player - if (!b.isModNeutronImmune && Vector.magnitude(Vector.sub(player.position, this.position)) < this.damageRadius) { - const DRAIN = 0.0015 - if (mech.energy > DRAIN) { - mech.energy -= DRAIN - } else { - mech.energy = 0; - mech.damage(0.00015) - } - } - //aoe damage to mobs - for (let i = 0, len = mob.length; i < len; i++) { - if (Vector.magnitude(Vector.sub(mob[i].position, this.position)) < this.damageRadius) { - if (mob[i].shield) { - mob[i].damage(5 * b.dmgScale * 0.025); + if (this.damageRadius < 15) { + this.endCycle = 0; + } else { + //aoe damage to player + + if (!b.isModNeutronImmune && Vector.magnitude(Vector.sub(player.position, this.position)) < this.damageRadius) { + const DRAIN = 0.0015 + if (mech.energy > DRAIN) { + mech.energy -= DRAIN } else { - mob[i].damage(b.dmgScale * 0.025); + mech.energy = 0; + mech.damage(0.00015) } - mob[i].locatePlayer(); } + //aoe damage to mobs + for (let i = 0, len = mob.length; i < len; i++) { + if (Vector.magnitude(Vector.sub(mob[i].position, this.position)) < this.damageRadius) { + if (mob[i].shield) { + mob[i].damage(5 * b.dmgScale * 0.023); + } else { + mob[i].damage(b.dmgScale * 0.023); + } + mob[i].locatePlayer(); + } + } + ctx.beginPath(); + ctx.arc(this.position.x, this.position.y, this.damageRadius, 0, 2 * Math.PI); + ctx.globalCompositeOperation = "lighter" + ctx.fillStyle = `rgba(25,139,170,${0.2+0.06*Math.random()})`; + ctx.fill(); + ctx.globalCompositeOperation = "source-over" } - ctx.beginPath(); - ctx.arc(this.position.x, this.position.y, this.damageRadius, 0, 2 * Math.PI); - ctx.globalCompositeOperation = "lighter" - ctx.fillStyle = `rgba(25,139,170,${0.3+0.06*Math.random()})`; - ctx.fill(); - ctx.globalCompositeOperation = "source-over" } } } @@ -3472,7 +3474,7 @@ const b = { name: "spores", description: "fire a sporangium that discharges spores", ammo: 0, - ammoPack: (game.difficultyMode > 3) ? 3 : 4, + ammoPack: 5, have: false, isStarterGun: false, isEasyToAim: true, @@ -3480,33 +3482,105 @@ const b = { const me = bullet.length; const dir = mech.angle; bullet[me] = Bodies.polygon(mech.pos.x + 30 * Math.cos(mech.angle), mech.pos.y + 30 * Math.sin(mech.angle), 20, 4.5, b.fireAttributes(dir, false)); - b.fireProps(mech.crouch ? 60 : 40, mech.crouch ? 28 : 14, dir, me); //cd , speed + b.fireProps(mech.crouch ? 50 : 30, mech.crouch ? 30 : 16, dir, me); //cd , speed Matter.Body.setDensity(bullet[me], 0.000001); - bullet[me].endCycle = game.cycle + 80; + bullet[me].endCycle = Infinity; bullet[me].frictionAir = 0; bullet[me].friction = 0.5; + bullet[me].radius = 4.5; + bullet[me].maxRadius = 30; bullet[me].restitution = 0.3; bullet[me].minDmgSpeed = 0; + bullet[me].stuck = function () {}; bullet[me].onDmg = function () {}; bullet[me].do = function () { - if (!mech.isBodiesAsleep) { - const SCALE = 1.022 - Matter.Body.scale(this, SCALE, SCALE); - this.frictionAir += 0.00023; + function onCollide(that) { + that.collisionFilter.mask = 0; //non collide with everything + Matter.Body.setVelocity(that, { + x: 0, + y: 0 + }); + that.do = that.grow; } - this.force.y += this.mass * 0.00045; + const mobCollisions = Matter.Query.collides(this, mob) + if (mobCollisions.length) { + onCollide(this) + this.stuckTo = mobCollisions[0].bodyA + + if (this.stuckTo.isVerticesChange) { + this.stuckToRelativePosition = { + x: 0, + y: 0 + } + } else { + //find the relative position for when the mob is at angle zero by undoing the mobs rotation + this.stuckToRelativePosition = Vector.rotate(Vector.sub(this.position, this.stuckTo.position), -this.stuckTo.angle) + } + this.stuck = function () { + if (this.stuckTo && this.stuckTo.alive) { + const rotate = Vector.rotate(this.stuckToRelativePosition, this.stuckTo.angle) //add in the mob's new angle to the relative position vector + Matter.Body.setPosition(this, Vector.add(Vector.add(rotate, this.stuckTo.velocity), this.stuckTo.position)) + Matter.Body.setVelocity(this, this.stuckTo.velocity); //so that it will move properly if it gets unstuck + } else { + this.collisionFilter.mask = cat.map; //non collide with everything but map + this.stuck = function () { + this.force.y += this.mass * 0.0006; + } + } + } + } else { + const bodyCollisions = Matter.Query.collides(this, body) + if (bodyCollisions.length) { + onCollide(this) + this.stuckTo = bodyCollisions[0].bodyA + //find the relative position for when the mob is at angle zero by undoing the mobs rotation + this.stuckToRelativePosition = Vector.rotate(Vector.sub(this.position, this.stuckTo.position), -this.stuckTo.angle) + this.stuck = function () { + if (this.stuckTo) { + const rotate = Vector.rotate(this.stuckToRelativePosition, this.stuckTo.angle) //add in the mob's new angle to the relative position vector + Matter.Body.setPosition(this, Vector.add(Vector.add(rotate, this.stuckTo.velocity), this.stuckTo.position)) + // Matter.Body.setVelocity(this, this.stuckTo.velocity); //so that it will move properly if it gets unstuck + } else { + this.force.y += this.mass * 0.0006; + } + } + } else { + if (Matter.Query.collides(this, map).length) { + onCollide(this) + } else { //if colliding with nothing just fall + this.force.y += this.mass * 0.0006; + } + } + } + //draw green glow + ctx.fillStyle = "rgba(0,200,125,0.16)"; + ctx.beginPath(); + 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 (!mech.isBodiesAsleep) { + const SCALE = 1.013 + 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 ctx.fillStyle = "rgba(0,200,125,0.16)"; ctx.beginPath(); - ctx.arc(this.position.x, this.position.y, 26, 0, 2 * Math.PI); + ctx.arc(this.position.x, this.position.y, this.maxRadius, 0, 2 * Math.PI); ctx.fill(); }; //spawn bullets on end bullet[me].onEnd = function () { - const NUM = 10; + const NUM = 10 for (let i = 0; i < NUM; i++) { b.spore(this) } diff --git a/js/level.js b/js/level.js index a0edbfc..6e024b6 100644 --- a/js/level.js +++ b/js/level.js @@ -22,8 +22,9 @@ const level = { // b.giveMod("impact shear"); // b.giveMod("clock gating"); // b.giveGuns("neutron bomb") + // b.giveGuns("spores") // mech.setField("pilot wave") - // mech.setField("perfect diamagnetism") + // mech.setField("phase decoherence field") level.intro(); //starting level // level.testing(); @@ -158,8 +159,8 @@ const level = { // spawn.bomberBoss(2900, -500) // spawn.shooterBoss(1200, -500) // spawn.spinner(1200, -500) - // spawn.grower(1600, -500) - spawn.cellBossCulture(1600, -500) + spawn.stabber(1600, -500) + // spawn.cellBossCulture(1600, -500) // spawn.shooter(1600, -500) // spawn.shield(mob[mob.length - 1], 1200, -500, 1); diff --git a/js/player.js b/js/player.js index fcfff3a..b5d1dd3 100644 --- a/js/player.js +++ b/js/player.js @@ -1588,15 +1588,15 @@ const mech = { } //calculate laser collision let best; - let range = b.isModPlasmaRange * (175 + (mech.crouch ? 450 : 350) * Math.sqrt(Math.random())) //+ 100 * Math.sin(mech.cycle * 0.3); - const dir = mech.angle // + 0.04 * (Math.random() - 0.5) + let range = b.isModPlasmaRange * (140 + (mech.crouch ? 400 : 300) * Math.sqrt(Math.random())) //+ 100 * Math.sin(mech.cycle * 0.3); + // const dir = mech.angle // + 0.04 * (Math.random() - 0.5) const path = [{ - x: mech.pos.x + 20 * Math.cos(dir), - y: mech.pos.y + 20 * Math.sin(dir) + x: mech.pos.x + 20 * Math.cos(mech.angle), + y: mech.pos.y + 20 * Math.sin(mech.angle) }, { - x: mech.pos.x + range * Math.cos(dir), - y: mech.pos.y + range * Math.sin(dir) + x: mech.pos.x + range * Math.cos(mech.angle), + y: mech.pos.y + range * Math.sin(mech.angle) } ]; const vertexCollision = function (v1, v1End, domain) { @@ -1658,12 +1658,12 @@ const mech = { y: best.y }; if (best.who.alive) { - const dmg = 0.55 * b.dmgScale; //********** SCALE DAMAGE HERE ********************* + const dmg = 0.8 * b.dmgScale; //********** SCALE DAMAGE HERE ********************* best.who.damage(dmg); best.who.locatePlayer(); //push mobs away - const force = Vector.mult(Vector.normalise(Vector.sub(mech.pos, path[1])), -0.01 * Math.sqrt(best.who.mass)) + const force = Vector.mult(Vector.normalise(Vector.sub(mech.pos, path[1])), -0.02 * Math.sqrt(best.who.mass)) Matter.Body.applyForce(best.who, path[1], force) // const angle = Math.atan2(player.position.y - best.who.position.y, player.position.x - best.who.position.x); // const mass = Math.min(Math.sqrt(best.who.mass), 6); @@ -1832,8 +1832,15 @@ const mech = { mech.fieldPhase = 0; mech.hold = function () { + function expandField() { + if (this.fieldRange < 2000) { + this.fieldRange += 100 + drawField(this.fieldRange) + } + } + function drawField(radius) { - radius *= 0.8 + 0.7 * mech.energy; + radius *= 0.9 + 1 * mech.energy; const rotate = mech.cycle * 0.005; mech.fieldPhase += 0.5 - 0.5 * Math.sqrt(Math.max(0.01, Math.min(mech.energy, 1))); const off1 = 1 + 0.06 * Math.sin(mech.fieldPhase); @@ -1862,7 +1869,10 @@ const mech = { mech.isStealth = false //isStealth disables most uses of foundPlayer() player.collisionFilter.mask = cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield //normal collisions if (mech.isHolding) { - this.fieldRange = 2000; + if (this.fieldRange < 2000) { + this.fieldRange += 100 + drawField(this.fieldRange) + } mech.drawHold(mech.holdingTarget); mech.holding(); mech.throwBlock(); @@ -1870,7 +1880,7 @@ const mech = { mech.grabPowerUp(); mech.lookForPickUp(); - const DRAIN = 0.0004 + 0.0002 * player.speed + ((!b.modRenormalization && mech.fireCDcycle > mech.cycle) ? 0.005 : 0.0017) + const DRAIN = 0.0003 + 0.00015 * player.speed + ((!b.modRenormalization && mech.fireCDcycle > mech.cycle) ? 0.005 : 0.001) if (mech.energy > DRAIN) { mech.energy -= DRAIN; // if (mech.energy < 0.001) { @@ -1878,7 +1888,7 @@ const mech = { // mech.energy = 0; // mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists) // } - this.fieldRange = this.fieldRange * 0.87 + 0.13 * 160 + this.fieldRange = this.fieldRange * 0.8 + 0.2 * 160 drawField(this.fieldRange) mech.isStealth = true //isStealth disables most uses of foundPlayer() @@ -1925,10 +1935,14 @@ const mech = { } } else if (mech.holdingTarget && mech.fieldCDcycle < mech.cycle) { //holding, but field button is released mech.pickUp(); + if (this.fieldRange < 2000) { + this.fieldRange += 100 + drawField(this.fieldRange) + } } else { // this.fieldRange = 3000 if (this.fieldRange < 2000 && mech.holdingTarget === null) { - this.fieldRange += 40 + this.fieldRange += 100 drawField(this.fieldRange) } mech.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists) diff --git a/js/spawn.js b/js/spawn.js index 7f9aa0d..665e762 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -925,20 +925,20 @@ const spawn = { me.rotateVelocity = Math.min(0.0054, 0.0022 * game.accelScale * game.accelScale) * (level.levelsCleared > 8 ? 1 : -1) me.do = function () { this.fill = '#' + Math.random().toString(16).substr(-6); //flash colors - // Matter.Body.rotate(this, -0.003 / (0.3 + this.health)) - // if (!mech.isBodiesAsleep) Matter.Body.rotate(me, this.rotateVelocity) - //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 (!mech.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(me, this.count * this.rotateVelocity) } - } - if (!slowed) { - this.count++ - Matter.Body.setAngle(me, this.count * this.rotateVelocity) } // this.torque -= this.inertia * 0.0000025 / (4 + this.health); @@ -1058,7 +1058,7 @@ const spawn = { 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 - this.vertices = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices)) + // this.vertices = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices)) } }; me.do = function () { @@ -1368,7 +1368,7 @@ const spawn = { y: 0 }; me.onDeath = function () { //helps collisions functions work better after vertex have been changed - this.vertices = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices)) + // this.vertices = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices)) } // spawn.shield(me, x, y); me.do = function () { diff --git a/todo.txt b/todo.txt index 0a72fd2..6e18747 100644 --- a/todo.txt +++ b/todo.txt @@ -1,15 +1,9 @@ +sporangium gun now sticks to things, takes longer to germinate, ammo and fire rate are increased. +plasma field does 50% more damage, pushes 20% harder, but has 20% less range + ************** TODO - n-gon ************** -mod - neutron bomb, water shielding, player takess no damage or energy drain - also increase range? - -extend neutron mob sticking code to foam gun and mines? - -phase field is kinda annoying - large vision range, - faster animation (instant?) - shrink vision range slowly over time, not with energy - also shrink when firing or moving? +mod - if energy goes zero after shield block, knock back and stun nearby mobs mod - frozen mobs take +33% damage