diff --git a/js/bullet.js b/js/bullet.js index 43966d6..04ac2b7 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -379,7 +379,10 @@ const b = { laser(where = { x: mech.pos.x + 20 * Math.cos(mech.angle), y: mech.pos.y + 20 * Math.sin(mech.angle) - }, angle = mech.angle, dmg = mod.laserDamage, reflections = mod.laserReflections, isThickBeam = false) { + }, whereEnd = { + x: where.x + 3000 * Math.cos(mech.angle), + y: where.y + 3000 * Math.sin(mech.angle) + }, dmg = mod.laserDamage, reflections = mod.laserReflections, isThickBeam = false) { const reflectivity = 1 - 1 / (reflections * 1.5) let damage = b.dmgScale * dmg let best = { @@ -391,14 +394,13 @@ const b = { v2: null }; const color = "#f00"; - const range = 3000; const path = [{ x: where.x, y: where.y }, { - x: where.x + range * Math.cos(angle), - y: where.y + range * Math.sin(angle) + x: whereEnd.x, + y: whereEnd.y } ]; const vertexCollision = function (v1, v1End, domain) { @@ -470,7 +472,7 @@ const b = { const d = Vector.sub(path[path.length - 1], path[path.length - 2]); const nn = Vector.mult(n, 2 * Vector.dot(d, n)); const r = Vector.normalise(Vector.sub(d, nn)); - path[path.length] = Vector.add(Vector.mult(r, range), path[path.length - 1]); + path[path.length] = Vector.add(Vector.mult(r, 3000), path[path.length - 1]); }; checkForCollisions(); @@ -802,6 +804,7 @@ const b = { mobs.statusSlow(who, 60) this.endCycle = game.cycle if (mod.isHeavyWater) mobs.statusDoT(who, 0.1, 300) + if (mod.iceEnergy && !who.shield) mech.energy += mod.iceEnergy //&& mech.energy < mech.maxEnergy }, onEnd() {}, do() { @@ -1323,7 +1326,7 @@ const b = { minDmgSpeed: 2, lookFrequency: 40 + Math.floor(7 * Math.random()), acceleration: 0.0015 * (1 + 0.3 * Math.random()), - range: 500 * (1 + 0.2 * Math.random()) + 150 * mod.isLaserBotUpgrade, + range: 700 * (1 + 0.1 * Math.random()) + 250 * mod.isLaserBotUpgrade, followRange: 150 + Math.floor(30 * Math.random()), offPlayer: { x: 0, @@ -1351,17 +1354,19 @@ const b = { y: this.velocity.y * 0.95 }); //find targets - if (!(game.cycle % this.lookFrequency) && !mech.isCloak) { + if (!(game.cycle % this.lookFrequency)) { this.lockedOn = null; - let closeDist = this.range; - for (let i = 0, len = mob.length; i < len; ++i) { - const DIST = Vector.magnitude(Vector.sub(this.vertices[0], mob[i].position)); - if (DIST - mob[i].radius < closeDist && - !mob[i].isShielded && - Matter.Query.ray(map, this.vertices[0], mob[i].position).length === 0 && - Matter.Query.ray(body, this.vertices[0], mob[i].position).length === 0) { - closeDist = DIST; - this.lockedOn = mob[i] + if (!mech.isCloak) { + let closeDist = this.range; + for (let i = 0, len = mob.length; i < len; ++i) { + const DIST = Vector.magnitude(Vector.sub(this.vertices[0], mob[i].position)); + if (DIST - mob[i].radius < closeDist && + !mob[i].isShielded && + Matter.Query.ray(map, this.vertices[0], mob[i].position).length === 0 && + Matter.Query.ray(body, this.vertices[0], mob[i].position).length === 0) { + closeDist = DIST; + this.lockedOn = mob[i] + } } } //randomize position relative to player @@ -1374,42 +1379,46 @@ const b = { } //hit target with laser if (this.lockedOn && this.lockedOn.alive && mech.energy > 0.15) { - mech.energy -= 0.0014 * mod.isLaserDiode - //make sure you can still see vertex - const DIST = Vector.magnitude(Vector.sub(this.vertices[0], this.lockedOn.position)); - if (DIST - this.lockedOn.radius < this.range + 150 && - Matter.Query.ray(map, this.vertices[0], this.lockedOn.position).length === 0 && - Matter.Query.ray(body, this.vertices[0], this.lockedOn.position).length === 0) { - //move towards the target - this.force = Vector.add(this.force, Vector.mult(Vector.normalise(Vector.sub(this.lockedOn.position, this.position)), 0.0013)) - //find the closest vertex - let bestVertexDistance = Infinity - let bestVertex = null - for (let i = 0; i < this.lockedOn.vertices.length; i++) { - const dist = Vector.magnitude(Vector.sub(this.vertices[0], this.lockedOn.vertices[i])); - if (dist < bestVertexDistance) { - bestVertex = i - bestVertexDistance = dist - } - } - const dmg = b.dmgScale * (0.06 + 0.08 * this.isUpgraded); - this.lockedOn.damage(dmg); - this.lockedOn.locatePlayer(); + mech.energy -= 0.0012 * mod.isLaserDiode + // const sub = Vector.sub(this.lockedOn.position, this.vertices[0]) + // const angle = Math.atan2(sub.y, sub.x); + b.laser(this.vertices[0], this.lockedOn.position, b.dmgScale * (0.06 + 0.08 * this.isUpgraded)) - ctx.beginPath(); //draw laser - ctx.moveTo(this.vertices[0].x, this.vertices[0].y); - ctx.lineTo(this.lockedOn.vertices[bestVertex].x, this.lockedOn.vertices[bestVertex].y); - ctx.strokeStyle = "#f00"; - ctx.lineWidth = "2" - ctx.lineDashOffset = 300 * Math.random() - ctx.setLineDash([50 + 100 * Math.random(), 100 * Math.random()]); - ctx.stroke(); - ctx.setLineDash([0, 0]); - ctx.beginPath(); - ctx.arc(this.lockedOn.vertices[bestVertex].x, this.lockedOn.vertices[bestVertex].y, Math.sqrt(dmg) * 100, 0, 2 * Math.PI); - ctx.fillStyle = "#f00"; - ctx.fill(); - } + // //make sure you can still see vertex + // const DIST = Vector.magnitude(Vector.sub(this.vertices[0], this.lockedOn.position)); + // if (DIST - this.lockedOn.radius < this.range + 150 && + // Matter.Query.ray(map, this.vertices[0], this.lockedOn.position).length === 0 && + // Matter.Query.ray(body, this.vertices[0], this.lockedOn.position).length === 0) { + // //move towards the target + // this.force = Vector.add(this.force, Vector.mult(Vector.normalise(Vector.sub(this.lockedOn.position, this.position)), 0.0013)) + // //find the closest vertex + // let bestVertexDistance = Infinity + // let bestVertex = null + // for (let i = 0; i < this.lockedOn.vertices.length; i++) { + // const dist = Vector.magnitude(Vector.sub(this.vertices[0], this.lockedOn.vertices[i])); + // if (dist < bestVertexDistance) { + // bestVertex = i + // bestVertexDistance = dist + // } + // } + // const dmg = b.dmgScale * (0.06 + 0.08 * this.isUpgraded); + // this.lockedOn.damage(dmg); + // this.lockedOn.locatePlayer(); + + // ctx.beginPath(); //draw laser + // ctx.moveTo(this.vertices[0].x, this.vertices[0].y); + // ctx.lineTo(this.lockedOn.vertices[bestVertex].x, this.lockedOn.vertices[bestVertex].y); + // ctx.strokeStyle = "#f00"; + // ctx.lineWidth = "2" + // ctx.lineDashOffset = 300 * Math.random() + // ctx.setLineDash([50 + 100 * Math.random(), 100 * Math.random()]); + // ctx.stroke(); + // ctx.setLineDash([0, 0]); + // ctx.beginPath(); + // ctx.arc(this.lockedOn.vertices[bestVertex].x, this.lockedOn.vertices[bestVertex].y, Math.sqrt(dmg) * 100, 0, 2 * Math.PI); + // ctx.fillStyle = "#f00"; + // ctx.fill(); + // } } } }) @@ -3231,25 +3240,31 @@ const b = { if (mod.isWideLaser) { const off = 8 const dmg = 0.4 * mod.laserDamage // 5 * 0.4 = 200% more damage - b.laser({ + const where = { x: mech.pos.x + 20 * Math.cos(mech.angle), y: mech.pos.y + 20 * Math.sin(mech.angle) - }, mech.angle, dmg, 0, true) + } + b.laser(where, { + x: where.x + 3000 * Math.cos(mech.angle), + y: where.y + 3000 * Math.sin(mech.angle) + }, dmg, 0, true) for (let i = 1; i < 3; i++) { - b.laser(Vector.add({ - x: mech.pos.x + 20 * Math.cos(mech.angle), - y: mech.pos.y + 20 * Math.sin(mech.angle) - }, { + let whereOff = Vector.add(where, { x: i * off * Math.cos(mech.angle + Math.PI / 2), y: i * off * Math.sin(mech.angle + Math.PI / 2) - }), mech.angle, dmg, 0, true) - b.laser(Vector.add({ - x: mech.pos.x + 20 * Math.cos(mech.angle), - y: mech.pos.y + 20 * Math.sin(mech.angle) - }, { + }) + b.laser(whereOff, { + x: whereOff.x + 3000 * Math.cos(mech.angle), + y: whereOff.y + 3000 * Math.sin(mech.angle) + }, dmg, 0, true) + whereOff = Vector.add(where, { x: i * off * Math.cos(mech.angle - Math.PI / 2), y: i * off * Math.sin(mech.angle - Math.PI / 2) - }), mech.angle, dmg, 0, true) + }) + b.laser(whereOff, { + x: whereOff.x + 3000 * Math.cos(mech.angle), + y: whereOff.y + 3000 * Math.sin(mech.angle) + }, dmg, 0, true) } } else if (mod.beamSplitter) { let dmg = mod.laserDamage * 0.9 @@ -3257,10 +3272,19 @@ const b = { x: mech.pos.x + 20 * Math.cos(mech.angle), y: mech.pos.y + 20 * Math.sin(mech.angle) } - b.laser(where, mech.angle, dmg) + b.laser(where, { + x: where.x + 3000 * Math.cos(mech.angle), + y: where.y + 3000 * Math.sin(mech.angle) + }, dmg) for (let i = 1; i < 1 + mod.beamSplitter; i++) { - b.laser(where, mech.angle + i * 0.2, dmg) - b.laser(where, mech.angle - i * 0.2, dmg) + b.laser(where, { + x: where.x + 3000 * Math.cos(mech.angle + i * 0.2), + y: where.y + 3000 * Math.sin(mech.angle + i * 0.2) + }, dmg) + b.laser(where, { + x: where.x + 3000 * Math.cos(mech.angle - i * 0.2), + y: where.y + 3000 * Math.sin(mech.angle - i * 0.2) + }, dmg) dmg *= 0.9 } } else { diff --git a/js/level.js b/js/level.js index ad37c55..7206aa8 100644 --- a/js/level.js +++ b/js/level.js @@ -15,10 +15,10 @@ const level = { // game.zoomScale = 1000; // game.setZoom(); // mech.isCloak = true; - // mech.setField("metamaterial cloaking") + // mech.setField("perfect diamagnetism") // b.giveGuns("laser") - // for (let i = 0; i < 1; i++) { - // mod.giveMod("diffuse beam"); + // for (let i = 0; i < 10; i++) { + // mod.giveMod("laser-bot"); // } // mod.giveMod("orbit-bot upgrade") @@ -118,7 +118,7 @@ const level = { spawn.mapRect(-950, -1800, 8200, 800); //roof spawn.mapRect(-250, -700, 1000, 900); // shelf spawn.mapRect(-250, -1200, 1000, 250); // shelf roof - powerUps.spawnStartingPowerUps(600, -800); + // powerUps.spawnStartingPowerUps(600, -800); powerUps.spawn(550, -800, "reroll", false); function blockDoor(x, y, blockSize = 58) { @@ -150,7 +150,7 @@ const level = { // spawn.sniper(1800, -120) // spawn.sniper(2200, -120) // spawn.cellBossCulture(1600, -500) - spawn.starter(1600, -500, 160) + spawn.starter(1600, -500) // spawn.powerUpBoss(1600, -500) // spawn.shield(mob[mob.length - 1], 1200, -500, 1); diff --git a/js/mods.js b/js/mods.js index e2dc509..470f51b 100644 --- a/js/mods.js +++ b/js/mods.js @@ -603,7 +603,7 @@ const mod = { }, { name: "laser-bot", - description: "a bot defends the space around you
uses a short range laser that drains energy", + description: "a bot uses energy to emit a laser
targeting nearby mobs", maxCount: 9, count: 0, allowed() { @@ -816,9 +816,9 @@ const mod = { maxCount: 1, count: 0, allowed() { - return true + return mod.totalBots() > 1 || mod.haveGunCheck("drone") || mod.haveGunCheck("mine") || mod.haveGunCheck("spores") || mech.fieldUpgrades[mech.fieldMode].name === "nano-scale manufacturing" }, - requires: "", + requires: "drones, spores, mines, or bots", effect() { mod.isNoFireDefense = true }, @@ -2208,7 +2208,7 @@ const mod = { maxCount: 1, count: 0, allowed() { - return mod.haveGunCheck("ice IX") || (mech.fieldUpgrades[mech.fieldMode].name === "nano-scale manufacturing" && mod.isIceField) + return mod.haveGunCheck("ice IX") || mod.isIceField }, requires: "ice IX", effect() { @@ -2218,6 +2218,22 @@ const mod = { mod.isHeavyWater = false; } }, + { + name: "thermoelectric effect", + description: "ice IX bullets give you 7% energy
after they collide with mobs", + maxCount: 9, + count: 0, + allowed() { + return mod.haveGunCheck("ice IX") || mod.isIceField + }, + requires: "ice IX", + effect() { + mod.iceEnergy += 0.07 + }, + remove() { + mod.iceEnergy = 0; + } + }, { name: "necrophoresis", description: "foam bullets grow and split into 3 copies
when the mob they are stuck to dies", @@ -2354,7 +2370,7 @@ const mod = { }, { name: "beam splitter", - description: `your laser is split into diverging beams
decrease damage by 10%`, + description: `your laser gains 2 diverging beams
decrease laser damage by 10%`, maxCount: 9, count: 0, allowed() { @@ -2370,7 +2386,7 @@ const mod = { }, { name: "diffuse beam", - description: "laser beam is wider and doesn't reflect
increase damage by 100%", + description: "laser beam is wider and doesn't reflect
increase laser damage by 100%", maxCount: 1, count: 0, allowed() { @@ -2989,5 +3005,6 @@ const mod = { isNoFireDefense: null, isNoFireDamage: null, duplicateChance: null, - beamSplitter: null + beamSplitter: null, + iceEnergy: null } \ No newline at end of file diff --git a/js/player.js b/js/player.js index 1cb6116..7e50818 100644 --- a/js/player.js +++ b/js/player.js @@ -1303,6 +1303,20 @@ const mech = { // mech.fieldArc = 0.3; //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob) // mech.calculateFieldThreshold(); mech.hold = function () { + + //cap mob speed based on distance + for (let i = 0; i < mob.length; i++) { + const distance = Vector.magnitude(Vector.sub(mech.pos, mob[i].position)) + const range = 1000 + if (distance < range) { + const cap = Math.max(0.01 * distance, 4) + if (mob[i].speed > cap) { + Matter.Body.setVelocity(mob[i], Vector.mult(Vector.normalise(mob[i].velocity), cap)); //set velocity to cap, but keep the direction + } + } + } + + const wave = Math.sin(mech.cycle * 0.022); mech.fieldRange = 170 + 12 * wave mech.fieldArc = 0.33 + 0.045 * wave //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob) diff --git a/js/powerup.js b/js/powerup.js index 6c3f4b9..70f6437 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -152,8 +152,7 @@ const powerUps = { //give ammo to all guns in inventory if (mod.isAmmoForGun) { const target = b.guns[b.activeGun] - target.ammo += Math.ceil(Math.random() * target.ammoPack) - target.ammo += Math.ceil(Math.random() * target.ammoPack) + target.ammo += Math.ceil(Math.random() * target.ammoPack) + Math.ceil(Math.random() * target.ammoPack) } else { for (let i = 0, len = b.inventory.length; i < len; i++) { const target = b.guns[b.inventory[i]] diff --git a/todo.txt b/todo.txt index b17e338..77ba18d 100644 --- a/todo.txt +++ b/todo.txt @@ -1,15 +1,19 @@ -laser mod: beam splitter - laser is split into diverging beams, but does 10% less damage +laser bots now use the same laser code as the player +mod: thermoelectric effect - ice IX bullets give you 7% energy after they collides with mobs ************** TODO - n-gon ************** -laser mod, increase damage, but ass some angular spread to 5 laser beam - require diffuse +a gun that gives back energy + if your energy is below 90% your drones stay near you and give energy regen -use the b.laser() function +buff neutron bomb? + less fire CD? mod set a max speed cap based on distance from player while field is active - mod for a field, or bot? - name: something about speed of light being the top speed + name: eddy current brake + who runs the code? + new bot + perfect diamagnetism vacuum bomb applies status effect to mobs that makes blocks attracted to them