diff --git a/.DS_Store b/.DS_Store index 2bf9398..8eea4f3 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/js/bullet.js b/js/bullet.js index 73f5c09..f1a7817 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -595,7 +595,8 @@ const b = { newDist < dist && !mob[i].isBadTarget && Matter.Query.ray(map, path[0], mob[i].position).length === 0 && - Matter.Query.ray(body, path[0], mob[i].position).length === 0 + Matter.Query.ray(body, path[0], mob[i].position).length === 0 && + !mob[i].isInvulnerable ) { dist = newDist best.who = mob[i] @@ -1271,148 +1272,148 @@ const b = { } } }, - dart(where, angle = m.angle, size = 0.8) { - //find a target - const closest = { - score: 10000, - position: null - } - for (let i = 0, len = mob.length; i < len; ++i) { - if (mob[i].alive && !mob[i].isBadTarget && Matter.Query.ray(map, where, mob[i].position).length === 0) { - const dot = Vector.dot({ x: Math.cos(angle), y: Math.sin(angle) }, Vector.normalise(Vector.sub(mob[i].position, where))) //the dot product of diff and dir will return how much over lap between the vectors - const dist = Vector.magnitude(Vector.sub(where, mob[i].position)) - // if (dist < closest.score && ((dist > 500 && dot > 0) || (dot > 0.9))) { //target closest mob that player is looking at and isn't too close to target - if (dist < closest.score && dot > 0.9 - 0.0004 * dist) { //target closest mob that player is looking at and isn't too close to target - closest.score = dist - closest.position = mob[i].position - } - } - } - if (!closest.position) { - // const unit = Vector.mult(sub(simulation.mouseInGame, where), 10000) - closest.position = Vector.mult(Vector.sub(simulation.mouseInGame, where), 10000) - } - const me = bullet.length; - bullet[me] = Bodies.fromVertices(where.x, where.y, [{ x: -20 * size, y: 2 * size, index: 0, isInternal: false }, { x: -20 * size, y: -2 * size, index: 1, isInternal: false }, { x: 5 * size, y: -2 * size, index: 4, isInternal: false }, { x: 20 * size, y: 0, index: 3, isInternal: false }, { x: 5 * size, y: 2 * size, index: 4, isInternal: false }], { - cycle: 0, - angle: angle, - friction: 1, - frictionAir: 0.15, - thrustMag: 0.03, - turnRate: 0.15, //0.015 - drawStringControlMagnitude: 3000 + 5000 * Math.random(), - drawStringFlip: (Math.round(Math.random()) ? 1 : -1), - dmg: 7, //damage done in addition to the damage from momentum - classType: "bullet", - endCycle: simulation.cycle + 120, - collisionFilter: { - category: cat.bullet, - mask: tech.isShieldPierce ? cat.body | cat.mob | cat.mobBullet : cat.body | cat.mob | cat.mobBullet | cat.mobShield, - }, - minDmgSpeed: 0, - lookFrequency: Math.floor(7 + Math.random() * 3), - density: 0.001, //0.001 is normal for blocks, 0.008 is normal for harpoon, 0.008*6 when buffed - beforeDmg(who) { - if (tech.isShieldPierce && who.isShielded) { //disable shields - who.isShielded = false - requestAnimationFrame(() => { who.isShielded = true }); - } - if (tech.fragments) { - b.targetedNail(this.vertices[2], tech.fragments * Math.floor(2 + 1.5 * Math.random())) - this.endCycle = 0; - } - if (!who.isBadTarget) { - this.frictionAir = 0.01 - this.do = this.doNoTargeting - } - }, - onEnd() {}, - doNoTargeting: function() { - // this.force.y += this.mass * 0.001; - if (Matter.Query.collides(this, map).length) { //stick in walls - this.collisionFilter.mask = 0; - Matter.Body.setAngularVelocity(this, 0) - Matter.Body.setVelocity(this, { - x: 0, - y: 0 - }); - this.do = () => { - // if (!Matter.Query.collides(this, map).length) this.force.y += this.mass * 0.001; - } - } - }, - do() { - this.cycle++ - // if (this.cycle > 40) { - // this.frictionAir = 0.003 - // this.do = this.doNoTargeting - // } - // if (closest.target) { //rotate towards the target - const face = { x: Math.cos(this.angle), y: Math.sin(this.angle) }; - const vectorGoal = Vector.normalise(Vector.sub(this.position, closest.position)); - const cross = Vector.cross(vectorGoal, face) - if (cross > 0.01) { - Matter.Body.rotate(this, this.turnRate * Math.sqrt(cross)); - } else if (cross < 0.01) { - Matter.Body.rotate(this, -this.turnRate * Math.sqrt(Math.abs(cross))); - } - this.force.x += this.thrustMag * this.mass * Math.cos(this.angle); - this.force.y += this.thrustMag * this.mass * Math.sin(this.angle); - // } - if (Matter.Query.collides(this, map).length) { //stick in walls - this.collisionFilter.mask = 0; - Matter.Body.setAngularVelocity(this, 0) - Matter.Body.setVelocity(this, { - x: 0, - y: 0 - }); - this.do = this.doNoTargeting - } - // else if (!(this.cycle % 2)) { //look for a target if you don't have one - // simulation.drawList.push({ //add dmg to draw queue - // x: this.position.x, - // y: this.position.y, - // radius: 10, - // color: simulation.mobDmgColor, - // time: simulation.drawTime - // }); - // let closest = { - // distance: 2000, - // target: null - // } - // const dir = Vector.normalise(this.velocity) //make a vector for direction of length 1 - // for (let i = 0, len = mob.length; i < len; ++i) { - // if ( - // mob[i].alive && !mob[i].isBadTarget && - // Matter.Query.ray(map, this.position, mob[i].position).length === 0 && //check for map in Line of sight - // Vector.dot(dir, Vector.normalise(Vector.sub(mob[i].position, this.position))) > 0.55 //the dot product of diff and dir will return how much over lap between the vectors - // ) { - // const dist = Vector.magnitude(Vector.sub(this.position, mob[i].position)) - // if (dist < closest.distance) { - // closest.distance = dist - // closest.target = mob[i] - // } - // } - // } - // if (closest.target) { - // target = closest.target - // this.turnRate = 0.05 - // this.frictionAir = 0.8 - // } - // } - }, - }); - Matter.Body.setVelocity(bullet[me], { - x: m.Vx / 2 + 40 * Math.cos(bullet[me].angle), - y: m.Vy / 2 + 40 * Math.sin(bullet[me].angle) - }); - // if (!closest.target) { - // bullet[me].frictionAir = 0.002 - // bullet[me].do = bullet[me].doNoTargeting - // } - Composite.add(engine.world, bullet[me]); //add bullet to world + // dart(where, angle = m.angle, size = 0.8) { + // //find a target + // const closest = { + // score: 10000, + // position: null + // } + // for (let i = 0, len = mob.length; i < len; ++i) { + // if (mob[i].alive && !mob[i].isBadTarget && Matter.Query.ray(map, where, mob[i].position).length === 0) { + // const dot = Vector.dot({ x: Math.cos(angle), y: Math.sin(angle) }, Vector.normalise(Vector.sub(mob[i].position, where))) //the dot product of diff and dir will return how much over lap between the vectors + // const dist = Vector.magnitude(Vector.sub(where, mob[i].position)) + // // if (dist < closest.score && ((dist > 500 && dot > 0) || (dot > 0.9))) { //target closest mob that player is looking at and isn't too close to target + // if (dist < closest.score && dot > 0.9 - 0.0004 * dist) { //target closest mob that player is looking at and isn't too close to target + // closest.score = dist + // closest.position = mob[i].position + // } + // } + // } + // if (!closest.position) { + // // const unit = Vector.mult(sub(simulation.mouseInGame, where), 10000) + // closest.position = Vector.mult(Vector.sub(simulation.mouseInGame, where), 10000) + // } + // const me = bullet.length; + // bullet[me] = Bodies.fromVertices(where.x, where.y, [{ x: -20 * size, y: 2 * size, index: 0, isInternal: false }, { x: -20 * size, y: -2 * size, index: 1, isInternal: false }, { x: 5 * size, y: -2 * size, index: 4, isInternal: false }, { x: 20 * size, y: 0, index: 3, isInternal: false }, { x: 5 * size, y: 2 * size, index: 4, isInternal: false }], { + // cycle: 0, + // angle: angle, + // friction: 1, + // frictionAir: 0.15, + // thrustMag: 0.03, + // turnRate: 0.15, //0.015 + // drawStringControlMagnitude: 3000 + 5000 * Math.random(), + // drawStringFlip: (Math.round(Math.random()) ? 1 : -1), + // dmg: 7, //damage done in addition to the damage from momentum + // classType: "bullet", + // endCycle: simulation.cycle + 120, + // collisionFilter: { + // category: cat.bullet, + // mask: tech.isShieldPierce ? cat.body | cat.mob | cat.mobBullet : cat.body | cat.mob | cat.mobBullet | cat.mobShield, + // }, + // minDmgSpeed: 0, + // lookFrequency: Math.floor(7 + Math.random() * 3), + // density: 0.001, //0.001 is normal for blocks, 0.008 is normal for harpoon, 0.008*6 when buffed + // beforeDmg(who) { + // if (tech.isShieldPierce && who.isShielded) { //disable shields + // who.isShielded = false + // requestAnimationFrame(() => { who.isShielded = true }); + // } + // if (tech.fragments) { + // b.targetedNail(this.vertices[2], tech.fragments * Math.floor(2 + 1.5 * Math.random())) + // this.endCycle = 0; + // } + // if (!who.isBadTarget) { + // this.frictionAir = 0.01 + // this.do = this.doNoTargeting + // } + // }, + // onEnd() {}, + // doNoTargeting: function() { + // // this.force.y += this.mass * 0.001; + // if (Matter.Query.collides(this, map).length) { //stick in walls + // this.collisionFilter.mask = 0; + // Matter.Body.setAngularVelocity(this, 0) + // Matter.Body.setVelocity(this, { + // x: 0, + // y: 0 + // }); + // this.do = () => { + // // if (!Matter.Query.collides(this, map).length) this.force.y += this.mass * 0.001; + // } + // } + // }, + // do() { + // this.cycle++ + // // if (this.cycle > 40) { + // // this.frictionAir = 0.003 + // // this.do = this.doNoTargeting + // // } + // // if (closest.target) { //rotate towards the target + // const face = { x: Math.cos(this.angle), y: Math.sin(this.angle) }; + // const vectorGoal = Vector.normalise(Vector.sub(this.position, closest.position)); + // const cross = Vector.cross(vectorGoal, face) + // if (cross > 0.01) { + // Matter.Body.rotate(this, this.turnRate * Math.sqrt(cross)); + // } else if (cross < 0.01) { + // Matter.Body.rotate(this, -this.turnRate * Math.sqrt(Math.abs(cross))); + // } + // this.force.x += this.thrustMag * this.mass * Math.cos(this.angle); + // this.force.y += this.thrustMag * this.mass * Math.sin(this.angle); + // // } + // if (Matter.Query.collides(this, map).length) { //stick in walls + // this.collisionFilter.mask = 0; + // Matter.Body.setAngularVelocity(this, 0) + // Matter.Body.setVelocity(this, { + // x: 0, + // y: 0 + // }); + // this.do = this.doNoTargeting + // } + // // else if (!(this.cycle % 2)) { //look for a target if you don't have one + // // simulation.drawList.push({ //add dmg to draw queue + // // x: this.position.x, + // // y: this.position.y, + // // radius: 10, + // // color: simulation.mobDmgColor, + // // time: simulation.drawTime + // // }); + // // let closest = { + // // distance: 2000, + // // target: null + // // } + // // const dir = Vector.normalise(this.velocity) //make a vector for direction of length 1 + // // for (let i = 0, len = mob.length; i < len; ++i) { + // // if ( + // // mob[i].alive && !mob[i].isBadTarget && + // // Matter.Query.ray(map, this.position, mob[i].position).length === 0 && //check for map in Line of sight + // // Vector.dot(dir, Vector.normalise(Vector.sub(mob[i].position, this.position))) > 0.55 //the dot product of diff and dir will return how much over lap between the vectors + // // ) { + // // const dist = Vector.magnitude(Vector.sub(this.position, mob[i].position)) + // // if (dist < closest.distance) { + // // closest.distance = dist + // // closest.target = mob[i] + // // } + // // } + // // } + // // if (closest.target) { + // // target = closest.target + // // this.turnRate = 0.05 + // // this.frictionAir = 0.8 + // // } + // // } + // }, + // }); + // Matter.Body.setVelocity(bullet[me], { + // x: m.Vx / 2 + 40 * Math.cos(bullet[me].angle), + // y: m.Vy / 2 + 40 * Math.sin(bullet[me].angle) + // }); + // // if (!closest.target) { + // // bullet[me].frictionAir = 0.002 + // // bullet[me].do = bullet[me].doNoTargeting + // // } + // Composite.add(engine.world, bullet[me]); //add bullet to world - }, + // }, grapple(where, angle = m.angle, harpoonSize = 1) { const me = bullet.length; const returnRadius = 100 * Math.sqrt(harpoonSize) @@ -2012,7 +2013,8 @@ const b = { for (let i = 0, len = mob.length; i < len; ++i) { if ( mob[i].alive && !mob[i].isBadTarget && - Matter.Query.ray(map, this.position, mob[i].position).length === 0 + Matter.Query.ray(map, this.position, mob[i].position).length === 0 && + !mob[i].isInvulnerable // && Matter.Query.ray(body, this.position, mob[i].position).length === 0 ) { const futureDist = Vector.magnitude(Vector.sub(futurePos, mob[i].position)); @@ -2639,7 +2641,8 @@ const b = { !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 + Matter.Query.ray(body, this.position, mob[i].position).length === 0 && + !mob[i].isInvulnerable ) { if (tech.isExplosionStun) b.AoEStunEffect(this.position, 700 + mob[i].radius + random); if (tech.isMineSentry) { @@ -2753,7 +2756,7 @@ const b = { this.lockedOn = null; let closeDist = Infinity; for (let i = 0, len = mob.length; i < len; ++i) { - if (!mob[i].isBadTarget && Matter.Query.ray(map, this.position, mob[i].position).length === 0) { + if (!mob[i].isBadTarget && Matter.Query.ray(map, this.position, mob[i].position).length === 0 && !mob[i].isInvulnerable) { const targetVector = Vector.sub(this.position, mob[i].position) const dist = Vector.magnitude(targetVector) * (Math.random() + 0.5); if (dist < closeDist) { @@ -2841,7 +2844,7 @@ const b = { this.lockedOn = null; let closeDist = Infinity; for (let i = 0, len = mob.length; i < len; ++i) { - if (!mob[i].isBadTarget && Matter.Query.ray(map, this.position, mob[i].position).length === 0) { + if (!mob[i].isBadTarget && Matter.Query.ray(map, this.position, mob[i].position).length === 0 && !mob[i].isInvulnerable) { const targetVector = Vector.sub(this.position, mob[i].position) const dist = Vector.magnitude(targetVector) * (Math.random() + 0.5); if (dist < closeDist) { @@ -2957,7 +2960,8 @@ const b = { if ( !mob[i].isBadTarget && Matter.Query.ray(map, this.position, mob[i].position).length === 0 && - Matter.Query.ray(body, this.position, mob[i].position).length === 0 + Matter.Query.ray(body, this.position, mob[i].position).length === 0 && + !mob[i].isInvulnerable ) { const TARGET_VECTOR = Vector.sub(this.position, mob[i].position) const DIST = Vector.magnitude(TARGET_VECTOR); @@ -3059,7 +3063,6 @@ const b = { Matter.Body.scale(this, scale, scale); } else { this.force.y += this.mass * 0.0002; - if (!(simulation.cycle % this.lookFrequency)) { //find mob targets this.lockedOn = null; @@ -3068,7 +3071,8 @@ const b = { if ( !mob[i].isBadTarget && Matter.Query.ray(map, this.position, mob[i].position).length === 0 && - Matter.Query.ray(body, this.position, mob[i].position).length === 0 + Matter.Query.ray(body, this.position, mob[i].position).length === 0 && + !mob[i].isInvulnerable ) { const TARGET_VECTOR = Vector.sub(this.position, mob[i].position) const DIST = Vector.magnitude(TARGET_VECTOR); @@ -3297,7 +3301,8 @@ const b = { if ( !mob[i].isBadTarget && Matter.Query.ray(map, this.position, mob[i].position).length === 0 && - Matter.Query.ray(body, this.position, mob[i].position).length === 0 + Matter.Query.ray(body, this.position, mob[i].position).length === 0 && + !mob[i].isInvulnerable ) { const TARGET_VECTOR = Vector.sub(this.position, mob[i].position) const DIST = Vector.magnitude(TARGET_VECTOR); @@ -3785,9 +3790,10 @@ const b = { const dist = Vector.magnitude(Vector.sub(position, mob[i].position)); if ( dist < range + mob[i].radius && - (!mob[i].isBadTarget) && //|| mob[i].isMobBullet + !mob[i].isBadTarget && //|| mob[i].isMobBullet Matter.Query.ray(map, position, mob[i].position).length === 0 && - Matter.Query.ray(body, position, mob[i].position).length === 0 + Matter.Query.ray(body, position, mob[i].position).length === 0 && + !mob[i].isInvulnerable ) { targets.push(Vector.add(mob[i].position, Vector.mult(mob[i].velocity, dist / 60))) //predict where the mob will be in a few cycles } @@ -4280,7 +4286,8 @@ const b = { dist < 3000000 && Matter.Query.ray(map, this.position, mob[i].position).length === 0 && Matter.Query.ray(body, this.position, mob[i].position).length === 0 && - !mob[i].isShielded + !mob[i].isShielded && + !mob[i].isInvulnerable ) { const unit = Vector.normalise(Vector.sub(Vector.add(mob[i].position, Vector.mult(mob[i].velocity, Math.sqrt(dist) / 60)), this.position)) if (this.isUpgraded) { @@ -4338,7 +4345,8 @@ const b = { mob[i].alive && !mob[i].isBadTarget && dist2 > 40000 && - Matter.Query.ray(map, this.position, mob[i].position).length === 0 + Matter.Query.ray(map, this.position, mob[i].position).length === 0 && + !mob[i].isInvulnerable ) { this.cd = simulation.cycle + this.delay; const angle = Vector.angle(this.position, mob[i].position) @@ -4670,10 +4678,12 @@ const b = { let closeDist = tech.isPlasmaRange * 1000; for (let i = 0, len = mob.length; i < len; ++i) { const DIST = Vector.magnitude(Vector.sub(this.position, mob[i].position)) - mob[i].radius; - if (DIST < closeDist && - (!mob[i].isBadTarget || mob[i].isMobBullet) && + if ( + DIST < closeDist && (!mob[i].isBadTarget || mob[i].isMobBullet) && Matter.Query.ray(map, this.position, mob[i].position).length === 0 && - Matter.Query.ray(body, this.position, mob[i].position).length === 0) { + Matter.Query.ray(body, this.position, mob[i].position).length === 0 && + !mob[i].isInvulnerable + ) { closeDist = DIST; this.lockedOn = mob[i] } @@ -6376,7 +6386,7 @@ const b = { const dir = { x: Math.cos(angle), y: Math.sin(angle) }; //make a vector for the player's direction of length 1; used in dot product for (let i = 0, len = mob.length; i < len; ++i) { - if (mob[i].alive && !mob[i].isBadTarget && !mob[i].shield && Matter.Query.ray(map, m.pos, mob[i].position).length === 0) { + if (mob[i].alive && !mob[i].isBadTarget && !mob[i].shield && Matter.Query.ray(map, m.pos, mob[i].position).length === 0 && !mob[i].isInvulnerable) { const dot = Vector.dot(dir, Vector.normalise(Vector.sub(mob[i].position, m.pos))) //the dot product of diff and dir will return how much over lap between the vectors const dist = Vector.magnitude(Vector.sub(where, mob[i].position)) // console.log(dot, 0.95 - Math.min(dist * 0.00015, 0.3)) @@ -6521,7 +6531,7 @@ const b = { const range = 450 * (tech.isFilament ? 1 + 0.005 * Math.min(110, this.ammo) : 1) let targetCount = 0 for (let i = 0, len = mob.length; i < len; ++i) { - if (mob[i].alive && !mob[i].isBadTarget && !mob[i].shield && Matter.Query.ray(map, m.pos, mob[i].position).length === 0) { + if (mob[i].alive && !mob[i].isBadTarget && !mob[i].shield && Matter.Query.ray(map, m.pos, mob[i].position).length === 0 && !mob[i].isInvulnerable) { const dot = Vector.dot(dir, Vector.normalise(Vector.sub(mob[i].position, m.pos))) //the dot product of diff and dir will return how much over lap between the vectors const dist = Vector.magnitude(Vector.sub(where, mob[i].position)) if (dist < range && dot > 0.9) { //lower dot product threshold for targeting then if you only have one harpoon //target closest mob that player is looking at and isn't too close to target @@ -6553,7 +6563,7 @@ const b = { //single harpoon const dir = { x: Math.cos(m.angle), y: Math.sin(m.angle) }; //make a vector for the player's direction of length 1; used in dot product for (let i = 0, len = mob.length; i < len; ++i) { - if (mob[i].alive && !mob[i].isBadTarget && Matter.Query.ray(map, m.pos, mob[i].position).length === 0) { + if (mob[i].alive && !mob[i].isBadTarget && Matter.Query.ray(map, m.pos, mob[i].position).length === 0 && !mob[i].isInvulnerable) { const dot = Vector.dot(dir, Vector.normalise(Vector.sub(mob[i].position, m.pos))) //the dot product of diff and dir will return how much over lap between the vectors const dist = Vector.magnitude(Vector.sub(where, mob[i].position)) if (dist < closest.distance && dot > 0.98 - Math.min(dist * 0.00014, 0.3)) { //target closest mob that player is looking at and isn't too close to target diff --git a/js/index.js b/js/index.js index bbb4704..8278b91 100644 --- a/js/index.js +++ b/js/index.js @@ -52,7 +52,7 @@ const cat = { } const color = { //light - background: "#ddd", + // background: "#ddd", // used instead: document.body.style.backgroundColor block: "rgba(140,140,140,0.85)", blockS: "#222", map: "#444", diff --git a/js/level.js b/js/level.js index c7c8af0..43a3512 100644 --- a/js/level.js +++ b/js/level.js @@ -18,14 +18,16 @@ const level = { // // simulation.isHorizontalFlipped = true // m.addHealth(Infinity) // m.setField("time dilation") - // b.giveGuns("nail gun") + // b.giveGuns("spores") // tech.giveTech("closed timelike curve") // tech.giveTech("retrocausality") - // tech.giveTech("pneumatic actuator") + // tech.giveTech("clock gating") // tech.giveTech("6s half-life") // for (let i = 0; i < 10; i++) tech.giveTech("replication") // tech.giveTech("eternalism") - // for (let i = 0; i < 10; i++) tech.giveTech("ammonium nitrate") + // m.maxHealth = 100 + // m.health = m.maxHealth + // for (let i = 0; i < 10; i++) tech.giveTech("tungsten carbide") // for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "tech"); // for (let i = 0; i < 10; i++) powerUps.directSpawn(450, -50, "research"); // for (let i = 0; i < 15; i++) tech.giveTech() @@ -33,11 +35,15 @@ const level = { // powerUps.research.changeRerolls(100000) // tech.tech[297].frequency = 100 // m.immuneCycle = Infinity //you can't take damage - // level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why + // level.difficultyIncrease(20) //30 is near max on hard //60 is near max on why // simulation.enableConstructMode() //used to build maps in testing mode // level.testing(); - // spawn.snakeSpitBoss(1900, -500) - // level.reservoir(); //not in rotation, used for testing + // simulation.fpsCap = 30 //new fps + // simulation.fpsInterval = 1000 / simulation.fpsCap; + //how long to wait to return to normal fps + // m.defaultFPSCycle = m.cycle + 20 + Math.min(90, Math.floor(200 * dmg)) + // spawn.timeSkipBoss(1900, -500) + // level.reactor(); //not in rotation, used for testing if (simulation.isTraining) { level.walk(); } else { level.intro(); } //normal starting level ************************************************ // powerUps.research.changeRerolls(3000) @@ -2619,7 +2625,7 @@ const level = { // level.difficultyIncrease(14); //hard mode level 7 level.defaultZoom = 1500 simulation.zoomTransition(level.defaultZoom) - document.body.style.backgroundColor = color.background //"#ddd"; + document.body.style.backgroundColor = "#ddd"; spawn.mapRect(-950, 0, 8200, 800); //ground spawn.mapRect(-950, -1200, 800, 1400); //left wall spawn.mapRect(-950, -1800, 8200, 800); //roof @@ -2761,22 +2767,23 @@ const level = { for (let i = 0; i < 9; ++i) powerUps.spawn(1200 + 550 * Math.random(), -1700, "ammo") for (let i = 0; i < 3; ++i) powerUps.spawn(1200 + 550 * Math.random(), -1700, "heal"); const scale = Math.pow(simulation.difficulty, 0.73) //hard around 30, why around 54 - if (Math.random() < 0.07 && simulation.difficulty > 24) { - for (let i = 0, len = scale * 0.25 / 4; i < len; ++i) spawn.timeBoss(1487 + 200 * i, -1525, 60, false); //spawn 1-2 at difficulty 15 - for (let i = 0, len = scale * 0.1 / 4; i < len; ++i) spawn.bounceBoss(1487 + 200 * i, -1525, 80, false); - for (let i = 0, len = scale * 0.16 / 4; i < len; ++i) spawn.sprayBoss(1487 + 200 * i, -1525, 30, false) - for (let i = 0, len = scale * 0.23 / 4; i < len; ++i) spawn.mineBoss(1487 + 200 * i, -1525, 50, false); - } else { - if (Math.random() < 0.25) { - for (let i = 0, len = scale * 0.25; i < len; ++i) spawn.timeBoss(1487 + 200 * i, -1525, 80, false); //spawn 1-2 at difficulty 15 - } else if (Math.random() < 0.33) { - for (let i = 0, len = scale * 0.1; i < len; ++i) spawn.bounceBoss(1487 + 200 * i, -1525, 80, false); //spawn 1-2 at difficulty 15 - } else if (Math.random() < 0.5) { - for (let i = 0, len = scale * 0.16; i < len; ++i) spawn.sprayBoss(1487 + 200 * i, -1525, 30, false) //spawn 2-3 at difficulty 15 - } else { - for (let i = 0, len = scale * 0.23; i < len; ++i) spawn.mineBoss(1487 + 200 * i, -1525, 50, false); //spawn 3-4 at difficulty 15 - } - } + for (let i = 0, len = scale * 0.23; i < len; ++i) spawn.mineBoss(1487 + 200 * i, -1525, 50, false); //spawn 3-4 at difficulty 15 + // if (Math.random() < 0.07 && simulation.difficulty > 24) { + // for (let i = 0, len = scale * 0.25 / 4; i < len; ++i) spawn.timeBoss(1487 + 200 * i, -1525, 60, false); //spawn 1-2 at difficulty 15 + // for (let i = 0, len = scale * 0.1 / 4; i < len; ++i) spawn.bounceBoss(1487 + 200 * i, -1525, 80, false); + // for (let i = 0, len = scale * 0.16 / 4; i < len; ++i) spawn.sprayBoss(1487 + 200 * i, -1525, 30, false) + // for (let i = 0, len = scale * 0.23 / 4; i < len; ++i) spawn.mineBoss(1487 + 200 * i, -1525, 50, false); + // } else { + // if (Math.random() < 0.25) { + // for (let i = 0, len = scale * 0.25; i < len; ++i) spawn.timeBoss(1487 + 200 * i, -1525, 80, false); //spawn 1-2 at difficulty 15 + // } else if (Math.random() < 0.33) { + // for (let i = 0, len = scale * 0.1; i < len; ++i) spawn.bounceBoss(1487 + 200 * i, -1525, 80, false); //spawn 1-2 at difficulty 15 + // } else if (Math.random() < 0.5) { + // for (let i = 0, len = scale * 0.16; i < len; ++i) spawn.sprayBoss(1487 + 200 * i, -1525, 30, false) //spawn 2-3 at difficulty 15 + // } else { + // for (let i = 0, len = scale * 0.23; i < len; ++i) spawn.mineBoss(1487 + 200 * i, -1525, 50, false); //spawn 3-4 at difficulty 15 + // } + // } spawn.secondaryBossChance(2200, -800) } } else { @@ -4740,19 +4747,15 @@ const level = { skyscrapers() { const boost1 = level.boost(475, 0, 1300) const boost2 = level.boost(4450, 0, 1300); - level.custom = () => { boost1.query(); boost2.query(); - ctx.fillStyle = "#d4f4f4" ctx.fillRect(1350, -2100, 400, 250) ctx.fillStyle = "#d4d4d7" ctx.fillRect(3350, -1300, 50, 1325) ctx.fillRect(1300, -1800, 750, 1800) - level.exit.drawAndCheck(); - level.enter.draw(); }; level.customTopLayer = () => { @@ -4766,20 +4769,16 @@ const level = { ctx.fillStyle = "rgba(0,0,0,0.15)" ctx.fillRect(-250, -300, 450, 300) }; - level.setPosToSpawn(-50, -60); //normal spawn spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20); level.exit.x = 1500; level.exit.y = -1875; - level.defaultZoom = 2000 simulation.zoomTransition(level.defaultZoom) powerUps.spawnStartingPowerUps(1475, -1175); spawn.debris(750, -2200, 3700, 16); //16 debris per level document.body.style.backgroundColor = "#dcdcde"; - // simulation.draw.mapFill = "#444" - // simulation.draw.bodyFill = "rgba(140,140,140,0.85)" - // simulation.draw.bodyStroke = "#222" + spawn.mapRect(-300, 0, 5100, 300); //***********ground spawn.mapRect(-300, -350, 50, 400); //far left starting left wall spawn.mapRect(-300, -10, 500, 50); //far left starting ground @@ -4844,13 +4843,12 @@ const level = { spawn.randomMob(-100, -1700, -0.2); spawn.randomGroup(3700, -1500, 0.4); spawn.randomGroup(1700, -900, 0.4); - if (simulation.difficulty > 1) spawn.randomLevelBoss(2600, -2300); + if (simulation.difficulty > 1) spawn.randomLevelBoss(2800 + 200 * Math.random(), -2200 + 200 * Math.random()); powerUps.addResearchToLevel() //needs to run after mobs are spawned - spawn.secondaryBossChance(3075, -2050) + spawn.secondaryBossChance(4000, -1825) if (simulation.isHorizontalFlipped) { //flip the map horizontally level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit - boost1.boostBounds.min.x = -boost1.boostBounds.min.x - 100 boost1.boostBounds.max.x = -boost1.boostBounds.max.x + 100 boost2.boostBounds.min.x = -boost2.boostBounds.min.x - 100 diff --git a/js/player.js b/js/player.js index dfd14f6..ff046a4 100644 --- a/js/player.js +++ b/js/player.js @@ -1379,7 +1379,10 @@ const m = { x: player.velocity.x - (15 * unit.x) / massRoot, y: player.velocity.y - (15 * unit.y) / massRoot }); - if (who.isOrbital) Matter.Body.setVelocity(who, { x: 0, y: 0 }); + if (who.isUnstable) { + if (m.fieldCDcycle < m.cycle + 30) m.fieldCDcycle = m.cycle + 30 + who.death(); + } if (m.crouch) { Matter.Body.setVelocity(player, { @@ -1762,7 +1765,10 @@ const m = { x: player.velocity.x - (30 * unit.x) / massRoot, y: player.velocity.y - (30 * unit.y) / massRoot }); - if (mob[i].isOrbital) Matter.Body.setVelocity(mob[i], { x: 0, y: 0 }); + if (mob[i].isUnstable) { + if (m.fieldCDcycle < m.cycle + 10) m.fieldCDcycle = m.cycle + 10 + mob[i].death(); + } if (!isFree) { //player knock backs if (mob[i].isDropPowerUp && player.speed < 12) { const massRootCap = Math.sqrt(Math.min(10, Math.max(0.2, mob[i].mass))); diff --git a/js/powerup.js b/js/powerup.js index b4eca9b..92333b2 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -758,6 +758,10 @@ const powerUps = { text += `
" + for (let i = 0; i < this.state[j].length; i++) { + if (this.state[j][i]) { + text += "⬛" //"█" //"■" + } else { + text += "⬜" //" " //"□" + } + } + text += "
" + } + return text + }, + }, { name: "cosmogonic myth", description: `open a portal to a primordial version of reality" - for (let i = 0; i < this.state[j].length; i++) { - if (this.state[j][i]) { - text += "⬛" //"█" //"■" - } else { - text += "⬜" //" " //"□" - } - } - text += "
" - } - return text - }, - }, //************************************************** //************************************************** undefined / lore //************************************************** tech diff --git a/todo.txt b/todo.txt index 904ec56..e6c8ced 100644 --- a/todo.txt +++ b/todo.txt @@ -1,40 +1,32 @@ ******************************************************** NEXT PATCH ************************************************** -tech: propagator - 67% damage, lose 1/2 second of time when a mob dies +boss orbitals and mineBoss mines are destroyed when you deflect them with your field +drones, spores and other bullets that target mobs, will not target invulnerable mobs +timeSKipBoss is a bit slower with a bit less time skipping + fixed color to better match level background colors -timeSkipBoss is back, maybe it will not cause bugs this time - immune to harm unless player is inside horizon - player loses time when inside horizon - -snake bosses are immune to harm until your remove their tail - -mob shields are 30% stronger -time dilation: retrocausality automatically grabs power ups -eternalism 50->40% damage -paradigm shift 10->16% chance to get a research when ejecting tech -reaction inhibitor 11->13% mob health reduction -recycling 1->0.5% health for 5 seconds - up to 2.5% per mob kill at normal max health +JUNK tech: path integral - your next tech choice has almost all possible choices bug fixes -******************************************************** TODO ******************************************************** -make targeting skip invulnerable mobs - drones, spores, harpoon, missiles?, mines, nail on death - this helps beat snake boss - spores are biggest issue +*********************************************************** TODO ***************************************************** -let blocking instantly destroy the red orbitals? since they can't be deflected - also mines on reactor level? - also any bullet? +timeskip flickers with tech: clock gating, and game pause after large hit + probably not related to timeskip, related to graphics effect + not a big problem, actually it's kinda neat effect + only fix if there is a clear solution + +JUNK tech show 20+ options in tech selection + +bullets that can target the player + occurs if no mobs targets around + worms? drones? missiles? spores? + all of the above? BUG time skip probably led to player being able to move, and game not being paused for a few seconds while the death screen faded in also small chance it happened with rewind instead, but unlikely -make one value to track all the +dmg effects that don't need dynamic calculations - update it with a set damage function - block manufacturing - molecular assembler tech Holding r-click will create a slowly increasing in size block, which will be thrown on release @@ -48,10 +40,6 @@ make MEE work with harm reduction how to nerf MEE maybe harm reduction could also reduce energy regen -simulation.timeSkip(60) - maybe run simulation.timeSkip(60) in a room in labs - mob fires laser/bullets that timeSkip player - Currently, the mob just deals higher damage on impact, which is annoying although not hard to compete with nor unique By "redesign" I mean replacing instances of the regular mob, since the same code is used for the tiny red projectiles (I think) just add a new mob and remove the old one from the rotation The new mob should be as such, a "real" exploding mob: @@ -65,7 +53,6 @@ Regular state: red About to explode: animation to dark red Exploding: several shockwaves from the explosion points and tiny trails given to the shrapnel for a second or two until they deaccelerate - make laser gain damage and energy drain from fire delay tech wording? put it in the gun description