diff --git a/js/level.js b/js/level.js index 67d8451..5fac585 100644 --- a/js/level.js +++ b/js/level.js @@ -9,7 +9,7 @@ const level = { levelsCleared: 0, //see level.populateLevels: (intro, ... , reservoir, reactor, ... , gauntlet, final) added later playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber", "pavilion"], - communityLevels: ["stronghold", "basement", "crossfire", "vats", "run", "n-gon", "house", "perplex", "coliseum", "tunnel"], + communityLevels: ["stronghold", "basement", "crossfire", "vats", "run", "n-gon", "house", "perplex", "coliseum", "tunnel", "islands"], trainingLevels: ["walk", "crouch", "jump", "hold", "throw", "throwAt", "deflect", "heal", "fire", "nailGun", "shotGun", "superBall", "matterWave", "missile", "stack", "mine", "grenades", "harpoon"], levels: [], start() { @@ -20,7 +20,7 @@ const level = { // tech.giveTech("grappling hook") // tech.giveTech("capacitor bank") // for (let i = 0; i < 2; i++) powerUps.directSpawn(0, 0, "tech"); - // for (let i = 0; i < 9; i++) tech.giveTech("dynamo-bot") + // for (let i = 0; i < 9; i++) tech.giveTech("overcharge") // for (let i = 10; i < tech.tech.length; i++) { tech.tech[i].isBanished = true } // powerUps.research.changeRerolls(100000) // for (let i = 0; i < 2; i++) tech.giveTech("undefined") @@ -31,7 +31,7 @@ const level = { // m.immuneCycle = Infinity //you can't take damage // level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why // simulation.enableConstructMode() //used to build maps in testing mode - // level.reactor(); + // level.islands(); // level.testing(); //not in rotation, used for testing if (simulation.isTraining) { level.walk(); } else { level.intro(); } //normal starting level ************************************************ // powerUps.research.changeRerolls(3000) @@ -113,7 +113,7 @@ const level = { for (let i = 0; i < 2; i++) powerUps.spawn(level.exit.x + 10 * (Math.random() - 0.5), level.exit.y - 100 + 10 * (Math.random() - 0.5), "tech", false) //exit // for (let i = 0; i < 2; i++) powerUps.spawn(player.position.x + 90 * (Math.random() - 0.5), player.position.y + 90 * (Math.random() - 0.5), "tech", false); //start } - if (m.plasmaBall) m.plasmaBall.isOn = false + if (m.plasmaBall) this.reset() }, trainingText(say) { simulation.lastLogTime = 0; //clear previous messages @@ -2544,8 +2544,8 @@ const level = { level.difficultyIncrease(15) //30 is near max on hard //60 is near max on why m.addHealth(Infinity) - spawn.starter(1900, -500, 200) //big boy - // for (let i = 0; i < 10; ++i) spawn.launcher(1900, -500) + // spawn.starter(1900, -500, 200) //big boy + for (let i = 0; i < 10; ++i) spawn.launcher(1900, -500) // spawn.slashBoss(1900, -500) // spawn.launcherBoss(3200, -500) // spawn.laserTargetingBoss(1700, -500) @@ -8932,6 +8932,350 @@ const level = { initialSpawn == true; } }, + islands() { + const boost1 = level.boost(58500, -18264, 1300); + let portal2, portal3; + // const removeIndex1 = map.length - 1; + const drip1 = level.drip(59300, -18975, -18250, 100); // drip(x, yMin, yMax, period = 100, color = "hsla(160, 100%, 35%, 0.5)") { + const drip2 = level.drip(60000, -18953, -18250, 150); + const drip3 = level.drip(60905, -18652, -18250, 70); + const slimePit1 = level.hazard(58850, -18300, 2275, 100, 0.01); //hazard(x, y, width, height, damage = 0.003) spawn.mapRect(58850, -18300, 2275, 100); + const slimePit2 = level.hazard(74400, -18075, 350, 100, 0.01); + let isSpawnedBoss = false; + level.custom = () => { + level.exit.drawAndCheck(); + boost1.query(); + level.enter.draw(); + drip1.draw(); + drip2.draw(); + drip3.draw(); + // portal[2].query(); + // portal[3].query(); + // portal[0].draw(); + // portal[1].draw(); + // portal[2].draw(); + // portal[3].draw(); + portal2[2].query(); + portal2[3].query(); + portal2[0].draw(); + portal2[1].draw(); + portal2[2].draw(); + portal2[3].draw(); + portal3[2].query(); + portal3[3].query(); + portal3[0].draw(); + portal3[1].draw(); + portal3[2].draw(); + portal3[3].draw(); + }; + level.customTopLayer = () => { + slimePit1.query(); + slimePit2.query(); + ctx.fillStyle = `rgba(68, 68, 68, ${Math.max(0.3,Math.min((-17650 - m.pos.y) / 100, 0.99))})`; + ctx.fillRect(58390, -17655, 1490, 740); + }; + level.setPosToSpawn(57680, -18330); + level.exit.x = 76343; + level.exit.y = -18020; + spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 30); + spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 30); + level.defaultZoom = 2000; + simulation.zoomTransition(level.defaultZoom); + document.body.style.backgroundColor = "#00000"; + // spawn.setSpawnList = [ + // "hopper", + // "slasher", + // "striker", + // "stabber", + // "springer", + // "pulsar", + // "sneaker", + // "spinner", + // "grower", + // "focuser", + // "spawner", + // ]; + spawn.mapRect(57800, -18550, 50, 100); + spawn.mapRect(57500, -18550, 50, 275); + spawn.mapRect(66900, -18675, 300, 200); + spawn.mapRect(66925, -19050, 125, 225); + spawn.mapRect(67825, -16975, 125, 100); + spawn.mapRect(74900, -18075, 225, 100); + spawn.mapRect(73925, -18225, 150, 275); + spawn.mapRect(76200, -18325, 50, 125); + spawn.mapRect(76525, -18325, 75, 400); + spawn.mapRect(61325, -18350, 50, 25); + spawn.mapRect(61450, -18425, 50, 25); + spawn.mapRect(61475, -18450, 25, 25); + spawn.mapRect(58725, -18350, 125, 50); + spawn.mapRect(58675, -18275, 50, 75); + spawn.mapRect(58600, -18275, 75, 75); + spawn.mapRect(58675, -18325, 50, 50); + spawn.mapRect(58250, -16925, 1825, 1050); + spawn.mapRect(57500, -18200, 4475, 550); + spawn.mapRect(61500, -18475, 475, 275); + spawn.mapRect(62175, -18575, 325, 400); + spawn.mapRect(62900, -18850, 525, 375); + spawn.mapRect(63900, -18925, 450, 400); + spawn.mapRect(64725, -19000, 625, 500); + spawn.mapRect(65825, -19050, 675, 400); + spawn.mapRect(66800, -18950, 400, 400); + spawn.mapRect(68775, -18850, 525, 400); + spawn.mapRect(67375, -16900, 1800, 1450); + spawn.mapRect(67375, -17475, 325, 575); + spawn.mapRect(68900, -17500, 250, 500); + spawn.mapRect(69425, -17050, 500, 475); + spawn.mapRect(70400, -17150, 425, 175); + spawn.mapRect(71175, -17325, 450, 325); + spawn.mapRect(72000, -17425, 325, 300); + spawn.mapRect(72725, -17450, 350, 275); + spawn.mapRect(70050, -18800, 550, 350); + spawn.mapRect(67750, -19400, 375, 1200); + spawn.mapRect(67750, -18200, 1425, 700); + spawn.mapRect(66800, -18550, 575, 1650); + spawn.mapRect(66800, -16900, 575, 1450); + spawn.mapRect(67350, -18175, 250, 750); + spawn.mapRect(71050, -18450, 725, 275); + spawn.mapRect(72100, -18150, 475, 200); + spawn.mapRect(73325, -17975, 3275, 475); + spawn.mapRect(73175, -17775, 150, 300); + spawn.mapRect(72975, -17675, 225, 250); + spawn.mapRect(76200, -18325, 400, 75); + spawn.mapRect(76525, -18250, 75, 275); + spawn.mapRect(76200, -18250, 50, 50); + spawn.mapRect(57500, -17675, 900, 1800); + spawn.mapRect(59875, -17675, 1975, 1800); + spawn.mapRect(57550, -18275, 225, 75); + spawn.mapRect(61375, -18375, 50, 50); + spawn.mapRect(61100, -18350, 75, 50); + spawn.mapRect(61175, -18325, 50, 25); + spawn.mapRect(61850, -16525, 250, 175); + spawn.mapRect(57500, -18500, 50, 325); + spawn.mapRect(57500, -18550, 350, 50); + spawn.mapRect(57800, -18500, 50, 50); + spawn.mapRect(61275, -18325, 375, 125); + spawn.mapRect(61425, -18400, 200, 75); + spawn.mapRect(62125, -18575, 125, 75); + spawn.mapRect(62250, -18200, 175, 125); + spawn.mapRect(62850, -18725, 100, 75); + spawn.mapRect(63075, -18550, 225, 225); + spawn.mapRect(62800, -18275, 75, 75); + spawn.mapRect(62500, -18475, 75, 50); + spawn.mapRect(63825, -18900, 150, 50); + spawn.mapRect(63950, -18575, 150, 125); + spawn.mapRect(64200, -18550, 100, 250); + spawn.mapRect(64925, -18525, 200, 275); + spawn.mapRect(64625, -18425, 75, 125); + spawn.mapRect(65225, -18675, 150, 175); + spawn.mapRect(65350, -18950, 75, 100); + spawn.mapRect(65950, -18575, 75, 150); + spawn.mapRect(66000, -18725, 225, 175); + spawn.mapRect(66275, -18675, 75, 125); + spawn.mapRect(66275, -18550, 75, 75); + spawn.mapRect(66150, -18550, 100, 50); + spawn.mapRect(66225, -18875, 25, 150); + spawn.mapRect(66200, -18750, 75, 25); + spawn.mapRect(66925, -19100, 125, 150); + spawn.mapRect(66000, -19100, 75, 50); + spawn.mapRect(65000, -19075, 100, 75); + spawn.mapRect(66750, -18625, 100, 100); + spawn.mapRect(68050, -18500, 350, 350); + spawn.mapRect(68125, -18975, 150, 475); + spawn.mapRect(69850, -18675, 150, 200); + spawn.mapRect(70000, -18625, 150, 50); + spawn.mapRect(68850, -18575, 325, 225); + spawn.mapRect(69100, -18400, 75, 100); + spawn.mapRect(70150, -18525, 125, 200); + spawn.mapRect(70425, -18525, 125, 200); + spawn.mapRect(70250, -18350, 175, 225); + spawn.mapRect(70325, -18475, 50, 150); + spawn.mapRect(70275, -18450, 150, 150); + spawn.mapRect(71175, -18250, 525, 250); + spawn.mapRect(71050, -18200, 150, 375); + spawn.mapRect(70925, -18300, 200, 250); + spawn.mapRect(71425, -18525, 175, 150); + spawn.mapRect(70225, -18950, 275, 250); + spawn.mapRect(70475, -17050, 225, 175); + spawn.mapRect(70625, -17250, 100, 150); + spawn.mapRect(71300, -17150, 200, 350); + spawn.mapRect(71100, -17250, 125, 100); + spawn.mapRect(71550, -17400, 150, 150); + spawn.mapRect(67675, -17150, 225, 300); + spawn.mapRect(68225, -17000, 100, 125); + spawn.mapRect(67900, -16975, 375, 100); + spawn.mapRect(68275, -16950, 150, 50); + spawn.bodyRect(76200, -18200, 50, 200); + spawn.mapRect(76200, -18000, 50, 25); + spawn.bodyRect(57800, -18450, 50, 175); + spawn.mapRect(68725, -17600, 300, 250); + spawn.mapRect(68625, -17550, 175, 100); + spawn.mapRect(68850, -17400, 150, 125); + spawn.mapRect(69325, -16900, 200, 225); + spawn.mapRect(69575, -16625, 175, 275); + spawn.mapRect(69850, -16875, 250, 200); + spawn.mapRect(69875, -16650, 150, 300); + spawn.mapRect(69825, -16800, 375, 325); + spawn.mapRect(69650, -16775, 325, 475); + spawn.mapRect(71975, -17325, 100, 125); + spawn.mapRect(72075, -17200, 150, 150); + spawn.mapRect(72275, -17350, 150, 150); + spawn.mapRect(72325, -17275, 150, 225); + spawn.mapRect(72225, -18050, 200, 225); + spawn.mapRect(71925, -18150, 250, 175); + spawn.mapRect(72075, -18275, 125, 175); + spawn.mapRect(72500, -18025, 125, 175); + spawn.mapRect(72400, -17975, 150, 175); + spawn.mapRect(73925, -18225, 350, 275); + spawn.mapRect(74750, -18125, 275, 175); + spawn.mapRect(74250, -18100, 150, 75); + spawn.mapRect(74275, -18050, 200, 75); + spawn.mapRect(73750, -18100, 275, 125); + spawn.mapRect(73075, -17475, 3525, 300); + spawn.mapRect(73275, -17600, 3325, 225); + spawn.mapRect(57775, -18250, 150, 50); + spawn.mapRect(57775, -18275, 75, 25); + spawn.mapRect(57925, -18225, 50, 25); + spawn.debris(68300, -17000, 3700, 16); + spawn.mapRect(62000, -16525, 100, 200); + spawn.mapRect(59125, -19125, 325, 200); + spawn.mapRect(59925, -19175, 350, 225); + spawn.mapRect(60800, -18850, 275, 200); + spawn.mapRect(75025, -18075, 200, 100); + spawn.mapRect(75225, -18025, 100, 50); + spawn.bodyRect(74300, -18150, 50, 25); + spawn.bodyRect(73850, -18150, 75, 75); + spawn.bodyRect(74700, -18000, 75, 50); + spawn.bodyRect(74250, -18325, 25, 25); + spawn.bodyRect(74275, -18325, 25, 25); + spawn.bodyRect(74275, -18325, 25, 25); + spawn.bodyRect(74300, -18325, 100, 25); + // portal = level.portal( + // { + // x: 58625, + // y: -16925, + // }, + // 1.5 * Math.PI, + // { + // //right + // x: 58625, + // y: -17650, + // }, + // 2.5 * Math.PI + // ); //right + portal2 = level.portal({ + x: 61920, + y: -16525, + }, + 1.5 * Math.PI, { + //right + x: 58400, + y: -17325, + }, + 2 * Math.PI + ); + portal3 = level.portal({ + x: 59865, + y: -17300, + }, + 3 * Math.PI, { + //right + x: 60820, + y: -31130, + }, + 2.5 * Math.PI + ); + + spawn.mapRect(60275, -32250, 975, 400); + spawn.mapRect(60375, -31925, 275, 225); + spawn.mapRect(61025, -31950, 175, 300); + spawn.mapRect(60825, -31725, 100, 350); + spawn.mapRect(60675, -31875, 200, 225); + spawn.mapRect(60225, -31950, 100, 725); + spawn.mapRect(60250, -31525, 250, 375); + spawn.mapRect(60675, -31475, 425, 350); + spawn.mapRect(60625, -32500, 225, 300); + spawn.mapRect(61025, -32325, 125, 175); + spawn.mapRect(60375, -32325, 175, 150); + spawn.mapRect(60250, -19075, 100, 100); + spawn.randomMob(59850, -18825, Infinity); + spawn.randomMob(62325, -18800, Infinity); + spawn.randomMob(61725, -18800, Infinity); + spawn.randomMob(63050, -19025, Infinity); + spawn.randomMob(64100, -19200, Infinity); + spawn.randomMob(64225, -19100, Infinity); + spawn.randomMob(64875, -19300, Infinity); + spawn.randomMob(65125, -19325, Infinity); + spawn.randomMob(65850, -19275, Infinity); + spawn.randomMob(66200, -19300, Infinity); + spawn.randomMob(65975, -19425, Infinity); + spawn.randomMob(67925, -19600, Infinity); + spawn.randomMob(66975, -19275, Infinity); + spawn.randomMob(67550, -18750, Infinity); + spawn.randomMob(69625, -17275, Infinity); + spawn.randomMob(70550, -17350, Infinity); + spawn.randomMob(71375, -17475, Infinity); + spawn.randomMob(72200, -17600, Infinity); + spawn.randomMob(73000, -18025, Infinity); + spawn.randomMob(73850, -18350, Infinity); + spawn.randomMob(75725, -18300, Infinity); + spawn.randomMob(75875, -18275, Infinity); + spawn.randomMob(75700, -18200, Infinity); + spawn.randomMob(75550, -18275, Infinity); + spawn.randomMob(75825, -18150, Infinity); + spawn.randomMob(75575, -18150, Infinity); + spawn.randomGroup(75575, -18150, 0); + // powerUps.spawn(59352, -17115, "tech"); + level.chain(67250, -19325, 0, true, 14, 20); + spawn.mapRect(58725, -18300, 125, 100); + spawn.mapRect(61100, -18300, 175, 100); + spawn.mapRect(67175, -19375, 100, 100); + spawn.mapRect(59125, -19125, 325, 200); + spawn.mapRect(59925, -19175, 350, 225); + spawn.mapRect(60800, -18850, 275, 200); + spawn.mapRect(60850, -18725, 50, 200); + spawn.mapRect(60950, -18675, 50, 200); + spawn.mapRect(59975, -19025, 50, 250); + spawn.mapRect(60125, -19025, 50, 400); + spawn.mapRect(60075, -19025, 50, 450); + spawn.mapRect(59425, -19075, 100, 100); + spawn.mapRect(59175, -19000, 100, 225); + spawn.mapRect(59325, -19000, 75, 450); + spawn.mapRect(59050, -19000, 100, 100); + spawn.mapRect(61050, -18775, 100, 75); + spawn.mapRect(60725, -18850, 125, 125); + spawn.bodyRect(61850, -16525, 250, 175); + if (simulation.difficulty > 1) { + spawn.randomGroup(75575, -18150, 0); + spawn.randomLevelBoss(68450, -17300); + } + if (!isSpawnedBoss) { + isSpawnedBoss = true; + if (Math.random() < 0.33) { + for ( + let i = 0, len = Math.min(simulation.difficulty / 20, 6); i < len; + ++i + ) + spawn.bounceBoss(59025, -17325, 50, true); + } else if (Math.random() < 0.5) { + for ( + let i = 0, len = Math.min(simulation.difficulty / 9, 8); i < len; + ++i + ) + spawn.sprayBoss(59025, -17325, 50, true); + } else { + for ( + let i = 0, len = Math.min(simulation.difficulty / 6, 10); i < len; + ++i + ) + spawn.mineBoss(59025, -17325, 50, true); + } + // for (let i = 0, len = 3 + simulation.difficulty / 20; i < len; ++i) spawn.mantisBoss(1487 + 300 * i, -1525, 35, false) + } + simulation.fallHeight = -15000; + powerUps.addResearchToLevel(); + powerUps.spawn(3000, -230, "heal"); + // level.difficultyIncrease(60) + }, // ******************************************************************************************************** // ******************************************************************************************************** // ***************************************** training levels ********************************************** diff --git a/js/player.js b/js/player.js index 1d7c66b..c94ebd6 100644 --- a/js/player.js +++ b/js/player.js @@ -2090,25 +2090,21 @@ const m = { Matter.Composite.remove(engine.world, m.plasmaBall); } if (tech.isPlasmaBall) { - // m.plasmaBall = { - // position: { x: m.pos.x + 10 * Math.cos(m.angle), y: m.pos.y + 10 * Math.sin(m.angle) }, - // velocity: { x: 0, y: 0 }, - // radius: 1, - // } - m.plasmaBall = Bodies.circle(m.pos.x + 10 * Math.cos(m.angle), m.pos.y + 10 * Math.sin(m.angle), 1, { - collisionFilter: { - group: 0, - category: 0, - mask: 0 //cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield - }, + // collisionFilter: { + // group: 0, + // category: 0, + // mask: 0 //cat.body | cat.map | cat.mob | cat.mobBullet | cat.mobShield + // }, + isSensor: true, frictionAir: 0, - alpha: 0.6, + alpha: 0.7, + isPopping: false, isAttached: false, isOn: false, drain: 0.0015, radiusLimit: 10, - damage: 0.4, + damage: 0.6, setPositionToNose() { const nose = { x: m.pos.x + 10 * Math.cos(m.angle), y: m.pos.y + 10 * Math.sin(m.angle) } Matter.Body.setPosition(this, Vector.add(nose, Vector.mult(Vector.normalise(Vector.sub(nose, m.pos)), this.circleRadius))); @@ -2128,38 +2124,124 @@ const m = { }, scale(scale) { Matter.Body.scale(m.plasmaBall, scale, scale); //shrink fast - if (this.circleRadius < this.radiusLimit) this.isOn = false + if (this.circleRadius < this.radiusLimit) this.reset() + }, + reset() { + const scale = 1 / m.plasmaBall.circleRadius + Matter.Body.scale(m.plasmaBall, scale, scale); //grow + this.alpha = 0.7 + this.isOn = false + this.isPopping = false }, do() { if (this.isOn) { //collisions with map if (Matter.Query.collides(this, map).length > 0) { if (this.isAttached) { - this.scale(Math.max(0.9, 1 - 0.05 / m.plasmaBall.circleRadius)) + this.scale(Math.max(0.9, 0.998 - 0.1 / m.plasmaBall.circleRadius)) } else { - this.scale(Math.max(0.9, 0.98 - 0.05 / m.plasmaBall.circleRadius)) - if (this.speed > 2.5) { - const scale = 0.96 - Matter.Body.setVelocity(this, { - x: scale * this.velocity.x, - y: scale * this.velocity.y - }); - } + this.isPopping = true } } + if (this.isPopping) { + this.alpha -= 0.03 + if (this.alpha < 0.1) { + this.reset() + } else { + const scale = 1.04 + 4 / Math.max(1, m.plasmaBall.circleRadius) + Matter.Body.scale(m.plasmaBall, scale, scale); //grow + } + // if (this.speed > 2.5) { + // const slow = 0.9 + // Matter.Body.setVelocity(this, { + // x: slow * this.velocity.x, + // y: slow * this.velocity.y + // }); + // } + } //collisions with mobs - const whom = Matter.Query.collides(this, mob) + // const whom = Matter.Query.collides(this, mob) + // const dmg = this.damage * m.dmgScale + // for (let i = 0, len = whom.length; i < len; i++) { + // const mobHit = (who) => { + // if (who.alive) { + // if (!this.isAttached && !who.isMobBullet) this.isPopping = true + // who.damage(dmg); + // // if (who.shield) this.scale(Math.max(0.9, 0.99 - 0.5 / m.plasmaBall.circleRadius)) + // if (who.speed > 5) { + // Matter.Body.setVelocity(who, { //friction + // x: who.velocity.x * 0.6, + // y: who.velocity.y * 0.6 + // }); + // } else { + // Matter.Body.setVelocity(who, { //friction + // x: who.velocity.x * 0.93, + // y: who.velocity.y * 0.93 + // }); + // } + // } + // } + // mobHit(whom[i].bodyA) + // mobHit(whom[i].bodyB) + // } + + //damage nearby mobs const dmg = this.damage * m.dmgScale - for (let i = 0, len = whom.length; i < len; i++) { - if (whom[i].bodyA.alive) { - whom[i].bodyA.damage(dmg); - if (whom[i].bodyA.shield) this.scale(Math.max(0.9, 0.99 - 0.5 / m.plasmaBall.circleRadius)) - } - if (whom[i].bodyB.alive) { - whom[i].bodyB.damage(dmg); - if (whom[i].bodyB.shield) this.scale(Math.max(0.9, 0.99 - 0.5 / m.plasmaBall.circleRadius)) + const arcList = [] + for (let i = 0, len = mob.length; i < len; i++) { + const sub = Vector.magnitude(Vector.sub(this.position, mob[i].position)) + if (sub < this.circleRadius + mob[i].radius) { + + if (mob[i].alive) { + if (!this.isAttached && !mob[i].isMobBullet) this.isPopping = true + mob[i].damage(dmg); + if (mob[i].speed > 5) { + Matter.Body.setVelocity(mob[i], { //friction + x: mob[i].velocity.x * 0.6, + y: mob[i].velocity.y * 0.6 + }); + } else { + Matter.Body.setVelocity(mob[i], { //friction + x: mob[i].velocity.x * 0.93, + y: mob[i].velocity.y * 0.93 + }); + } + } + } else if (sub < 150 + 1.3 * this.circleRadius + mob[i].radius && !(m.cycle % 20)) { //populate electrical arc list + arcList.push(mob[i]) + // mob[i].damage(dmg * 0.1); } + } + // + if (arcList.length) { + const who = arcList[Math.floor(Math.random() * arcList.length)] + who.damage(dmg * 5); + + //draw arcs + // const unit = Vector.rotate({ x: 1, y: 0 }, Math.random() * 6.28) + const sub = Vector.sub(who.position, this.position) + const unit = Vector.normalise(sub) + let len = 12 + const step = Vector.magnitude(sub) / (len + 2) + let x = this.position.x + let y = this.position.y + ctx.beginPath(); + ctx.moveTo(x, y); + for (let i = 0; i < len; i++) { + x += step * (unit.x + 1 * (Math.random() - 0.5)) + y += step * (unit.y + 1 * (Math.random() - 0.5)) + ctx.lineTo(x, y); + } + ctx.lineTo(who.position.x, who.position.y); + ctx.strokeStyle = "#88f"; + ctx.lineWidth = 4 + Math.random(); + ctx.stroke(); + } + + + + //slowly slow down if too fast if (this.speed > 8) { const scale = 0.997 @@ -2172,11 +2254,11 @@ const m = { //graphics const radius = this.circleRadius * (0.99 + 0.02 * Math.random()) + 3 * Math.random() const gradient = ctx.createRadialGradient(this.position.x, this.position.y, 0, this.position.x, this.position.y, radius); - this.alpha = 0.5 + 0.1 * Math.random() - gradient.addColorStop(0, `rgba(255,255,255,${this.alpha})`); - gradient.addColorStop(0.18 + 0.1 * Math.random(), `rgba(255,150,255,${this.alpha})`); - gradient.addColorStop(1, `rgba(255,0,255,${this.alpha})`); - // gradient.addColorStop(1, `rgba(255,150,255,${this.alpha})`); + const alpha = this.alpha + 0.15 * Math.random() + gradient.addColorStop(0, `rgba(255,255,255,${alpha})`); + gradient.addColorStop(0.35 + 0.1 * Math.random(), `rgba(255,150,255,${alpha})`); + gradient.addColorStop(1, `rgba(255,0,255,${alpha})`); + // gradient.addColorStop(1, `rgba(255,150,255,${alpha})`); ctx.fillStyle = gradient ctx.beginPath(); ctx.arc(this.position.x, this.position.y, radius, 0, 2 * Math.PI); @@ -2211,8 +2293,12 @@ const m = { } }, }); + Composite.add(engine.world, m.plasmaBall); + // m.plasmaBall.startingVertices = m.plasmaBall.vertices.slice(); + // console.log(m.plasmaBall.startingVertices, m.plasmaBall.vertices) + m.hold = function() { if (m.isHolding) { m.drawHold(m.holdingTarget); @@ -2224,17 +2310,24 @@ const m = { //field is active if (!m.plasmaBall.isAttached) { //return ball to player - const scale = 0.7 - Matter.Body.scale(m.plasmaBall, scale, scale); //shrink fast - if (m.plasmaBall.circleRadius < m.plasmaBall.radiusLimit) { + if (m.plasmaBall.isOn) { + m.plasmaBall.isPopping = true + } else { m.plasmaBall.isAttached = true m.plasmaBall.isOn = true m.plasmaBall.setPositionToNose() } + // const scale = 0.7 + // Matter.Body.scale(m.plasmaBall, scale, scale); //shrink fast + // if (m.plasmaBall.circleRadius < m.plasmaBall.radiusLimit) { + // m.plasmaBall.isAttached = true + // m.plasmaBall.isOn = true + // m.plasmaBall.setPositionToNose() + // } } else if (m.energy > m.plasmaBall.drain) { //charge up when attached if (tech.isCapacitor) { m.energy -= m.plasmaBall.drain * 2; - const scale = 1 + 3 * 16 * Math.pow(Math.max(1, m.plasmaBall.circleRadius), -1.8) + const scale = 1 + 48 * Math.pow(Math.max(1, m.plasmaBall.circleRadius), -1.8) Matter.Body.scale(m.plasmaBall, scale, scale); //grow } else { m.energy -= m.plasmaBall.drain; @@ -2242,12 +2335,40 @@ const m = { Matter.Body.scale(m.plasmaBall, scale, scale); //grow } if (m.energy > m.maxEnergy) { - m.energy -= m.plasmaBall.drain; + m.energy -= m.plasmaBall.drain * 2; const scale = 1 + 16 * Math.pow(Math.max(1, m.plasmaBall.circleRadius), -1.8) Matter.Body.scale(m.plasmaBall, scale, scale); //grow } m.plasmaBall.setPositionToNose() - //add friction for player when holding ball, maybe more friction in vertical + + + //add friction for player when holding ball, more friction in vertical + // const floatScale = Math.sqrt(m.plasmaBall.circleRadius) + // const friction = 0.0002 * floatScale + // const slowY = (player.velocity.y > 0) ? Math.max(0.8, 1 - friction * player.velocity.y * player.velocity.y) : Math.max(0.98, 1 - friction * Math.abs(player.velocity.y)) //down : up + // Matter.Body.setVelocity(player, { + // x: Math.max(0.95, 1 - friction * Math.abs(player.velocity.x)) * player.velocity.x, + // y: slowY * player.velocity.y + // }); + + // if (player.velocity.y > 7) player.force.y -= 0.95 * player.mass * simulation.g //less gravity when falling fast + // player.force.y -= Math.min(0.95, 0.05 * floatScale) * player.mass * simulation.g; //undo some gravity on up or down + // console.log(friction) + + //float + const slowY = (player.velocity.y > 0) ? Math.max(0.8, 1 - 0.002 * player.velocity.y * player.velocity.y) : Math.max(0.98, 1 - 0.001 * Math.abs(player.velocity.y)) //down : up + Matter.Body.setVelocity(player, { + x: Math.max(0.95, 1 - 0.003 * Math.abs(player.velocity.x)) * player.velocity.x, + y: slowY * player.velocity.y + }); + if (player.velocity.y > 5) { + player.force.y -= 0.9 * player.mass * simulation.g //less gravity when falling fast + } else { + player.force.y -= 0.5 * player.mass * simulation.g; + } + + + } else { m.fieldCDcycle = m.cycle + 90; diff --git a/js/tech.js b/js/tech.js index a669253..823fda6 100644 --- a/js/tech.js +++ b/js/tech.js @@ -6585,7 +6585,7 @@ const tech = { isBot: true, isBotTech: true, allowed() { - return m.fieldUpgrades[m.fieldMode].name === "plasma torch" && (build.isExperimentSelection || powerUps.research.count > 0) + return m.fieldUpgrades[m.fieldMode].name === "plasma torch" && (build.isExperimentSelection || powerUps.research.count > 0) && !tech.isPlasmaBall && !tech.isExtruder }, requires: "plasma torch", effect() { @@ -6639,7 +6639,7 @@ const tech = { }, { name: "plasma ball", - description: "charge up a ball of plasma and fire it", + description: "grow an expanding ball of plasma
increases damage and energy drain", isFieldTech: true, maxCount: 1, count: 0, @@ -6660,7 +6660,7 @@ const tech = { }, { name: "extruder", - description: "plasma torch extrudes a thin hot wire
increases damage and energy drain", + description: "extrude a thin hot wire of plasma
increases damage and energy drain", isFieldTech: true, maxCount: 1, count: 0, @@ -7923,7 +7923,7 @@ const tech = { oscillator1.connect(gainNode1); gainNode1.connect(audioCtx.destination); oscillator1.type = "sine"; // 'sine' 'square', 'sawtooth', 'triangle' and 'custom' - oscillator1.frequency.value = 853; // value in hertz + oscillator1.frequency.value = 850; // value in hertz oscillator1.start(); const oscillator2 = audioCtx.createOscillator(); @@ -7932,7 +7932,7 @@ const tech = { oscillator2.connect(gainNode2); gainNode2.connect(audioCtx.destination); oscillator2.type = "sine"; // 'sine' 'square', 'sawtooth', 'triangle' and 'custom' - oscillator2.frequency.value = 960; // value in hertz + oscillator2.frequency.value = 957; // value in hertz oscillator2.start(); return audioCtx } diff --git a/todo.txt b/todo.txt index b911fad..5d17455 100644 --- a/todo.txt +++ b/todo.txt @@ -1,27 +1,25 @@ ******************************************************** NEXT PATCH ************************************************** plasma ball - moves faster - grows/drains extra fast when you have excess energy - -bug: technical debt no longer produces negative damage at high tech levels - maybe this was causing the NaN position bug? + once released explodes on mobs or map + slows mobs + grows at 2x rate if you have energy above max + player is slowed when holding plasma ball + every 20 cycles damage a nearby mob + next patch plasma ball tech ******************************************************** TODO ******************************************************** - plasma ball - damage is fine - disable plasma torch tech with no effect on plasma ball - change size/alpha when touching mobs - explode when touching mobs like spirit bomb? - player angle rotation speed while firing adds to fire speed - tech upgrade to get electrical arcs that randomly damage nearby mobs - could work for all branches of plasma torch - tech: black hole: gives the plasma ball gravity + delay on returning to player is annoying + scale float effect with ball size + tech upgrades + more electric arcs + greatly improve floating effects while holding + black hole: gives the plasma ball gravity + suck or stun on explosion? plasma orb increases in size and power as it eats enemies - maybe does damage to player to grow faster? - tech that makes it explode when it expires + while attached? bug: often game puts player position at NaN try: