diff --git a/js/bullet.js b/js/bullet.js index 0bcc948..84d9e6d 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -1495,7 +1495,7 @@ const b = { // ******************************** Guns ********************************************* // ************************************************************************************************** // ************************************************************************************************** - giveGuns(gun = "random", ammoPacks = 6) { + giveGuns(gun = "random", ammoPacks = 10) { if (mod.isOneGun) b.removeAllGuns(); if (gun === "random") { //find what guns player doesn't have @@ -1538,8 +1538,8 @@ const b = { name: "minigun", description: "rapidly fire a stream of small bullets
fire delay decreases as you shoot", ammo: 0, - ammoPack: 75, - defaultAmmoPack: 75, + ammoPack: 70, + defaultAmmoPack: 70, recordedAmmo: 0, have: false, nextFireCycle: 0, //use to remember how longs its been since last fire, used to reset count @@ -1577,7 +1577,7 @@ const b = { name: "shotgun", description: "fire a burst of short range bullets
crouch to reduce recoil", ammo: 0, - ammoPack: 9, + ammoPack: 8, have: false, fire() { let knock, spread @@ -1647,7 +1647,7 @@ const b = { name: "super balls", description: "fire four balls in a wide arc
balls bounce with no momentum loss", ammo: 0, - ammoPack: 15, + ammoPack: 13, have: false, num: 5, fire() { @@ -1702,8 +1702,8 @@ const b = { name: "flechettes", description: "fire a volley of uranium-235 needles
does damage over 3 seconds", ammo: 0, - ammoPack: 42, - defaultAmmoPack: 42, + ammoPack: 38, + defaultAmmoPack: 38, have: false, count: 0, //used to track how many shots are in a volley before a big CD lastFireCycle: 0, //use to remember how longs its been since last fire, used to reset count @@ -1806,7 +1806,7 @@ const b = { name: "wave beam", description: "emit a sine wave of oscillating particles
particles slowly propagate through solids", ammo: 0, - ammoPack: 110, + ammoPack: 100, have: false, fire() { mech.fireCDcycle = mech.cycle + Math.floor(3 * b.fireCD); // cool down @@ -1941,7 +1941,7 @@ const b = { name: "missiles", description: "launch missiles that accelerate towards mobs
explodes when near target", ammo: 0, - ammoPack: 5, + ammoPack: 4, have: false, fireCycle: 0, ammoLoaded: 0, @@ -1997,8 +1997,8 @@ const b = { name: "flak", description: "fire a cluster of short range projectiles
explodes on contact or after half a second", ammo: 0, - ammoPack: 6, - defaultAmmoPack: 6, //use to revert ammoPack after mod changes drop rate + ammoPack: 5, + defaultAmmoPack: 5, //use to revert ammoPack after mod changes drop rate have: false, fire() { mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 25 : 10) * b.fireCD); // cool down @@ -2041,7 +2041,7 @@ const b = { name: "grenades", description: "lob a single bouncy projectile
explodes on contact or after one second", ammo: 0, - ammoPack: 7, + ammoPack: 6, have: false, fire() { const me = bullet.length; @@ -2211,7 +2211,7 @@ const b = { name: "neutron bomb", description: "toss a chunk of Cf-252 that emits neutrons
damages and drains energy in area of effect", ammo: 0, - ammoPack: 7, + ammoPack: 6, have: false, fire() { const me = bullet.length; @@ -2391,7 +2391,7 @@ const b = { name: "spores", description: "fire a sporangium that discharges spores
spores seek out nearby mobs", ammo: 0, - ammoPack: 5, + ammoPack: 4, have: false, fire() { const me = bullet.length; @@ -2511,7 +2511,7 @@ const b = { name: "drones", description: "deploy drones that crash into mobs
crashes reduce their lifespan by 1 second", ammo: 0, - ammoPack: 15, + ammoPack: 13, have: false, fire() { b.drone(mech.crouch ? 45 : 1) @@ -2522,7 +2522,7 @@ const b = { name: "ice IX", description: "synthesize short-lived ice crystals
crystals seek out and freeze mobs", ammo: 0, - ammoPack: 73, + ammoPack: 69, have: false, fire() { if (mech.crouch) { @@ -2539,7 +2539,7 @@ const b = { name: "foam", description: "spray bubbly foam that sticks to mobs
slows mobs and does damage over time", ammo: 0, - ammoPack: 50, + ammoPack: 45, have: false, fire() { mech.fireCDcycle = mech.cycle + Math.floor((mech.crouch ? 20 : 6) * b.fireCD); // cool down diff --git a/js/engine.js b/js/engine.js index f0e91a4..5e9f772 100644 --- a/js/engine.js +++ b/js/engine.js @@ -175,8 +175,8 @@ function collisionChecks(event) { y: mob[k].velocity.y - 8 * Math.sin(angle) }); - if (mod.isAnnihilation && !mob[k].shield && !mob[k].isShielded && mech.energy > 0.2) { - mech.energy -= 0.2 + if (mod.isAnnihilation && !mob[k].shield && !mob[k].isShielded && mech.energy > 0.33) { + mech.energy -= 0.33 mech.immuneCycle = 0; //player doesn't go immune to collision damage mob[k].death(); game.drawList.push({ @@ -224,7 +224,7 @@ function collisionChecks(event) { if (v > 9) { let dmg = 0.06 * b.dmgScale * v * obj.mass * mod.throwChargeRate; if (mod.isCrit && !mob[k].seePlayer.recall && !mob[k].shield) dmg *= 5 - if (mob[k].isShielded) dmg *= 0.4 + if (mob[k].isShielded) dmg *= 0.35 mob[k].damage(dmg, true); if (mob[k].distanceToPlayer2() < 1000000) mob[k].foundPlayer(); game.drawList.push({ diff --git a/js/mob.js b/js/mob.js index 510da75..49123a5 100644 --- a/js/mob.js +++ b/js/mob.js @@ -306,20 +306,6 @@ const mobs = { } } }, - seePlayerByDistAndLOS() { - if (!(game.cycle % this.seePlayerFreq)) { - if ( - this.distanceToPlayer2() < this.seeAtDistance2 && - Matter.Query.ray(map, this.position, this.mechPosRange()).length === 0 && - Matter.Query.ray(body, this.position, this.mechPosRange()).length === 0 && - !mech.isStealth - ) { - this.foundPlayer(); - } else if (this.seePlayer.recall) { - this.lostPlayer(); - } - } - }, isLookingAtPlayer(threshold) { const diff = Vector.normalise(Vector.sub(player.position, this.position)); //make a vector for the mob's direction of length 1 diff --git a/js/mods.js b/js/mods.js index e094746..c2b96c6 100644 --- a/js/mods.js +++ b/js/mods.js @@ -268,14 +268,14 @@ const mod = { }, { name: "electrostatic discharge", - description: "increase damage by 25%
25% increased delay after firing", + description: "increase damage by 20%
20% increased delay after firing", maxCount: 1, count: 0, allowed() { return true }, effect() { - mod.slowFire = 1.25 + mod.slowFire = 1.2 b.setFireCD(); }, remove() { @@ -2124,7 +2124,7 @@ const mod = { }, { name: "plasma jet", - description: "increase plasma torch's range by 33%", + description: "increase plasma torch's range by 27%", maxCount: 9, count: 0, allowed() { @@ -2132,7 +2132,7 @@ const mod = { }, requires: "plasma torch", effect() { - mod.isPlasmaRange += 0.33; + mod.isPlasmaRange += 0.27; }, remove() { mod.isPlasmaRange = 1; @@ -2174,7 +2174,7 @@ const mod = { }, { name: "annihilation", - description: "after touching mobs, they are annihilated
drains 20% of base energy", + description: "after touching mobs, they are annihilated
drains 33% of base energy", maxCount: 1, count: 0, allowed() { @@ -2214,7 +2214,7 @@ const mod = { }, requires: "standing wave harmonics", effect() { - mod.blockDmg += 0.5 //if you change this value also update the for loop in the electricity graphics in mech.pushMass + mod.blockDmg += 0.35 //if you change this value also update the for loop in the electricity graphics in mech.pushMass }, remove() { mod.blockDmg = 0; diff --git a/js/player.js b/js/player.js index f6a91ed..7429c45 100644 --- a/js/player.js +++ b/js/player.js @@ -972,7 +972,7 @@ const mech = { //draw electricity const step = 40 ctx.beginPath(); - for (let i = 0, len = 2 * mod.blockDmg; i < len; i++) { + for (let i = 0, len = 2.5 * mod.blockDmg; i < len; i++) { let x = mech.pos.x - 20 * unit.x; let y = mech.pos.y - 20 * unit.y; ctx.moveTo(x, y); @@ -1298,9 +1298,8 @@ const mech = { }, { name: "nano-scale manufacturing", - description: "excess energy used to build drones
energy regeneration is doubled", + description: "excess energy used to build drones
increase energy regeneration by 100%", effect: () => { - // mech.fieldRegen *= 2; mech.hold = function () { if (mech.energy > mech.maxEnergy - 0.02 && mech.fieldCDcycle < mech.cycle) { if (mod.isSporeField) { @@ -1483,7 +1482,7 @@ const mech = { } else if ((keys[32] || game.mouseDownRight) && mech.fieldCDcycle < mech.cycle) { //not hold but field button is pressed mech.grabPowerUp(); mech.lookForPickUp(); - const DRAIN = 0.0017 + const DRAIN = 0.002 if (mech.energy > DRAIN) { mech.energy -= DRAIN; if (mech.energy < 0) { @@ -1492,7 +1491,7 @@ const mech = { } //calculate laser collision let best; - let range = mod.isPlasmaRange * (140 + (mech.crouch ? 400 : 300) * Math.sqrt(Math.random())) //+ 100 * Math.sin(mech.cycle * 0.3); + let range = mod.isPlasmaRange * (120 + (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(mech.angle), diff --git a/js/powerup.js b/js/powerup.js index f85c107..dd43d0a 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -488,7 +488,7 @@ const powerUps = { } }, addRerollToLevel() { //add a random power up to a location that has a mob, mostly used to give each level one randomly placed reroll - if (mob.length && Math.random() < 0.9) { // 80% chance + if (mob.length && Math.random() < 0.8) { // 80% chance const index = Math.floor(Math.random() * mob.length) powerUps.spawn(mob[index].position.x, mob[index].position.y, "reroll"); if (Math.random() < mod.bayesian) powerUps.spawn(mob[index].position.x, mob[index].position.y, "reroll"); diff --git a/js/spawn.js b/js/spawn.js index b978659..2530998 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -81,7 +81,8 @@ const spawn = { } } }, - randomLevelBoss(x, y, options = ["shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "powerUpBoss"]) { + //"shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", + randomLevelBoss(x, y, options = ["powerUpBoss"]) { // other bosses: suckerBoss, laserBoss, tetherBoss, snakeBoss //all need a particular level to work so they are not included spawn[options[Math.floor(Math.random() * options.length)]](x, y) }, @@ -108,7 +109,7 @@ const spawn = { this.gravity(); this.checkStatus(); if (this.seePlayer.recall) { - this.seePlayerByDistAndLOS(); + this.seePlayerCheck(); this.attraction(); //tether to other blocks ctx.beginPath(); @@ -116,7 +117,7 @@ const spawn = { if (mob[i].isGrouper && mob[i] != this && mob[i].dropPowerUp) { //don't tether to self, bullets, shields, ... const distance2 = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)) if (distance2 < this.groupingRangeMax) { - if (!mob[i].seePlayer.recall) mob[i].seePlayerByDistAndLOS(); //wake up sleepy mobs + if (!mob[i].seePlayer.recall) mob[i].seePlayerCheck(); //wake up sleepy mobs if (distance2 > this.groupingRangeMin) { const angle = Math.atan2(mob[i].position.y - this.position.y, mob[i].position.x - this.position.x); const forceMag = this.groupingStrength * mob[i].mass; @@ -231,23 +232,28 @@ const spawn = { mobs.spawn(x, y, vertices, radius, "transparent"); let me = mob[mob.length - 1]; me.isBoss = true; - me.frictionAir = 0.05 - me.seeAtDistance2 = 600000; - me.accelMag = 0.0005 * game.accelScale; - if (map.length) me.searchTarget = map[Math.floor(Math.random() * (map.length - 1))].position; //required for search - Matter.Body.setDensity(me, 0.001); //normal is 0.001 + me.frictionAir = 0.025 + me.seeAtDistance2 = 9000000; + me.accelMag = 0.0006 * game.accelScale; + Matter.Body.setDensity(me, 0.002); //normal is 0.001 me.collisionFilter.mask = cat.bullet | cat.player - // me.memory = 480; - // me.seePlayerFreq = 40 + Math.floor(10 * Math.random()) + me.memory = Infinity; + me.seePlayerFreq = 85 + Math.floor(10 * Math.random()) me.lockedOn = null; if (vertices === 9) { + //on primary spawn powerUps.spawnBossPowerUp(me.position.x, me.position.y) - powerUp[powerUp.length - 1].collisionFilter.mask = 0 - me.powerUpInventory = [powerUp[powerUp.length - 1]]; + powerUps.spawn(me.position.x, me.position.y, "heal"); + powerUps.spawn(me.position.x, me.position.y, "ammo"); + } else { + me.foundPlayer(); } me.onDeath = function () { + this.leaveBody = false; + this.dropPowerUp = false; + if (vertices > 3) spawn.powerUpBoss(this.position.x, this.position.y, vertices - 1) for (let i = 0; i < powerUp.length; i++) { powerUp[i].collisionFilter.mask = cat.map | cat.powerUp @@ -266,7 +272,7 @@ const spawn = { }) } - this.seePlayerByLookingAt(); + this.seePlayerCheckByDistance(); this.attraction(); this.checkStatus(); }; diff --git a/todo.txt b/todo.txt index a3ca2e5..836a69f 100644 --- a/todo.txt +++ b/todo.txt @@ -1,27 +1,13 @@ -removed eay to aim setting - the addition of gun selection make this setting less important - -mod: bot upgrades - forked into 4 different mods for each bot - effect is increased to 100% improvement (up from 40%) - -drones are more likely to pick up power ups -mod harvester: now also gives the drone immortality - -new level boss: after it dies it returns with one less vertex - also it steals all your power ups (what!) +power up level boss: adjustments ************** TODO - n-gon ************** -ghosters are always visible -ghoster mobs eat power ups and drop them on death - draw ghoster if it has a power up - or just always draw ghoster? - if no power ups on map go for player +level concept: several stationary platforms that are free to rotate, but with some air friction -give mobs more animal-like behaviors - like rain world - give mobs something to do when they don't see player - explore map +foam isFoamGrowOnDeath causes performance issues when too many mobs die fast + +give mobs more animal-like behaviors like rain world + mobs play, look for food, explore mobs some times aren't aggressive when low on life or after taking a large hit mobs can fight each other