diff --git a/index.html b/index.html index e1ddda8..5bf8d13 100644 --- a/index.html +++ b/index.html @@ -362,7 +362,7 @@ --> - + @@ -371,7 +371,7 @@ - + diff --git a/js/bullet.js b/js/bullet.js index 7fe27a2..0b9f762 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -29,7 +29,7 @@ const b = { } } } else { - simulation.makeTextLog(`${b.guns[b.activeGun].name}.ammo = 0`); + simulation.makeTextLog(`${b.guns[b.activeGun].name}.ammo: 0`); } mech.fireCDcycle = mech.cycle + 30; //fire cooldown } @@ -796,7 +796,7 @@ const b = { b.grenade = grenadeDefault } }, - missile(where, angle, speed, size = 1, spawn = 0) { + missile(where, angle, speed, size = 1) { const me = bullet.length; bullet[me] = Bodies.rectangle(where.x, where.y, 30 * size, 4 * size, { angle: angle, @@ -821,14 +821,6 @@ const b = { onEnd() { b.explosion(this.position, this.explodeRad * size); //makes bullet do explosive damage at end if (tech.fragments) b.targetedNail(this.position, tech.fragments * 5) - if (spawn) { - for (let i = 0; i < tech.recursiveMissiles; i++) { - if (0.2 - 0.02 * i > Math.random()) { - b.missile(this.position, this.angle + Math.PI + 0.5 * (Math.random() - 0.5), 0, 0.33 + size, tech.recursiveMissiles) - break; - } - } - } }, lockedOn: null, tryToLockOn() { @@ -901,7 +893,7 @@ const b = { } }, }); - const thrust = 0.0065 * bullet[me].mass; + const thrust = 0.0066 * bullet[me].mass * (tech.missileSize ? 0.6 : 1); Matter.Body.setVelocity(bullet[me], { x: mech.Vx / 2 + speed * Math.cos(angle), y: mech.Vy / 2 + speed * Math.sin(angle) @@ -1594,7 +1586,7 @@ const b = { if (tech.iceEnergy && !who.shield && !who.isShielded && who.dropPowerUp && who.alive) { setTimeout(function() { if (!who.alive) { - mech.energy += tech.iceEnergy + mech.energy += tech.iceEnergy * 0.8 mech.addHealth(tech.iceEnergy * 0.04) } }, 10); @@ -1971,8 +1963,9 @@ const b = { for (let i = 0; i < tech.nailBotCount; i++) b.nailBot() for (let i = 0; i < tech.foamBotCount; i++) b.foamBot() for (let i = 0; i < tech.boomBotCount; i++) b.boomBot() - for (let i = 0; i < tech.plasmaBotCount; i++) b.plasmaBot() for (let i = 0; i < tech.orbitBotCount; i++) b.orbitBot() + for (let i = 0; i < tech.plasmaBotCount; i++) b.plasmaBot() + for (let i = 0; i < tech.missileBotCount; i++) b.missileBot() if (tech.isIntangible && mech.isCloak) { for (let i = 0; i < bullet.length; i++) { if (bullet[i].botType) bullet[i].collisionFilter.mask = cat.map | cat.bullet | cat.mobBullet | cat.mobShield @@ -2022,32 +2015,82 @@ const b = { category: cat.bullet, mask: cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield }, - lockedOn: null, - beforeDmg() { - this.lockedOn = null - }, + beforeDmg() {}, onEnd() {}, do() { - if (this.lastLookCycle < simulation.cycle && !mech.isCloak) { - this.lastLookCycle = simulation.cycle + (this.isUpgraded ? 15 : 80) - let target - for (let i = 0, len = mob.length; i < len; i++) { - const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)); - if (dist < 3000000 && //1400*1400 - Matter.Query.ray(map, this.position, mob[i].position).length === 0 && - Matter.Query.ray(body, this.position, mob[i].position).length === 0) { - target = Vector.add(mob[i].position, Vector.mult(mob[i].velocity, Math.sqrt(dist) / 60)) - const SPEED = 50 - b.nail(this.position, Vector.mult(Vector.normalise(Vector.sub(target, this.position)), SPEED), 0.4) - break; - } - } - } const distanceToPlayer = Vector.magnitude(Vector.sub(this.position, mech.pos)) if (distanceToPlayer > this.range) { //if far away move towards player this.force = Vector.mult(Vector.normalise(Vector.sub(mech.pos, this.position)), this.mass * this.acceleration) } else { //close to player Matter.Body.setVelocity(this, Vector.add(Vector.mult(this.velocity, 0.90), Vector.mult(player.velocity, 0.17))); //add player's velocity + + if (this.lastLookCycle < simulation.cycle && !mech.isCloak) { + this.lastLookCycle = simulation.cycle + (this.isUpgraded ? 15 : 80) + let target + for (let i = 0, len = mob.length; i < len; i++) { + const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)); + if (dist < 3000000 && //1400*1400 + Matter.Query.ray(map, this.position, mob[i].position).length === 0 && + Matter.Query.ray(body, this.position, mob[i].position).length === 0) { + target = Vector.add(mob[i].position, Vector.mult(mob[i].velocity, Math.sqrt(dist) / 60)) + const SPEED = 50 + const unit = Vector.normalise(Vector.sub(target, this.position)) + b.nail(this.position, Vector.mult(unit, SPEED), 0.4) + this.force = Vector.mult(unit, -0.01 * this.mass) + break; + } + } + } + } + } + }) + World.add(engine.world, bullet[me]); //add bullet to world + }, + missileBot(position = { x: mech.pos.x + 50 * (Math.random() - 0.5), y: mech.pos.y + 50 * (Math.random() - 0.5) }) { + simulation.makeTextLog(`b.missileBot()`); + const me = bullet.length; + bullet[me] = Bodies.rectangle(position.x, position.y, 28, 11, { + botType: "foam", + angle: mech.angle, + friction: 0, + frictionStatic: 0, + frictionAir: 0.055, + restitution: 0.7, + dmg: 0, // 0.14 //damage done in addition to the damage from momentum + minDmgSpeed: 2, + lookFrequency: 70, + cd: 0, + delay: 90, + range: 80, + endCycle: Infinity, + classType: "bullet", + collisionFilter: { + category: cat.bullet, + mask: cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield + }, + beforeDmg() {}, + onEnd() {}, + do() { + const distanceToPlayer = Vector.magnitude(Vector.sub(this.position, mech.pos)) + if (distanceToPlayer > this.range) { //if far away move towards player + this.force = Vector.mult(Vector.normalise(Vector.sub(mech.pos, this.position)), this.mass * 0.006) + } else { //close to player + Matter.Body.setVelocity(this, Vector.add(Vector.mult(this.velocity, 0.90), Vector.mult(player.velocity, 0.17))); //add player's velocity + + if (this.cd < simulation.cycle && !(simulation.cycle % this.lookFrequency) && !mech.isCloak) { + for (let i = 0, len = mob.length; i < len; i++) { + const dist2 = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)); + if (Matter.Query.ray(map, this.position, mob[i].position).length === 0 && dist2 > 250000) { + this.cd = simulation.cycle + this.delay; + const angle = Vector.angle(this.position, mob[i].position) + Matter.Body.setAngle(this, angle) + // Matter.Body.setAngularVelocity(this, 0.025) + this.force = Vector.mult(Vector.normalise(Vector.sub(this.position, mob[i].position)), this.mass * 0.02) + b.missile(this.position, angle, -8, 0.7 * (tech.missileSize ? 1.5 : 1)) + break; + } + } + } } } }) @@ -2068,7 +2111,7 @@ const b = { restitution: 0.6 * (1 + 0.5 * Math.random()), dmg: 0, // 0.14 //damage done in addition to the damage from momentum minDmgSpeed: 2, - lookFrequency: 60 + Math.floor(17 * Math.random()) - 20 * tech.isFoamBotUpgrade, + lookFrequency: 60 + Math.floor(17 * Math.random()) - 30 * tech.isFoamBotUpgrade, cd: 0, delay: 100, acceleration: 0.005 * (1 + 0.5 * Math.random()), @@ -2079,32 +2122,30 @@ const b = { category: cat.bullet, mask: cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield }, - lockedOn: null, - beforeDmg() { - this.lockedOn = null - }, + beforeDmg() {}, onEnd() {}, do() { - if (this.cd < simulation.cycle && !(simulation.cycle % this.lookFrequency) && !mech.isCloak) { - let target - for (let i = 0, len = mob.length; i < len; i++) { - const dist = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)); - if (dist < 1000000 && Matter.Query.ray(map, this.position, mob[i].position).length === 0) { - this.cd = simulation.cycle + this.delay; - target = Vector.add(mob[i].position, Vector.mult(mob[i].velocity, Math.sqrt(dist) / 60)) - const radius = 6 + 7 * Math.random() - const SPEED = 29 - radius * 0.5; //(mech.crouch ? 32 : 20) - radius * 0.7; - const velocity = Vector.mult(Vector.normalise(Vector.sub(target, this.position)), SPEED) - b.foam(this.position, velocity, radius + 9 * this.isUpgraded) - break; - } - } - } const distanceToPlayer = Vector.magnitude(Vector.sub(this.position, mech.pos)) if (distanceToPlayer > this.range) { //if far away move towards player this.force = Vector.mult(Vector.normalise(Vector.sub(mech.pos, this.position)), this.mass * this.acceleration) } else { //close to player Matter.Body.setVelocity(this, Vector.add(Vector.mult(this.velocity, 0.90), Vector.mult(player.velocity, 0.17))); //add player's velocity + + if (this.cd < simulation.cycle && !(simulation.cycle % this.lookFrequency) && !mech.isCloak) { + let target + for (let i = 0, len = mob.length; i < len; i++) { + const dist2 = Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)); + if (dist2 < 1000000 && Matter.Query.ray(map, this.position, mob[i].position).length === 0) { + this.cd = simulation.cycle + this.delay; + target = Vector.add(mob[i].position, Vector.mult(mob[i].velocity, Math.sqrt(dist2) / 60)) + const radius = 6 + 7 * Math.random() + const SPEED = 29 - radius * 0.5; //(mech.crouch ? 32 : 20) - radius * 0.7; + const velocity = Vector.mult(Vector.normalise(Vector.sub(target, this.position)), SPEED) + b.foam(this.position, velocity, radius + 7 * this.isUpgraded) + break; + } + } + } } } }) @@ -2804,18 +2845,34 @@ const b = { World.add(engine.world, bullet[me]); //add bullet to world } } else if (tech.isNailShot) { - for (let i = 0; i < 14; i++) { - const dir = mech.angle + (Math.random() - 0.5) * spread * 0.2 - const pos = { - x: mech.pos.x + 35 * Math.cos(mech.angle) + 15 * (Math.random() - 0.5), - y: mech.pos.y + 35 * Math.sin(mech.angle) + 15 * (Math.random() - 0.5) + if (mech.crouch) { + for (let i = 0; i < 11; i++) { + const dir = mech.angle + (Math.random() - 0.5) * 0.015 + const pos = { + x: mech.pos.x + 35 * Math.cos(mech.angle) + 15 * (Math.random() - 0.5), + y: mech.pos.y + 35 * Math.sin(mech.angle) + 15 * (Math.random() - 0.5) + } + speed = 39 + 7 * Math.random() + const velocity = { + x: speed * Math.cos(dir), + y: speed * Math.sin(dir) + } + b.nail(pos, velocity, 1.2) } - speed = 35 + 15 * Math.random() - const velocity = { - x: speed * Math.cos(dir), - y: speed * Math.sin(dir) + } else { + for (let i = 0; i < 15; i++) { + const dir = mech.angle + (Math.random() - 0.5) * 0.42 + const pos = { + x: mech.pos.x + 35 * Math.cos(mech.angle) + 15 * (Math.random() - 0.5), + y: mech.pos.y + 35 * Math.sin(mech.angle) + 15 * (Math.random() - 0.5) + } + speed = 34 + 6 * Math.random() + const velocity = { + x: speed * Math.cos(dir), + y: speed * Math.sin(dir) + } + b.nail(pos, velocity, 1.2) } - b.nail(pos, velocity, 1.2) } } else { const side = 22 @@ -2912,15 +2969,15 @@ const b = { name: "flechettes", description: "fire a volley of uranium-235 needles
does radioactive damage over 3 seconds", ammo: 0, - ammoPack: 65, - defaultAmmoPack: 65, + ammoPack: 75, + defaultAmmoPack: 75, 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 fire() { function makeFlechette(angle = mech.angle + 0.02 * (Math.random() - 0.5)) { const me = bullet.length; - bullet[me] = Bodies.rectangle(mech.pos.x + 40 * Math.cos(mech.angle), mech.pos.y + 40 * Math.sin(mech.angle), 45, 1.4, b.fireAttributes(angle)); + bullet[me] = Bodies.rectangle(mech.pos.x + 40 * Math.cos(mech.angle), mech.pos.y + 40 * Math.sin(mech.angle), 45, 1, b.fireAttributes(angle)); bullet[me].collisionFilter.mask = tech.pierce ? 0 : cat.body; //cat.mobShield | //cat.map | cat.body | Matter.Body.setDensity(bullet[me], 0.00001); //0.001 is normal bullet[me].endCycle = simulation.cycle + 180; @@ -2954,16 +3011,15 @@ const b = { } } else { this.endCycle = 0; - if (tech.isFlechetteExplode && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.975) { - // mobs.statusStun(who, 120) + if (tech.isFlechetteExplode && !who.shield && Vector.dot(Vector.normalise(Vector.sub(who.position, this.position)), Vector.normalise(this.velocity)) > 0.97) { this.explodeRad = 300 + 60 * Math.random(); b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end } who.foundPlayer(); if (tech.isFastDot) { - mobs.statusDoT(who, 3.78, 30) + mobs.statusDoT(who, 4, 30) } else { - mobs.statusDoT(who, 0.63, tech.isSlowDot ? 360 : 180) + mobs.statusDoT(who, 0.7, tech.isSlowDot ? 360 : 180) } simulation.drawList.push({ //add dmg to draw queue x: this.position.x, @@ -2991,6 +3047,7 @@ const b = { x: mech.Vx / 2 + SPEED * Math.cos(angle), y: mech.Vy / 2 + SPEED * Math.sin(angle) }); + Matter.Body.setDensity(bullet[me], 0.00001); World.add(engine.world, bullet[me]); //add bullet to world } makeFlechette() @@ -2999,14 +3056,12 @@ const b = { makeFlechette(mech.angle - 0.02 - 0.005 * Math.random()) } - const CD = (mech.crouch) ? 50 : 20 + const CD = (mech.crouch) ? 40 : 15 if (this.lastFireCycle + CD < mech.cycle) this.count = 0 //reset count if it cycles past the CD this.lastFireCycle = mech.cycle if (this.count > ((mech.crouch) ? 8 : 1)) { this.count = 0 mech.fireCDcycle = mech.cycle + Math.floor(CD * b.fireCD); // cool down - const who = bullet[bullet.length - 1] - Matter.Body.setDensity(who, 0.00001); } else { this.count++ mech.fireCDcycle = mech.cycle + Math.floor(2 * b.fireCD); // cool down @@ -3126,62 +3181,88 @@ const b = { }, { name: "missiles", - description: "launch missiles that accelerate towards mobs
explodes when near target", + description: "launch homing missiles that explode
crouch to rapidly launch smaller missiles", ammo: 0, - ammoPack: 3.3, + ammoPack: 3.5, have: false, fireCycle: 0, ammoLoaded: 0, fire() { - //missile(where, dir, speed, size = 1, spawn = 0) { - if (tech.is3Missiles) { - if (mech.crouch) { - mech.fireCDcycle = mech.cycle + 17 * b.fireCD; // cool down - for (let i = 0; i < 3; i++) { - b.missile({ - x: mech.pos.x, - y: mech.pos.y - 40 - }, -Math.PI / 2 + 0.08 * (1 - i) + 0.3 * (Math.random() - 0.5), 0, 0.7, tech.recursiveMissiles) - bullet[bullet.length - 1].force.x -= 0.015 * (i - 1); - } - } else { - mech.fireCDcycle = mech.cycle + 55 * b.fireCD; // cool down - const direction = { - x: Math.cos(mech.angle), - y: Math.sin(mech.angle) - } - const push = Vector.mult(Vector.perp(direction), 0.02) - for (let i = 0; i < 3; i++) { - b.missile({ - x: mech.pos.x + 40 * direction.x, - y: mech.pos.y + 40 * direction.y - }, mech.angle + 0.06 * (Math.random() - 0.5), 5, 0.7, tech.recursiveMissiles) - bullet[bullet.length - 1].force.x += push.x * (i - 1); - bullet[bullet.length - 1].force.y += push.y * (i - 1); - } + const countReduction = Math.pow(0.9, tech.missileCount) + if (mech.crouch) { + mech.fireCDcycle = mech.cycle + 10 * b.fireCD / countReduction; // cool down + + const size = countReduction * (tech.missileSize ? 1.32 : 0.88) + const where = { + x: mech.pos.x, + y: mech.pos.y - 40 + } + for (let i = 0; i < tech.missileCount; i++) { + b.missile(where, -Math.PI / 2 + 0.2 * (Math.random() - 0.5) * Math.sqrt(tech.missileCount), -2, size) + bullet[bullet.length - 1].force.x += 0.004 * size * (i - (tech.missileCount - 1) / 2); } } else { - if (mech.crouch) { - mech.fireCDcycle = mech.cycle + 17 * b.fireCD; // cool down - const off = Math.random() - 0.5 - b.missile({ - x: mech.pos.x, - y: mech.pos.y - 40 - }, - -Math.PI / 2 + 0.15 * off, 0, 1, tech.recursiveMissiles) - bullet[bullet.length - 1].force.x += off * 0.03; - // bullet[bullet.length - 1].force.y += push.y * (i - 1); - } else { - mech.fireCDcycle = mech.cycle + 55 * b.fireCD; // cool down - b.missile({ - x: mech.pos.x + 40 * Math.cos(mech.angle), - y: mech.pos.y + 40 * Math.sin(mech.angle) - 3 - }, - mech.angle + (0.5 - Math.random()) * (mech.crouch ? 0 : 0.2), 20, 1, tech.recursiveMissiles) - // bullet[bullet.length - 1].force.y += 0.01; //a small push down at first to make it seem like the missile is briefly falling - } + mech.fireCDcycle = mech.cycle + 50 * b.fireCD / countReduction; // cool down + const size = countReduction * (tech.missileSize ? 1.5 : 1) + const direction = { + x: Math.cos(mech.angle), + y: Math.sin(mech.angle) + } + const push = Vector.mult(Vector.perp(direction), 0.02 * size / Math.sqrt(tech.missileCount)) + const where = { + x: mech.pos.x + 40 * direction.x, + y: mech.pos.y + 40 * direction.y + } + for (let i = 0; i < tech.missileCount; i++) { + b.missile(where, mech.angle, 0, size) + bullet[bullet.length - 1].force.x += push.x * (i - (tech.missileCount - 1) / 2); + bullet[bullet.length - 1].force.y += push.y * (i - (tech.missileCount - 1) / 2); + } } + // if (tech.missileCount) { + // if (mech.crouch) { + // for (let i = 0; i < 3; i++) { + // b.missile({ + // x: mech.pos.x, + // y: mech.pos.y - 40 + // }, -Math.PI / 2 + 0.08 * (1 - i) + 0.3 * (Math.random() - 0.5), 0, 0.6 * (tech.missileSize ? 1.5 : 1)) + // bullet[bullet.length - 1].force.x -= 0.015 * (i - 1); + // } + // } else { + // mech.fireCDcycle = mech.cycle + 80 * b.fireCD; // cool down + // const direction = { + // x: Math.cos(mech.angle), + // y: Math.sin(mech.angle) + // } + // const push = Vector.mult(Vector.perp(direction), 0.02) + // for (let i = 0; i < 3; i++) { + // b.missile({ + // x: mech.pos.x + 40 * direction.x, + // y: mech.pos.y + 40 * direction.y + // }, mech.angle + 0.06 * (Math.random() - 0.5), 5, 0.7 * (tech.missileSize ? 1.5 : 1)) + // bullet[bullet.length - 1].force.x += push.x * (i - 1); + // bullet[bullet.length - 1].force.y += push.y * (i - 1); + // } + // } + // } else { + // if (mech.crouch) { + // mech.fireCDcycle = mech.cycle + 10 * b.fireCD; // cool down + // const off = Math.random() - 0.5 + // b.missile({ + // x: mech.pos.x, + // y: mech.pos.y - 40 + // }, + // -Math.PI / 2 + 0.15 * off, 0, 0.83 * (tech.missileSize ? 1.5 : 1)) + // bullet[bullet.length - 1].force.x += off * 0.03; + // // bullet[bullet.length - 1].force.y += push.y * (i - 1); + // } else { + // mech.fireCDcycle = mech.cycle + 55 * b.fireCD; // cool down + + // // bullet[bullet.length - 1].force.y += 0.01; //a small push down at first to make it seem like the missile is briefly falling + // } + + // } } }, { @@ -3773,7 +3854,7 @@ const b = { mech.fireCDcycle = mech.cycle mech.energy -= mech.fieldRegen + tech.laserFieldDrain * tech.isLaserDiode const divergence = mech.crouch ? 0.15 : 0.2 - let dmg = 0.1 + tech.laserDamage * Math.pow(0.9, tech.laserDamage) + let dmg = tech.laserDamage * Math.pow(0.9, tech.beamSplitter) //Math.pow(0.9, tech.laserDamage) const where = { x: mech.pos.x + 20 * Math.cos(mech.angle), y: mech.pos.y + 20 * Math.sin(mech.angle) @@ -3844,7 +3925,7 @@ const b = { } else { mech.fireCDcycle = mech.cycle mech.energy -= mech.fieldRegen + tech.laserFieldDrain * tech.isLaserDiode - const dmg = 0.5 * tech.laserDamage // 3.5 * 0.55 = 200% more damage + const dmg = 0.4 * tech.laserDamage // 3.5 * 0.55 = 200% more damage ctx.strokeStyle = "#f00"; let spacing, len if (tech.wideLaser === 3) { @@ -3886,10 +3967,9 @@ const b = { let energy = 0.27 * Math.min(mech.energy, 1.5) mech.energy -= energy * tech.isLaserDiode if (tech.beamSplitter) { - energy *= 0.66 + energy *= Math.pow(0.9, tech.beamSplitter) b.pulse(energy, mech.angle) for (let i = 1; i < 1 + tech.beamSplitter; i++) { - energy *= 0.9 b.pulse(energy, mech.angle - i * 0.27) b.pulse(energy, mech.angle + i * 0.27) } diff --git a/js/engine.js b/js/engine.js index 97b8e37..8713c40 100644 --- a/js/engine.js +++ b/js/engine.js @@ -123,7 +123,7 @@ function collisionChecks(event) { y: mob[k].velocity.y - 8 * Math.sin(angle) }); - if (tech.isAnnihilation && !mob[k].shield && !mob[k].isShielded && mech.energy > 0.34 * mech.maxEnergy) { + if (tech.isAnnihilation && !mob[k].shield && !mob[k].isShielded && mob[k].dropPowerUp && mech.energy > 0.34 * mech.maxEnergy) { mech.energy -= 0.33 * mech.maxEnergy mech.immuneCycle = 0; //player doesn't go immune to collision damage mob[k].death(); diff --git a/js/level.js b/js/level.js index 1107c60..8550ec4 100644 --- a/js/level.js +++ b/js/level.js @@ -13,13 +13,14 @@ const level = { start() { if (level.levelsCleared === 0) { //this code only runs on the first level // simulation.enableConstructMode() //used to build maps in testing mode - // level.difficultyIncrease(1) + // level.difficultyIncrease(20) // simulation.zoomScale = 1000; // simulation.setZoom(); // mech.setField("plasma torch") - // b.giveGuns("wave beam") + // b.giveGuns("missiles") // tech.giveTech("CPT reversal") - // tech.giveTech("CPT gun") + // tech.giveTech("missile-bot") + // tech.giveTech("nail-bot") // for (let i = 0; i < 15; i++) tech.giveTech("plasma jet") level.intro(); //starting level @@ -62,8 +63,7 @@ const level = { tech.armorFromPowerUps += gain mech.setMaxHealth(); // if (powerUps.totalPowerUps) simulation.makeTextLog(" max health increased by " + (gain * 100).toFixed(0) + "%", 300) - simulation.makeTextLog(`mech.maxHealth += ${(gain).toFixed(3)} -
${mech.maxHealth.toFixed(3)}`) + simulation.makeTextLog(`mech.maxHealth += ${(gain).toFixed(2)}`) } if (tech.isHealLowHealth) { const len = Math.floor((mech.maxHealth - mech.health) / 0.5) @@ -146,7 +146,7 @@ const level = { spawn.bodyRect(x + 5, y - 260 + i * blockSize, 30, blockSize); } } - blockDoor(710, -710); + // blockDoor(710, -710); spawn.mapRect(2500, -1200, 200, 750); //right wall blockDoor(2585, -210) spawn.mapRect(2500, -200, 200, 300); //right wall @@ -159,7 +159,7 @@ const level = { spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump // spawn.boost(1500, 0, 900); - // spawn.starter(1900, -500, 200) //big boy + spawn.starter(1900, -500, 200) //big boy // spawn.exploder(2900, -500) // spawn.launcherBoss(1200, -500) // spawn.laserTargetingBoss(1600, -400) diff --git a/js/player.js b/js/player.js index 72c5256..dbfd4cd 100644 --- a/js/player.js +++ b/js/player.js @@ -1507,7 +1507,7 @@ const mech = { } } else if (tech.isMissileField) { mech.energy -= 0.55; - b.missile({ x: mech.pos.x, y: mech.pos.y - 40 }, -Math.PI / 2, 0, 1, tech.recursiveMissiles) + b.missile({ x: mech.pos.x, y: mech.pos.y - 40 }, -Math.PI / 2, 0, 1) } else if (tech.isIceField) { mech.energy -= 0.057; b.iceIX(1) @@ -1540,13 +1540,13 @@ const mech = { }, { name: "negative mass field", - description: "use energy to nullify  gravity
reduce harm by 40%
blocks held by the field have a lower mass", + description: "use energy to nullify  gravity
reduce harm by 45%
blocks held by the field have a lower mass", fieldDrawRadius: 0, effect: () => { mech.fieldFire = true; mech.holdingMassScale = 0.03; //can hold heavier blocks with lower cost to jumping mech.fieldMeterColor = "#000" - mech.fieldHarmReduction = 0.6; + mech.fieldHarmReduction = 0.55; mech.fieldDrawRadius = 0; mech.hold = function() { diff --git a/js/powerup.js b/js/powerup.js index d363bb0..e1f3e2b 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -53,7 +53,7 @@ const powerUps = { powerUps.tech.banishLog.push(powerUps.tech.choiceLog[powerUps.tech.choiceLog.length - 1 - i]) } } - simulation.makeTextLog(`${Math.max(0,powerUps.tech.lastTotalChoices - powerUps.tech.banishLog.length)} estimated tech choices remaining`) + simulation.makeTextLog(`powerUps.tech.length: ${Math.max(0,powerUps.tech.lastTotalChoices - powerUps.tech.banishLog.length)}`) } } if (tech.manyWorlds && powerUps.reroll.rerolls === 0) { @@ -127,7 +127,8 @@ const powerUps = { powerUps.tech.banishLog.push(powerUps.tech.choiceLog[powerUps.tech.choiceLog.length - 1 - i]) } } - simulation.makeTextLog(`${Math.max(0,powerUps.tech.lastTotalChoices - powerUps.tech.banishLog.length)} estimated tech choices remaining`) + // simulation.makeTextLog(`${Math.max(0,powerUps.tech.lastTotalChoices - powerUps.tech.banishLog.length)} estimated tech choices remaining`) + simulation.makeTextLog(`powerUps.tech.length: ${Math.max(0,powerUps.tech.lastTotalChoices - powerUps.tech.banishLog.length)}`) } powerUps[type].effect(); }, @@ -168,26 +169,23 @@ const powerUps = { return 17; }, effect() { - //give ammo to all guns in inventory - if (tech.isAmmoForGun && b.inventory.length > 0) { + if (tech.isAmmoForGun && b.inventory.length > 0 && b.activeGun) { const target = b.guns[b.activeGun] - const ammoAdded = Math.ceil(Math.random() * target.ammoPack) + Math.ceil(Math.random() * target.ammoPack) - target.ammo += ammoAdded - // simulation.makeTextLog(`
  ${ammoAdded} ammo added`, 300) - simulation.makeTextLog(`${target.name}.ammo += ${ammoAdded} -
