diff --git a/.DS_Store b/.DS_Store index 89ee7b3..fca212d 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/js/bullet.js b/js/bullet.js index e55ae1c..950a4a3 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -1578,7 +1578,7 @@ const b = { restitution: 0.5, dmg: 0, // 0.14 //damage done in addition to the damage from momentum minDmgSpeed: 2, - lookFrequency: 60 + Math.floor(7 * Math.random()), + lookFrequency: 67 + Math.floor(7 * Math.random()), drain: 0.7 * tech.isLaserDiode * tech.laserFieldDrain, isArmed: false, torqueMagnitude: 0.000003 * (Math.round(Math.random()) ? 1 : -1), @@ -1611,7 +1611,7 @@ const b = { Matter.Query.ray(body, this.position, mob[i].position).length === 0 ) { this.do = this.laserSpin - this.endCycle = simulation.cycle + 300 + this.endCycle = simulation.cycle + 360 // if (this.angularSpeed < 0.01) this.torque += this.inertia * this.torqueMagnitude * 5 //spin this.isArmed = true } diff --git a/js/level.js b/js/level.js index e93dc71..a67103f 100644 --- a/js/level.js +++ b/js/level.js @@ -15,11 +15,11 @@ const level = { // simulation.zoomScale = 1000; // simulation.setZoom(); // simulation.enableConstructMode() //used to build maps in testing mode - // m.setField("standing wave harmonics") + // m.setField("plasma torch") + // for (let i = 0; i < 9; i++) tech.giveTech("spherical harmonics") // b.giveGuns("laser") // tech.isExplodeRadio = true - // for (let i = 0; i < 5; i++) tech.giveTech("spherical harmonics") - // tech.giveTech("expansion") + // tech.giveTech("Z-pinch") // tech.giveTech("MACHO") // tech.giveTech("potential well") // for (let i = 0; i < 3; i++) tech.giveTech("packet length") @@ -55,7 +55,7 @@ const level = { // level.vats() //community level // level["n-gon"]() //community level // level.tunnel() //community level - // tech.giveTech("undefined") + // for (let i = 0; i < 7; i++) tech.giveTech("undefined") // lore.techCount = 6 // localSettings.loreCount = 1; // localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage @@ -1152,7 +1152,7 @@ const level = { spawn.bodyRect(x + 5, y - 260 + i * blockSize, 30, blockSize); } } - // blockDoor(710, -710); + blockDoor(710, -710); // for (let i = 0; i < 30; i++) powerUps.directSpawn(710, -710, "tech"); spawn.mapRect(2500, -1200, 200, 750); //right wall diff --git a/js/player.js b/js/player.js index 2445843..a8f25b8 100644 --- a/js/player.js +++ b/js/player.js @@ -1135,58 +1135,73 @@ const m = { //throw the body m.fieldCDcycle = m.cycle + 15; m.isHolding = false; - //bullet-like collisions - m.holdingTarget.collisionFilter.category = tech.isBlockBullets ? cat.bullet : cat.body; - m.holdingTarget.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield; - //check every second to see if player is away from thrown body, and make solid - const solid = function(that) { - const dx = that.position.x - player.position.x; - const dy = that.position.y - player.position.y; - if (that.speed < 3 && dx * dx + dy * dy > 10000 && that !== m.holdingTarget) { - that.collisionFilter.category = cat.body; //make solid - that.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet; //can hit player now - } else { - setTimeout(solid, 40, that); + + if (tech.isBlockExplosion && m.throwCharge > 5) { //remove the block body and pulse in the direction you are facing + //m.throwCharge > 5 seems to be when the field full colors in a block you are holding + m.throwCharge = 0; + m.throwCycle = m.cycle + 180 //used to detect if a block was thrown in the last 3 seconds + m.definePlayerMass() //return to normal player mass + m.energy += 3 * Math.sqrt(m.holdingTarget.mass) + //remove block before pulse, so it doesn't get in the way + for (let i = 0; i < body.length; i++) { + if (body[i] === m.holdingTarget) { + Matter.World.remove(engine.world, body[i]); + body.splice(i, 1); + } } - }; - setTimeout(solid, 200, m.holdingTarget); - - const charge = Math.min(m.throwCharge / 5, 1) - //***** scale throw speed with the first number, 80 ***** - let speed = 80 * charge * Math.min(1, 0.8 / Math.pow(m.holdingTarget.mass, 0.25)); - - if (Matter.Query.collides(m.holdingTarget, map).length !== 0) { - speed *= 0.7 //drop speed by 30% if touching map - if (Matter.Query.ray(map, m.holdingTarget.position, m.pos).length !== 0) speed = 0 //drop to zero if the center of the block can't see the center of the player through the map - //|| Matter.Query.ray(body, m.holdingTarget.position, m.pos).length > 1 - } - - m.throwCharge = 0; - m.throwCycle = m.cycle + 180 //used to detect if a block was thrown in the last 3 seconds - Matter.Body.setVelocity(m.holdingTarget, { - x: player.velocity.x * 0.5 + Math.cos(m.angle) * speed, - y: player.velocity.y * 0.5 + Math.sin(m.angle) * speed - }); - //player recoil //stronger in x-dir to prevent jump hacking - - Matter.Body.setVelocity(player, { - x: player.velocity.x - Math.cos(m.angle) * speed / (m.crouch ? 30 : 10) * Math.sqrt(m.holdingTarget.mass), - y: player.velocity.y - Math.sin(m.angle) * speed / 30 * Math.sqrt(m.holdingTarget.mass) - }); - m.definePlayerMass() //return to normal player mass - - if (tech.isAddBlockMass) { - const expand = function(that, massLimit) { - if (that.mass < massLimit) { - const scale = 1.05; - Matter.Body.scale(that, scale, scale); - setTimeout(expand, 20, that, massLimit); + b.pulse(50 * Math.pow(m.holdingTarget.mass, 0.25), m.angle) + } else { //normal throw + //bullet-like collisions + m.holdingTarget.collisionFilter.category = tech.isBlockBullets ? cat.bullet : cat.body; + m.holdingTarget.collisionFilter.mask = cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet | cat.mobShield; + //check every second to see if player is away from thrown body, and make solid + const solid = function(that) { + const dx = that.position.x - player.position.x; + const dy = that.position.y - player.position.y; + if (that.speed < 3 && dx * dx + dy * dy > 10000 && that !== m.holdingTarget) { + that.collisionFilter.category = cat.body; //make solid + that.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet; //can hit player now + } else { + setTimeout(solid, 40, that); } }; - expand(m.holdingTarget, Math.min(20, m.holdingTarget.mass * 3)) + setTimeout(solid, 200, m.holdingTarget); + + const charge = Math.min(m.throwCharge / 5, 1) + //***** scale throw speed with the first number, 80 ***** + let speed = 80 * charge * Math.min(1, 0.8 / Math.pow(m.holdingTarget.mass, 0.25)); + + if (Matter.Query.collides(m.holdingTarget, map).length !== 0) { + speed *= 0.7 //drop speed by 30% if touching map + if (Matter.Query.ray(map, m.holdingTarget.position, m.pos).length !== 0) speed = 0 //drop to zero if the center of the block can't see the center of the player through the map + //|| Matter.Query.ray(body, m.holdingTarget.position, m.pos).length > 1 + } + + m.throwCharge = 0; + m.throwCycle = m.cycle + 180 //used to detect if a block was thrown in the last 3 seconds + Matter.Body.setVelocity(m.holdingTarget, { + x: player.velocity.x * 0.5 + Math.cos(m.angle) * speed, + y: player.velocity.y * 0.5 + Math.sin(m.angle) * speed + }); + //player recoil //stronger in x-dir to prevent jump hacking + + Matter.Body.setVelocity(player, { + x: player.velocity.x - Math.cos(m.angle) * speed / (m.crouch ? 30 : 10) * Math.sqrt(m.holdingTarget.mass), + y: player.velocity.y - Math.sin(m.angle) * speed / 30 * Math.sqrt(m.holdingTarget.mass) + }); + m.definePlayerMass() //return to normal player mass + + if (tech.isAddBlockMass) { + const expand = function(that, massLimit) { + if (that.mass < massLimit) { + const scale = 1.05; + Matter.Body.scale(that, scale, scale); + setTimeout(expand, 20, that, massLimit); + } + }; + expand(m.holdingTarget, Math.min(20, m.holdingTarget.mass * 3)) + } } - - } } else { m.isHolding = false @@ -1353,11 +1368,8 @@ const m = { }, pushMobs360(range) { // find mobs in range in any direction for (let i = 0, len = mob.length; i < len; ++i) { - if ( - Vector.magnitude(Vector.sub(mob[i].position, m.pos)) - mob[i].radius < range && - !mob[i].isShielded && - Matter.Query.ray(map, mob[i].position, m.pos).length === 0 - ) { + if (Vector.magnitude(Vector.sub(mob[i].position, m.pos)) - mob[i].radius < range && !mob[i].isShielded) { + // && Matter.Query.ray(map, mob[i].position, m.pos).length === 0 mob[i].locatePlayer(); m.pushMass(mob[i]); } @@ -1495,25 +1507,16 @@ const m = { }, { name: "standing wave harmonics", - description: "3 oscillating shields are permanently active
deflecting drains energy with no cool down
reduce harm and deflecting recoil by 25%", + description: "3 oscillating shields are permanently active
deflecting drains energy with no cool down
deflecting has 75% less recoil", //harm and effect: () => { // m.fieldHarmReduction = 0.80; m.fieldBlockCD = 0; - m.fieldHarmReduction = 0.75; + // m.fieldHarmReduction = 0.75; m.blockingRecoil = 1 //4 is normal m.fieldRange = 175 m.fieldShieldingScale = Math.pow(0.5, (tech.harmonics - 3)) m.harmonicRadius = 1 //for smoothing function when player holds mouse (for harmonicAtomic) m.harmonic3Phase = () => { //normal standard 3 different 2-d circles - if (tech.isStandingWaveExpand) { - if (input.field) { - const oldHarmonicRadius = m.harmonicRadius - m.harmonicRadius = 0.985 * m.harmonicRadius + 0.015 * 2.5 - m.energy -= 0.3 * (m.harmonicRadius - oldHarmonicRadius) - } else { - m.harmonicRadius = 0.998 * m.harmonicRadius + 0.002 * 1 - } - } const fieldRange1 = (0.7 + 0.3 * Math.sin(m.cycle / 23)) * m.fieldRange * m.harmonicRadius const fieldRange2 = (0.63 + 0.37 * Math.sin(m.cycle / 37)) * m.fieldRange * m.harmonicRadius const fieldRange3 = (0.65 + 0.35 * Math.sin(m.cycle / 47)) * m.fieldRange * m.harmonicRadius @@ -1533,15 +1536,6 @@ const m = { m.harmonicAtomic = () => { //several ellipses spinning about different axises const rotation = simulation.cycle * 0.002 const phase = simulation.cycle * 0.03 - if (tech.isStandingWaveExpand) { - if (input.field) { - const oldHarmonicRadius = m.harmonicRadius - m.harmonicRadius = 0.985 * m.harmonicRadius + 0.015 * 2.5 - m.energy -= 0.3 * (m.harmonicRadius - oldHarmonicRadius) - } else { - m.harmonicRadius = 0.998 * m.harmonicRadius + 0.002 * 1 - } - } const radius = m.fieldRange * m.harmonicRadius //+ 20 * Math.sin(m.cycle * 0.05) ctx.lineWidth = 1; ctx.strokeStyle = "rgba(110,170,200,0.9)" @@ -1585,6 +1579,15 @@ const m = { m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists) } if (m.energy > 0.1 && m.fieldCDcycle < m.cycle) { + if (tech.isStandingWaveExpand) { + if (input.field) { + const oldHarmonicRadius = m.harmonicRadius + m.harmonicRadius = 0.985 * m.harmonicRadius + 0.015 * 2.5 + m.energy -= 0.45 * (m.harmonicRadius - oldHarmonicRadius) + } else { + m.harmonicRadius = 0.997 * m.harmonicRadius + 0.003 * 1 + } + } m.harmonicShield() } diff --git a/js/simulation.js b/js/simulation.js index 245ee06..103c5e8 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -1,7 +1,7 @@ // game Object ******************************************************** //********************************************************************* const simulation = { - loop() {}, //main game loop, gets se tto normal or testing loop + loop() {}, //main game loop, gets set to normal or testing loop normalLoop() { simulation.gravity(); Engine.update(engine, simulation.delta); @@ -525,18 +525,9 @@ const simulation = { level.levels.push("tunnel"); level.levels = shuffle(level.levels); //shuffles order of maps level.levels.splice(0, 9); //remove some random levels to make up for adding the community levels - - lore.techCount = 0; //remove undefined tech for community maps - for (let i = 0, len = tech.tech.length; i < len; i++) { - if (tech.tech[i].isLore) { - tech.tech[i].frequency = 0; - tech.tech[i].count = 0; - } - } } else { level.levels = shuffle(level.levels); //shuffles order of maps } - level.levels.unshift("intro"); //add level to the start of the randomized levels list level.levels.push("gauntlet"); //add level to the end of the randomized levels list level.levels.push("final"); //add level to the end of the randomized levels list @@ -657,6 +648,7 @@ const simulation = { simulation.fpsInterval = 1000 / simulation.fpsCap; simulation.then = Date.now(); requestAnimationFrame(cycle); //starts game loop + }, clearTimeouts() { let id = window.setTimeout(function() {}, 0); diff --git a/js/spawn.js b/js/spawn.js index 3981963..028db52 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -242,120 +242,127 @@ const spawn = { me.isBoss = true; me.frictionAir = 0.01; me.memory = Infinity; + me.hasRunDeathScript = false me.locatePlayer(); const density = 0.25 Matter.Body.setDensity(me, density); //extra dense //normal is 0.001 //makes effective life much larger // spawn.shield(me, x, y, 1); me.onDeath = function() { + if (!this.hasRunDeathScript) { + this.hasRunDeathScript = true + //make a block body to replace this one + //this body is too big to leave behind in the normal way mobs.replace() + const len = body.length; + const v = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices)) //might help with vertex collision issue, not sure + body[len] = Matter.Bodies.fromVertices(this.position.x, this.position.y, v); + Matter.Body.setVelocity(body[len], { x: 0, y: -3 }); + Matter.Body.setAngularVelocity(body[len], this.angularVelocity); + body[len].collisionFilter.category = cat.body; + body[len].collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet; + body[len].classType = "body"; + World.add(engine.world, body[len]); //add to world + const expand = function(that, massLimit) { + const scale = 1.05; + Matter.Body.scale(that, scale, scale); + if (that.mass < massLimit) setTimeout(expand, 20, that, massLimit); + }; + expand(body[len], 200) - //make a block body to replace this one - //this body is too big to leave behind in the normal way mobs.replace() - const len = body.length; - const v = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices)) //might help with vertex collision issue, not sure - body[len] = Matter.Bodies.fromVertices(this.position.x, this.position.y, v); - Matter.Body.setVelocity(body[len], { x: 0, y: -3 }); - Matter.Body.setAngularVelocity(body[len], this.angularVelocity); - body[len].collisionFilter.category = cat.body; - body[len].collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet; - body[len].classType = "body"; - World.add(engine.world, body[len]); //add to world - const expand = function(that, massLimit) { - const scale = 1.05; - Matter.Body.scale(that, scale, scale); - if (that.mass < massLimit) setTimeout(expand, 20, that, massLimit); - }; - expand(body[len], 200) + function unlockExit() { + if (simulation.isHorizontalFlipped) { + level.exit.x = -5500 - 100; + } else { + level.exit.x = 5500; + } + level.exit.y = -330; + Matter.World.remove(engine.world, map[map.length - 1]); + map.splice(map.length - 1, 1); + simulation.draw.setPaths(); //redraw map draw path + } - function unlockExit() { - level.exit.x = 5500; - level.exit.y = -330; - Matter.World.remove(engine.world, map[map.length - 1]); - map.splice(map.length - 1, 1); - simulation.draw.setPaths(); //redraw map draw path - } + //add lore level as next level if player took lore tech earlier in the game + if (lore.techCount > (lore.techGoal - 1) && !simulation.isCheating) { + simulation.makeTextLog(`undefined = ${lore.techCount}/${lore.techGoal}
level.levels.push("null")`); + level.levels.push("null") + //remove block map element so exit is clear + unlockExit() + } else { //reset game + let count = 0 - //add lore level as next level if player took lore tech earlier in the game - if (lore.techCount > (lore.techGoal - 1) && !simulation.isCheating) { - simulation.makeTextLog(`undefined = ${lore.techCount}/${lore.techGoal}
level.levels.push("null")`); - level.levels.push("null") - //remove block map element so exit is clear - unlockExit() - } else { //reset game - let count = 0 - - function loop() { - if (!simulation.paused) { - count++ - if (count < 600) { - if (count === 1) simulation.makeTextLog(`//enter testing mode to set level.levels.length to Infinite`); - if (!(count % 60)) simulation.makeTextLog(`simulation.analysis = ${(count/60- Math.random()).toFixed(3)}`); - } else if (count === 600) { - simulation.makeTextLog(`simulation.analysis = 1 //analysis complete`); - } else if (count === 720) { - simulation.makeTextLog(`undefined = ${lore.techCount}/${lore.techGoal}`) - } else if (count === 900) { - simulation.makeTextLog(`World.clear(engine.world) //simulation successful`); - } else if (count === 1140) { - // tech.isImmortal = false; - // m.death() - // m.alive = false; - // simulation.paused = true; - // m.health = 0; - // m.displayHealth(); - document.getElementById("health").style.display = "none" - document.getElementById("health-bg").style.display = "none" - document.getElementById("text-log").style.opacity = 0; //fade out any active text logs - document.getElementById("fade-out").style.opacity = 1; //slowly fades out - // build.shareURL(false) + function loop() { + if (!simulation.paused) { + count++ + if (count < 600) { + if (count === 1) simulation.makeTextLog(`//enter testing mode to set level.levels.length to Infinite`); + if (!(count % 60)) simulation.makeTextLog(`simulation.analysis = ${(count/60- Math.random()).toFixed(3)}`); + } else if (count === 600) { + simulation.makeTextLog(`simulation.analysis = 1 //analysis complete`); + } else if (count === 720) { + simulation.makeTextLog(`undefined = ${lore.techCount}/${lore.techGoal}`) + } else if (count === 900) { + simulation.makeTextLog(`World.clear(engine.world) //simulation successful`); + } else if (count === 1140) { + // tech.isImmortal = false; + // m.death() + // m.alive = false; + // simulation.paused = true; + // m.health = 0; + // m.displayHealth(); + document.getElementById("health").style.display = "none" + document.getElementById("health-bg").style.display = "none" + document.getElementById("text-log").style.opacity = 0; //fade out any active text logs + document.getElementById("fade-out").style.opacity = 1; //slowly fades out + // build.shareURL(false) + setTimeout(function() { + simulation.paused = true; + World.clear(engine.world); + Engine.clear(engine); + simulation.splashReturn(); + }, 6000); + return + } + } + if (simulation.testing) { + unlockExit() setTimeout(function() { - simulation.paused = true; - World.clear(engine.world); - Engine.clear(engine); - simulation.splashReturn(); - }, 6000); - return + simulation.makeTextLog(`level.levels.length = Infinite`); + }, 1500); + } else { + requestAnimationFrame(loop); } } - if (simulation.testing) { - unlockExit() - setTimeout(function() { - simulation.makeTextLog(`level.levels.length = Infinite`); - }, 1500); - } else { - requestAnimationFrame(loop); - } + requestAnimationFrame(loop); } - requestAnimationFrame(loop); - } - // for (let i = 0; i < 3; i++) - level.difficultyIncrease(simulation.difficultyMode) //ramp up damage - //remove power Ups, to avoid spamming console - function removeAll(array) { - for (let i = 0; i < array.length; ++i) Matter.World.remove(engine.world, array[i]); - } - removeAll(powerUp); - powerUp = []; + // for (let i = 0; i < 3; i++) + level.difficultyIncrease(simulation.difficultyMode) //ramp up damage + //remove power Ups, to avoid spamming console + function removeAll(array) { + for (let i = 0; i < array.length; ++i) Matter.World.remove(engine.world, array[i]); + } + removeAll(powerUp); + powerUp = []; - //pull in particles - for (let i = 0, len = body.length; i < len; ++i) { - const velocity = Vector.mult(Vector.normalise(Vector.sub(this.position, body[i].position)), 65) - const pushUp = Vector.add(velocity, { x: 0, y: -0.5 }) - Matter.Body.setVelocity(body[i], Vector.add(body[i].velocity, pushUp)); - } - //damage all mobs - for (let i = 0, len = mob.length; i < len; ++i) { - if (mob[i] !== this) mob[i].damage(Infinity, true); - } + //pull in particles + for (let i = 0, len = body.length; i < len; ++i) { + const velocity = Vector.mult(Vector.normalise(Vector.sub(this.position, body[i].position)), 65) + const pushUp = Vector.add(velocity, { x: 0, y: -0.5 }) + Matter.Body.setVelocity(body[i], Vector.add(body[i].velocity, pushUp)); + } + //damage all mobs + for (let i = 0, len = mob.length; i < len; ++i) { + if (mob[i] !== this) mob[i].damage(Infinity, true); + } - //draw stuff - for (let i = 0, len = 22; i < len; i++) { - simulation.drawList.push({ //add dmg to draw queue - x: this.position.x, - y: this.position.y, - radius: (i + 1) * 150, - color: `rgba(255,255,255,0.17)`, - time: 5 * (len - i + 1) - }); + //draw stuff + for (let i = 0, len = 22; i < len; i++) { + simulation.drawList.push({ //add dmg to draw queue + x: this.position.x, + y: this.position.y, + radius: (i + 1) * 150, + color: `rgba(255,255,255,0.17)`, + time: 5 * (len - i + 1) + }); + } } }; me.onDamage = function() {}; @@ -448,7 +455,7 @@ const spawn = { } const len = (this.totalCycles / 400 + simulation.difficulty / 2 - 30) / 15 for (let i = 0; i < len; i++) { - spawn.randomLevelBoss(3000 + 2000 * (Math.random() - 0.5), -1100 + 200 * (Math.random() - 0.5)) + spawn.randomLevelBoss(-3000 + 2000 * (Math.random() - 0.5), -1100 + 200 * (Math.random() - 0.5)) } } } @@ -1760,8 +1767,8 @@ const spawn = { y: me.position.y }, bodyB: me, - stiffness: 0.001, - damping: 1 + stiffness: 0.0001, + damping: 0.3 }); World.add(engine.world, me.constraint); }, 2000); //add in a delay in case the level gets flipped left right @@ -1876,18 +1883,18 @@ const spawn = { mobs.spawn(x, y, 3, radius, "#f08"); let me = mob[mob.length - 1]; - setTimeout(() => { //fix mob in place, but allow rotation - me.constraint = Constraint.create({ - pointA: { - x: me.position.x, - y: me.position.y - }, - bodyB: me, - stiffness: 0.0001, - damping: 1 - }); - World.add(engine.world, me.constraint); - }, 2000); //add in a delay in case the level gets flipped left right + // setTimeout(() => { //fix mob in place, but allow rotation + // me.constraint = Constraint.create({ + // pointA: { + // x: me.position.x, + // y: me.position.y + // }, + // bodyB: me, + // stiffness: 0.00001, + // damping: 0.1 + // }); + // World.add(engine.world, me.constraint); + // }, 2000); //add in a delay in case the level gets flipped left right me.vertices = Matter.Vertices.rotate(me.vertices, Math.PI, me.position); //make the pointy side of triangle the front Matter.Body.rotate(me, Math.random() * Math.PI * 2); diff --git a/js/tech.js b/js/tech.js index f5d10d2..f5433df 100644 --- a/js/tech.js +++ b/js/tech.js @@ -14,6 +14,14 @@ } } lore.techCount = 0; + if (simulation.isCommunityMaps || simulation.isCheating) { + for (let i = 0, len = tech.tech.length; i < len; i++) { + if (tech.tech[i].isLore) { + tech.tech[i].frequency = 0; + tech.tech[i].count = 0; + } + } + } // tech.removeJunkTechFromPool(); // tech.removeLoreTechFromPool(); // tech.addLoreTechToPool(); @@ -742,7 +750,7 @@ count: 0, frequency: 2, allowed() { - return tech.explosiveRadius === 1 && !tech.isSmallExplosion && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1) + return tech.explosiveRadius === 1 && !tech.isSmallExplosion && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1 || tech.isBlockExplosion) }, requires: "an explosive damage source, not ammonium nitrate or nitroglycerin", effect: () => { @@ -759,7 +767,7 @@ count: 0, frequency: 2, allowed() { - return !tech.isExplodeRadio && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1) + return !tech.isExplodeRadio && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1 || tech.isBlockExplosion) }, requires: "an explosive damage source, not iridium-192", effect: () => { @@ -776,7 +784,7 @@ count: 0, frequency: 2, allowed() { - return !tech.isExplodeRadio && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1) + return !tech.isExplodeRadio && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1 || tech.isBlockExplosion) }, requires: "an explosive damage source, not iridium-192", effect: () => { @@ -794,7 +802,7 @@ frequency: 2, isBadRandomOption: true, allowed() { - return !tech.isRewindGrenade && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField) + return !tech.isRewindGrenade && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.isBlockExplosion) }, requires: "an explosive damage source, not causality bombs", effect: () => { @@ -812,7 +820,7 @@ count: 0, frequency: 2, allowed() { - return !tech.isExplodeRadio && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1) + return !tech.isExplodeRadio && (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1 || tech.isBlockExplosion) }, requires: "an explosive damage source, not iridium-192", effect() { @@ -830,7 +838,7 @@ count: 0, frequency: 2, allowed() { - return tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isMissileField || tech.isExplodeMob || tech.isPulseLaser + return tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isMissileField || tech.isExplodeMob || tech.isPulseLaser || tech.isBlockExplosion }, requires: "an explosive damage source", effect: () => { @@ -881,7 +889,7 @@ count: 0, frequency: 2, allowed() { - return (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1) && !tech.sporesOnDeath && !tech.nailsDeathMob && !tech.botSpawner && !tech.isMobBlockFling && !tech.iceIXOnDeath + return (tech.haveGunCheck("missiles") || tech.isIncendiary || (tech.haveGunCheck("grenades") && !tech.isNeutronBomb) || tech.haveGunCheck("vacuum bomb") || tech.isPulseLaser || tech.isMissileField || tech.boomBotCount > 1 || tech.isBlockExplosion) && !tech.sporesOnDeath && !tech.nailsDeathMob && !tech.botSpawner && !tech.isMobBlockFling && !tech.iceIXOnDeath }, requires: "an explosive damage source, no other mob death tech", effect: () => { @@ -3063,27 +3071,6 @@ }, remove() {} }, - { - name: "booby trap", - description: "drop a mine after picking up a power up
add 9 JUNK tech to the potential pool", - maxCount: 1, - count: 0, - frequency: 1, - frequencyDefault: 1, - allowed() { - return tech.duplicationChance() > 0 - }, - requires: "some power up duplication", - effect() { - tech.isMineDrop = true; - if (tech.isMineDrop) b.mine(m.pos, { x: 0, y: 0 }, 0, tech.isMineAmmoBack) - tech.addJunkTechToPool(13) - }, - remove() { - tech.isMineDrop = false; - if (this.count > 0) tech.removeJunkTechFromPool(13) - } - }, { name: "unified field theory", description: `in the pause menu, change your field
by clicking on your field's box`, @@ -4079,6 +4066,27 @@ tech.isMineSentry = false; } }, + { + name: "booby trap", + description: "drop a mine after picking up a power up
add 13 JUNK tech to the potential pool", + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return tech.isMineSentry === true || tech.isLaserMine === true || tech.isMineAmmoBack === true + }, + requires: "some mine tech", + effect() { + tech.isMineDrop = true; + if (tech.isMineDrop) b.mine(m.pos, { x: 0, y: 0 }, 0, tech.isMineAmmoBack) + tech.addJunkTechToPool(13) + }, + remove() { + tech.isMineDrop = false; + if (this.count > 0) tech.removeJunkTechFromPool(13) + } + }, { name: "mycelial fragmentation", description: "sporangium release an extra spore
once a second during their growth phase", @@ -4613,35 +4621,14 @@ //************************************************** field //************************************************** tech //************************************************** - // { - // name: "frequency resonance", - // description: "standing wave harmonics shield is retuned
increase size and deflecting efficiency by 50%", - // isFieldTech: true, - // maxCount: 9, - // count: 0, - // frequency: 2, - // allowed() { - // return m.fieldUpgrades[m.fieldMode].name === "standing wave harmonics" - // }, - // requires: "standing wave harmonics", - // effect() { - // tech.frequencyResonance = this.count + 1 // +1 because count updates later - // m.fieldRange = 175 + 175 * 0.25 * tech.frequencyResonance - // m.fieldShieldingScale = Math.pow(0.5, tech.frequencyResonance) - // }, - // remove() { - // m.fieldRange = 175; - // m.fieldShieldingScale = 1; - // tech.frequencyResonance = 0 - // } - // }, + { name: "spherical harmonics", description: "standing wave oscillates in a 3rd dimension
increasing deflecting efficiency by 40%", isFieldTech: true, maxCount: 9, count: 0, - frequency: 4, + frequency: 3, allowed() { return m.fieldUpgrades[m.fieldMode].name === "standing wave harmonics" }, @@ -4659,7 +4646,7 @@ }, { name: "expansion", - description: "using standing wave field drains energy
to temporarily expand its radius", + description: "using standing wave field uses energy
to temporarily expand its radius", // description: "use energy to expand standing wave
the field slowly contracts when not used", isFieldTech: true, maxCount: 1, @@ -5053,6 +5040,24 @@ tech.isPlasmaRange = 1; } }, + { + name: "tokamak", + description: "throwing a block convert it into energy
and a laser pulse explosion cluster", + isFieldTech: true, + maxCount: 1, + count: 0, + frequency: 2, + allowed() { + return m.fieldUpgrades[m.fieldMode].name === "plasma torch" + }, + requires: "plasma torch", + effect() { + tech.isBlockExplosion = true; + }, + remove() { + tech.isBlockExplosion = false; + } + }, { name: "micro-extruder", description: "plasma torch extrudes a thin hot wire
increases damage, energy drain, and lag", @@ -6876,7 +6881,6 @@ droneCycleReduction: null, droneEnergyReduction: null, isNoHeals: null, - // frequencyResonance: null, isAlwaysFire: null, isDroneRespawn: null, deathSpawns: null, @@ -6897,5 +6901,6 @@ isSneakAttack: null, isFallingDamage: null, harmonics: null, - isStandingWaveExpand: null + isStandingWaveExpand: null, + isBlockExplosion: null } \ No newline at end of file diff --git a/todo.txt b/todo.txt index b0c0c75..37ed81f 100644 --- a/todo.txt +++ b/todo.txt @@ -1,9 +1,17 @@ ******************************************************** NEXT PATCH ******************************************************** +tech: tokamak - instead of throwing a block convert it into energy and a pulse explosion + requires plasma +standing wave field no longer gives 25% harm reduction +standing wave field can now block through walls + +bug fixes ******************************************************** BUGS ******************************************************** +a couple times people have reported the final boss dropping extra bodies on death + figure out how to undo ship mode if you die in ship mode it spawns with m.look set to non ship methods look is set in many tech and in startGame @@ -26,23 +34,24 @@ is there a way to check if the player is stuck inside the map or block ******************************************************** TODO ******************************************************** -spherical harmonics improve blocking efficiency - 9x stacks - gain cool multi ellipse atomic graphic - 1st stack gives 3x atomic graphic - more stacks give more ellipse for atomic graphic -spherical harmonics unlocks tech that increases shield radius when you hold field input +throwing a block removes the block and fires a pulse with a size that scales with the size of the block + must have a charge above some threshold + plasma field tech + gain 100 energy? +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 -what about the single axis graphic? +tech: at the start of a new level remove 5 research and spawn a second boss + +what about the single axis graphic? (find the code in standing wave harmonic) maybe just save it for a mob + maybe use it on lore tech: picking up heal power ups when at full health does harm equal to the heal values benefit on pick up: get 1% damage -draw a rotating ring, like a 3-D spinning ring effect - an ellipse the has sine function on one of it's parameters - buttons can now on/off boosts energy conservation 6% damage recovered as energy @@ -50,8 +59,6 @@ energy conservation 6% damage recovered as energy junk tech Weak Anthropic Principle: you get a second chance at life, but .... - -negative effect: remove air control mob: molecule shapes - 2 separate mobs joined by a bond use constraints: just spawn 2x or 3x groupings @@ -193,10 +200,6 @@ flavor - your bullets destroy blocks power ups spores -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 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