diff --git a/.DS_Store b/.DS_Store index 07779f0..dc334b0 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/js/bullet.js b/js/bullet.js index 88218d1..e680101 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -115,6 +115,7 @@ const b = { } }, giveGuns(gun = "random", ammoPacks = 10) { + if (tech.ammoCap) ammoPacks = 0.45 * tech.ammoCap if (tech.isOneGun) b.removeAllGuns(); if (gun === "random") { //find what guns player doesn't have @@ -131,7 +132,7 @@ const b = { for (let i = 0; i < b.guns.length; i++) { b.inventory[i] = i; b.guns[i].have = true; - b.guns[i].ammo = Math.floor(b.guns[i].ammoPack * ammoPacks); + b.guns[i].ammo = Math.ceil(b.guns[i].ammoPack * ammoPacks); } b.activeGun = 0; } else { @@ -148,7 +149,7 @@ const b = { } if (!b.guns[gun].have) b.inventory.push(gun); b.guns[gun].have = true; - b.guns[gun].ammo = Math.floor(b.guns[gun].ammoPack * ammoPacks); + b.guns[gun].ammo = Math.ceil(b.guns[gun].ammoPack * ammoPacks); if (b.activeGun === null) { b.activeGun = gun //if no active gun switch to new gun if (b.guns[b.activeGun].charge) b.guns[b.activeGun].charge = 0; //set foam charge to zero if foam is a new gun @@ -1148,7 +1149,32 @@ const b = { } }, - onEnd() {}, + caughtPowerUp: null, + dropCaughtPowerUp() { + if (this.caughtPowerUp) { + this.caughtPowerUp.collisionFilter.category = cat.powerUp + this.caughtPowerUp.collisionFilter.mask = cat.map | cat.powerUp + this.caughtPowerUp = null + } + }, + onEnd() { + if (this.caughtPowerUp && !simulation.isChoosing && (this.caughtPowerUp.name !== "heal" || m.health !== m.maxHealth || tech.isOverHeal)) { + let index = null //find index + for (let i = 0, len = powerUp.length; i < len; ++i) { + if (powerUp[i] === this.caughtPowerUp) index = i + } + if (index !== null) { + powerUps.onPickUp(this.caughtPowerUp); + this.caughtPowerUp.effect(); + Matter.Composite.remove(engine.world, this.caughtPowerUp); + powerUp.splice(index, 1); + } else { + this.dropCaughtPowerUp() + } + } else { + this.dropCaughtPowerUp() + } + }, drawString() { if (isReturn) { const where = { @@ -1183,50 +1209,37 @@ const b = { break; } } - // if you grabbed a power up, stop it near the player - // for (let i = 0, len = powerUp.length; i < len; ++i) { //near power up - // if (Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 6000) { - // Matter.Body.setVelocity(powerUp[i], { x: 0, y: -2 }) - // break - // } - // } - - for (let i = 0, len = powerUp.length; i < len; ++i) { - if ( //use power up if it is close enough - Vector.magnitudeSquared(Vector.sub(this.position, powerUp[i].position)) < 6000 && - !simulation.isChoosing && - (powerUp[i].name !== "heal" || m.health !== m.maxHealth || tech.isOverHeal) - ) { - powerUps.onPickUp(powerUp[i]); - Matter.Body.setVelocity(player, { //player knock back, after grabbing power up - x: player.velocity.x + powerUp[i].velocity.x / player.mass * 1, - y: player.velocity.y + powerUp[i].velocity.y / player.mass * 1 - }); - powerUp[i].effect(); - Matter.Composite.remove(engine.world, powerUp[i]); - powerUp.splice(i, 1); - break; //because the array order is messed up after splice - } - } - } else { - let isPulling = false - for (let i = 0, len = powerUp.length; i < len; ++i) { //near power up - if (Vector.magnitudeSquared(Vector.sub(this.vertices[2], powerUp[i].position)) < 3000) { - Matter.Body.setVelocity(powerUp[i], this.velocity) - Matter.Body.setPosition(powerUp[i], this.vertices[2]) - isPulling = true - this.endCycle += 0.5 //it pulls back slower, so this prevents it from ending early - break //just pull 1 power up if possible - } - } 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 * (isPulling ? 0.6 : 1)) + const returnForce = Vector.mult(Vector.normalise(sub), rangeScale * this.thrustMag * this.mass) this.force.x -= returnForce.x this.force.y -= returnForce.y this.drawString() + this.grabPowerUp() + } + }, + grabPowerUp() { //grab power ups near the tip of the harpoon + if (this.caughtPowerUp) { + Matter.Body.setPosition(this.caughtPowerUp, Vector.add(this.vertices[2], this.velocity)) + Matter.Body.setVelocity(this.caughtPowerUp, { x: 0, y: 0 }) + } else { //&& simulation.cycle % 2 + for (let i = 0, len = powerUp.length; i < len; ++i) { + const radius = powerUp[i].circleRadius + 25 + if (Vector.magnitudeSquared(Vector.sub(this.vertices[2], powerUp[i].position)) < radius * radius) { + if (powerUp[i].name !== "heal" || m.health !== m.maxHealth || tech.isOverHeal) { + this.caughtPowerUp = powerUp[i] + Matter.Body.setVelocity(powerUp[i], { x: 0, y: 0 }) + Matter.Body.setPosition(powerUp[i], this.vertices[2]) + powerUp[i].collisionFilter.category = 0 + powerUp[i].collisionFilter.mask = 0 + this.thrustMag *= 0.6 + this.endCycle += 0.5 //it pulls back slower, so this prevents it from ending early + break //just pull 1 power up if possible + } + } + } } }, do() { @@ -1240,11 +1253,14 @@ const b = { 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 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() } } else if (this.cycle > 30) { this.frictionAir = 0.003 @@ -4730,7 +4746,7 @@ const b = { name: "mine", description: "toss a proximity mine that sticks to walls
refund undetonated mines on exiting a level", //fires nails at mobs within range ammo: 0, - ammoPack: 1.1, + ammoPack: 1.25, have: false, do() {}, fire() { diff --git a/js/level.js b/js/level.js index fad38b7..5514b23 100644 --- a/js/level.js +++ b/js/level.js @@ -2292,18 +2292,14 @@ const level = { // spawn.focuser(1600, -500) // spawn.laserTargetingBoss(1700, -120) // spawn.bomberBoss(1400, -500) - // spawn.beamer(1800, -120) - // spawn.orbitalBoss(1600, -500) - // spawn.powerUpBoss(1600, -500) - // spawn.cellBossCulture(1600, -500) + // spawn.laser(1800, -120) + // spawn.laserBombingBoss(1600, -500) // spawn.laserTargetingBoss(1600, -500) - // spawn.laser(1200, -500) - + // spawn.laserBoss(1600, -500) + // spawn.cellBossCulture(1600, -500) spawn.nodeGroup(1200, -500, "grenadier") spawn.nodeGroup(1800, -500, "grenadier") spawn.nodeGroup(1200, 0, "grenadier") - - // spawn.snakeBoss(1200, -500) // spawn.suckerBoss(2900, -500) // spawn.randomMob(1600, -500) diff --git a/js/mob.js b/js/mob.js index 0c00e86..613c8a5 100644 --- a/js/mob.js +++ b/js/mob.js @@ -532,7 +532,7 @@ const mobs = { vertexCollision(this.position, look, body); if (!m.isCloak) vertexCollision(this.position, look, [playerBody, playerHead]); // hitting player - if (best.who === player) { + if (best.who === playerBody || best.who === playerHead) { if (m.immuneCycle < m.cycle) { const dmg = 0.0012 * simulation.dmgScale; m.damage(dmg); diff --git a/js/powerup.js b/js/powerup.js index 2e7ba11..5e0aadd 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -455,23 +455,34 @@ const powerUps = { return 17; }, effect() { - if (tech.isAmmoForGun && b.inventory.length > 0 && b.activeGun) { + if (tech.isAmmoForGun && b.inventory.length > 0 && b.activeGun) { //give extra ammo to one gun only with tech logistics const target = b.guns[b.activeGun] if (target.ammo !== Infinity) { - const ammoAdded = Math.ceil((0.7 * Math.random() + 0.7 * Math.random()) * target.ammoPack) - target.ammo += ammoAdded - simulation.makeTextLog(`${target.name}.ammo += ${ammoAdded}`) + if (tech.ammoCap) { + const ammoAdded = Math.ceil(target.ammoPack * 0.7 * tech.ammoCap) //0.7 is average + target.ammo = ammoAdded + simulation.makeTextLog(`${target.name}.ammo = ${ammoAdded}`) + } else { + const ammoAdded = Math.ceil((0.7 * Math.random() + 0.7 * Math.random()) * target.ammoPack) + target.ammo += ammoAdded + simulation.makeTextLog(`${target.name}.ammo += ${ammoAdded}`) + } } } else { //give ammo to all guns in inventory for (let i = 0, len = b.inventory.length; i < len; i++) { const target = b.guns[b.inventory[i]] if (target.ammo !== Infinity) { - const ammoAdded = Math.ceil((0.5 * Math.random() + 0.4 * Math.random()) * target.ammoPack) //Math.ceil(Math.random() * target.ammoPack) - target.ammo += ammoAdded - simulation.makeTextLog(`${target.name}.ammo += ${ammoAdded}`) + if (tech.ammoCap) { + const ammoAdded = Math.ceil(target.ammoPack * 0.45 * tech.ammoCap) //0.45 is average + target.ammo = ammoAdded + simulation.makeTextLog(`${target.name}.ammo = ${ammoAdded}`) + } else { + const ammoAdded = Math.ceil((0.45 * Math.random() + 0.45 * Math.random()) * target.ammoPack) //Math.ceil(Math.random() * target.ammoPack) + target.ammo += ammoAdded + simulation.makeTextLog(`${target.name}.ammo += ${ammoAdded}`) + } } } - } simulation.updateGunHUD(); } diff --git a/js/spawn.js b/js/spawn.js index e298c93..b40cf7f 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -645,8 +645,8 @@ const spawn = { // vertexCollision(where, look, mob); vertexCollision(where, look, map); vertexCollision(where, look, body); - if (!m.isCloak) vertexCollision(where, look, [player]); - if (best.who && best.who === player && m.immuneCycle < m.cycle) { + if (!m.isCloak) vertexCollision(where, look, [playerBody, playerHead]); + if (best.who && (best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) { if (m.immuneCycle < m.cycle + 60 + tech.collisionImmuneCycles) m.immuneCycle = m.cycle + 60 + tech.collisionImmuneCycles; //player is immune to damage extra time m.damage(dmg); simulation.drawList.push({ //add dmg to draw queue @@ -2014,7 +2014,6 @@ const spawn = { mobs.spawn(x, y, 3, radius, color); let me = mob[mob.length - 1]; me.isBoss = true; - me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front Matter.Body.rotate(me, Math.random() * Math.PI * 2); me.accelMag = 0.00018 * Math.sqrt(simulation.accelScale); @@ -2025,10 +2024,7 @@ const spawn = { me.frictionStatic = 0; me.friction = 0; me.lookTorque = 0.000001 * (Math.random() > 0.5 ? -1 : 1); - me.fireDir = { - x: 0, - y: 0 - } + me.fireDir = { x: 0, y: 0 } Matter.Body.setDensity(me, 0.008); //extra dense //normal is 0.001 //makes effective life much larger spawn.shield(me, x, y, 1); spawn.spawnOrbitals(me, radius + 200 + 300 * Math.random()) @@ -2128,16 +2124,14 @@ const spawn = { if (!m.isCloak) vertexCollision(this.position, look, [playerBody, playerHead]); // hitting player - if (best.who === player) { - if (m.immuneCycle < m.cycle) { - const dmg = 0.002 * simulation.dmgScale; - m.damage(dmg); - //draw damage - ctx.fillStyle = color; - ctx.beginPath(); - ctx.arc(best.x, best.y, dmg * 10000, 0, 2 * Math.PI); - ctx.fill(); - } + if ((best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) { + const dmg = 0.002 * simulation.dmgScale; + m.damage(dmg); + //draw damage + ctx.fillStyle = color; + ctx.beginPath(); + ctx.arc(best.x, best.y, dmg * 10000, 0, 2 * Math.PI); + ctx.fill(); } //draw beam if (best.dist2 === Infinity) best = look; @@ -2258,7 +2252,7 @@ const spawn = { if (!m.isCloak) vertexCollision(this.position, look, [playerBody, playerHead]); // hitting player - if (best.who === player) { + if (best.who === playerBody || best.who === playerHead) { this.targetingCount++ if (this.targetingCount > this.targetingTime) { this.targetingCount -= 10; @@ -2763,8 +2757,8 @@ const spawn = { // vertexCollision(where, look, mob); vertexCollision(where, look, map); vertexCollision(where, look, body); - if (!m.isCloak) vertexCollision(where, look, [player]); - if (best.who && best.who === player && m.immuneCycle < m.cycle) { + if (!m.isCloak) vertexCollision(where, look, [playerBody, playerHead]); + if (best.who && (best.who === playerBody || best.who === playerHead) && m.immuneCycle < m.cycle) { m.immuneCycle = m.cycle + tech.collisionImmuneCycles + 60; //player is immune to damage for an extra second const dmg = 0.14 * simulation.dmgScale; m.damage(dmg); diff --git a/js/tech.js b/js/tech.js index 615a17c..1495410 100644 --- a/js/tech.js +++ b/js/tech.js @@ -416,8 +416,8 @@ description: `${powerUps.orb.ammo()} give 80% more ammo
but it's only added to your current gun`, maxCount: 1, count: 0, - frequency: 2, - frequencyDefault: 2, + frequency: 1, + frequencyDefault: 1, allowed() { return !tech.isEnergyNoAmmo }, @@ -450,6 +450,25 @@ }, remove() {} }, + { + name: "cache", + description: `${powerUps.orb.ammo()} gives 11x more ammo, but
you can't store any more ammo than that`, + maxCount: 1, + count: 0, + frequency: 1, + frequencyDefault: 1, + allowed() { + return !tech.isEnergyNoAmmo + }, + requires: "not exciton-lattice", + effect() { + tech.ammoCap = 11; + powerUps.ammo.effect() + }, + remove() { + tech.ammoCap = 0; + } + }, { name: "catabolism", description: `firing while out of ammo spawns ${powerUps.orb.ammo(4)}
and reduces your maximum health by 1`, @@ -473,8 +492,8 @@ description: "every other crouched shot uses no ammo
+6 JUNK to the potential tech pool", maxCount: 1, count: 0, - frequency: 2, - frequencyDefault: 2, + frequency: 1, + frequencyDefault: 1, allowed() { return true }, @@ -8120,5 +8139,6 @@ isFilament: null, // isSpear: null, isLargeHarpoon: null, - extraHarpoons: null + extraHarpoons: null, + ammoCap: null } \ No newline at end of file diff --git a/todo.txt b/todo.txt index b3cdbd1..a37f92f 100644 --- a/todo.txt +++ b/todo.txt @@ -1,17 +1,14 @@ ******************************************************** NEXT PATCH ************************************************** -gun alt fire is determined by the down key not the player crouch state - (so you can control alt fire when in the air or stuck in a tunnel) - I did this with text replace, so it could produce some bugs +tech: cache - ammo power ups give 11x ammo, but you can't hold over 11x ammo harpoon - automatically uses power ups that return to player - will aim at harder to hit targets, and possible miss - returns extra fast if it is far from the player - bullets last a bit longer so they don't despawn early - cd on miss fire lowered to 1.5s (was 3s) + grabs 1 power up on the way out, or in + harpooned power ups are predictable + they attach to the harpoon instead of using physics to move towards player bugs fixes + lasers were broke, but I fixed them ******************************************************** TODO ******************************************************** @@ -19,9 +16,15 @@ bugs fixes disable zoom progress when paused -gun: harpoon - return to player is slower for heavier harpoons +harpoon + post launch tracking: more airFriction, more thrust, harder turning + if no target found slow down and aim much better? harpoon tech + tech that buffs alt fire: + remove the string, all shots are alt fire + alt fire has a 50% chance to not use ammo? + ammo power ups are 10% more likely to spawn from dead mobs + ammo power ups give the harpoon 2x more ammo holding down fire lets the string extend farther, this can overwrite crouch mode can't have 2+ harpoons @@ -32,15 +35,11 @@ harpoon tech grappling hook? remove string in all modes, why? increase ammo - post launch tracking: more airFriction, more thrust, harder turning - if no target found slow down and aim much better? tracking so good harpoon can hit a target, circle around and hit it again doesn't seem to be good physics level:lab too much walking around and too much platforming -set blockBoss frequency to 1x not 2x - tech - explode after getting hit, but while you are immune to harm on mouse down wormhole shows a possible wormhole @@ -475,6 +474,7 @@ possible names for tech hypergraph gnarl SQUID (for superconducting quantum interference device) is a very sensitive magnetometer used to measure extremely subtle magnetic fields, based on superconducting loops containing Josephson junctions. + nuclear pasta - hard matter in neutron star a tutorial / lore intro needs to be optional so it doesn't slow experienced players