${target.ammo}`) - } else { - let text = ''; + if (target.ammo !== Infinity) { + const ammoAdded = Math.ceil(Math.random() * target.ammoPack) + Math.ceil(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(Math.random() * target.ammoPack) target.ammo += ammoAdded - if (i !== 0) text += "
" - text += `${target.name}.ammo += ${ammoAdded}` + simulation.makeTextLog(`${target.name}.ammo += ${ammoAdded}`) } } - simulation.makeTextLog(text) + } simulation.updateGunHUD(); } @@ -375,7 +373,8 @@ const powerUps = { for (let i = 0, len = tech.tech.length; i < len; i++) { if (tech.tech[i].name === "erase") powerUps.ejectTech(i) } - simulation.makeTextLog(`No tech left
erased tech have been recovered`) + // simulation.makeTextLog(`No tech left
erased tech have been recovered`) + simulation.makeTextLog(`powerUps.tech.length: ${Math.max(0,powerUps.tech.lastTotalChoices - powerUps.tech.banishLog.length)}`) powerUps.spawn(mech.pos.x, mech.pos.y, "tech"); powerUps.endDraft("tech"); } else { diff --git a/js/simulation.js b/js/simulation.js index 5be4742..2cf037f 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -522,6 +522,7 @@ const simulation = { tech.foamBotCount = 0; tech.boomBotCount = 0; tech.plasmaBotCount = 0; + tech.missileBotCount = 0; b.setFireCD(); simulation.updateTechHUD(); diff --git a/js/tech.js b/js/tech.js index 005dc14..038dc22 100644 --- a/js/tech.js +++ b/js/tech.js @@ -83,7 +83,7 @@ const tech = { if (tech.isEnergyNoAmmo) dmg *= 1.5 if (tech.isDamageForGuns) dmg *= 1 + 0.07 * b.inventory.length if (tech.isLowHealthDmg) dmg *= 1 + 0.6 * Math.max(0, 1 - mech.health) - if (tech.isHarmDamage && mech.lastHarmCycle + 600 > mech.cycle) dmg *= 2; + if (tech.isHarmDamage && mech.lastHarmCycle + 600 > mech.cycle) dmg *= 3; if (tech.isEnergyLoss) dmg *= 1.5; if (tech.isAcidDmg && mech.health > 1) dmg *= 1.4; if (tech.restDamage > 1 && player.speed < 1) dmg *= tech.restDamage @@ -100,7 +100,7 @@ const tech = { return (tech.isBayesian ? 0.2 : 0) + tech.cancelCount * 0.04 + tech.duplicateChance + mech.duplicateChance }, totalBots() { - return tech.foamBotCount + tech.nailBotCount + tech.laserBotCount + tech.boomBotCount + tech.plasmaBotCount + tech.orbitBotCount + return tech.foamBotCount + tech.nailBotCount + tech.laserBotCount + tech.boomBotCount + tech.orbitBotCount + tech.plasmaBotCount + tech.missileBotCount }, tech: [{ name: "electrolytes", @@ -136,7 +136,7 @@ const tech = { }, { name: "exothermic process", - description: "increase damage by 50%
if a mob dies drain stored energy by 25%", + description: "increase damage by 50%
if a mob dies drain energy by 25%", maxCount: 1, count: 0, allowed() { @@ -250,7 +250,7 @@ const tech = { }, { name: "negative feedback", - description: "increase damage by 6%
for every 10 missing base health", + description: "increase damage by 6%
for every 10 health below 100", maxCount: 1, count: 0, allowed() { @@ -266,7 +266,7 @@ const tech = { }, { name: "radiative equilibrium", - description: "for 10 seconds after receiving harm
increase damage by 100%", + description: "for 10 seconds after receiving harm
increase damage by 200%", maxCount: 1, count: 0, allowed() { @@ -561,7 +561,7 @@ const tech = { }, { name: "foam-bot", - description: "a bot fires foam at targets in line of sight", + description: "a bot fires foam at nearby targets", maxCount: 9, count: 0, allowed() { @@ -805,14 +805,18 @@ const tech = { b.boomBot(); } tech.boomBotCount *= 2 - for (let i = 0; i < tech.plasmaBotCount; i++) { - b.plasmaBot(); - } - tech.plasmaBotCount *= 2 for (let i = 0; i < tech.orbitBotCount; i++) { b.orbitBot(); } tech.orbitBotCount *= 2 + for (let i = 0; i < tech.plasmaBotCount; i++) { + b.plasmaBot(); + } + tech.plasmaBotCount *= 2 + for (let i = 0; i < tech.missileBotCount; i++) { + b.missileBot(); + } + tech.missileBotCount *= 2 }, remove() {} }, @@ -906,7 +910,7 @@ const tech = { }, { name: "Pauli exclusion", - description: `immune to harm for 0.5 seconds longer
after receiving harm from a collision`, + description: `immune to harm for an extra 0.75 seconds
after receiving harm from a collision`, maxCount: 9, count: 0, allowed() { @@ -914,7 +918,7 @@ const tech = { }, requires: "", effect() { - tech.collisionImmuneCycles += 30; + tech.collisionImmuneCycles += 45; mech.immuneCycle = mech.cycle + tech.collisionImmuneCycles; //player is immune to collision damage for 30 cycles }, remove() { @@ -1384,7 +1388,7 @@ const tech = { }, { name: "Bayesian statistics", - description: "20% chance to duplicate spawned power ups
after a collision, eject 1 tech", + description: "20% chance to duplicate spawned power ups
after a collision, eject 1 tech", maxCount: 1, count: 0, allowed() { @@ -1773,9 +1777,9 @@ const tech = { maxCount: 1, count: 0, allowed() { - return (powerUps.reroll.rerolls > 5 || build.isCustomSelection) && !tech.isDeterminism + return (powerUps.reroll.rerolls > 2 || build.isCustomSelection) && !tech.isDeterminism }, - requires: "not determinism, at least 4 rerolls", + requires: "not determinism, at least 3 rerolls", effect() { tech.isBanish = true for (let i = 0; i < 4; i++) { @@ -2052,7 +2056,7 @@ const tech = { }, { name: "critical bifurcation", - description: "nails do 400% more damage
when they strike near the center of a mob", + description: "nail gun nails do 400% more damage
when they strike near the center of a mob", isGunTech: true, maxCount: 1, count: 0, @@ -2428,25 +2432,42 @@ const tech = { } }, { - name: "recursion", - description: "after missiles explode they have a
20% chance to launch a larger missile", + name: "cruise missile", + description: "missiles travel 50% slower,
but have a 50% larger explosive payload", isGunTech: true, - maxCount: 6, + maxCount: 1, count: 0, allowed() { return tech.haveGunCheck("missiles") || tech.isMissileField }, requires: "missiles", effect() { - tech.recursiveMissiles++ + tech.missileSize = true }, remove() { - tech.recursiveMissiles = 0; + tech.missileSize = false } }, { name: "MIRV", - description: "launch 3 small missiles instead of 1
1.5x increase in delay after firing", + description: "launch +1 missile at a time
decrease size and fire rate by 10%", + isGunTech: true, + maxCount: 9, + count: 0, + allowed() { + return tech.haveGunCheck("missiles") + }, + requires: "missiles", + effect() { + tech.missileCount++; + }, + remove() { + tech.missileCount = 1; + } + }, + { + name: "missile-bot", + description: "a bot fires missiles at far away targets", isGunTech: true, maxCount: 1, count: 0, @@ -2455,10 +2476,11 @@ const tech = { }, requires: "missiles", effect() { - tech.is3Missiles = true; + tech.missileBotCount++; + b.missileBot(); }, remove() { - tech.is3Missiles = false; + tech.missileBotCount = 0; } }, { @@ -2776,7 +2798,7 @@ const tech = { }, { name: "thermoelectric effect", - description: "killing mobs with ice IX gives 4 health
and 100 energy", + description: "killing mobs with ice IX gives 4 health
and 80 energy", isGunTech: true, maxCount: 9, count: 0, @@ -3034,14 +3056,14 @@ const tech = { }, requires: "laser, not specular reflection
not diffraction grating", effect() { - this.description = `add 10 more laser beams into into your past` + this.description = `add 5 more laser beams into into your past` tech.historyLaser++ for (i = 0, len = b.guns.length; i < len; i++) { //find which gun if (b.guns[i].name === "laser") b.guns[i].chooseFireMethod() } }, remove() { - this.description = "laser beam is spread into your recent past
increase total laser damage by 200%" + this.description = "laser beam is spread into your recent past
increase total beam damage by 300%" tech.historyLaser = 0 for (i = 0, len = b.guns.length; i < len; i++) { //find which gun if (b.guns[i].name === "laser") b.guns[i].chooseFireMethod() @@ -3050,7 +3072,7 @@ const tech = { }, { name: "pulse", - description: "convert 25% of your energy into a pulsed laser
instantly initiates a fusion explosion", + description: "convert 25% of your energy into a pulsed laser
that instantly initiates a fusion explosion", isGunTech: true, maxCount: 1, count: 0, @@ -3769,6 +3791,7 @@ const tech = { foamBotCount: null, boomBotCount: null, plasmaBotCount: null, + missileBotCount: null, orbitBotCount: null, collisionImmuneCycles: null, blockDmg: null, @@ -3796,7 +3819,6 @@ const tech = { isMineAmmoBack: null, isPlasmaRange: null, isFreezeMobs: null, - recursiveMissiles: null, isIceCrystals: null, throwChargeRate: null, isBlockStun: null, @@ -3816,7 +3838,7 @@ const tech = { isPulseStun: null, restDamage: null, isRPG: null, - is3Missiles: null, + missileCount: null, isDeterminism: null, isSuperDeterminism: null, isHarmReduce: null, @@ -3919,6 +3941,7 @@ const tech = { isRewindGrenade: null, isExtruder: null, isEndLevelPowerUp: null, - isRewindGun: null + isRewindGun: null, + missileSize: null } \ No newline at end of file diff --git a/style.css b/style.css index 0750829..ea7ed8e 100644 --- a/style.css +++ b/style.css @@ -521,7 +521,7 @@ summary { } .color-m { - color: hsl(253, 57%, 52%); + color: hsl(253, 100%, 50%); letter-spacing: 1px; } diff --git a/todo.txt b/todo.txt index 84fc8f7..ccb41fd 100644 --- a/todo.txt +++ b/todo.txt @@ -1,17 +1,19 @@ ******************************************************** NEXT PATCH ******************************************************** -updated in game console style and all messages to match real game commands -new names inline with lore, tech-> tech, game -> simulation - this is probably going to cause many minor bugs, so let me know what you find -new reroll display in power up selection +fixed some math on laser tech: diffraction grating and slow light propagation + they were giving too much damage -tech: rocket-propelled now works with all grenade tech +flechettes are slightly improved in: ammo, damage, fire rate + +tech - MIRV can now stack up to 9 bonus missiles +removed tech - recursive missiles +tech: cruise missile - 50% larger size, but travels 50% slower +tech: missileBot - requires gun: missiles ******************************************************** BUGS ******************************************************** -check for crouch after rewind - CPT, tesseract - +CPT check for crouch after rewind + (always) make it so that when you are immune to harm you can either jump on mobs or you pass through them (always) is there a way to check if the player is stuck inside the map or block @@ -33,7 +35,7 @@ check for crouch after rewind (once) bug - mine spawned one new mine every second after sticking to the top right corner of a wall - notes: had only gun mine, techmine reclamation, field plasma, + notes: had only gun mine, tech mine reclamation, field plasma, (repeatable almost every time) bug - mines spawn extra mines when fired at thin map wall while jumping @@ -46,31 +48,39 @@ rename reroll > resample, reset, retry, remeasure in game console + set highlighting rules + mech, tech, level are all highlighted + maybe the first term in each variable should get a highlight make all commands actually work input.key commands don't work rewrite to not be a console command? add commands death, max health, max energy, rewind -mechanic: use gun swap as an active ability for several tech +mine tech: laser mines - mines hover in the air + maybe they can be thrown a short distance, but they have no gravity and high friction, so they hover + when a mob gets close they spin and fire 3 unaimed lasers from their vertexes + with tech:sentry the mines spin immediately, and spin 2x times longer? + +mechanic: use gun swap as an active ability ideas? - trigger damage immunity for 3 seconds, but drain energy? + trigger damage immunity for 3 seconds, but drain ammo push away nearby mobs, but drain energy produce ammo, but take 1 damage +tech: time dilation - when you exit time dilation rewind to the state you entered + position, velocity, and health + no energy cost CPT gun seems a bit weak right now. How to buff the gun? -technail gun: slow and accurate -techfoam: fast and inaccurate - mob ability bombs/bullets that suck in player -techwhere you can't stop firing, how to code? +tech where you can't stop firing, how to code? -tech laser beams push like plasma torch pushes with directional force +tech: laser beams push like plasma torch pushes with directional force -mechanic: technological dead end - add tech to the techpool with a dumb effect +mechanic: technological dead end - add tech to the tech pool with a dumb effect don't show up in custom? negative effect (one time effects are better to avoid code clutter) make the player rainbow colors @@ -96,14 +106,14 @@ tech "Circadian Rhythm": Become immune to harm for 1 second every 10 seconds whi tech "High Risk": Spawn two bosses per level. maybe limit to just the power up boss and spawn it at the exit every time to keep it simple also weaken the player - remove a techup? + remove a tech? lower harm reduction? increase game difficulty by one level -techthat requires integrated armament +tech that requires integrated armament tech- reset level - you trade a techfor a chance at killing a new level boss and farming more ammo + you trade a tech for a chance at killing a new level boss and farming more ammo resets health, ammo (but not tech, fields, guns, ... ?) scramble level order? or same level @@ -131,12 +141,12 @@ tech when mobs are at full health you do 40% to them tech- move super fast, go intangible, drain energy very fast this is like a dodge roll - techfor standing wave?, cloaking? + tech for standing wave?, cloaking? -techpilot wave: mini black hole - pull mobs and blocks in with more force +tech pilot wave: mini black hole - pull mobs and blocks in with more force also from farther away also do damage? -techpilot wave: antigravity - blocks have no gravity for a few seconds after exiting the field +tech pilot wave: antigravity - blocks have no gravity for a few seconds after exiting the field maybe they bounce too? maybe they explode? @@ -167,18 +177,18 @@ wormhole - make it clear when the wormhole can and can't teleport to a location time dilation - slow down the game engine by 1/2, but run an extra player cycle to simulate slow motion flavor - your bullets destroy blocks - this isn't really a bonus, so maybe just add this as flavor to another techfield/gun + this isn't really a bonus, so maybe just add this as flavor to another tech field/gun a chance for destroyed blocks to drop stuff power ups spores -techplasma : plasma length increases then decreases as you hold down the field button (like stabbing with a spear) +tech plasma : plasma length increases then decreases as you hold down the field button (like stabbing with a spear) grows to 1.5 longer after 0.3 seconds, then returns to normal length over 1 second, until field is pressed again extra energy is drained when field is longer using a reroll gives 3 options for tech, and 3 options for guns/fields/tech - or 6 options for tech (rewrite techselection to work with 1-6 options) - the second stack of 3 tech could have repeats, so you don't have to write new techcode + or 6 options for tech (rewrite tech selection to work with 1-6 options) + the second stack of 3 tech could have repeats, so you don't have to write new tech code adjust css to make 2 columns of 3 can't use with cardinality @@ -192,7 +202,7 @@ new power up - increase damage and fire speed, for 15 seconds tech "Solar Power": Energy regeneration is doubled while standing still run in the 1 second check -mechanic - remove a random techas a condition for picking up a really good mod +mechanic - remove a random tech as a condition for picking up a really good mod mechanic - do something for 2 seconds after firing if (mech.fireCDcycle + 120) @@ -236,7 +246,7 @@ have some mobs spawn in later in the level (in hard and why modes) after some mobs are dead after the boss is killed -look for tech that could update description text with count and techis information +look for tech that could update description text with count and tech is information can only use variables that change in effect() and remove() this.description = `8% chance to duplicate spawned power ups
chance to duplicate = ${techduplicateChance}` @@ -244,7 +254,7 @@ mouse event e.which is deprecated add some more computer / AI stuff to the level lore text -mechanic - shrink mech.baseHealth in a techor field +mechanic - shrink mech.baseHealth in a tech or field standing wave harmonics tech- push things away push scales with mass up to about 4 @@ -366,12 +376,15 @@ n-gon outreach ideas ******************************************************** LORE ******************************************************** - lore - a robot (the player) gains self awareness - each techgun/field is a new tech +cool names for tech + strange loop + +lore - a robot (the player) gains self awareness + each tech gun/field is a new tech all the technology leads to the singularity each game run is actually the mech simulating a possible escape this is why the graphics are so bad, its just a simulation - final techis "this is just a simulation" + final tech is "this is just a simulation" you get immortality and Infinity damage the next level is the final level when you die with Quantum Immortality there is a chance of lore text @@ -435,12 +448,13 @@ ending outline first time win on east or normal they talk about: how many runs the player has done they guess why + player is asked to stand on an in game button to enable the vocoder they reveal the player is running simulations, and it isn't real they ask the player to communicate jump twice if you understand they ask the player to enter console commands give ammo or tech or something - They tell the play a console command to permenantly enable custom and testing mode (in local storage) + They tell the play a console command to permanently enable custom and testing mode (in local storage) players can use this command in the future to enable custom and testing without beating the game even if local storage is wiped they then tell the player the command to increase the difficulty and the command to restart the game. If you win on hard or why: