diff --git a/.DS_Store b/.DS_Store index 6747dd1..c44dc7c 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/js/bullet.js b/js/bullet.js index a3237a3..1a4a158 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -29,6 +29,7 @@ const b = { } if (m.holdingTarget) m.drop(); } + b.guns[b.activeGun].do(); }, fireNotMove() { //added && player.speed < 0.5 && m.onGround if (input.fire && m.fireCDcycle < m.cycle && (!input.field || m.fieldFire) && b.inventory.length && player.speed < 0.5 && m.onGround && Math.abs(m.yOff - m.yOffGoal) < 1) { @@ -39,6 +40,7 @@ const b = { } if (m.holdingTarget) m.drop(); } + b.guns[b.activeGun].do(); }, fireNotMoveAlwaysFire() { //added && player.speed < 0.5 && m.onGround //removed input.fire && (!input.field || m.fieldFire) if (m.fireCDcycle < m.cycle && b.inventory.length && player.speed < 0.5 && m.onGround && Math.abs(m.yOff - m.yOffGoal) < 1) { @@ -49,6 +51,7 @@ const b = { } if (m.holdingTarget) m.drop(); } + b.guns[b.activeGun].do(); }, fireFloat() { //added && player.speed < 0.5 && m.onGround if (input.fire && (!input.field || m.fieldFire) && b.inventory.length) { @@ -67,6 +70,7 @@ const b = { player.force.x = 0 player.force.y = 0 } + b.guns[b.activeGun].do(); }, fireWithAmmo() { //triggers after firing when you have ammo b.guns[b.activeGun].fire(); @@ -3373,6 +3377,7 @@ const b = { ammoPack: 5.5, defaultAmmoPack: 5.5, have: false, + do() {}, fire() { let knock, spread if (m.crouch) { @@ -3537,6 +3542,7 @@ const b = { ammoPack: 12, have: false, num: 5, + do() {}, fire() { const SPEED = m.crouch ? 43 : 32 m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 25 : 18) * b.fireCD); // cool down @@ -3600,6 +3606,7 @@ const b = { ammo: 0, ammoPack: 70, have: false, + do() {}, fire() { m.fireCDcycle = m.cycle + Math.floor(3 * b.fireCD); // cool down const dir = m.angle @@ -3712,6 +3719,7 @@ const b = { have: false, fireCycle: 0, ammoLoaded: 0, + do() {}, fire() { const countReduction = Math.pow(0.9, tech.missileCount) if (m.crouch) { @@ -3826,6 +3834,7 @@ const b = { ammo: 0, ammoPack: 5, have: false, + do() {}, fire() { m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 40 : 30) * b.fireCD); // cool down b.grenade() @@ -3836,6 +3845,7 @@ const b = { ammo: 0, ammoPack: 2.7, have: false, + do() {}, fire() { if (tech.isLaserMine) { //laser mine const speed = m.crouch ? 50 : 20 @@ -3863,6 +3873,7 @@ const b = { ammo: 0, ammoPack: 3, have: false, + do() {}, fire() { const me = bullet.length; const dir = m.angle; @@ -3993,6 +4004,7 @@ const b = { ammoPack: 14, defaultAmmoPack: 14, have: false, + do() {}, fire() { if (m.crouch) { b.drone({ x: m.pos.x + 30 * Math.cos(m.angle) + 10 * (Math.random() - 0.5), y: m.pos.y + 30 * Math.sin(m.angle) + 10 * (Math.random() - 0.5) }, 45) @@ -4009,6 +4021,7 @@ const b = { // ammo: 0, // ammoPack: 64, // have: false, + // do() {}, // fire() { // if (m.crouch) { // b.iceIX(10, 0.3) @@ -4026,17 +4039,21 @@ const b = { ammo: 0, ammoPack: 36, have: false, - fire() { - let radius, spread - if (m.crouch) { - spread = 0.2 * (Math.random() - 0.5) - radius = 10 + 5 * Math.random() + (tech.isAmmoFoamSize && this.ammo < 300) * 12 - m.fireCDcycle = m.cycle + Math.floor(15 * b.fireCD); // cool down - } else { - spread = 0.5 * (Math.random() - 0.5) - radius = 4 + 6 * Math.random() + (tech.isAmmoFoamSize && this.ammo < 300) * 12 - m.fireCDcycle = m.cycle + Math.floor(5 * b.fireCD); // cool down + charge: 0, + isCharging: false, + do() { + if (this.charge > 0 && !input.fire) { + this.charge-- + this.fireFoam() } + }, + fire() { + this.charge++ + m.fireCDcycle = m.cycle + Math.floor((1 + 0.35 * this.charge) * b.fireCD); + }, + fireFoam() { + const spread = (m.crouch ? 0.05 : 0.6) * (Math.random() - 0.5) + const radius = 5 + 8 * Math.random() + (tech.isAmmoFoamSize && this.ammo < 300) * 12 const SPEED = 18 - radius * 0.4; const dir = m.angle + 0.15 * (Math.random() - 0.5) const velocity = { @@ -4065,12 +4082,52 @@ const b = { b.foam(position, Vector.rotate(velocity, spread), radius) } } + // fire() { + // let radius, spread + // if (m.crouch) { + // spread = 0.2 * (Math.random() - 0.5) + // radius = 10 + 5 * Math.random() + (tech.isAmmoFoamSize && this.ammo < 300) * 12 + // m.fireCDcycle = m.cycle + Math.floor(15 * b.fireCD); // cool down + // } else { + // spread = 0.5 * (Math.random() - 0.5) + // radius = 4 + 6 * Math.random() + (tech.isAmmoFoamSize && this.ammo < 300) * 12 + // m.fireCDcycle = m.cycle + Math.floor(5 * b.fireCD); // cool down + // } + // const SPEED = 18 - radius * 0.4; + // const dir = m.angle + 0.15 * (Math.random() - 0.5) + // const velocity = { + // x: SPEED * Math.cos(dir), + // y: SPEED * Math.sin(dir) + // } + // const position = { + // x: m.pos.x + 30 * Math.cos(m.angle), + // y: m.pos.y + 30 * Math.sin(m.angle) + // } + // if (tech.foamFutureFire) { + // simulation.drawList.push({ //add dmg to draw queue + // x: position.x, + // y: position.y, + // radius: 5, + // color: "rgba(0,0,0,0.1)", + // time: 15 * tech.foamFutureFire + // }); + // setTimeout(() => { + // if (!simulation.paused) { + // b.foam(position, Vector.rotate(velocity, spread), radius) + // bullet[bullet.length - 1].damage = (1 + 1.27 * tech.foamFutureFire) * (tech.isFastFoam ? 0.048 : 0.012) //double damage + // } + // }, 250 * tech.foamFutureFire); + // } else { + // b.foam(position, Vector.rotate(velocity, spread), radius) + // } + // } }, { name: "rail gun", description: "use energy to launch a high-speed dense rod
hold left mouse to charge, release to fire", ammo: 0, ammoPack: 3.15, have: false, + do() {}, fire() { function pushAway(range) { //push away blocks when firing for (let i = 0, len = mob.length; i < len; ++i) { @@ -4425,6 +4482,7 @@ const b = { ammoPack: Infinity, have: false, nextFireCycle: 0, //use to remember how longs its been since last fire, used to reset count + do() {}, fire() { }, @@ -4443,10 +4501,10 @@ const b = { // this.fire = this.firePhoton }, - firePhoton() { - m.fireCDcycle = m.cycle + Math.floor((tech.isPulseAim ? 25 : 50) * b.fireCD); // cool down - b.photon({ x: m.pos.x + 23 * Math.cos(m.angle), y: m.pos.y + 23 * Math.sin(m.angle) }, m.angle) - }, + // firePhoton() { + // m.fireCDcycle = m.cycle + Math.floor((tech.isPulseAim ? 25 : 50) * b.fireCD); // cool down + // b.photon({ x: m.pos.x + 23 * Math.cos(m.angle), y: m.pos.y + 23 * Math.sin(m.angle) }, m.angle) + // }, fireLaser() { if (m.energy < tech.laserFieldDrain) { m.fireCDcycle = m.cycle + 100; // cool down if out of energy @@ -4616,6 +4674,7 @@ const b = { lastFireCycle: 0, holdCount: 0, activeGunIndex: null, + do() {}, fire() { if (this.lastFireCycle === m.cycle - 1) { //button has been held down this.rewindCount += 8; diff --git a/js/level.js b/js/level.js index fc1aaed..f90ca47 100644 --- a/js/level.js +++ b/js/level.js @@ -16,11 +16,11 @@ const level = { // simulation.zoomScale = 1000; // simulation.setZoom(); // m.setField("nano-scale manufacturing") - // b.giveGuns("nail gun") + // b.giveGuns("foam") // tech.isExplodeRadio = true // for (let i = 0; i < 1; i++) tech.giveTech("dynamo-bot") - // tech.giveTech("diffraction grating") - // tech.giveTech("pulse") + // tech.giveTech("superfluidity") + // tech.giveTech("ice crystal nucleation") // tech.giveTech("needle gun") // tech.giveTech("cardinality") // tech.giveTech("Bayesian statistics") @@ -111,7 +111,10 @@ const level = { simulation.makeTextLog(`simulation.amplitude = ${Math.random()}`); m.switchWorlds() simulation.trails() - for (let i = 0; i < 2; i++) powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "tech", false); + powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "tech", false); + powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "heal", false); + powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "ammo", false); + powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "research", false); } if (tech.isHealLowHealth) { const len = Math.floor((m.maxHealth - m.health) / 0.5) @@ -1108,7 +1111,7 @@ const level = { // simulation.difficulty = 30 spawn.starter(1900, -500, 100) //big boy - // spawn.grower(1900, -500) + spawn.grower(1900, -500) // spawn.pulsarBoss(1900, -500) // spawn.shooterBoss(1900, -500) // spawn.launcherBoss(1200, -500) diff --git a/js/mob.js b/js/mob.js index 5e3eba0..ec836b2 100644 --- a/js/mob.js +++ b/js/mob.js @@ -47,51 +47,55 @@ const mobs = { applySlow(who) //look for mobs near the target if (tech.isAoESlow) { - const range = (320 + 150 * Math.random()) ** 2 + const range2 = (180 + 170 * Math.random()) ** 2 for (let i = 0, len = mob.length; i < len; i++) { - if (Vector.magnitudeSquared(Vector.sub(who.position, mob[i].position)) < range) applySlow(mob[i]) + if (who !== mob[i] && Vector.magnitudeSquared(Vector.sub(who.position, mob[i].position)) < range2 + mob[i].radius) { + console.log(mob[i]) + applySlow(mob[i]) + } } simulation.drawList.push({ x: who.position.x, y: who.position.y, - radius: Math.sqrt(range), + radius: Math.sqrt(range2), color: "rgba(0,100,255,0.05)", - time: 3 + time: simulation.drawTime }); } - function applySlow() { - if (!who.shield && !who.isShielded && !m.isBodiesAsleep) { - if (who.isBoss) cycles = Math.floor(cycles * 0.25) - let i = who.status.length + function applySlow(whom) { + console.log() + if (!whom.shield && !whom.isShielded && !m.isBodiesAsleep) { + if (whom.isBoss) cycles = Math.floor(cycles * 0.25) + let i = whom.status.length while (i--) { - if (who.status[i].type === "slow") who.status.splice(i, 1); //remove other "slow" effects on this mob + if (whom.status[i].type === "slow") whom.status.splice(i, 1); //remove other "slow" effects on this mob } - who.isSlowed = true; - who.status.push({ + whom.isSlowed = true; + whom.status.push({ effect() { const speedCap = 2 const drag = 0.95 - Matter.Body.setVelocity(who, { - x: Math.min(speedCap, who.velocity.x) * drag, - y: Math.min(speedCap, who.velocity.y) * drag + Matter.Body.setVelocity(whom, { + x: Math.min(speedCap, whom.velocity.x) * drag, + y: Math.min(speedCap, whom.velocity.y) * drag }); - Matter.Body.setAngularVelocity(who, 0); + Matter.Body.setAngularVelocity(whom, 0); ctx.beginPath(); - ctx.moveTo(who.vertices[0].x, who.vertices[0].y); - for (let j = 1, len = who.vertices.length; j < len; ++j) { - ctx.lineTo(who.vertices[j].x, who.vertices[j].y); + ctx.moveTo(whom.vertices[0].x, whom.vertices[0].y); + for (let j = 1, len = whom.vertices.length; j < len; ++j) { + ctx.lineTo(whom.vertices[j].x, whom.vertices[j].y); } - ctx.lineTo(who.vertices[0].x, who.vertices[0].y); + ctx.lineTo(whom.vertices[0].x, whom.vertices[0].y); ctx.strokeStyle = "rgba(0,100,255,0.8)"; ctx.lineWidth = 15; ctx.stroke(); - ctx.fillStyle = who.fill + ctx.fillStyle = whom.fill ctx.fill(); }, endEffect() { //check to see if there are not other freeze effects? - who.isSlowed = false; + whom.isSlowed = false; }, type: "slow", endCycle: simulation.cycle + cycles, diff --git a/js/player.js b/js/player.js index 4c5fcd0..17acbb8 100644 --- a/js/player.js +++ b/js/player.js @@ -1660,7 +1660,7 @@ const m = { m.holdingMassScale = 0.01; //can hold heavier blocks with lower cost to jumping m.fieldMeterColor = "#333" m.eyeFillColor = m.fieldMeterColor - m.fieldHarmReduction = 0.55; + m.fieldHarmReduction = 0.45; //55% reduction m.fieldDrawRadius = 0; m.hold = function() { diff --git a/js/simulation.js b/js/simulation.js index 99a7fb6..9531fe6 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -250,10 +250,9 @@ const simulation = { ctx.fillStyle = simulation.drawList[i].color; ctx.fill(); if (simulation.drawList[i].time) { - //remove when timer runs out simulation.drawList[i].time--; } else { - simulation.drawList.splice(i, 1); + if (!m.isBodiesAsleep) simulation.drawList.splice(i, 1); //remove when timer runs out } } }, diff --git a/js/tech.js b/js/tech.js index 4d97b4e..02e454e 100644 --- a/js/tech.js +++ b/js/tech.js @@ -159,6 +159,10 @@ spawn.randomLevelBoss(m.pos.x, m.pos.y + range, bossOptions); spawn.randomLevelBoss(m.pos.x - range, m.pos.y, bossOptions); spawn.randomLevelBoss(m.pos.x, m.pos.y - range, bossOptions); + spawn.randomLevelBoss(m.pos.x + range, m.pos.y + range, bossOptions); + spawn.randomLevelBoss(m.pos.x + range, m.pos.y - range, bossOptions); + spawn.randomLevelBoss(m.pos.x - range, m.pos.y + range, bossOptions); + spawn.randomLevelBoss(m.pos.x - range, m.pos.y - range, bossOptions); } }, tech: [{ @@ -2399,7 +2403,7 @@ }, { name: "many-worlds", - description: "each new level is an alternate reality
find 2 tech power ups in that reality", + description: "each level is an alternate reality, where you
find a tech, heal, ammo, and research", maxCount: 1, count: 0, frequency: 1, @@ -2711,7 +2715,7 @@ }, { name: "parthenogenesis", - description: "each level has a chance to spawn a level boss
equal to double your duplication chance", + description: "levels have a chance to spawn a 2nd boss
equal to double your duplication chance", maxCount: 1, count: 0, frequency: 2, @@ -2728,14 +2732,14 @@ }, { name: "apomixis", - description: "after reaching 100% duplication chance
immediately spawn 4 level bosses", + description: "after reaching 100% duplication chance
immediately spawn 8 bosses", maxCount: 1, count: 0, - frequency: 2, + frequency: 6, allowed() { - return tech.isDuplicateBoss + return tech.duplicationChance() > 0.66 }, - requires: "parthenogenesis", + requires: "duplication chance above 66%", effect() { tech.is100Duplicate = true; tech.maxDuplicationEvent() diff --git a/todo.txt b/todo.txt index d44425f..e711bc9 100644 --- a/todo.txt +++ b/todo.txt @@ -1,15 +1,13 @@ ******************************************************** NEXT PATCH ******************************************************** -perfect diamagnetism now has a 1/12 of a second cooldown after blocking (1/2 other fields) -perfect diamagnetism can get bremsstrahlung now +apomixis spawns 8 bosses (up from 4) -standing wave harmonic field blocks now block large mobs more reliably - -tech: triple point - blocking makes iceIX crystals - unlocked with: standing wave harmonic field or perfect diamagnetism +foam gun now charges up until you release the fire button ******************************************************** BUGS ******************************************************** +increase the width on the grid by a few pixels so that very small screens or people with odd fonts don't goto a new line + you have to press z once to get copy to work for simulation.enableConstructMode() sometimes not sure how to reproduce, but it happens often on the first draw @@ -38,34 +36,10 @@ fix door.isOpen actually meaning isClosed? ******************************************************** TODO ******************************************************** -tech: pressing the gun switch keys instead cycles through bot upgrades, switching all of your bots accordingly - -import the procedural level generation from one of the older versions of the game as one single level - tech plasma field - plasma field becomes an aoe damage field with the same radius 200% more energy drain, 100% more damage draw a square (or two) that rapidly spins -blocking produces ice-IX - at the block location? - how to get bullets to not hit the blocked mob - spawn at player head? - only applies to blocking with a cool down - nano-scale? - standing wave harmonics - maybe just a chance to proc for perfect diamagnetism - -tech field: while _____ is active take 100% more harm and do 100% more damage - while firing - or while plasma field is active - -quantum foam: hold fire to charge up foam, release fire to let go an amount relative to hold long you held fire - foam gun fires a bullet that tracks how long mouse is down - when mouse is up it streams out a hose of foam based on how long foam was down - bullet is small and hidden - -flipflop, but toggles after a kill - new level: procedural generation several small rooms are linked by portals the portals have a randomized pattern @@ -93,18 +67,9 @@ mob vision: look at player history https://abitawake.com/news/articles/enemy-ai-chasing-a-player-without-navigation2d-or-a-star-pathfinding write find in spawn undo exploder, but commented out -tech: chitin - take 50% less damage, reduce harm reduction by 5% after each collision - Mob: "Tentacle": Sits on wall. Is a black blob. When you get near it, reaches out and grabs you, similar to wires. Does not deal damage. maybe it could be immune to damage? but it is spawned by an actual mob -wormhole, or CPT tech: after taking damage teleport in direction of mouse - after collision - -mob sniper: draw aim graphics before fire - -tech laser: photon - laser, but it can only move 100 pixels a cycle - mob - after taking damage attack outwardly grows @@ -135,10 +100,6 @@ lore: a tutorial / lore intro put something on the intro map maybe a button triggers something -tech: add an eject button for each power up in the pause menu - also list all bot types in pause menu - with option to eject? - add back in gamepad support but does anyone care? https://github.com/landgreen/landgreen.github.io/search?q=gamepadconnected