From fe05a57a1378b6225fabcdcae886365a03914031 Mon Sep 17 00:00:00 2001 From: landgreen Date: Tue, 15 Jun 2021 05:58:28 -0700 Subject: [PATCH] toggle tech supertemporal - fire your super balls at the same place in space, but delayed in time super ball starts with 3 not 4 balls, but they are is 25% larger, 10% faster, and 25% lower divergence (this makes adding more balls much stronger) gun - super balls has 15% less ammo standing wave harmonics - still has no block cooldown, but now it has a cooldown for how often it can drain energy this should make rapidly blocking drain upto 10x less energy base blocking cost have increased by 25% wormhole gets 10% duplication (was 7%) ice-IX does 15% more damage new level element - toggle(x, y, isLockOn = false) similar to a button but doesn't require a block used on the level highrise can toggle "off and on" or "lock on" --- .DS_Store | Bin 6148 -> 6148 bytes js/bullet.js | 136 +++++++++++++++++++++++++++-------------- js/level.js | 155 +++++++++++++++++++++++++++++++++-------------- js/player.js | 60 ++++++++++-------- js/simulation.js | 1 + js/tech.js | 49 ++++++++++++--- todo.txt | 53 ++++++++++------ 7 files changed, 311 insertions(+), 143 deletions(-) diff --git a/.DS_Store b/.DS_Store index 46287fc1dca646a82d03f3619d13d5ca4036af16..2c19a3b443cf101dd6295747f8bb35f6b6a59f7a 100644 GIT binary patch delta 21 ccmZoMXffEJ#mp4XK3Rv^kFj8LHFKv307Gg8{Qv*} delta 21 ccmZoMXffEJ#mwY%eXfour balls in a wide arc
balls bounce with no momentum loss", ammo: 0, - ammoPack: 13, + ammoPack: 11, have: false, // num: 5, do() {}, - fire() { - const SPEED = m.crouch ? 43 : 32 + fireOne() { + const SPEED = m.crouch ? 43 : 36 m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 23 : 15) * b.fireCD); // cool down - if (tech.oneSuperBall) { - let dir = m.angle + let dir = m.angle + 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, 21 * tech.bulletSize, b.fireAttributes(dir, false)); + World.add(engine.world, bullet[me]); //add bullet to world + Matter.Body.setVelocity(bullet[me], { + x: SPEED * Math.cos(dir), + y: SPEED * Math.sin(dir) + }); + // Matter.Body.setDensity(bullet[me], 0.0001); + bullet[me].endCycle = simulation.cycle + Math.floor(300 + 90 * Math.random()); + bullet[me].minDmgSpeed = 0; + bullet[me].restitution = 1; + bullet[me].friction = 0; + bullet[me].do = function() { + this.force.y += this.mass * 0.0012; + }; + bullet[me].beforeDmg = function(who) { + mobs.statusStun(who, 180) // (2.3) * 2 / 14 ticks (2x damage over 7 seconds) + if (tech.isIncendiary) { + b.explosion(this.position, this.mass * 285); //makes bullet do explosive damage at end + this.endCycle = 0 + } + }; + }, + fireMulti() { + const SPEED = m.crouch ? 43 : 36 + m.fireCDcycle = m.cycle + Math.floor((m.crouch ? 23 : 15) * b.fireCD); // 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 me = bullet.length; - bullet[me] = Bodies.polygon(m.pos.x + 30 * Math.cos(m.angle), m.pos.y + 30 * Math.sin(m.angle), 12, 21 * tech.bulletSize, b.fireAttributes(dir, false)); + 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)); World.add(engine.world, bullet[me]); //add bullet to world Matter.Body.setVelocity(bullet[me], { x: SPEED * Math.cos(dir), y: SPEED * Math.sin(dir) }); // Matter.Body.setDensity(bullet[me], 0.0001); - bullet[me].endCycle = simulation.cycle + Math.floor(300 + 90 * Math.random()); + bullet[me].endCycle = simulation.cycle + Math.floor((300 + 90 * Math.random()) * tech.isBulletsLastLonger); bullet[me].minDmgSpeed = 0; - bullet[me].restitution = 1; + bullet[me].restitution = 0.99; bullet[me].friction = 0; bullet[me].do = function() { - this.force.y += this.mass * 0.0012; + this.force.y += this.mass * 0.001; }; - bullet[me].beforeDmg = function(who) { - mobs.statusStun(who, 180) // (2.3) * 2 / 14 ticks (2x damage over 7 seconds) + bullet[me].beforeDmg = function() { if (tech.isIncendiary) { - b.explosion(this.position, this.mass * 265); //makes bullet do explosive damage at end + b.explosion(this.position, this.mass * 350 + 60 * Math.random()); //makes bullet do explosive damage at end this.endCycle = 0 } }; - } else { - b.muzzleFlash(20); - const SPREAD = m.crouch ? 0.08 : 0.15 - let dir = m.angle - SPREAD * (tech.superBallNumber - 1) / 2; - for (let i = 0; i < tech.superBallNumber; 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, 9 * tech.bulletSize, b.fireAttributes(dir, false)); - World.add(engine.world, bullet[me]); //add bullet to world - Matter.Body.setVelocity(bullet[me], { - x: SPEED * Math.cos(dir), - y: SPEED * Math.sin(dir) - }); - // Matter.Body.setDensity(bullet[me], 0.0001); - bullet[me].endCycle = simulation.cycle + Math.floor((300 + 90 * Math.random()) * tech.isBulletsLastLonger); - bullet[me].minDmgSpeed = 0; - bullet[me].restitution = 0.99; - bullet[me].friction = 0; - bullet[me].do = function() { - this.force.y += this.mass * 0.001; - }; - bullet[me].beforeDmg = function() { - if (tech.isIncendiary) { - b.explosion(this.position, this.mass * 330 + 60 * Math.random()); //makes bullet do explosive damage at end - this.endCycle = 0 - } - }; - dir += SPREAD; - } + dir += SPREAD; } - } + }, + fireQueue() { + const SPEED = m.crouch ? 43 : 36 + const dir = m.angle + const x = m.pos.x + 30 * Math.cos(m.angle) + const y = m.pos.y + 30 * Math.sin(m.angle) + const delay = Math.floor((m.crouch ? 18 : 12) * b.fireCD) + m.fireCDcycle = m.cycle + delay; // cool down + + for (let i = 0; i < tech.superBallNumber; i++) { + setTimeout(() => { + if (!simulation.paused) { + const me = bullet.length; + bullet[me] = Bodies.polygon(x, y, 12, 11 * tech.bulletSize, b.fireAttributes(dir, false)); + World.add(engine.world, bullet[me]); //add bullet to world + Matter.Body.setVelocity(bullet[me], { + x: SPEED * Math.cos(dir), + y: SPEED * Math.sin(dir) + }); + bullet[me].endCycle = simulation.cycle + Math.floor(330 * tech.isBulletsLastLonger); + bullet[me].minDmgSpeed = 0; + bullet[me].restitution = 0.99; + bullet[me].friction = 0; + bullet[me].do = function() { + this.force.y += this.mass * 0.001; + }; + bullet[me].beforeDmg = function() { + if (tech.isIncendiary) { + b.explosion(this.position, this.mass * 350 + 60 * Math.random()); //makes bullet do explosive damage at end + this.endCycle = 0 + } + }; + m.fireCDcycle = m.cycle + delay; // cool down + } + }, 50 * i + 100); + } + }, + chooseFireMethod() { //set in simulation.startGame + if (tech.oneSuperBall) { + this.fire = this.fireOne + } else if (tech.superBallDelay) { + this.fire = this.fireQueue + } else { + this.fire = this.fireMulti + } + }, + fire() {} }, { name: "wave beam", description: "emit a wave packet of oscillating particles
that propagates through solids", diff --git a/js/level.js b/js/level.js index 7ff1993..d493762 100644 --- a/js/level.js +++ b/js/level.js @@ -15,21 +15,20 @@ const level = { // simulation.zoomScale = 1000; // simulation.setZoom(); // simulation.enableConstructMode() //used to build maps in testing mode - // m.setField("negative mass field") + // simulation.isHorizontalFlipped = true + // level.difficultyIncrease(30) + // m.setField("standing wave harmonics") + // tech.giveTech("spherical harmonics") // for (let i = 0; i < 9; i++) tech.giveTech("spherical harmonics") - // b.giveGuns("laser") + // b.giveGuns("super balls") // tech.isExplodeRadio = true // tech.giveTech("Z-pinch") // tech.giveTech("MACHO") - // tech.giveTech("potential well") + // tech.giveTech("supertemporal") // for (let i = 0; i < 3; i++) tech.giveTech("packet length") // for (let i = 0; i < 3; i++) tech.giveTech("propagation") // for (let i = 0; i < 3; i++) tech.giveTech("bound state") // for (let i = 0; i < 9; i++) tech.giveTech("WIMPs") - // tech.giveTech("attract") - // level.difficultyIncrease(30) - // simulation.isHorizontalFlipped = true - // tech.isFlyFaster = true level.intro(); //starting level // level.testing(); //not in rotation, used for testing @@ -42,8 +41,8 @@ const level = { // level.skyscrapers(); // level.aerie(); // level.rooftops(); - // level.warehouse(); - // level.highrise(); + // level.warehouse(); + // level.highrise(); // level.office(); // level.gauntlet(); //only fighting, very simple map, before final boss // level.house() //community level @@ -260,7 +259,7 @@ const level = { }, addToWorld() { //needs to be run to put bodies into the world for (let i = 0; i < body.length; i++) { - if (body[i] !== m.holdingTarget) { + if (body[i] !== m.holdingTarget && !body[i].isNoSetCollision) { body[i].collisionFilter.category = cat.body; body[i].collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet } @@ -548,6 +547,71 @@ const level = { composite[composite.length] = rotor return rotor }, + toggle(x, y, isLockOn = false) { + spawn.mapVertex(x + 65, y + 2, "70 10 -70 10 -40 -10 40 -10"); + map[map.length - 1].restitution = 0; + map[map.length - 1].friction = 1; + map[map.length - 1].frictionStatic = 1; + + spawn.bodyRect(x, y, 125, 15) //Portal platform + let flip = body[body.length - 1]; + flip.isNoSetCollision = true //prevents collision form being rewritten in level.addToWorld + flip.collisionFilter.category = cat.body + flip.collisionFilter.mask = cat.player | cat.body + + flip.isNotHoldable = true + flip.frictionAir = 0.01 + flip.restitution = 0 + Matter.Body.setDensity(flip, 0.003) + Matter.Body.setAngle(flip, (-0.25 - 0.5) * Math.PI) + setTimeout(function() {}, 100); + + cons[cons.length] = Constraint.create({ + pointA: { + x: x + 65, + y: y + }, + bodyB: flip, + stiffness: 1, + length: 0 + }); + World.add(engine.world, [cons[cons.length - 1]]); + + + return { + flip: flip, + isOn: false, + query() { + const limit = { + right: (-0.25 - 0.5) * Math.PI, + left: (0.25 - 0.5) * Math.PI + } + if (flip.angle < limit.right) { + Matter.Body.setAngle(flip, limit.right) + Matter.Body.setAngularVelocity(flip, 0); + if (!isLockOn) this.isOn = false + } else if (flip.angle > limit.left) { + Matter.Body.setAngle(flip, limit.left) + Matter.Body.setAngularVelocity(flip, 0); + this.isOn = true + } + + if (this.isOn) { + ctx.beginPath(); + ctx.moveTo(flip.vertices[0].x, flip.vertices[0].y); + for (let j = 1; j < flip.vertices.length; j++) { + ctx.lineTo(flip.vertices[j].x, flip.vertices[j].y); + } + ctx.lineTo(flip.vertices[0].x, flip.vertices[0].y); + ctx.fillStyle = "#3df" + ctx.fill(); + ctx.lineWidth = 1; + ctx.strokeStyle = simulation.draw.bodyStroke; + ctx.stroke(); + } + }, + } + }, button(x, y, width = 126) { spawn.mapVertex(x + 65, y + 2, "100 10 -100 10 -70 -10 70 -10"); map[map.length - 1].restitution = 0; @@ -1109,17 +1173,19 @@ const level = { spawn.mapRect(475, -25, 25, 50); //edge shelf }, testing() { - const button = level.button(200, -700) + // const button = level.button(200, -700) + const toggle = level.toggle(200, -700) level.custom = () => { - button.query(); - button.draw(); + // button.draw(); ctx.fillStyle = "rgba(0,255,255,0.1)"; ctx.fillRect(6400, -550, 300, 350); level.playerExitCheck(); level.exit.draw(); level.enter.draw(); }; - level.customTopLayer = () => {}; + level.customTopLayer = () => { + toggle.query(); + }; level.setPosToSpawn(0, -750); //normal spawn spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20); @@ -1171,7 +1237,7 @@ const level = { // spawn.grower(1900, -500) // spawn.pulsarBoss(1900, -500) // spawn.shooterBoss(1900, -500) - spawn.historyBoss(1200, -500) + // spawn.historyBoss(1200, -500) // spawn.laserTargetingBoss(1600, -400) // spawn.striker(1600, -500) // spawn.laserTargetingBoss(1700, -120) @@ -2018,7 +2084,7 @@ const level = { level.enter.draw(); }; level.customTopLayer = () => { - ctx.fillStyle = "rgba(0,20,40,0.2)" + ctx.fillStyle = "rgba(0,20,40,0.25)" ctx.fillRect(-250, -400, 1800, 775) ctx.fillRect(1800, -275, 850, 775) ctx.fillRect(5200, 125, 450, 200) @@ -2073,18 +2139,18 @@ const level = { //tall platform spawn.mapVertex(1125, -450, "325 0 250 80 -250 80 -325 0 -250 -80 250 -80"); //base - spawn.mapRect(150, -500, 1400, 100); //far left starting ceiling + spawn.mapRect(150, -500, 1410, 100); //far left starting ceiling spawn.mapRect(625, -2450, 1000, 50); //super high shade spawn.bodyRect(1300, -3600, 150, 150); //shield from laser //tall platform spawn.mapVertex(2225, -250, "325 0 250 80 -250 80 -325 0 -250 -80 250 -80"); //base spawn.mapRect(1725, -2800, 1000, 50); //super high shade - spawn.mapRect(1800, -300, 850, 100); //far left starting ceiling + spawn.mapRect(1790, -300, 870, 100); //far left starting ceiling spawn.bodyRect(2400, -2950, 150, 150); //shield from laser //tall platform - spawn.mapVertex(3350, 200, "400 0 -400 0 -275 -275 275 -275"); //base - spawn.bodyRect(3400, -150, 150, 150); + spawn.mapVertex(3350, 175, "425 0 -425 0 -275 -300 275 -300"); //base + spawn.bodyRect(3350, -150, 200, 120); spawn.mapRect(2850, -3150, 1000, 50); //super high shade spawn.bodyRect(3675, -3470, 525, 20); //plank spawn.bodyRect(3600, -3450, 200, 300); //plank support block @@ -2165,7 +2231,7 @@ const level = { }; level.customTopLayer = () => { elevator.move() - ctx.fillStyle = "rgba(0,20,40,0.2)" + ctx.fillStyle = "rgba(0,20,40,0.25)" ctx.fillRect(250 - 1800, -400, 1800, 775) ctx.fillRect(-1800 - 850, -275, 850, 775) ctx.fillRect(-5200 - 450, 125, 450, 200) @@ -2738,10 +2804,14 @@ const level = { highrise() { const elevator1 = level.elevator(-790, -190, 180, 25, -1150) //, 0.007 elevator1.addConstraint(); - const button1 = level.button(-500, -200) + // const button1 = level.button(-500, -200) + const toggle1 = level.toggle(-500, -200) //(x,y,isLockOn = true/false) + const elevator2 = level.elevator(-3630, -1000, 180, 25, -1740) //, 0.007 elevator2.addConstraint(); - const button2 = level.button(-3100, -1330) + // const button2 = level.button(-3100, -1330) + const toggle2 = level.toggle(-3100, -1330) //(x,y,isLockOn = true/false) + level.custom = () => { // ctx.fillStyle = "#d0d0d2" @@ -2755,9 +2825,9 @@ const level = { level.enter.draw(); }; level.customTopLayer = () => { - button1.query(); - button1.draw(); - if (button1.isUp) { + // button1.draw(); + toggle1.query(); + if (!toggle1.isOn) { if (elevator1.isOn) { elevator1.isOn = false elevator1.frictionAir = 0.2 @@ -2778,9 +2848,9 @@ const level = { ctx.fillRect(-700, -1140, 1, 975) } - button2.query(); - button2.draw(); - if (button2.isUp) { + toggle2.query(); + // button2.draw(); + if (!toggle2.isOn) { if (elevator2.isOn) { elevator2.isOn = false elevator2.frictionAir = 0.2 @@ -2874,7 +2944,7 @@ const level = { spawn.mapRect(-4450, -600, 2300, 750); spawn.mapRect(-2225, -450, 175, 550); // spawn.mapRect(-2600, -975, 450, 50); - spawn.mapRect(-3425, -1325, 525, 50); + spawn.mapRect(-3425, -1325, 525, 75); spawn.mapRect(-3425, -2200, 525, 50); spawn.mapRect(-2600, -1700, 450, 50); // spawn.mapRect(-2600, -2450, 450, 50); @@ -2944,17 +3014,12 @@ const level = { // boost1.boostBounds.max.x = -boost1.boostBounds.max.x + 100 level.setPosToSpawn(300, -700); //-x elevator1.holdX = -elevator1.holdX // flip the elevator horizontally - elevator2.removeConstraint(); - elevator2.addConstraint(); + elevator1.removeConstraint(); + elevator1.addConstraint(); elevator2.holdX = -elevator2.holdX // flip the elevator horizontally elevator2.removeConstraint(); elevator2.addConstraint(); - button1.min.x = -button1.min.x - 126 // flip the button horizontally - button1.max.x = -button1.max.x + 126 // flip the button horizontally - button2.min.x = -button2.min.x - 126 // flip the button horizontally - button2.max.x = -button2.max.x + 126 // flip the button horizontally - level.custom = () => { ctx.fillStyle = "#cff" //exit ctx.fillRect(4425 - 425, -3050, 425, 275) @@ -2963,9 +3028,8 @@ const level = { level.enter.draw(); }; level.customTopLayer = () => { - button1.query(); - button1.draw(); - if (button1.isUp) { + toggle1.query(); + if (!toggle1.isOn) { if (elevator1.isOn) { elevator1.isOn = false elevator1.frictionAir = 0.2 @@ -2986,9 +3050,8 @@ const level = { ctx.fillRect(700 - 1, -1140, 1, 975) } - button2.query(); - button2.draw(); - if (button2.isUp) { + toggle2.query(); + if (!toggle2.isOn) { if (elevator2.isOn) { elevator2.isOn = false elevator2.frictionAir = 0.2 @@ -3038,7 +3101,7 @@ const level = { }; level.customTopLayer = () => { - ctx.fillStyle = "rgba(0,0,0,0.1)"; //shadows and lights + ctx.fillStyle = "rgba(0,0,0,0.15)"; //shadows and lights ctx.beginPath() ctx.moveTo(-1800, -500) ctx.lineTo(-910, -500) //3rd floor light @@ -3125,7 +3188,7 @@ const level = { isElevators = true elevator1 = level.elevator(-1780, 500, 260, 40, 7, 0.0003) elevator2 = level.elevator(820, 1300, 260, 40, 607, 0.0003) - elevator3 = level.elevator(-2755, 1260, 160, 40, 1000, 0.006) + elevator3 = level.elevator(-2755, 1260, 160, 40, 850, 0.003) spawn.bodyRect(-2375, 1300, 100, 100); spawn.bodyRect(-2325, 1250, 50, 50); spawn.bodyRect(-2275, 1350, 125, 50); @@ -3291,7 +3354,7 @@ const level = { }; } level.customTopLayer = () => { - ctx.fillStyle = "rgba(0,0,0,0.1)"; //shadows and lights + ctx.fillStyle = "rgba(0,0,0,0.15)"; //shadows and lights ctx.beginPath() ctx.moveTo(1800, -500) ctx.lineTo(910, -500) //3rd floor light diff --git a/js/player.js b/js/player.js index b3d1dcb..f29205c 100644 --- a/js/player.js +++ b/js/player.js @@ -1276,11 +1276,7 @@ const m = { } } }, - pushMass(who) { - const speed = Vector.magnitude(Vector.sub(who.velocity, player.velocity)) - const fieldBlockCost = (0.025 + Math.sqrt(who.mass) * speed * 0.002) * m.fieldShieldingScale; - const unit = Vector.normalise(Vector.sub(player.position, who.position)) - + pushMass(who, fieldBlockCost = (0.025 + Math.sqrt(who.mass) * Vector.magnitude(Vector.sub(who.velocity, player.velocity)) * 0.002) * m.fieldShieldingScale) { if (m.energy > fieldBlockCost * 0.2) { //shield needs at least some of the cost to block m.energy -= fieldBlockCost if (m.energy < 0) m.energy = 0; @@ -1292,6 +1288,7 @@ const m = { for (let i = 0; i < tech.blockingIce; i++) b.iceIX(10, m.angle + Math.random() - 0.5, m.pos) } } + const unit = Vector.normalise(Vector.sub(player.position, who.position)) if (tech.blockDmg) { who.damage(tech.blockDmg * b.dmgScale) //draw electricity @@ -1364,15 +1361,6 @@ 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 - mob[i].locatePlayer(); - m.pushMass(mob[i]); - } - } - }, lookForPickUp() { //find body to pickup if (m.energy > m.fieldRegen) m.energy -= m.fieldRegen; const grabbing = { @@ -1505,15 +1493,14 @@ const m = { }, { name: "standing wave harmonics", - description: "3 oscillating shields are permanently active
deflecting drains energy with no cool down
deflecting has 50% less recoil", //harm and + description: "3 oscillating shields are permanently active
deflecting protects you in every direction
deflecting has 50% less recoil", //drains energy + drainCD: 0, effect: () => { - // m.fieldHarmReduction = 0.80; m.fieldBlockCD = 0; - // m.fieldHarmReduction = 0.75; m.blockingRecoil = 2 //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.fieldShieldingScale = 1.3 * Math.pow(0.6, (tech.harmonics - 2)) + m.harmonic3Phase = () => { //normal standard 3 different 2-d circles 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 @@ -1529,12 +1516,24 @@ const m = { ctx.beginPath(); ctx.arc(m.pos.x, m.pos.y, fieldRange3, 0, 2 * Math.PI); ctx.fill(); - m.pushMobs360(netfieldRange); + //360 block + for (let i = 0, len = mob.length; i < len; ++i) { + if (Vector.magnitude(Vector.sub(mob[i].position, m.pos)) - mob[i].radius < netfieldRange && !mob[i].isShielded) { // && Matter.Query.ray(map, mob[i].position, m.pos).length === 0 + mob[i].locatePlayer(); + if (this.drainCD > m.cycle) { + m.pushMass(mob[i], 0); + } else { + m.pushMass(mob[i]); + this.drainCD = m.cycle + 10 + } + } + } } + m.harmonicRadius = 1 //for smoothing function when player holds mouse (for harmonicAtomic) m.harmonicAtomic = () => { //several ellipses spinning about different axises const rotation = simulation.cycle * 0.002 const phase = simulation.cycle * 0.03 - const radius = m.fieldRange * m.harmonicRadius //+ 20 * Math.sin(m.cycle * 0.05) + const radius = m.fieldRange * m.harmonicRadius ctx.lineWidth = 1; ctx.strokeStyle = "rgba(110,170,200,0.9)" ctx.fillStyle = "rgba(110,170,200," + Math.min(0.7, m.energy * (0.13 + 0.15 * Math.random()) * (3 / tech.harmonics)) + ")"; @@ -1545,7 +1544,18 @@ const m = { ctx.fill(); ctx.stroke(); } - m.pushMobs360(radius); + //360 block + for (let i = 0, len = mob.length; i < len; ++i) { + if (Vector.magnitude(Vector.sub(mob[i].position, m.pos)) - mob[i].radius < radius && !mob[i].isShielded) { // && Matter.Query.ray(map, mob[i].position, m.pos).length === 0 + mob[i].locatePlayer(); + if (this.drainCD > m.cycle) { + m.pushMass(mob[i], 0); + } else { + m.pushMass(mob[i]); + this.drainCD = m.cycle + 10 + } + } + } } if (tech.harmonics === 2) { m.harmonicShield = m.harmonic3Phase @@ -1577,8 +1587,6 @@ const m = { } m.harmonicShield() } - - m.drawFieldMeter() } } @@ -2479,9 +2487,9 @@ const m = { }, { name: "wormhole", - description: "use energy to tunnel through a wormhole
wormholes attract blocks and power ups
7% chance to duplicate spawned power ups", //
bullets may also traverse wormholes + description: "use energy to tunnel through a wormhole
wormholes attract blocks and power ups
10% chance to duplicate spawned power ups", //
bullets may also traverse wormholes effect: function() { - m.duplicateChance = 0.07 + m.duplicateChance = 0.1 powerUps.setDo(); //needed after adjusting duplication chance m.hold = function() { diff --git a/js/simulation.js b/js/simulation.js index 8e6a2b6..df04f95 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -540,6 +540,7 @@ const simulation = { for (i = 0, len = b.guns.length; i < len; i++) { //find which gun if (b.guns[i].name === "laser") b.guns[i].chooseFireMethod() if (b.guns[i].name === "nail gun") b.guns[i].chooseFireMethod() + if (b.guns[i].name === "super balls") b.guns[i].chooseFireMethod() } tech.dynamoBotCount = 0; tech.nailBotCount = 0; diff --git a/js/tech.js b/js/tech.js index c13b58a..8d6773c 100644 --- a/js/tech.js +++ b/js/tech.js @@ -3643,7 +3643,33 @@ tech.superBallNumber++ }, remove() { - tech.superBallNumber = 4; + tech.superBallNumber = 3; + } + }, + { + name: "supertemporal", + description: "fire super ball from the same point in space
but separated by 0.1 seconds in time", + isGunTech: true, + maxCount: 1, + count: 0, + frequency: 2, + allowed() { + return tech.haveGunCheck("super balls") && !tech.oneSuperBall + }, + requires: "super balls, but not the tech super ball or super duper", + effect() { + tech.superBallDelay = true + for (i = 0, len = b.guns.length; i < len; i++) { //find which gun + if (b.guns[i].name === "super balls") b.guns[i].chooseFireMethod() + } + }, + remove() { + if (tech.superBallDelay) { + tech.superBallDelay = false; + for (i = 0, len = b.guns.length; i < len; i++) { //find which gun + if (b.guns[i].name === "super balls") b.guns[i].chooseFireMethod() + } + } } }, { @@ -3654,14 +3680,22 @@ count: 0, frequency: 2, allowed() { - return tech.haveGunCheck("super balls") && tech.superBallNumber === 4 + return tech.haveGunCheck("super balls") && tech.superBallNumber === 3 && !tech.superBallDelay }, - requires: "super balls, but not super duper", + requires: "super balls, but not super duper or super queue", effect() { tech.oneSuperBall = true; + for (i = 0, len = b.guns.length; i < len; i++) { //find which gun + if (b.guns[i].name === "super balls") b.guns[i].chooseFireMethod() + } }, remove() { - tech.oneSuperBall = false; + if (tech.oneSuperBall) { + tech.oneSuperBall = false; + for (i = 0, len = b.guns.length; i < len; i++) { //find which gun + if (b.guns[i].name === "super balls") b.guns[i].chooseFireMethod() + } + } } }, { @@ -4559,12 +4593,12 @@ requires: "standing wave harmonics", effect() { tech.harmonics++ - m.fieldShieldingScale = Math.pow(0.6, (tech.harmonics - 2)) + m.fieldShieldingScale = 1.3 * Math.pow(0.6, (tech.harmonics - 2)) m.harmonicShield = m.harmonicAtomic }, remove() { tech.harmonics = 2 - m.fieldShieldingScale = Math.pow(0.6, (tech.harmonics - 2)) + m.fieldShieldingScale = 1.3 * Math.pow(0.6, (tech.harmonics - 2)) m.harmonicShield = m.harmonic3Phase } }, @@ -6893,5 +6927,6 @@ isFallingDamage: null, harmonics: null, isStandingWaveExpand: null, - isBlockExplosion: null + isBlockExplosion: null, + superBallDelay: null } \ No newline at end of file diff --git a/todo.txt b/todo.txt index e0cec0b..fd05420 100644 --- a/todo.txt +++ b/todo.txt @@ -1,24 +1,28 @@ ******************************************************** NEXT PATCH ******************************************************** +tech supertemporal - fire your super balls at the same place in space, but delayed in time -tech: WIMPs now requires wormhole - gives 3-9 research now (was 2-3) +super ball starts with 3 not 4 balls, but they are is 25% larger, 10% faster, and 25% lower divergence + (this makes adding more balls much stronger) +gun - super balls has 15% less ammo -tech: eddy current brake - is 15% larger and caps mob speeds at 20% slower +standing wave harmonics - still has no block cooldown, but now it has a cooldown for how often it can drain energy + this should make rapidly blocking drain upto 10x less energy + base blocking cost have increased by 25% + +wormhole gets 10% duplication (was 7%) +ice-IX does 15% more damage + +new level element - toggle(x, y, isLockOn = false) + similar to a button but doesn't require a block + used on the level highrise + can toggle "off and on" or "lock on" -bug fixes ******************************************************** BUGS ******************************************************** -sharing 1 stack of spherical harmonics doesn't activate visually -https://landgreen.github.io/sidescroller/index.html?&tech0=crystallizer&tech1=thermoelectric%20effect&tech2=thermoelectric%20effect&tech3=spherical%20harmonics&tech4=expansion&tech5=triple%20point&tech6=triple%20point&tech7=flux%20pinning&field=standing%20wave%20harmonics&difficulty=4&level=0&noPower=0 - 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 - Why does micro-extruder lag so much blue triangle boss can move backwards and aim away from you if set up properly @@ -45,28 +49,39 @@ labs - procedural generation 1500px, 3000px per room room types entrance - no mobs, starting power ups` - exit - plenty of mobs + exit - possible duplication boss spawn location up, down - 2 paired rooms - boost, elevator, portal boss - standard random boss spawns - empty - just a dead end - possible duplication boss spawn location - button - opens door to exit room + empty - a dead end + button - like empty, but also has a switch that opens door to exit room room ideas - - gravity room + low gravity room, controlled with a button? portal room endlessly falling blocks down a slide, that the player has to climb up portal + rotor + falling blocks = perpetual motion laser room slime radiation room + spinner room + +make a switch level element + basically button, but go off and on when it hits player (or block?) + use a constrained body like a spinner + use offset constraint? like in vats + can this work? + check location of center of mass for on/off state + only collide with player, but run code that stops it from rotating too far + part of it is inside switch map element + player moving left go on, right go off as if they are pushing the switch in that direction ? + indicate on/off + angle of stick "light-switch" + with colors? ******************************************************** TODO ******************************************************** standing wave harmonics - can block too often on the same mob if you push it into a corner - add a small cooldown - return to normal knock back // 4 + add a cool down that only stops energy drain and iceIX, but still lets you block let standing wave harmonics get tech decorrelation -* inductive coupling - sucks without catabolism, too much delayed gratification. should probably be bundled with transceiver chip - tech: cloaking field - decrease/increase cooldown on sneak attack? decrease/increase damage bonus? decrease/increase visual radius?