diff --git a/.DS_Store b/.DS_Store index 9ebb094..ed82f45 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/js/bullet.js b/js/bullet.js index beded82..ee19419 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -713,11 +713,11 @@ const b = { }, setGrenadeMode() { - grenadeDefault = function(where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }, angle = m.angle) { + grenadeDefault = function(where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }, angle = m.angle, size = 1) { const me = bullet.length; bullet[me] = Bodies.circle(where.x, where.y, 15, b.fireAttributes(angle, false)); - Matter.Body.setDensity(bullet[me], 0.0005); - bullet[me].explodeRad = 300; + Matter.Body.setDensity(bullet[me], 0.0003); + bullet[me].explodeRad = 300 * size; bullet[me].onEnd = function() { b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end if (tech.fragments) b.targetedNail(this.position, tech.fragments * 4) @@ -738,11 +738,11 @@ const b = { }; Composite.add(engine.world, bullet[me]); //add bullet to world } - grenadeRPG = function(where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }, angle = m.angle) { + grenadeRPG = function(where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }, angle = m.angle, size = 1) { const me = bullet.length; bullet[me] = Bodies.circle(where.x, where.y, 15, b.fireAttributes(angle, false)); - Matter.Body.setDensity(bullet[me], 0.0005); - bullet[me].explodeRad = 305; + Matter.Body.setDensity(bullet[me], 0.0003); + bullet[me].explodeRad = 305 * size; bullet[me].onEnd = function() { b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end if (tech.fragments) b.targetedNail(this.position, tech.fragments * 4) @@ -773,11 +773,11 @@ const b = { } }; } - grenadeRPGVacuum = function(where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }, angle = m.angle) { + grenadeRPGVacuum = function(where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }, angle = m.angle, size = 1) { const me = bullet.length; bullet[me] = Bodies.circle(where.x, where.y, 15, b.fireAttributes(angle, false)); - Matter.Body.setDensity(bullet[me], 0.0005); - bullet[me].explodeRad = 350 + Math.floor(Math.random() * 50) + tech.isBlockExplode * 110 + Matter.Body.setDensity(bullet[me], 0.0003); + bullet[me].explodeRad = 350 * size + Math.floor(Math.random() * 50) + tech.isBlockExplode * 110 bullet[me].onEnd = function() { b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end if (tech.fragments) b.targetedNail(this.position, tech.fragments * 4) @@ -849,11 +849,11 @@ const b = { } }; } - grenadeVacuum = function(where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }, angle = m.angle) { + grenadeVacuum = function(where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }, angle = m.angle, size = 1) { const me = bullet.length; bullet[me] = Bodies.circle(where.x, where.y, 20, b.fireAttributes(angle, false)); - Matter.Body.setDensity(bullet[me], 0.0003); - bullet[me].explodeRad = 350 + Math.floor(Math.random() * 50) + tech.isBlockExplode * 100 + Matter.Body.setDensity(bullet[me], 0.0002); + bullet[me].explodeRad = 350 * size + Math.floor(Math.random() * 50) + tech.isBlockExplode * 100 bullet[me].onEnd = function() { b.explosion(this.position, this.explodeRad); //makes bullet do explosive damage at end if (tech.fragments) b.targetedNail(this.position, tech.fragments * 6) @@ -920,10 +920,10 @@ const b = { Composite.add(engine.world, bullet[me]); //add bullet to world } - grenadeNeutron = function(where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }, angle = m.angle) { + grenadeNeutron = function(where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }, angle = m.angle, size = 1) { const me = bullet.length; bullet[me] = Bodies.polygon(where.x, where.y, 10, 4, b.fireAttributes(angle, false)); - b.fireProps(m.crouch ? 45 : 25, m.crouch ? 35 : 20, angle, me); //cd , speed + b.fireProps((m.crouch ? 45 : 25) / Math.pow(0.93, tech.missileCount), m.crouch ? 35 : 20, angle, me); //cd , speed Matter.Body.setDensity(bullet[me], 0.000001); bullet[me].endCycle = Infinity; bullet[me].frictionAir = 0; @@ -932,7 +932,7 @@ const b = { bullet[me].restitution = 0; bullet[me].minDmgSpeed = 0; bullet[me].damageRadius = 100; - bullet[me].maxDamageRadius = 450 + 130 * tech.isNeutronSlow //+ 150 * Math.random() + bullet[me].maxDamageRadius = 450 * size + 130 * tech.isNeutronSlow //+ 150 * Math.random() bullet[me].radiusDecay = (0.81 + 0.15 * tech.isNeutronSlow) / tech.isBulletsLastLonger bullet[me].stuckTo = null; bullet[me].stuckToRelativePosition = null; @@ -1604,7 +1604,7 @@ const b = { laserMine(position, velocity = { x: 0, y: -8 }) { const me = bullet.length; bullet[me] = Bodies.polygon(position.x, position.y, 3, 25, { - bulletType: "mine", + bulletType: "laser mine", angle: m.angle, friction: 0, frictionAir: 0.025, @@ -1612,8 +1612,8 @@ const b = { dmg: 0, // 0.14 //damage done in addition to the damage from momentum minDmgSpeed: 2, lookFrequency: 67 + Math.floor(7 * Math.random()), - drain: 0.5 * tech.isLaserDiode * tech.laserFieldDrain, - isArmed: false, + drain: 0.62 * tech.isLaserDiode * tech.laserFieldDrain, + isDetonated: false, torqueMagnitude: 0.000003 * (Math.round(Math.random()) ? 1 : -1), range: 1500, endCycle: Infinity, @@ -1623,17 +1623,7 @@ const b = { mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield }, beforeDmg() {}, - onEnd() { - if (tech.isMineAmmoBack && (!this.isArmed || Math.random() < 0.2)) { //get ammo back from tech.isMineAmmoBack - for (i = 0, len = b.guns.length; i < len; i++) { //find which gun - if (b.guns[i].name === "mine") { - b.guns[i].ammo++ - simulation.updateGunHUD(); - break; - } - } - } - }, + onEnd() {}, do() { if (!(simulation.cycle % this.lookFrequency) && m.energy > this.drain) { //find mob targets for (let i = 0, len = mob.length; i < len; ++i) { @@ -1648,7 +1638,7 @@ const b = { if (this.angularSpeed < 0.5) this.torque += this.inertia * this.torqueMagnitude * 200 //spin this.endCycle = simulation.cycle + 360 + 120 // if (this.angularSpeed < 0.01) this.torque += this.inertia * this.torqueMagnitude * 5 //spin - this.isArmed = true + this.isDetonated = true break } } @@ -1669,7 +1659,7 @@ const b = { for (let i = 0; i < 3; i++) { const where = this.vertices[i] const endPoint = Vector.add(where, Vector.mult(Vector.normalise(Vector.sub(where, this.position)), 2500)) - b.laser(where, endPoint, tech.laserDamage * 14, this.reflections, true) + b.laser(where, endPoint, tech.laserDamage * 13, this.reflections, true) } ctx.stroke(); // ctx.globalAlpha = 1; @@ -1704,28 +1694,26 @@ const b = { lookFrequency: 0, range: 700, beforeDmg() {}, + onEnd() { + if (this.isArmed) b.targetedNail(this.position, tech.isMineSentry ? 7 : 22, 40 + 10 * Math.random(), 1200, true, 2.2) //targetedNail(position, num = 1, speed = 40 + 10 * Math.random(), range = 1200, isRandomAim = true, damage = 1.4) { + }, do() { this.force.y += this.mass * 0.002; //extra gravity let collide = Matter.Query.collides(this, map) //check if collides with map if (collide.length > 0) { for (let i = 0; i < collide.length; i++) { if (collide[i].bodyA.collisionFilter.category === cat.map) { // || collide[i].bodyB.collisionFilter.category === cat.map) { - const angle = Vector.angle(collide[i].normal, { - x: 1, - y: 0 - }) + const angle = Vector.angle(collide[i].normal, { x: 1, y: 0 }) Matter.Body.setAngle(this, Math.atan2(collide[i].tangent.y, collide[i].tangent.x)) //move until touching map again after rotation for (let j = 0; j < 10; j++) { if (Matter.Query.collides(this, map).length > 0) { //touching map if (angle > -0.2 || angle < -1.5) { //don't stick to level ground + Matter.Body.setVelocity(this, { x: 0, y: 0 }); Matter.Body.setStatic(this, true) //don't set to static if not touching map this.collisionFilter.mask = cat.map | cat.bullet } else { - Matter.Body.setVelocity(this, { - x: 0, - y: 0 - }); + Matter.Body.setVelocity(this, { x: 0, y: 0 }); Matter.Body.setAngularVelocity(this, 0) } this.arm(); @@ -1752,55 +1740,7 @@ const b = { } if (this.stillCount > 25) this.arm(); }, - // sentry() { - // this.collisionFilter.mask = cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield | cat.bullet //can now collide with other bullets - // this.lookFrequency = simulation.cycle + 60 - // this.do = function() { //overwrite the do method for this bullet - // this.force.y += this.mass * 0.002; //extra gravity - // if (simulation.cycle > this.lookFrequency) { - // const random = 300 * Math.random - // for (let i = 0, len = mob.length; i < len; ++i) { - // if ( - // !mob[i].isBadTarget && - // Vector.magnitude(Vector.sub(this.position, mob[i].position)) < 700 + mob[i].radius + random && - // Matter.Query.ray(map, this.position, mob[i].position).length === 0 && - // Matter.Query.ray(body, this.position, mob[i].position).length === 0 - // ) { - - // this.lookFrequency = 8 + Math.floor(3 * Math.random()) - // this.endCycle = simulation.cycle + 900 - // this.do = function() { //overwrite the do method for this bullet - // this.force.y += this.mass * 0.002; //extra gravity - // if (!(simulation.cycle % this.lookFrequency) && !m.isBodiesAsleep) { //find mob targets - // // this.endCycle -= 8 - // b.targetedNail(this.position, 1, 45 + 5 * Math.random(), 1100, false, 2) //targetedNail(position, num = 1, speed = 40 + 10 * Math.random(), range = 1200, isRandomAim = true, damage = 1.4) { - // if (!(simulation.cycle % (this.lookFrequency * 6))) { - // simulation.drawList.push({ - // x: this.position.x, - // y: this.position.y, - // radius: 8, - // color: "#fe0", - // time: 4 - // }); - // } - // } - // } - - // } - // } - // } - // } - // }, arm() { - //false alert - // for (let i = 0, len = mob.length; i < len; i++) { - // if (!mob[i].seePlayer.recall && Vector.magnitudeSquared(Vector.sub(this.position, mob[i].position)) < 4000000) { //2000 range - // mob[i].seePlayer.recall = 240; //cycles before mob falls a sleep - // mob[i].seePlayer.position.x = this.position.x; - // mob[i].seePlayer.position.y = this.position.y; - // } - // } - this.collisionFilter.mask = cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield | cat.bullet //can now collide with other bullets this.lookFrequency = simulation.cycle + 60 this.do = function() { //overwrite the do method for this bullet @@ -1848,11 +1788,8 @@ const b = { break } else { this.endCycle = 0 //end life if mob is near and visible - if (Math.random() < 0.8) isAmmoBack = false; //20% chance to get ammo back after detonation break } - - } } } @@ -1860,29 +1797,6 @@ const b = { } } }, - onEnd() { - if (this.isArmed) { - b.targetedNail(this.position, tech.isMineSentry ? 7 : 22, 40 + 10 * Math.random(), 1200, true, 2.2) //targetedNail(position, num = 1, speed = 40 + 10 * Math.random(), range = 1200, isRandomAim = true, damage = 1.4) { - } - if (tech.isMineAmmoBack && (!this.isArmed || Math.random() < 0.2)) { //get ammo back from tech.isMineAmmoBack - for (i = 0, len = b.guns.length; i < len; i++) { //find which gun - if (b.guns[i].name === "mine") { - b.guns[i].ammo++ - simulation.updateGunHUD(); - break; - } - } - } - // if (isAmmoBack) { //get ammo back from tech.isMineAmmoBack - // for (i = 0, len = b.guns.length; i < len; i++) { //find which gun - // if (b.guns[i].name === "mine") { - // b.guns[i].ammo++ - // simulation.updateGunHUD(); - // break; - // } - // } - // } - } }); bullet[bIndex].torque += bullet[bIndex].inertia * 0.0002 * (0.5 - Math.random()) Matter.Body.setVelocity(bullet[bIndex], velocity); @@ -2110,7 +2024,7 @@ const b = { }, iceIX(speed = 0, dir = m.angle + Math.PI * 2 * Math.random(), where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }) { const me = bullet.length; - const THRUST = 0.0006 + const THRUST = 0.0009 const RADIUS = 18 const SCALE = 1 - 0.08 / tech.isBulletsLastLonger bullet[me] = Bodies.polygon(where.x, where.y, 3, RADIUS, { @@ -2119,9 +2033,9 @@ const b = { friction: 0, frictionAir: 0.023, restitution: 0.9, - dmg: 0.55, //damage done in addition to the damage from momentum + dmg: 1, //damage done in addition to the damage from momentum lookFrequency: 14 + Math.floor(8 * Math.random()), - endCycle: simulation.cycle + 150 * tech.isBulletsLastLonger + Math.floor(25 * Math.random()), + endCycle: simulation.cycle + 100 * tech.isBulletsLastLonger + Math.floor(25 * Math.random()), classType: "bullet", collisionFilter: { category: cat.bullet, @@ -2607,7 +2521,7 @@ const b = { inertia: Infinity, frictionAir: 0.003, dmg: 0, //damage on impact - damage: (tech.isFastFoam ? 0.039 : 0.011) * (tech.isFoamTeleport ? 1.55 : 1), //damage done over time + damage: (tech.isFastFoam ? 0.039 : 0.011) * (tech.isFoamTeleport ? 1.5 : 1), //damage done over time scale: 1 - 0.006 / tech.isBulletsLastLonger * (tech.isFastFoam ? 1.65 : 1), classType: "bullet", collisionFilter: { @@ -2748,7 +2662,7 @@ const b = { } if (this.nextPortCycle < simulation.cycle) { //teleport around if you have tech.isFoamTeleport this.nextPortCycle = simulation.cycle + this.portFrequency - const range = 10 * Math.sqrt(this.radius) * Math.random() + const range = 15 * Math.sqrt(this.radius) * Math.random() Matter.Body.setPosition(this, Vector.add(this.position, Vector.rotate({ x: range, y: 0 }, 2 * Math.PI * Math.random()))) } } @@ -4043,9 +3957,9 @@ const b = { } } else if (tech.isIceShot) { const spread = (m.crouch ? 0.7 : 1.2) - for (let i = 0, len = 18 * (tech.isShotgunReversed ? 1.6 : 1); i < len; i++) { + for (let i = 0, len = 16 * (tech.isShotgunReversed ? 1.6 : 1); i < len; i++) { // iceIX(speed = 0, dir = m.angle + Math.PI * 2 * Math.random(), where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }) { - b.iceIX(25 + 32 * Math.random(), m.angle + spread * (Math.random() - 0.5)) + b.iceIX(25 + 20 * Math.random(), m.angle + spread * (Math.random() - 0.5)) } } else if (tech.isFoamShot) { const spread = (m.crouch ? 0.35 : 0.7) @@ -4132,8 +4046,9 @@ const b = { const SPEED = m.crouch ? 43 : 36 m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 23 : 15) * b.fireCDscale); // cool down const SPREAD = m.crouch ? 0.08 : 0.13 - let dir = m.angle - SPREAD * (tech.superBallNumber - 1) / 2; - for (let i = 0; i < tech.superBallNumber; i++) { + const num = tech.missileCount + 2 + let dir = m.angle - SPREAD * (num - 1) / 2; + for (let i = 0; i < num; i++) { const me = bullet.length; bullet[me] = Bodies.polygon(m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle), 12, 11 * tech.bulletSize, b.fireAttributes(dir, false)); Composite.add(engine.world, bullet[me]); //add bullet to world @@ -4163,6 +4078,7 @@ const b = { const dir = m.angle const x = m.pos.x const y = m.pos.y + const num = tech.missileCount + 2 const delay = Math.floor((m.crouch ? 18 : 12) * b.fireCDscale) m.fireCDcycle = m.cycle + delay; // cool down @@ -4194,7 +4110,7 @@ const b = { if (simulation.paused || m.isBodiesAsleep) { requestAnimationFrame(cycle) } else { count++ if (count % 2) fireBall() - if (count < tech.superBallNumber * 2 && m.alive) requestAnimationFrame(cycle); + if (count < num * 2 && m.alive) requestAnimationFrame(cycle); } } let count = 0 @@ -4640,14 +4556,21 @@ const b = { have: false, do() {}, fire() { - m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 40 : 30) * b.fireCDscale); // cool down - b.grenade() + const countReduction = Math.pow(0.93, tech.missileCount) + m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 40 : 30) * b.fireCDscale / countReduction); // cool down + const where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) } + const SPREAD = m.crouch ? 0.12 : 0.2 + let angle = m.angle - SPREAD * (tech.missileCount - 1) / 2; + for (let i = 0; i < tech.missileCount; i++) { + b.grenade(where, angle, countReduction) //function(where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }, angle = m.angle, size = 1) + angle += SPREAD + } }, }, { name: "mine", - description: "toss a proximity mine that sticks to walls
fires nails at mobs within range", + 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.4, + ammoPack: 1.1, have: false, do() {}, fire() { @@ -4657,33 +4580,17 @@ const b = { const velocity = { x: speed * Math.cos(m.angle), y: speed * Math.sin(m.angle) } b.laserMine(m.pos, velocity) } else { - const pos = { - x: m.pos.x + 30 * Math.cos(m.angle), - y: m.pos.y + 30 * Math.sin(m.angle) - } + const pos = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) } let speed = 36 - if (Matter.Query.point(map, pos).length > 0) { //don't fire if mine will spawn inside map - speed = -2 - } - b.mine(pos, { - x: speed * Math.cos(m.angle), - y: speed * Math.sin(m.angle) - }, 0, tech.isMineAmmoBack) + if (Matter.Query.point(map, pos).length > 0) speed = -2 //don't launch if mine will spawn inside map + b.mine(pos, { x: speed * Math.cos(m.angle), y: speed * Math.sin(m.angle) }, 0) } m.fireCDcycle = m.cycle + Math.floor(50 * b.fireCDscale); // cool down } else { - const pos = { - x: m.pos.x + 30 * Math.cos(m.angle), - y: m.pos.y + 30 * Math.sin(m.angle) - } + const pos = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) } let speed = 23 - if (Matter.Query.point(map, pos).length > 0) { //don't fire if mine will spawn inside map - speed = -2 - } - b.mine(pos, { - x: speed * Math.cos(m.angle), - y: speed * Math.sin(m.angle) - }, 0, tech.isMineAmmoBack) + if (Matter.Query.point(map, pos).length > 0) speed = -2 //don't launch if mine will spawn inside map + b.mine(pos, { x: speed * Math.cos(m.angle), y: speed * Math.sin(m.angle) }, 0) m.fireCDcycle = m.cycle + Math.floor(25 * b.fireCDscale); // cool down } } diff --git a/js/engine.js b/js/engine.js index fdfa9d1..9cb3e8d 100644 --- a/js/engine.js +++ b/js/engine.js @@ -175,8 +175,8 @@ function collisionChecks(event) { if (obj.classType === "bullet" && obj.speed > obj.minDmgSpeed) { obj.beforeDmg(mob[k]); //some bullets do actions when they hits things, like despawn //forces don't seem to work here let dmg = b.dmgScale * (obj.dmg + 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity))) - // console.log(obj.dmg, 0.15 * obj.mass * Vector.magnitude(Vector.sub(mob[k].velocity, obj.velocity))) if (tech.isCrit && mob[k].isStunned) dmg *= 4 + // console.log(dmg) mob[k].damage(dmg); if (mob[k].alive) mob[k].foundPlayer(); simulation.drawList.push({ //add dmg to draw queue diff --git a/js/level.js b/js/level.js index ec482df..6987d65 100644 --- a/js/level.js +++ b/js/level.js @@ -11,13 +11,14 @@ const level = { levels: [], start() { if (level.levelsCleared === 0) { //this code only runs on the first level + // simulation.enableConstructMode() //used to build maps in testing mode // localSettings.levelsClearedLastGame = 10 // level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why // simulation.isHorizontalFlipped = true - // b.giveGuns("mine") - // b.giveGuns("nail gun") - // m.setField("wormhole") + // b.giveGuns("grenades") // tech.giveTech("laser-mines") + // m.setField("metamaterial cloaking") + // for (let i = 0; i < 3; i++) tech.giveTech("super sized") // tech.giveTech("irradiated nails") // for (let i = 0; i < 9; i++) tech.giveTech("MIRV") @@ -51,7 +52,6 @@ const level = { // for (let i = 0; i < 30; i++) powerUps.spawn(player.position.x + Math.random() * 50, player.position.y - Math.random() * 50, "tech", false); // for (let i = 0; i < 7; i++) tech.giveTech("undefined") // lore.techCount = 6 - // simulation.enableConstructMode() //used to build maps in testing mode // simulation.isCheating = false //true; // localSettings.loreCount = 3; //this sets what conversation is heard @@ -2246,7 +2246,7 @@ const level = { for (let i = 0; i < 4; ++i) spawn.bodyRect(x + 5, y - 260 + i * blockSize, 30, blockSize); } // blockDoor(710, -710); - // for (let i = 0; i < 30; i++) powerUps.directSpawn(710, -710, "tech"); + // for (let i = 0; i < 200; i++) powerUps.directSpawn(710 + 1000 * Math.random(), -710 + 1000 * Math.random(), "tech"); spawn.mapRect(2500, -1200, 200, 750); //right wall blockDoor(2585, -210) @@ -4027,8 +4027,8 @@ const level = { // spawn.mapRect(-2600, -1975, 250, 25); spawn.mapRect(-2515, -2000, 180, 50); - spawn.bodyRect(-3410, -1425, 100, 100); - spawn.bodyRect(-3390, -1525, 100, 100); + spawn.bodyRect(-3410, -1425, 50, 50); + spawn.bodyRect(-3390, -1525, 40, 60); // spawn.bodyRect(-3245, -1425, 100, 100); //building 3 spawn.mapRect(-4450, -1750, 800, 1050); @@ -4171,16 +4171,6 @@ const level = { level.enter.draw(); }; - - // simulation.draw.mapPath = new Path2D(); - // for (let i = 0, len = map.length; i < len; ++i) { - // let vertices = map[i].vertices; - // simulation.draw.mapPath.moveTo(vertices[0].x, vertices[0].y); - // for (let j = 1; j < vertices.length; j += 1) { - // simulation.draw.mapPath.lineTo(vertices[j].x, vertices[j].y); - // } - // simulation.draw.mapPath.lineTo(vertices[0].x, vertices[0].y); - // } const lightingPath = new Path2D() //pre-draw the complex lighting path to save processing lightingPath.moveTo(-1800, -500) lightingPath.lineTo(-910, -500) //3rd floor light diff --git a/js/player.js b/js/player.js index fad4a75..895f481 100644 --- a/js/player.js +++ b/js/player.js @@ -642,7 +642,7 @@ const m = { tech.isDeathAvoidedThisLevel = true powerUps.research.changeRerolls(-1) simulation.makeTextLog(`m.research--
${powerUps.research.count}`) - for (let i = 0; i < 6; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "heal", false); + for (let i = 0; i < 5; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "heal", false); m.energy = m.maxEnergy if (m.immuneCycle < m.cycle + 300) m.immuneCycle = m.cycle + 300 //disable this.immuneCycle bonus seconds simulation.wipe = function() { //set wipe to have trails @@ -673,7 +673,7 @@ const m = { powerUps.research.changeRerolls(-1) simulation.makeTextLog(`m.research--
${powerUps.research.count}`) - for (let i = 0; i < 6; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "heal", false); + for (let i = 0; i < 5; i++) powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "heal", false); if (m.immuneCycle < m.cycle + 300) m.immuneCycle = m.cycle + 300 //disable this.immuneCycle bonus seconds simulation.wipe = function() { //set wipe to have trails ctx.fillStyle = "rgba(255,255,255,0.03)"; @@ -2125,9 +2125,10 @@ const m = { // m.fieldDamage = 2.46 // 1 + 146/100 m.fieldDrawRadius = 0 m.isSneakAttack = true; - const drawRadius = 1100 + const drawRadius = 900 m.hold = function() { + // console.log(m.holdingTarget) if (m.isHolding) { m.drawHold(m.holdingTarget); m.holding(); @@ -2194,29 +2195,27 @@ const m = { const wiggle = 0.15 * Math.sin(m.fieldPhase * 0.5) ctx.beginPath(); ctx.ellipse(m.pos.x, m.pos.y, m.fieldDrawRadius * (1 - wiggle), m.fieldDrawRadius * (1 + wiggle), m.fieldPhase, 0, 2 * Math.PI); - if (m.fireCDcycle > m.cycle && (input.field)) { - ctx.lineWidth = 5; - ctx.strokeStyle = `rgba(0, 204, 255,1)` - ctx.stroke() - } - ctx.fillStyle = "#fff" //`rgba(0,0,0,${0.5+0.5*m.energy})`; - ctx.globalCompositeOperation = "destination-in"; //in or atop + // if (m.fireCDcycle > m.cycle && (input.field)) {} + ctx.fillStyle = "#fff" + ctx.lineWidth = 2; + ctx.strokeStyle = "#000" + ctx.stroke() + // ctx.fillStyle = "#fff" //`rgba(0,0,0,${0.5+0.5*m.energy})`; + ctx.globalCompositeOperation = "destination-in"; ctx.fill(); ctx.globalCompositeOperation = "source-over"; - ctx.clip(); + // ctx.clip(); //seems to have a high performance cost } // const energy = Math.max(0.01, Math.min(m.energy, 1)) if (m.isCloak) { this.fieldRange = this.fieldRange * 0.9 + 0.1 * drawRadius - m.fieldDrawRadius = this.fieldRange * 0.9 //* Math.min(1, 0.3 + 0.5 * Math.min(1, energy * energy)); + m.fieldDrawRadius = this.fieldRange * 0.88 //* Math.min(1, 0.3 + 0.5 * Math.min(1, energy * energy)); + drawField() + } else if (this.fieldRange < 3000) { + this.fieldRange += 50 + m.fieldDrawRadius = this.fieldRange //* Math.min(1, 0.3 + 0.5 * Math.min(1, energy * energy)); drawField() - } else { - if (this.fieldRange < 3000) { - this.fieldRange += 200 - m.fieldDrawRadius = this.fieldRange //* Math.min(1, 0.3 + 0.5 * Math.min(1, energy * energy)); - drawField() - } } if (tech.isIntangible) { if (m.isCloak) { @@ -2478,7 +2477,8 @@ const m = { if ( dist2 < 5000 && !simulation.isChoosing && - (powerUp[i].name !== "heal" || m.health < 0.94 * m.maxHealth) + (powerUp[i].name !== "heal" || m.health !== m.maxHealth || tech.isOverHeal) + // (powerUp[i].name !== "heal" || m.health < 0.94 * m.maxHealth) // (powerUp[i].name !== "ammo" || b.guns[b.activeGun].ammo !== Infinity) ) { //use power up if it is close enough powerUps.onPickUp(powerUp[i]); diff --git a/js/powerup.js b/js/powerup.js index e862a0f..853a1d6 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -697,7 +697,7 @@ const powerUps = { if (tech.isLaserMine && m.crouch) { b.laserMine(who.position) } else { - b.mine(who.position, { x: 0, y: 0 }, 0, tech.isMineAmmoBack) + b.mine(who.position, { x: 0, y: 0 }, 0) } } if (tech.isRelay) { diff --git a/js/simulation.js b/js/simulation.js index 5589463..0904b6b 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -737,20 +737,20 @@ const simulation = { } } } - if (tech.isMineAmmoBack) { - let count = 0; - for (i = 0, len = bullet.length; i < len; i++) { //count mines left on map - if (bullet[i].bulletType === "mine") count++ - } - for (i = 0, len = b.guns.length; i < len; i++) { //find which gun is mine - if (b.guns[i].name === "mine") { - if (tech.isCrouchAmmo) count = Math.ceil(count / 2) - b.guns[i].ammo += count - simulation.updateGunHUD(); - break; - } + + let count = 0; + for (i = 0, len = bullet.length; i < len; i++) { //count mines left on map + if (bullet[i].bulletType === "mine" || bullet[i].bulletType === "laser mine") count++ + } + for (i = 0, len = b.guns.length; i < len; i++) { //find which gun is mine + if (b.guns[i].name === "mine") { + if (tech.isCrouchAmmo) count = Math.ceil(count / 2) + b.guns[i].ammo += count + simulation.updateGunHUD(); + break; } } + if (tech.isMutualism && !tech.isEnergyHealth) { for (let i = 0; i < bullet.length; i++) { if (bullet[i].isMutualismActive) { diff --git a/js/tech.js b/js/tech.js index 500a3fe..a5210ed 100644 --- a/js/tech.js +++ b/js/tech.js @@ -344,7 +344,7 @@ frequency: 2, frequencyDefault: 2, allowed() { - return (tech.isDamageForGuns || tech.isFireRateForGuns) && b.inventory.length + 5 < b.guns.length + return (tech.isDamageForGuns || tech.isFireRateForGuns) && b.inventory.length < b.guns.length - 5 //12-5 guns total }, requires: "arsenal or active cooling and less than 7 guns", effect() { @@ -470,7 +470,7 @@ }, { name: "desublimated ammunition", - description: "use 50% less ammo when crouching<
strong>+6 JUNK to the potential tech pool", + description: "use 50% less ammo when crouching
+6 JUNK to the potential tech pool", maxCount: 1, count: 0, frequency: 2, @@ -2695,7 +2695,7 @@ powerUps.research.changeRerolls(0) }, 1000); }, - description: "once per level, instead of dying
consume 1 research and spawn 6 heals", + description: "once per level, instead of dying
consume 1 research and spawn 5 heals", maxCount: 1, count: 0, frequency: 2, @@ -4042,7 +4042,7 @@ }, { name: "ice-shot", - description: "shotgun grows 18 freezing ice IX crystals", + description: "shotgun grows 15 freezing ice IX crystals", isGunTech: true, maxCount: 1, count: 0, @@ -4059,25 +4059,6 @@ tech.isIceShot = false; } }, - { - name: "super duper", - description: "fire 1 additional super ball", - isGunTech: true, - maxCount: 9, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return tech.haveGunCheck("super balls") && !tech.oneSuperBall - }, - requires: "super balls, but not the tech super ball", - effect() { - tech.superBallNumber++ - }, - remove() { - tech.superBallNumber = 3; - } - }, { name: "supertemporal", description: "fire super ball from the same point in space
but separated by 0.1 seconds in time", @@ -4114,7 +4095,7 @@ frequency: 2, frequencyDefault: 2, allowed() { - return tech.haveGunCheck("super balls") && tech.superBallNumber === 3 && !tech.superBallDelay + return tech.haveGunCheck("super balls") && tech.missileCount === 1 && !tech.superBallDelay }, requires: "super balls, but not super duper or supertemporal", effect() { @@ -4134,7 +4115,7 @@ }, { name: "super sized", - description: `super balls are 20% larger
increases mass and physical damage`, + description: `increase super ball radius by 17%
increases damage by about 35%`, isGunTech: true, maxCount: 9, count: 0, @@ -4145,7 +4126,7 @@ }, requires: "super balls", effect() { - tech.bulletSize += 0.15 + tech.bulletSize += 0.17 }, remove() { tech.bulletSize = 1; @@ -4321,25 +4302,6 @@ tech.missileSize = false } }, - { - name: "MIRV", - description: "missile gun and bot launch +1 missile
decrease size and fire rate by 10%", - isGunTech: true, - maxCount: 9, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return tech.haveGunCheck("missiles") || tech.missileBotCount - }, - requires: "missiles", - effect() { - tech.missileCount++; - }, - remove() { - tech.missileCount = 1; - } - }, { name: "missile-bot", description: "remove your missile gun
gain a bot that fires missiles at mobs", @@ -4368,6 +4330,25 @@ } } }, + { + name: "MIRV", + description: "fire +1 missile, grenade, and super ball
decrease explosion radius up to 10%", + isGunTech: true, + maxCount: 9, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return tech.haveGunCheck("missiles") || tech.missileBotCount || tech.haveGunCheck("grenades") || (tech.haveGunCheck("super balls") && !tech.oneSuperBall) + }, + requires: "missiles, grenades, super balls, not super ball", + effect() { + tech.missileCount++; + }, + remove() { + tech.missileCount = 1; + } + }, { name: "rocket-propelled grenade", description: "grenades rapidly accelerate forward
map collisions trigger an explosion", @@ -4421,7 +4402,7 @@ allowed() { return tech.isVacuumBomb && !tech.isExplodeRadio }, - requires: "vacuum bomb && not iridium-192", + requires: "vacuum bomb, not iridium-192", effect() { tech.isBlockExplode = true; //chain reaction }, @@ -4469,6 +4450,28 @@ tech.isNeutronSlow = false } }, + { + name: "booby trap", + description: "drop a mine after picking up a power up
+53 JUNK to the potential tech pool", + isGunTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return tech.haveGunCheck("mine") + }, + requires: "mines, not mine reclamation", + effect() { + tech.isMineDrop = true; + if (tech.isMineDrop) b.mine(m.pos, { x: 0, y: 0 }, 0) + tech.addJunkTechToPool(53) + }, + remove() { + tech.isMineDrop = false; + if (this.count > 0) tech.removeJunkTechFromPool(53) + } + }, { name: "laser-mines", description: "mines laid while you are crouched
use energy to emit 3 unaimed lasers", @@ -4488,25 +4491,6 @@ tech.isLaserMine = false; } }, - { - name: "mine reclamation", - description: "retrieve ammo from all undetonated mines
and 20% of mines after detonation", - isGunTech: true, - maxCount: 1, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return tech.haveGunCheck("mine") && !tech.isMineDrop - }, - requires: "mine, not bobby trap", - effect() { - tech.isMineAmmoBack = true; - }, - remove() { - tech.isMineAmmoBack = false; - } - }, { name: "sentry", description: "instead of detonating, mines target mobs
with a stream of nails for about 17 seconds", @@ -4545,28 +4529,6 @@ tech.isMineStun = false; } }, - { - name: "booby trap", - description: "drop a mine after picking up a power up
+30 JUNK to the potential tech pool", - isGunTech: true, - maxCount: 1, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return tech.haveGunCheck("mine") && !tech.isMineAmmoBack - }, - requires: "mines, not mine reclamation", - effect() { - tech.isMineDrop = true; - if (tech.isMineDrop) b.mine(m.pos, { x: 0, y: 0 }, 0, tech.isMineAmmoBack) - tech.addJunkTechToPool(30) - }, - remove() { - tech.isMineDrop = false; - if (this.count > 0) tech.removeJunkTechFromPool(30) - } - }, { name: "mycelial fragmentation", description: "sporangium release 6 extra spores
during their growth phase", @@ -4901,7 +4863,7 @@ }, { name: "uncertainty principle", - description: "foam bubbles randomly change position
increase foam damage per second by 55%", + description: "foam bubbles randomly change position
increase foam damage per second by 50%", isGunTech: true, maxCount: 1, count: 0, @@ -5964,7 +5926,10 @@ tech.isIntangible = true; }, remove() { - tech.isIntangible = false; + if (tech.isIntangible) { + tech.isIntangible = false; + player.collisionFilter.mask = cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield //normal collisions + } } }, { @@ -7730,7 +7695,6 @@ isPiezo: null, isFastDrones: null, isFastSpores: null, - superBallNumber: null, oneSuperBall: null, laserReflections: null, laserDamage: null, @@ -7745,7 +7709,6 @@ isSporeField: null, isMissileField: null, isIceField: null, - isMineAmmoBack: null, isPlasmaRange: null, isFreezeMobs: null, isIceCrystals: null, diff --git a/todo.txt b/todo.txt index 851b087..66d8c12 100644 --- a/todo.txt +++ b/todo.txt @@ -1,18 +1,26 @@ ******************************************************** NEXT PATCH ************************************************** -20% damage for all mine modes -laser mines spin super fast when it first finds a target, and a bit faster overall -mine sentry lasts 17 seconds (2 more seconds) +tech: MIRV - now effects grenades and super balls in addition to missiles + no change for super balls and missiles, but this is a new tech for grenades -desublimated ammunition comes with 7 JUNK tech -several foam tech do 5% less damage -shotgun has 1/9 less ammo -apomixis now requires 11 research -historyBoss takes 25% longer to reach it's minimum follow distance +undetonated mines are returned at the end of a level + removed tech: mine reclamation + mine gun has 30% less ammo + laser mines do 7% less damage + booby trap now comes with 53 JUNK (up from 33) but it's mines can be returned for ammo + +removed ctx.clip() from metamaterial cloaking field for performance reasons + the graphics look a bit different now, maybe not as good, maybe it's just different + +iceIX bullets last 50% less time, but do 50% more damage and have 25% more thrust + so it's more of a close range bullet + ice-shot has 2 fewer bullets -bug fixes ******************************************************** TODO ******************************************************** +tech MIRV applies to grenades + maybe also merge with tech: super balls?, laser refraction... + work on necroBoss from TheShwarma make spawned blocks in the direction of the player make it search the level for blocks, but also kinda avoid the player @@ -28,12 +36,10 @@ falling particle rain basically spores with no guidance lag if too many particles? -wormhole show where you would go on mouse down - trigger teleport on release - look into 360 wave beam lag aoe effect pushes mobs away, then rapidly pulls them in + for mines? tech: shrapnel - nails have an larger randomized 3 point shape triangle shape and they do more damage @@ -114,8 +120,6 @@ add back in gamepad support? but does anyone care? https://github.com/landgreen/landgreen.github.io/search?q=gamepadconnected -RPG default or tech: grenades detonate on your cursor / where your cursor was when they were fired - tech: time dilation - when you exit time dilation rewind to the state you entered position, velocity, and health no energy cost @@ -126,9 +130,6 @@ be able to open up custom mode in the normal game have a way to make limited changes as allowed by tech you pick up in game disable the in custom setting flag -super balls start at 3, not 4 - have to balance damage - make different move methods tech crouch charge jump tech double jump @@ -146,8 +147,6 @@ tech pilot wave: antigravity - blocks have no gravity for a few seconds after ex maybe they bounce too? maybe they explode? -wormhole - make it clear when the wormhole can and can't teleport to a location before the player clicks - new power up - increase damage and fire speed, for 15 seconds named boost? enabled by a tech