From 2dc633d2da100ea4547c0eb463787a38aaa4b18b Mon Sep 17 00:00:00 2001 From: landgreen Date: Sat, 16 Apr 2022 17:28:31 -0700 Subject: [PATCH] reactor reactions automonous navigation -> path integration sends spores and worms and drones to the next level with you MIRV gives 10->12% smaller radius and damage laser tech slow light has 33% less spacing tech exciton gives 70%->88% damage discrete optimization: 40%->35% damage and fire delay degenerate matter 60->66% harm reduction while field is active virtual particles 15% duplication is now allowed for time dilation railgun no longer uses extra ammo when firing multiple bullets with smelting smelting now costs more ammo with railgun plasma torch, ball, extruder all use 33% less energy, do 15% more damage bremsstrahlung does 15% more damage standing wave field gives 50 energy it's cooldown for blocking shields in now 0.5->0.33 s reactor fight now starts when you press a button, so you can prep spawns more ammo 4->7, heals 0->2 will no longer show up on levels 2,3,4 fewer bosses spawn at high difficulty levels has a small chance to spawn all 3 boss types sprayBoss is 25% slower, but it goes immune while spraying instead of shielding community maps have a short message onload giving credit to the author new level element balance - it's basically spinners and rotors combined I'm replacing all rotors to fix potential BUGS sewers, house, perplex, vats requirement text bug fixes --- .DS_Store | Bin 6148 -> 6148 bytes index.html | 235 +---------- js/bullet.js | 52 +-- js/index.js | 2 +- js/level.js | 1041 ++++++++++++++++++++++++++-------------------- js/player.js | 38 +- js/powerup.js | 2 +- js/simulation.js | 37 +- js/spawn.js | 25 +- js/tech.js | 192 +++++---- todo.txt | 66 ++- 11 files changed, 860 insertions(+), 830 deletions(-) diff --git a/.DS_Store b/.DS_Store index 760bd30b360168ef7bacc5894393f07f7f0907c6..15c8217acc8f4949ad4de2207b1fe6e31b700fe9 100644 GIT binary patch delta 23 ecmZoMXffEJ$;_;{KWMTJvoDj9!RBh_P7wf8+6Jot delta 23 ecmZoMXffEJ$;_ogx5N9tS-D diff --git a/index.html b/index.html index e1eec7b..bde0b5f 100644 --- a/index.html +++ b/index.html @@ -11,14 +11,12 @@ - n-gon -
@@ -29,45 +27,7 @@
- - - - - - - - - - - - - - - -
@@ -82,7 +42,6 @@ - training
@@ -140,7 +99,8 @@
controls
- To change controls click a box
+ To change controls click a box +
and press an unused key.

@@ -203,17 +163,13 @@
updates -
+
about -
- +
- Chat about n-gon in the discord.
Let me know about ideas, - or bugs. -
-
-
+ Chat about n-gon in the discord.
Let me know about ideas, or bugs. +


@@ -238,13 +191,7 @@ - Github hosts the source code for n-gon.
It's - written in JavaScript, CSS, and HTML. - + Github hosts the source code for n-gon.
It's written in JavaScript, CSS, and HTML using the matter.js 2-D physics library.
@@ -335,17 +282,6 @@ } - - @@ -360,19 +296,10 @@ - - @@ -398,26 +325,16 @@ - - Q W E - A S D - - - @@ -431,140 +348,7 @@ fire field - - - - - @@ -576,14 +360,9 @@ - - - - \ No newline at end of file diff --git a/js/bullet.js b/js/bullet.js index 8047c00..e96b75b 100644 --- a/js/bullet.js +++ b/js/bullet.js @@ -196,9 +196,9 @@ const b = { } }, - removeGun(gun, isRemoveSelection = false) { + removeGun(gunName) { for (let i = 0; i < b.guns.length; i++) { - if (b.guns[i].name === gun) { + if (b.guns[i].name === gunName && b.guns[i].have) { b.guns[i].have = false for (let j = 0; j < b.inventory.length; j++) { if (b.inventory[j] === i) { @@ -206,13 +206,12 @@ const b = { break } } - if (b.inventory.length) { + if (b.inventory.length > 0) { b.activeGun = b.inventory[0]; } else { b.activeGun = null; } simulation.makeGunHUD(); - if (isRemoveSelection) b.guns.splice(i, 1) //also remove gun from gun pool array break } } @@ -973,7 +972,7 @@ const b = { grenadeNeutron = function(where = { x: m.pos.x + 30 * Math.cos(m.angle), y: m.pos.y + 30 * Math.sin(m.angle) }, angle = m.angle, size = 1) { const me = bullet.length; bullet[me] = Bodies.polygon(where.x, where.y, 10, 4, b.fireAttributes(angle, false)); - b.fireProps((input.down ? 45 : 25) / Math.pow(0.93, tech.missileCount), input.down ? 35 : 20, angle, me); //cd , speed + b.fireProps((input.down ? 45 : 25) / Math.pow(0.92, tech.missileCount), input.down ? 35 : 20, angle, me); //cd , speed Matter.Body.setDensity(bullet[me], 0.000001); bullet[me].endCycle = Infinity; bullet[me].frictionAir = 0; @@ -1901,7 +1900,7 @@ const b = { frictionAir: 0.045, dmg: 0, //damage done in addition to the damage from momentum classType: "bullet", - endCycle: simulation.cycle + Math.floor((230 + 40 * Math.random()) * tech.isBulletsLastLonger), + endCycle: simulation.cycle + Math.floor((230 + 40 * Math.random()) * tech.isBulletsLastLonger + 120 * tech.isMissileBiggest + 60 * tech.isMissileBig), collisionFilter: { category: cat.bullet, mask: cat.map | cat.body | cat.mob | cat.mobBullet | cat.mobShield @@ -1992,7 +1991,7 @@ const b = { didExtruderDrain: false, canExtruderFire: true, extruder() { - const DRAIN = 0.0018 + const DRAIN = 0.0012 if (m.energy > DRAIN && b.canExtruderFire) { m.energy -= DRAIN if (m.energy < 0) { @@ -2011,7 +2010,7 @@ const b = { frictionAir: 0, isInHole: true, //this keeps the bullet from entering wormholes minDmgSpeed: 0, - dmg: m.dmgScale * 2.5, //damage also changes when you divide by mob.mass on in .do() + dmg: m.dmgScale * 2.7, //damage also changes when you divide by mob.mass on in .do() classType: "bullet", isBranch: false, restitution: 0, @@ -2070,7 +2069,7 @@ const b = { } }, plasma() { - const DRAIN = 0.0011 + const DRAIN = 0.00075 if (m.energy > DRAIN) { m.energy -= DRAIN; if (m.energy < 0) { @@ -2150,7 +2149,7 @@ const b = { y: best.y }; if (best.who.alive) { - const dmg = 0.8 * m.dmgScale; //********** SCALE DAMAGE HERE ********************* + const dmg = 0.9 * m.dmgScale; //********** SCALE DAMAGE HERE ********************* best.who.damage(dmg); best.who.locatePlayer(); @@ -2726,6 +2725,7 @@ const b = { dmg: tech.isMutualism ? 16.8 : 7, //bonus damage from tech.isMutualism lookFrequency: 100 + Math.floor(117 * Math.random()), classType: "bullet", + isSpore: true, collisionFilter: { category: cat.bullet, mask: cat.map | cat.mob | cat.mobBullet | cat.mobShield //no collide with body @@ -4235,7 +4235,7 @@ const b = { this.force = Vector.mult(Vector.normalise(Vector.sub(this.position, mob[i].position)), this.mass * 0.02) if (tech.missileCount > 1) { - const countReduction = Math.pow(0.93, tech.missileCount) + const countReduction = Math.pow(0.85, tech.missileCount) const size = 0.9 * Math.sqrt(countReduction) const direction = { x: Math.cos(angle), @@ -5765,7 +5765,7 @@ const b = { fireCycle: 0, do() {}, fire() { - const countReduction = Math.pow(0.9, tech.missileCount) + const countReduction = Math.pow(0.86, tech.missileCount) // if (input.down) { // m.fireCDcycle = m.cycle + tech.missileFireCD * b.fireCDscale / countReduction; // cool down // // for (let i = 0; i < tech.missileCount; i++) { @@ -6246,13 +6246,13 @@ const b = { const dist = Vector.magnitude(Vector.sub(where, mob[i].position)) // console.log(dot, 0.95 - Math.min(dist * 0.00015, 0.3)) if (dot > 0.95 - Math.min(dist * 0.00015, 0.3)) { //lower dot product threshold for targeting then if you only have one harpoon //target closest mob that player is looking at and isn't too close to target - if (this.ammo > -1) { - this.ammo-- - b.harpoon(where, input.down ? mob[i] : null, angle, harpoonSize, false) //Vector.angle(Vector.sub(where, mob[i].position), { x: 0, y: 0 }) - angle += SPREAD - targetCount++ - if (targetCount > tech.extraHarpoons) break - } + // if (this.ammo > -1) { + // this.ammo-- + b.harpoon(where, input.down ? mob[i] : null, angle, harpoonSize, false) //Vector.angle(Vector.sub(where, mob[i].position), { x: 0, y: 0 }) + angle += SPREAD + targetCount++ + if (targetCount > tech.extraHarpoons) break + // } } } } @@ -6260,14 +6260,14 @@ const b = { if (targetCount < tech.extraHarpoons + 1) { const num = tech.extraHarpoons + 1 - targetCount for (let i = 0; i < num; i++) { - if (this.ammo > -1) { - this.ammo-- - b.harpoon(where, null, angle, harpoonSize, false) - angle += SPREAD - } + // if (this.ammo > -1) { + // this.ammo-- + b.harpoon(where, null, angle, harpoonSize, false) + angle += SPREAD + // } } } - this.ammo++ //make up for the ammo used up in fire() + // this.ammo++ //make up for the ammo used up in fire() simulation.updateGunHUD(); } else { //look for closest mob in player's LoS @@ -7298,7 +7298,7 @@ const b = { m.fireCDcycle = m.cycle m.energy -= m.fieldRegen + tech.laserFieldDrain * tech.isLaserDiode const dmg = 0.4 * tech.laserDamage // 3.5 * 0.55 = 200% more damage - const spacing = Math.ceil(5.2 - 0.4 * tech.historyLaser) + const spacing = Math.ceil(4 - 0.3 * tech.historyLaser) ctx.beginPath(); b.laser({ x: m.pos.x + 20 * Math.cos(m.angle), diff --git a/js/index.js b/js/index.js index 7ef6e2e..8b14fda 100644 --- a/js/index.js +++ b/js/index.js @@ -280,7 +280,7 @@ const build = {
${botText}
health: (${(m.health*100).toFixed(0)} / ${(m.maxHealth*100).toFixed(0)})   energy: (${(m.energy*100).toFixed(0)} / ${(m.maxEnergy*100).toFixed(0)}) -
gun: ${b.activeGun !== null ? b.guns[b.activeGun].name: "null"}   ammo: ${b.activeGun !== null ? b.guns[b.activeGun].ammo: "0"} +
gun: ${b.activeGun === null || b.activeGun === undefined ? "undefined":b.guns[b.activeGun].name}   ammo: ${b.activeGun === null || b.activeGun === undefined ? "0":b.guns[b.activeGun].ammo}
fire delay decrease: ${((1-b.fireCDscale)*100).toFixed(b.fireCDscale < 0.1 ? 2 : 0)}%
duplication chance: ${(tech.duplicationChance()*100).toFixed(0)}%
tech: ${tech.totalCount}   research: ${powerUps.research.count} diff --git a/js/level.js b/js/level.js index 790b6cc..39e9699 100644 --- a/js/level.js +++ b/js/level.js @@ -18,13 +18,13 @@ const level = { // simulation.isHorizontalFlipped = true // m.setField("metamaterial cloaking") // b.giveGuns("missiles") - // tech.giveTech("nematodes") - // tech.giveTech("launch system") - // tech.giveTech("cruise missile") + // tech.giveTech("scrap-bot manufacturing") + // tech.giveTech("dynamo-bot upgrade") + // tech.giveTech("time crystals") // tech.giveTech("ICBM") // tech.giveTech("grappling hook") // tech.giveTech("annelids") - // for (let i = 0; i < 2; i++) powerUps.directSpawn(0, 0, "tech"); + // for (let i = 0; i < 10; i++) powerUps.directSpawn(0, 0, "tech"); // for (let i = 0; i < 9; i++) tech.giveTech("annelids") // for (let i = 10; i < tech.tech.length; i++) { tech.tech[i].isBanished = true } // powerUps.research.changeRerolls(100000) @@ -35,9 +35,9 @@ const level = { // tech.giveTech("extruder") // m.immuneCycle = Infinity //you can't take damage - // level.difficultyIncrease(10) //30 is near max on hard //60 is near max on why + // 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.islands(); + // level.reactor(); // level.testing(); //not in rotation, used for testing if (simulation.isTraining) { level.walk(); } else { level.intro(); } //normal starting level ************************************************ // powerUps.research.changeRerolls(3000) @@ -253,8 +253,8 @@ const level = { level.levels = shuffle(level.levels); //shuffles order of maps } // level.levels.splice(Math.floor(level.levels.length * (0.4 + 0.6 * Math.random())), 0, "reservoir"); //add level to the back half of the randomized levels list - level.levels.splice(Math.floor(Math.seededRandom((level.levels.length) * 0.4, level.levels.length)), 0, "reservoir"); //add level to the back half of the randomized levels list - level.levels.splice(Math.floor(Math.seededRandom((level.levels.length) * 0.4, level.levels.length)), 0, "reactor"); //add level to the back half of the randomized levels list + level.levels.splice(Math.floor(Math.seededRandom((level.levels.length) * 0.6, level.levels.length)), 0, "reservoir"); //add level to the back half of the randomized levels list + level.levels.splice(Math.floor(Math.seededRandom((level.levels.length) * 0.6, level.levels.length)), 0, "reactor"); //add level to the back half of the randomized levels list level.levels.splice(0, 2); //remove 2 levels from the start of the array if (!build.isExperimentSelection || (build.hasExperimentalMode && !simulation.isCheating)) { //experimental mode is endless, unless you only have an experiment Tech level.levels.unshift("intro"); //add level to the start of the randomized levels list @@ -440,6 +440,69 @@ const level = { Composite.add(engine.world, constraint); return constraint }, + rotor(x, y, width, height, density = 0.001, angle = 0, frictionAir = 0.001, angularVelocity = 0, rotationForce = 0.0005) { + x += width / 2 + y += height / 2 + const who = body[body.length] = Bodies.rectangle(x, y, width, height, { + collisionFilter: { + category: cat.map, + mask: cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet + }, + isNoSetCollision: true, + isNotHoldable: true, + frictionAir: frictionAir, + friction: 1, + frictionStatic: 1, + restitution: 0, + rotationForce: rotationForce + }); + Matter.Body.setAngle(who, angle) + Matter.Body.setAngularVelocity(who, angularVelocity); + + Matter.Body.setDensity(who, density) + const constraint = Constraint.create({ //fix rotor in place, but allow rotation + pointA: { + x: who.position.x, + y: who.position.y + }, + bodyB: who, + stiffness: 1, + damping: 1 + }); + Composite.add(engine.world, constraint); + who.center = { x: who.position.x, y: who.position.y } + who.rotate = function() { + if (!m.isBodiesAsleep) { + Matter.Body.applyForce(this, { + x: this.position.x + 100, + y: this.position.y + 100 + }, { + x: this.rotationForce * this.mass, + y: 0 + }) + } else { + Matter.Body.setAngularVelocity(this, 0); + } + } + // if (rotate) { + // rotor.rotate = function() { + // if (!m.isBodiesAsleep) { + // Matter.Body.applyForce(rotor, { + // x: rotor.position.x + 100, + // y: rotor.position.y + 100 + // }, { + // x: rotate * rotor.mass, + // y: 0 + // }) + // } else { + // Matter.Body.setAngularVelocity(rotor, 0); + // } + // } + // } + + + return who + }, boost(x, y, height = 1000) { //height is how high the player will be flung above y who = map[map.length] = Matter.Bodies.fromVertices(x + 50, y + 35, Vertices.fromPath("120 40 -120 40 -50 -40 50 -40"), { collisionFilter: { @@ -473,7 +536,7 @@ const level = { query(bullet) query(powerUp) //player collision - if (Matter.Query.region([player], this.boostBounds).length > 0) { + if (Matter.Query.region([player], this.boostBounds).length > 0 && !input.down) { m.buttonCD_jump = 0; // reset short jump counter to prevent short jumps on boosts m.hardLandCD = 0 // disable hard landing if (player.velocity.y > 26) { @@ -651,77 +714,77 @@ const level = { Composite.add(engine.world, who.constraint); return who }, - rotor(x, y, rotate = 0, radius = 800, width = 40, density = 0.0005) { - const rotor1 = Matter.Bodies.rectangle(x, y, width, radius, { - density: density, - isNotHoldable: true, - isNonStick: true, - collisionFilter: { - category: cat.map, - mask: cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet - }, - isNoSetCollision: true, - }); - const rotor2 = Matter.Bodies.rectangle(x, y, width, radius, { - angle: Math.PI / 2, - density: density, - isNotHoldable: true, - isNonStick: true, - collisionFilter: { - category: cat.map, - mask: cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet - }, - isNoSetCollision: true, - }); - rotor = Body.create({ //combine rotor1 and rotor2 - parts: [rotor1, rotor2], - restitution: 0, - collisionFilter: { - category: cat.map, - mask: cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet - }, - isNoSetCollision: true, - }); - Matter.Body.setPosition(rotor, { - x: x, - y: y - }); - Composite.add(engine.world, [rotor]); - body[body.length] = rotor1 - body[body.length] = rotor2 + // rotor(x, y, rotate = 0, radius = 800, width = 40, density = 0.0005) { + // const rotor1 = Matter.Bodies.rectangle(x, y, width, radius, { + // density: density, + // isNotHoldable: true, + // isNonStick: true, + // collisionFilter: { + // category: cat.map, + // mask: cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet + // }, + // isNoSetCollision: true, + // }); + // const rotor2 = Matter.Bodies.rectangle(x, y, width, radius, { + // angle: Math.PI / 2, + // density: density, + // isNotHoldable: true, + // isNonStick: true, + // collisionFilter: { + // category: cat.map, + // mask: cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet + // }, + // isNoSetCollision: true, + // }); + // rotor = Body.create({ //combine rotor1 and rotor2 + // parts: [rotor1, rotor2], + // restitution: 0, + // collisionFilter: { + // category: cat.map, + // mask: cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet + // }, + // isNoSetCollision: true, + // }); + // Matter.Body.setPosition(rotor, { + // x: x, + // y: y + // }); + // Composite.add(engine.world, [rotor]); + // body[body.length] = rotor1 + // body[body.length] = rotor2 - // setTimeout(function() { - // rotor.collisionFilter.category = cat.body; - // rotor.collisionFilter.mask = cat.body | cat.player | cat.bullet | cat.mob | cat.mobBullet //| cat.map - // }, 1000); + // // setTimeout(function() { + // // rotor.collisionFilter.category = cat.body; + // // rotor.collisionFilter.mask = cat.body | cat.player | cat.bullet | cat.mob | cat.mobBullet //| cat.map + // // }, 1000); - const constraint = Constraint.create({ //fix rotor in place, but allow rotation - pointA: { - x: x, - y: y - }, - bodyB: rotor - }); - Composite.add(engine.world, constraint); + // const constraint = Constraint.create({ //fix rotor in place, but allow rotation + // pointA: { + // x: x, + // y: y + // }, + // bodyB: rotor + // }); + // Composite.add(engine.world, constraint); - if (rotate) { - rotor.rotate = function() { - if (!m.isBodiesAsleep) { - Matter.Body.applyForce(rotor, { - x: rotor.position.x + 100, - y: rotor.position.y + 100 - }, { - x: rotate * rotor.mass, - y: 0 - }) - } else { - Matter.Body.setAngularVelocity(rotor, 0); - } - } - } - composite[composite.length] = rotor - return rotor - }, + // if (rotate) { + // rotor.rotate = function() { + // if (!m.isBodiesAsleep) { + // Matter.Body.applyForce(rotor, { + // x: rotor.position.x + 100, + // y: rotor.position.y + 100 + // }, { + // x: rotate * rotor.mass, + // y: 0 + // }) + // } else { + // Matter.Body.setAngularVelocity(rotor, 0); + // } + // } + // } + // composite[composite.length] = rotor + // return rotor + // }, toggle(x, y, isOn = false, isLockOn = false) { spawn.mapVertex(x + 65, y + 2, "70 10 -70 10 -40 -10 40 -10"); //toggle platform map[map.length - 1].restitution = 0; @@ -847,7 +910,7 @@ const level = { // const block = body[body.length] = Bodies.rectangle(x, y, width, height, { collisionFilter: { category: cat.map, - mask: cat.player | cat.body | cat.bullet | cat.powerUp // | cat.mob | cat.mobBullet + mask: cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet }, isNoSetCollision: true, inertia: Infinity, //prevents rotation @@ -896,7 +959,7 @@ const level = { this.returnCount = 15 } else { this.isThere = true - this.collisionFilter.mask = cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet + this.collisionFilter.mask = cat.player | cat.mob | cat.body | cat.bullet | cat.powerUp | cat.mobBullet this.fadeCount = this.fadeTime //delete any overlapping blocks const blocks = Matter.Query.collides(this, body) @@ -912,6 +975,20 @@ const level = { } } } + //delete any overlapping mobs + const mobsHits = Matter.Query.collides(this, mob) + for (let i = 0; i < mobsHits.length; i++) { + if (mobsHits[i].bodyB !== this && mobsHits[i].bodyB !== m.holdingTarget) { //dont' delete yourself <----- bug here maybe... + Matter.Composite.remove(engine.world, mobsHits[i].bodyB); + mobsHits[i].bodyB.isRemoveMeNow = true + for (let i = 1; i < mob.length; i++) { //find which index in body array it is and remove from array + if (mob[i].isRemoveMeNow) { + mob.splice(i, 1); + break + } + } + } + } } } } @@ -2554,7 +2631,7 @@ const level = { level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why m.addHealth(Infinity) - spawn.starter(1900, -500, 200) //big boy + // 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) @@ -2563,7 +2640,7 @@ const level = { // spawn.powerUpBossBaby(3200, -500) // spawn.snakeBoss(1700, -500) // spawn.streamBoss(3200, -500) - // spawn.pulsarBoss(1700, -500) + spawn.pulsarBoss(1700, -500) // spawn.spawnerBossCulture(3200, -500) // spawn.grenadierBoss(1700, -500) // spawn.growBossCulture(3200, -500) @@ -2582,7 +2659,7 @@ const level = { // for (let i = 0; i < 10; ++i) spawn.bodyRect(1600 + 5, -500, 30, 40); // for (let i = 0; i < 5; i++) spawn.focuser(1900, -500) - // spawn.pulsar(1900, -500) + spawn.pulsar(1900, -500) // spawn.shield(mob[mob.length - 1], 1900, -500, 1); // mob[mob.length - 1].isShielded = true // spawn.nodeGroup(1200, 0, "grenadier") @@ -2601,6 +2678,8 @@ const level = { document.body.style.backgroundColor = "#d0d5df" //"#d8dadf"; // powerUps.spawnStartingPowerUps(1475, -1175); // spawn.debris(750, -2200, 3700, 16); //16 debris per level + const button = level.button(1400, 0) + button.isUp = true spawn.mapRect(-1525, -2825, 1250, 4925); spawn.mapRect(-400, -2025, 625, 925); spawn.mapRect(-400, -750, 625, 1200); @@ -2613,7 +2692,6 @@ const level = { // spawn.bodyRect(1525, -100, 100, 100, 0.3); // spawn.bodyRect(2325, -50, 125, 50, 0.3); // spawn.bodyRect(2375, -100, 50, 50, 0.3); - for (let i = 0; i < 3; ++i) powerUps.spawn(400 + 2000 * Math.random(), -25, "ammo"); spawn.mapRect(-425, 0, 4200, 2100); spawn.mapRect(175, -1250, 50, 300); @@ -2654,22 +2732,6 @@ const level = { // player.force.y -= player.mass * simulation.g * 0.4; //float player if (isDoorsLocked) { - if (!isFightOver && !(simulation.cycle % 120)) { //once a second - let isFoundBoss = false - for (let i = 0; i < mob.length; i++) { - if (mob[i].isBoss) { - isFoundBoss = true - break - } - } - if (!isFoundBoss) { - isFightOver = true - doorIn.isClosing = false - doorOut.isClosing = false - powerUps.spawnBossPowerUp(2900, -100) - } - } - // if (mob.length > 0) { // doorIn.isClosing = true // doorOut.isClosing = true @@ -2687,25 +2749,55 @@ const level = { isDoorsLocked = true doorIn.isClosing = true doorOut.isClosing = true - if (!isSpawnedBoss) { - isSpawnedBoss = true - if (Math.random() < 0.33) { - for (let i = 0, len = Math.min(simulation.difficulty / 15, 7); i < len; ++i) spawn.bounceBoss(1487 + 200 * i, -1525, 80, false); - } else if (Math.random() < 0.5) { - for (let i = 0, len = Math.min(simulation.difficulty / 8, 8); i < len; ++i) spawn.sprayBoss(2400 - 150 * i, -225, 30, false) - } else { - for (let i = 0, len = Math.min(simulation.difficulty / 5, 11); i < len; ++i) spawn.mineBoss(1950, -250, 50, false); - } - // for (let i = 0, len = 3 + simulation.difficulty / 20; i < len; ++i) spawn.mantisBoss(1487 + 300 * i, -1525, 35, false) - } } - doorIn.openClose(); doorOut.openClose(); ctx.fillStyle = "#d5ebef" ctx.fillRect(2750, -375, 550, 375) level.enter.draw(); level.exit.drawAndCheck(); + + button.draw(); + if (button.isUp) { + button.query(); + } else if (!isSpawnedBoss) { + for (let i = 0; i < 4; ++i) { + setTimeout(() => { powerUps.spawn(300 + 800 * Math.random(), -1700, "ammo") }, 10000 * Math.random()); + } + for (let i = 0; i < 3; ++i) { + setTimeout(() => { powerUps.spawn(1800 + 800 * Math.random(), -1700, "ammo") }, 10000 * Math.random()); + } + powerUps.spawn(300 + 800 * Math.random(), -1700, "heal"); + powerUps.spawn(1800 + 800 * Math.random(), -1700, "heal"); + isSpawnedBoss = true + const scale = Math.pow(simulation.difficulty, 0.73) //hard around 30, why around 54 + if (Math.random() < 0.3) { + for (let i = 0, len = scale * 0.1; i < len; ++i) spawn.bounceBoss(1487 + 200 * i, -1525, 80, false); //spawn 1-2 at difficulty 15 + } else if (Math.random() < 0.45) { + for (let i = 0, len = scale * 0.17; i < len; ++i) spawn.sprayBoss(1487 + 200 * i, -1525, 30, false) //spawn 2-3 at difficulty 15 + } else if (Math.random() < 0.9) { + for (let i = 0, len = scale * 0.23; i < len; ++i) spawn.mineBoss(1487 + 200 * i, -1525, 50, false); //spawn 3-4 at difficulty 15 + } else { + for (let i = 0, len = scale * 0.1 / 3; i < len; ++i) spawn.bounceBoss(1487 + 200 * i, -1525, 80, false); + for (let i = 0, len = scale * 0.17 / 3; i < len; ++i) spawn.sprayBoss(1487 + 200 * i, -1525, 30, false) + for (let i = 0, len = scale * 0.23 / 3; i < len; ++i) spawn.mineBoss(1487 + 200 * i, -1525, 50, false); + } + } else if (!isFightOver && !(simulation.cycle % 120)) { //once a second look for any bosses + let isFoundBoss = false + for (let i = 0; i < mob.length; i++) { + if (mob[i].isBoss) { + isFoundBoss = true + break + } + } + if (!isFoundBoss) { + isFightOver = true + doorIn.isClosing = false + doorOut.isClosing = false + powerUps.spawnBossPowerUp(2900, -100) + powerUps.spawn(2900, -200, "tech") + } + } }; level.customTopLayer = () => { // if (isDoorsLocked) { @@ -3180,7 +3272,6 @@ const level = { } else { spawn.mapVertex(-687, -700, "-150 0 150 0 150 450 0 525 -150 450"); } - //right spawn.mapVertex(425 + 437, -50, "490 0 350 80 -350 80 -490 0 -350 -80 350 -80"); spawn.mapRect(325, -100, 1070, 100); @@ -3346,13 +3437,47 @@ const level = { spawn.mapVertex(1116, -2500, "0 0 300 0 150 600 0 600"); spawn.mapVertex(584, -2500, "0 0 300 0 300 600 150 600"); - if (Math.random() < 0.33) { + if (Math.random() < 0.1) { spinnerArray.push(level.spinner(65, -300, 40, 450, 0.003, Math.PI / 2)) - } else { + } else if (Math.random() < 0.25) { spinnerArray.push(level.spinner(65, -500, 40, 500, 0.003, 0, 0, -0.015)) // spinner(x, y, width, height, density = 0.001, angle = 0, frictionAir = 0.001, angularVelocity = 0) { const r = 250 const hexagon = `${r} 0 ${r * Math.cos(5.236)} ${r * Math.sin(5.236)} ${r * Math.cos(4.189)} ${r * Math.sin(4.189)} ${-r} 0 ${r * Math.cos(2.0944)} ${r * Math.sin(2.0944)} ${r * Math.cos(1.0472)} ${r * Math.sin(1.0472)} ` Matter.Body.setVertices(spinnerArray[spinnerArray.length - 1].bodyB, Vertices.fromPath(hexagon)) + } else { + const W = 410; + const H = 30; + spawn.bodyRect(-120, -75, W, H, 1, spawn.propsIsNotHoldable) + let b = body[body.length - 1]; + cons[cons.length] = Constraint.create({ + pointA: { + x: b.position.x - (W / 2) + 50 - 211, + y: b.position.y - 1825 + }, + bodyB: b, + pointB: { + x: -(W / 2) + 50, + y: 0 + }, + damping: 0.01, + stiffness: 0.002, + length: 1800 + }); + cons[cons.length] = Constraint.create({ + pointA: { + x: b.position.x + (W / 2) - 50 + 211, + y: b.position.y - 1825 + }, + bodyB: b, + pointB: { + x: (W / 2) - 50, + y: 0 + }, + damping: 0.01, + stiffness: 0.002, + length: 1800 + }); + Composite.add(engine.world, [cons[cons.length - 1], cons[cons.length - 2]]) } spinnerArray.push(level.spinner(50, -3325, 45, 600, 0.003, 0, 0, 0.01)) // spinner(x, y, width, height, density = 0.001, angle = 0, frictionAir = 0.001, angularVelocity = 0) { @@ -3846,30 +3971,29 @@ const level = { drip1.draw(); drip2.draw(); drip3.draw(); - button1.query(); button1.draw(); - - rotor.rotate(); - ctx.fillStyle = "hsl(175, 15%, 76%)" ctx.fillRect(9300, 2200, 600, 400) level.exit.drawAndCheck(); - level.enter.draw(); }; level.customTopLayer = () => { + rotor.rotate(); + ctx.fillStyle = "#233" ctx.beginPath(); - ctx.arc(balance1.pointA.x, balance1.pointA.y, 9, 0, 2 * Math.PI); - ctx.moveTo(balance2.pointA.x, balance2.pointA.y) - ctx.arc(balance2.pointA.x, balance2.pointA.y, 9, 0, 2 * Math.PI); - ctx.moveTo(balance3.pointA.x, balance3.pointA.y) - ctx.arc(balance3.pointA.x, balance3.pointA.y, 9, 0, 2 * Math.PI); - ctx.moveTo(balance4.pointA.x, balance4.pointA.y) - ctx.arc(balance4.pointA.x, balance4.pointA.y, 9, 0, 2 * Math.PI); - ctx.moveTo(balance5.pointA.x, balance5.pointA.y) - ctx.arc(balance5.pointA.x, balance5.pointA.y, 9, 0, 2 * Math.PI); + ctx.arc(balance1.center.x, balance1.center.y, 9, 0, 2 * Math.PI); + ctx.moveTo(balance2.center.x, balance2.center.y) + ctx.arc(balance2.center.x, balance2.center.y, 9, 0, 2 * Math.PI); + ctx.moveTo(balance3.center.x, balance3.center.y) + ctx.arc(balance3.center.x, balance3.center.y, 9, 0, 2 * Math.PI); + ctx.moveTo(balance4.center.x, balance4.center.y) + ctx.arc(balance4.center.x, balance4.center.y, 9, 0, 2 * Math.PI); + ctx.moveTo(balance5.center.x, balance5.center.y) + ctx.arc(balance5.center.x, balance5.center.y, 9, 0, 2 * Math.PI); + ctx.moveTo(rotor.center.x, rotor.center.y) + ctx.arc(rotor.center.x, rotor.center.y, 9, 0, 2 * Math.PI); ctx.fill(); hazard.query(); hazard.level(button1.isUp) @@ -3976,13 +4100,14 @@ const level = { if (simulation.isHorizontalFlipped) { //flip the map horizontally level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit - rotor = level.rotor(-5100, 2475, 0.001) //rotates other direction because flipped - balance1 = level.spinner(-300 - 25, -395, 25, 390, 0.001) //entrance - balance2 = level.spinner(-2605 - 390, 500, 390, 25, 0.001) //falling - balance3 = level.spinner(-2608 - 584, 1900, 584, 25, 0.001) //falling - balance4 = level.spinner(-9300 - 25, 2205, 25, 380, 0.001) //exit - balance5 = level.spinner(-2605 - 390, 1100, 390, 25, 0.001) //falling - + // rotor(x, y, width, height, density = 0.001, angle = 0, frictionAir = 0.001, angularVelocity = 0, rotationForce = 0.0005) { + // rotor = level.rotor(-5100, 2475, 0.001) //rotates other direction because flipped + rotor = level.rotor(-5600, 2390, 850, 50, 0.001, 0, 0.01, 0, 0.001) //balance(x, y, width, height, density = 0.001, angle = 0, frictionAir = 0.001, angularVelocity = 0, rotationForce = 0.0005) { + balance1 = level.rotor(-300 - 25, -395, 25, 390, 0.001) //entrance + balance2 = level.rotor(-2605 - 390, 500, 390, 25, 0.001) //falling + balance3 = level.rotor(-2608 - 584, 1900, 584, 25, 0.001) //falling + balance4 = level.rotor(-9300 - 25, 2205, 25, 380, 0.001) //exit + balance5 = level.rotor(-2605 - 390, 1100, 390, 25, 0.001) //falling // boost1.boostBounds.min.x = -boost1.boostBounds.min.x - 100 // boost1.boostBounds.max.x = -boost1.boostBounds.max.x + 100 // level.setPosToSpawn(300, -700); //-x // no need since 0 @@ -4008,12 +4133,13 @@ const level = { }; // level.customTopLayer = () => {}; } else { - rotor = level.rotor(5100, 2475, -0.001) - balance1 = level.spinner(300, -395, 25, 390, 0.001) //entrance - balance2 = level.spinner(2605, 500, 390, 25, 0.001) //falling - balance3 = level.spinner(2608, 1900, 584, 25, 0.001) //falling - balance4 = level.spinner(9300, 2205, 25, 380, 0.001) //exit - balance5 = level.spinner(2605, 1100, 390, 25, 0.001) //falling + // rotor = level.rotor(5100, 2475, -0.001) + rotor = level.rotor(4700, 2390, 850, 50, 0.001, 0, 0.01, 0, -0.001) //balance(x, y, width, height, density = 0.001, angle = 0, frictionAir = 0.001, angularVelocity = 0, rotationForce = 0.0005) { + balance1 = level.rotor(300, -395, 25, 390, 0.001) //entrance + balance2 = level.rotor(2605, 500, 390, 25, 0.001) //falling + balance3 = level.rotor(2608, 1900, 584, 25, 0.001) //falling + balance4 = level.rotor(9300, 2205, 25, 380, 0.001) //exit + balance5 = level.rotor(2605, 1100, 390, 25, 0.001) //falling } }, @@ -5540,6 +5666,8 @@ const level = { }, stronghold() { // player made level by Francois 👑 from discord + simulation.makeTextLog(`stronghold by Francois`); + const boost1 = level.boost(1470, -250, 1080) const boost2 = level.boost(-370, 0, 800) const boost3 = level.boost(4865, 0, 1800) @@ -5708,6 +5836,7 @@ const level = { powerUps.addResearchToLevel() //needs to run after mobs are spawned }, basement() { // player made level by Francois 👑 from discord + simulation.makeTextLog(`basement by Francois`); let button, door, buttonDoor, buttonPlateformEnd, doorPlateform let isLevelReversed = Math.random(); if (isLevelReversed < 0.7) { @@ -5996,320 +6125,322 @@ const level = { if (simulation.difficulty > 1) spawn.nodeGroup(2330, 1850, "spawns", 8, 20, 105); powerUps.chooseRandomPowerUp(3100, 1630); }, - detours() { //by Francois from discord - level.setPosToSpawn(0, 0); //lower start - level.exit.y = 150; - spawn.mapRect(level.enter.x, 45, 100, 20); - level.exit.x = 10625; - spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20); - level.defaultZoom = 1400; - simulation.zoomTransition(level.defaultZoom) - document.body.style.backgroundColor = "#d5d5d5"; - const BGColor = "rgba(0,0,0,0.1)"; - // level.fill.push({ - // x: -150, - // y: -250, - // width: 625, - // height: 325, - // color: BGColor - // }); - // level.fill.push({ - // x: 475, - // y: -520, - // width: 5375, - // height: 875, - // color: BGColor - // }); - // level.fill.push({ - // x: 5850, - // y: -1275, - // width: 2800, - // height: 2475, - // color: BGColor - // }); - // level.fill.push({ - // x: 8650, - // y: -500, - // width: 1600, - // height: 750, - // color: BGColor - // }); - // level.fill.push({ - // x: 10250, - // y: -700, - // width: 900, - // height: 950, - // color: BGColor - // }); - const balance = level.spinner(5500, -412.5, 25, 660) //entrance - const rotor = level.rotor(7000, 580, -0.001); - const doorSortieSalle = level.door(8590, -520, 20, 800, 750) - // let buttonSortieSalle - // let portalEnBas - let portalEnHaut - // let door3isClosing = false; + // detours() { //by Francois from discord + // simulation.makeTextLog(`detours by Francois`); + // level.setPosToSpawn(0, 0); //lower start + // level.exit.y = 150; + // spawn.mapRect(level.enter.x, 45, 100, 20); + // level.exit.x = 10625; + // spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20); + // level.defaultZoom = 1400; + // simulation.zoomTransition(level.defaultZoom) + // document.body.style.backgroundColor = "#d5d5d5"; + // const BGColor = "rgba(0,0,0,0.1)"; + // // level.fill.push({ + // // x: -150, + // // y: -250, + // // width: 625, + // // height: 325, + // // color: BGColor + // // }); + // // level.fill.push({ + // // x: 475, + // // y: -520, + // // width: 5375, + // // height: 875, + // // color: BGColor + // // }); + // // level.fill.push({ + // // x: 5850, + // // y: -1275, + // // width: 2800, + // // height: 2475, + // // color: BGColor + // // }); + // // level.fill.push({ + // // x: 8650, + // // y: -500, + // // width: 1600, + // // height: 750, + // // color: BGColor + // // }); + // // level.fill.push({ + // // x: 10250, + // // y: -700, + // // width: 900, + // // height: 950, + // // color: BGColor + // // }); + // const balance = level.spinner(5500, -412.5, 25, 660) //entrance + // const rotor = level.rotor(7000, 580, -0.001); + // const doorSortieSalle = level.door(8590, -520, 20, 800, 750) + // // let buttonSortieSalle + // // let portalEnBas + // let portalEnHaut + // // let door3isClosing = false; - function drawOnTheMapMapRect(x, y, dx, dy) { - spawn.mapRect(x, y, dx, dy); - len = map.length - 1 - map[len].collisionFilter.category = cat.map; - map[len].collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet; - Matter.Body.setStatic(map[len], true); //make static - Composite.add(engine.world, map[len]); //add to world - simulation.draw.setPaths() //update map graphics - } + // function drawOnTheMapMapRect(x, y, dx, dy) { + // spawn.mapRect(x, y, dx, dy); + // len = map.length - 1 + // map[len].collisionFilter.category = cat.map; + // map[len].collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet; + // Matter.Body.setStatic(map[len], true); //make static + // Composite.add(engine.world, map[len]); //add to world + // simulation.draw.setPaths() //update map graphics + // } - function drawOnTheMapBodyRect(x, y, dx, dy) { - spawn.bodyRect(x, y, dx, dy); - len = body.length - 1 - body[len].collisionFilter.category = cat.body; - body[len].collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet - Composite.add(engine.world, body[len]); //add to world - body[len].classType = "body" - } + // function drawOnTheMapBodyRect(x, y, dx, dy) { + // spawn.bodyRect(x, y, dx, dy); + // len = body.length - 1 + // body[len].collisionFilter.category = cat.body; + // body[len].collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet + // Composite.add(engine.world, body[len]); //add to world + // body[len].classType = "body" + // } - function spawnCouloirEnHaut() { - // level.fill.push({ - // x: 2575, - // y: -1150, - // width: 2550, - // height: 630, - // color: BGColor - // }); - // level.fill.push({ - // x: 1900, - // y: -2300, - // width: 1650, - // height: 1150, - // color: BGColor - // }); - // level.fill.push({ - // x: 3550, - // y: -1625, - // width: 1650, - // height: 475, - // color: BGColor - // }); - // level.fill.push({ - // x: 1800, - // y: -1120, - // width: 775, - // height: 600, - // color: BGColor - // }); - drawOnTheMapMapRect(3800, -270, 75, 75); - drawOnTheMapMapRect(3900, -895, 500, 75); - drawOnTheMapMapRect(3900, -1195, 75, 375); - drawOnTheMapMapRect(3525, -1195, 450, 75); - drawOnTheMapMapRect(3525, -1995, 50, 1575); - drawOnTheMapMapRect(3325, -1995, 50, 1575); - drawOnTheMapMapRect(3525, -1670, 1675, 75); - drawOnTheMapMapRect(5100, -1670, 100, 1250); - drawOnTheMapMapRect(1800, -1195, 1575, 75); - drawOnTheMapMapRect(1800, -1520, 375, 400); - drawOnTheMapMapRect(1800, -2370, 100, 1250); - drawOnTheMapMapRect(2375, -1845, 375, 250); - drawOnTheMapMapRect(2700, -1745, 650, 75); - drawOnTheMapMapRect(1800, -2370, 1775, 100); - drawOnTheMapMapRect(3525, -2370, 50, 775); - drawOnTheMapMapRect(4650, -1220, 550, 75); - drawOnTheMapBodyRect(3225, -1845, 100, 100); - drawOnTheMapBodyRect(3575, 1255, 125, 25); - drawOnTheMapBodyRect(2450, 2255, 25, 25); - drawOnTheMapBodyRect(3975, -945, 175, 50); - drawOnTheMapBodyRect(4825, -1295, 50, 75); - drawOnTheMapBodyRect(4850, -720, 250, 200); - drawOnTheMapBodyRect(4050, -970, 25, 25); - drawOnTheMapBodyRect(3075, -1245, 50, 50); - portalEnHaut = level.portal({ - x: 3650, - y: -1470 - }, Math.PI / 2, { - x: 3250, - y: -1473 - }, Math.PI / 2) + // function spawnCouloirEnHaut() { + // // level.fill.push({ + // // x: 2575, + // // y: -1150, + // // width: 2550, + // // height: 630, + // // color: BGColor + // // }); + // // level.fill.push({ + // // x: 1900, + // // y: -2300, + // // width: 1650, + // // height: 1150, + // // color: BGColor + // // }); + // // level.fill.push({ + // // x: 3550, + // // y: -1625, + // // width: 1650, + // // height: 475, + // // color: BGColor + // // }); + // // level.fill.push({ + // // x: 1800, + // // y: -1120, + // // width: 775, + // // height: 600, + // // color: BGColor + // // }); + // drawOnTheMapMapRect(3800, -270, 75, 75); + // drawOnTheMapMapRect(3900, -895, 500, 75); + // drawOnTheMapMapRect(3900, -1195, 75, 375); + // drawOnTheMapMapRect(3525, -1195, 450, 75); + // drawOnTheMapMapRect(3525, -1995, 50, 1575); + // drawOnTheMapMapRect(3325, -1995, 50, 1575); + // drawOnTheMapMapRect(3525, -1670, 1675, 75); + // drawOnTheMapMapRect(5100, -1670, 100, 1250); + // drawOnTheMapMapRect(1800, -1195, 1575, 75); + // drawOnTheMapMapRect(1800, -1520, 375, 400); + // drawOnTheMapMapRect(1800, -2370, 100, 1250); + // drawOnTheMapMapRect(2375, -1845, 375, 250); + // drawOnTheMapMapRect(2700, -1745, 650, 75); + // drawOnTheMapMapRect(1800, -2370, 1775, 100); + // drawOnTheMapMapRect(3525, -2370, 50, 775); + // drawOnTheMapMapRect(4650, -1220, 550, 75); + // drawOnTheMapBodyRect(3225, -1845, 100, 100); + // drawOnTheMapBodyRect(3575, 1255, 125, 25); + // drawOnTheMapBodyRect(2450, 2255, 25, 25); + // drawOnTheMapBodyRect(3975, -945, 175, 50); + // drawOnTheMapBodyRect(4825, -1295, 50, 75); + // drawOnTheMapBodyRect(4850, -720, 250, 200); + // drawOnTheMapBodyRect(4050, -970, 25, 25); + // drawOnTheMapBodyRect(3075, -1245, 50, 50); + // portalEnHaut = level.portal({ + // x: 3650, + // y: -1470 + // }, Math.PI / 2, { + // x: 3250, + // y: -1473 + // }, Math.PI / 2) - spawn.randomSmallMob(2500, -2070 + Math.random(), 1); - spawn.randomSmallMob(5000, -1370, 1); - spawn.randomMob(5000, -645, 0.9); - spawn.randomMob(4050, -970, 0.9); - spawn.randomSmallMob(2800, -1620, 0.7); - spawn.randomMob(2400, -1370, 0.5); - spawn.randomMob(3725, -1320, 0.3); - spawn.randomGroup(2115, -2020, 0.1) + // spawn.randomSmallMob(2500, -2070 + Math.random(), 1); + // spawn.randomSmallMob(5000, -1370, 1); + // spawn.randomMob(5000, -645, 0.9); + // spawn.randomMob(4050, -970, 0.9); + // spawn.randomSmallMob(2800, -1620, 0.7); + // spawn.randomMob(2400, -1370, 0.5); + // spawn.randomMob(3725, -1320, 0.3); + // spawn.randomGroup(2115, -2020, 0.1) - powerUps.spawn(5000, -1275, "heal"); + // powerUps.spawn(5000, -1275, "heal"); - levelCustom2(); - } - ////////////////////////////////////////// - level.custom = () => { - level.exit.drawAndCheck(); - rotor.rotate(); - // rotor2.rotate() + // levelCustom2(); + // } + // ////////////////////////////////////////// + // level.custom = () => { + // level.exit.drawAndCheck(); + // rotor.rotate(); + // // rotor2.rotate() - level.enter.draw(); - }; - level.customTopLayer = () => { - doorSortieSalle.draw(); - ctx.fillStyle = "#233" - ctx.beginPath(); - ctx.arc(balance.pointA.x, balance.pointA.y, 9, 0, 2 * Math.PI); - ctx.fill(); - }; - //////////////////////////////////////// - function levelCustom2() { - level.custom = () => { - portalEnHaut[2].query(); - portalEnHaut[3].query(); - rotor.rotate(); - doorSortieSalle.openClose(); - level.exit.drawAndCheck(); + // level.enter.draw(); + // }; + // level.customTopLayer = () => { + // doorSortieSalle.draw(); + // ctx.fillStyle = "#233" + // ctx.beginPath(); + // ctx.arc(balance.pointA.x, balance.pointA.y, 9, 0, 2 * Math.PI); + // ctx.fill(); + // }; + // //////////////////////////////////////// + // function levelCustom2() { + // level.custom = () => { + // portalEnHaut[2].query(); + // portalEnHaut[3].query(); + // rotor.rotate(); + // doorSortieSalle.openClose(); + // level.exit.drawAndCheck(); - level.enter.draw(); - }; - // ////////////////////////////////////// - level.customTopLayer = () => { - doorSortieSalle.draw(); - portalEnHaut[0].draw(); - portalEnHaut[1].draw(); - portalEnHaut[2].draw(); - portalEnHaut[3].draw(); - ctx.fillStyle = "#233" - ctx.beginPath(); - ctx.arc(balance.pointA.x, balance.pointA.y, 9, 0, 2 * Math.PI); - ctx.fill(); + // level.enter.draw(); + // }; + // // ////////////////////////////////////// + // level.customTopLayer = () => { + // doorSortieSalle.draw(); + // portalEnHaut[0].draw(); + // portalEnHaut[1].draw(); + // portalEnHaut[2].draw(); + // portalEnHaut[3].draw(); + // ctx.fillStyle = "#233" + // ctx.beginPath(); + // ctx.arc(balance.pointA.x, balance.pointA.y, 9, 0, 2 * Math.PI); + // ctx.fill(); - }; - } - //spawn box - spawn.mapRect(-200, -295, 75, 425); - spawn.mapRect(-200, 55, 700, 75); - spawn.mapRect(-200, -295, 700, 75); - spawn.bodyRect(470, -220, 25, 275); //porte spawn box - //couloir - spawn.mapRect(450, -520, 50, 300); //muret gauche haut - spawn.mapRect(450, 55, 50, 300); //muret gauche bas - spawn.mapRect(1700, -520, 50, 325); //muret 2 haut - spawn.mapRect(1700, 55, 50, 300); //muret 2 bas - spawn.mapRect(4375, 55, 50, 300); - spawn.mapRect(4575, 55, 50, 300); - spawn.bodyRect(4625, 155, 75, 100); - spawn.bodyRect(4725, 230, 50, 25); - if (Math.random() > 0.5) { - powerUps.chooseRandomPowerUp(4500, 200); - } else { - powerUps.chooseRandomPowerUp(8350, -630); - } - //blocs - spawn.bodyRect(7475, 1055, 50, 75); - spawn.bodyRect(7775, 1105, 25, 25); - spawn.bodyRect(6925, 1105, 125, 25); - spawn.bodyRect(6375, 380, 50, 50); - spawn.bodyRect(6425, -220, 125, 150); - spawn.bodyRect(6475, -245, 125, 25); - spawn.bodyRect(7675, -245, 100, 50); - spawn.bodyRect(7075, -520, 50, 100); - spawn.bodyRect(8400, -595, 100, 75); - spawn.bodyRect(1700, 5, 50, 50); - spawn.bodyRect(1700, -45, 50, 50); - spawn.bodyRect(1700, -95, 50, 50); - spawn.bodyRect(1700, -145, 50, 50); - spawn.bodyRect(1700, -195, 50, 50); - spawn.mapRect(450, -520, 1600, 100); //plafond 1 - spawn.mapRect(450, 255, 1600, 100); //sol 1 - spawn.mapRect(2250, -45, 1450, 75); //entresol - spawn.mapRect(3900, -520, 2000, 100); //plafond 2 - spawn.mapRect(3900, 255, 2000, 100); //sol 2 - //grande salle - spawn.bodyRect(5900, 830, 325, 300); //bloc en bas à gauche - spawn.mapRect(5775, -1295, 2900, 100); - spawn.mapRect(5775, 1130, 2900, 100); //plancher + sol grande salle - spawn.mapRect(5925, -70, 650, 50); //plateforme middle entrée - spawn.mapRect(7575, -520, 1100, 100); //sol salle en haut à droite - spawn.mapRect(6800, -420, 450, 50); //petite plateforme transition vers salle en haut - spawn.mapRect(7750, -1295, 75, 575); //mur gauche salle en haut à droite - spawn.mapRect(6100, 430, 375, 50); //plateforme en bas, gauche rotor - spawn.mapRect(7450, -195, 1225, 75); //longue plateforme - //murs grande salle - spawn.mapRect(5775, -1295, 125, 875); - spawn.mapRect(5775, 255, 125, 975); - spawn.mapRect(8550, -1295, 125, 875); - spawn.mapRect(8550, 180, 125, 1050); - //couloir 2 - spawn.mapRect(8875, -520, 1425, 325); - spawn.mapRect(8550, -520, 1750, 100); - spawn.mapRect(8550, 180, 2625, 100); - spawn.mapRect(10175, -745, 125, 325); - spawn.mapRect(10175, -745, 1000, 125); - spawn.mapRect(11050, -745, 125, 1025); - spawn.mapRect(8875, 80, 1425, 200); - //MOBS - spawn.randomSmallMob(900, -70, 1); - spawn.randomMob(4300, 95, 1); - spawn.randomSmallMob(6250, 630, 1); - spawn.randomMob(6255, -835, 0.9); - spawn.randomMob(8200, -900, 0.7); - spawn.randomMob(5700, -270, 0.7); - spawn.randomMob(8275, -320, 0.7); - spawn.randomMob(2700, -270, 0.7); - spawn.randomMob(7575, 950, 0.5); - spawn.randomMob(7000, -695, 0.4); - spawn.randomMob(1850, -345, 0.3); - spawn.randomMob(3600, -270, 0.3); - spawn.randomMob(1500, -270, 0.2); - spawn.randomMob(1250, 55, 0.2); - spawn.randomMob(8800, -45, 0.2); - spawn.randomGroup(8025, -845, 0.2); + // }; + // } + // //spawn box + // spawn.mapRect(-200, -295, 75, 425); + // spawn.mapRect(-200, 55, 700, 75); + // spawn.mapRect(-200, -295, 700, 75); + // spawn.bodyRect(470, -220, 25, 275); //porte spawn box + // //couloir + // spawn.mapRect(450, -520, 50, 300); //muret gauche haut + // spawn.mapRect(450, 55, 50, 300); //muret gauche bas + // spawn.mapRect(1700, -520, 50, 325); //muret 2 haut + // spawn.mapRect(1700, 55, 50, 300); //muret 2 bas + // spawn.mapRect(4375, 55, 50, 300); + // spawn.mapRect(4575, 55, 50, 300); + // spawn.bodyRect(4625, 155, 75, 100); + // spawn.bodyRect(4725, 230, 50, 25); + // if (Math.random() > 0.5) { + // powerUps.chooseRandomPowerUp(4500, 200); + // } else { + // powerUps.chooseRandomPowerUp(8350, -630); + // } + // //blocs + // spawn.bodyRect(7475, 1055, 50, 75); + // spawn.bodyRect(7775, 1105, 25, 25); + // spawn.bodyRect(6925, 1105, 125, 25); + // spawn.bodyRect(6375, 380, 50, 50); + // spawn.bodyRect(6425, -220, 125, 150); + // spawn.bodyRect(6475, -245, 125, 25); + // spawn.bodyRect(7675, -245, 100, 50); + // spawn.bodyRect(7075, -520, 50, 100); + // spawn.bodyRect(8400, -595, 100, 75); + // spawn.bodyRect(1700, 5, 50, 50); + // spawn.bodyRect(1700, -45, 50, 50); + // spawn.bodyRect(1700, -95, 50, 50); + // spawn.bodyRect(1700, -145, 50, 50); + // spawn.bodyRect(1700, -195, 50, 50); + // spawn.mapRect(450, -520, 1600, 100); //plafond 1 + // spawn.mapRect(450, 255, 1600, 100); //sol 1 + // spawn.mapRect(2250, -45, 1450, 75); //entresol + // spawn.mapRect(3900, -520, 2000, 100); //plafond 2 + // spawn.mapRect(3900, 255, 2000, 100); //sol 2 + // //grande salle + // spawn.bodyRect(5900, 830, 325, 300); //bloc en bas à gauche + // spawn.mapRect(5775, -1295, 2900, 100); + // spawn.mapRect(5775, 1130, 2900, 100); //plancher + sol grande salle + // spawn.mapRect(5925, -70, 650, 50); //plateforme middle entrée + // spawn.mapRect(7575, -520, 1100, 100); //sol salle en haut à droite + // spawn.mapRect(6800, -420, 450, 50); //petite plateforme transition vers salle en haut + // spawn.mapRect(7750, -1295, 75, 575); //mur gauche salle en haut à droite + // spawn.mapRect(6100, 430, 375, 50); //plateforme en bas, gauche rotor + // spawn.mapRect(7450, -195, 1225, 75); //longue plateforme + // //murs grande salle + // spawn.mapRect(5775, -1295, 125, 875); + // spawn.mapRect(5775, 255, 125, 975); + // spawn.mapRect(8550, -1295, 125, 875); + // spawn.mapRect(8550, 180, 125, 1050); + // //couloir 2 + // spawn.mapRect(8875, -520, 1425, 325); + // spawn.mapRect(8550, -520, 1750, 100); + // spawn.mapRect(8550, 180, 2625, 100); + // spawn.mapRect(10175, -745, 125, 325); + // spawn.mapRect(10175, -745, 1000, 125); + // spawn.mapRect(11050, -745, 125, 1025); + // spawn.mapRect(8875, 80, 1425, 200); + // //MOBS + // spawn.randomSmallMob(900, -70, 1); + // spawn.randomMob(4300, 95, 1); + // spawn.randomSmallMob(6250, 630, 1); + // spawn.randomMob(6255, -835, 0.9); + // spawn.randomMob(8200, -900, 0.7); + // spawn.randomMob(5700, -270, 0.7); + // spawn.randomMob(8275, -320, 0.7); + // spawn.randomMob(2700, -270, 0.7); + // spawn.randomMob(7575, 950, 0.5); + // spawn.randomMob(7000, -695, 0.4); + // spawn.randomMob(1850, -345, 0.3); + // spawn.randomMob(3600, -270, 0.3); + // spawn.randomMob(1500, -270, 0.2); + // spawn.randomMob(1250, 55, 0.2); + // spawn.randomMob(8800, -45, 0.2); + // spawn.randomGroup(8025, -845, 0.2); - if (simulation.difficulty > 2) { - // if (Math.random() < 0.2) { - // // tether ball - // spawn.tetherBoss(8000, 630, { x: 8550, y: 680 }) - // let me = mob[mob.length - 1]; - // me.onDeath = function() { //please don't edit the onDeath function this causes serious bugs - // this.removeCons(); //remove constraint - // spawnCouloirEnHaut() - // doorSortieSalle.isClosing = false; - // }; - // if (simulation.difficulty > 4) spawn.nodeGroup(8000, 630, "spawns", 8, 20, 105); - // } else { - spawn.randomLevelBoss(8000, 630, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss", "bomberBoss", "orbitalBoss", "pulsarBoss"]); - spawn.secondaryBossChance(8000, 630) - //find level boss index - let me - for (let i = 0, len = mob.length; i < len; i++) { - if (mob[i].isBoss) me = mob[i] - } - if (me) { - me.onDeath = function() { //please don't edit the onDeath function this causes serious bugs - spawnCouloirEnHaut() - doorSortieSalle.isClosing = false; - }; - } else { - spawnCouloirEnHaut() - doorSortieSalle.isClosing = false; - } - // } - } else { - spawn.randomLevelBoss(8000, 630, ["shooterBoss"]); - let me - for (let i = 0, len = mob.length; i < len; i++) { - if (mob[i].isBoss) me = mob[i] - } - if (me) { - me.onDeath = function() { //please don't edit the onDeath function this causes serious bugs - spawnCouloirEnHaut() - doorSortieSalle.isClosing = false; - }; - } else { - spawnCouloirEnHaut() - doorSortieSalle.isClosing = false; - } - } - }, + // if (simulation.difficulty > 2) { + // // if (Math.random() < 0.2) { + // // // tether ball + // // spawn.tetherBoss(8000, 630, { x: 8550, y: 680 }) + // // let me = mob[mob.length - 1]; + // // me.onDeath = function() { //please don't edit the onDeath function this causes serious bugs + // // this.removeCons(); //remove constraint + // // spawnCouloirEnHaut() + // // doorSortieSalle.isClosing = false; + // // }; + // // if (simulation.difficulty > 4) spawn.nodeGroup(8000, 630, "spawns", 8, 20, 105); + // // } else { + // spawn.randomLevelBoss(8000, 630, ["shooterBoss", "launcherBoss", "laserTargetingBoss", "spiderBoss", "laserBoss", "bomberBoss", "orbitalBoss", "pulsarBoss"]); + // spawn.secondaryBossChance(8000, 630) + // //find level boss index + // let me + // for (let i = 0, len = mob.length; i < len; i++) { + // if (mob[i].isBoss) me = mob[i] + // } + // if (me) { + // me.onDeath = function() { //please don't edit the onDeath function this causes serious bugs + // spawnCouloirEnHaut() + // doorSortieSalle.isClosing = false; + // }; + // } else { + // spawnCouloirEnHaut() + // doorSortieSalle.isClosing = false; + // } + // // } + // } else { + // spawn.randomLevelBoss(8000, 630, ["shooterBoss"]); + // let me + // for (let i = 0, len = mob.length; i < len; i++) { + // if (mob[i].isBoss) me = mob[i] + // } + // if (me) { + // me.onDeath = function() { //please don't edit the onDeath function this causes serious bugs + // spawnCouloirEnHaut() + // doorSortieSalle.isClosing = false; + // }; + // } else { + // spawnCouloirEnHaut() + // doorSortieSalle.isClosing = false; + // } + // } + // }, house() { //by Francois from discord - const rotor = level.rotor(4315, -315, -0.0002, 120, 20, 200); + simulation.makeTextLog(`house by Francois`); + const rotor = level.rotor(4251, -325, 120, 20, 200, 0, 0.01, 0, -0.0001); const hazard = level.hazard(4350, -1000, 300, 110); const doorBedroom = level.door(1152, -1150, 25, 250, 250); const doorGrenier = level.door(1152, -1625, 25, 150, 160); @@ -6785,6 +6916,7 @@ const level = { } }, perplex() { //by Oranger from discord + simulation.makeTextLog(`perplex by Oranger`); document.body.style.backgroundColor = "#dcdcde"; level.setPosToSpawn(-600, 400); spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20); @@ -6806,7 +6938,8 @@ const level = { x: 1700, y: -1700 }, -Math.PI / 2) //up - const rotor = level.rotor(-200, -1950, -0.001) + // rotor(x, y, width, height, density = 0.001, angle = 0, frictionAir = 0.001, angularVelocity = 0, rotationForce = 0.0005) { + const rotor = level.rotor(-600, -1950, 800, 50, 0.001, 0, 0.01, 0, -0.001) level.custom = () => { portal[2].query(true) @@ -6969,6 +7102,7 @@ const level = { spawn.secondaryBossChance(7725, 2275) }, coliseum() { + simulation.makeTextLog(`coliseum by iNoobBoi`); level.custom = () => { level.exit.drawAndCheck(); @@ -7119,6 +7253,8 @@ const level = { spawn.secondaryBossChance(6600, 600) }, crossfire() { + simulation.makeTextLog(`crossfire by iNoobBoi`); + //*1.5 //Level Setup const slimePitOne = level.hazard(0, 850, 3800, 120); @@ -7282,6 +7418,8 @@ const level = { spawn.debris(9300, -900, 400, debrisCount); }, vats() { // Made by Dablux#6610 on Discord + simulation.makeTextLog(`vats by Dablux`); + simulation.zoomScale = 1500; level.setPosToSpawn(4400, -1060) spawn.mapRect(level.enter.x, level.enter.y + 30, 100, 20) @@ -7304,7 +7442,10 @@ const level = { const deliverySlime2 = level.hazard(3700, -461, 100, 1141) const slimePit = level.hazard(700, 1200, 2500, 1300, 0.004, "hsla(160, 100%, 35%,0.75)") const topSlime = level.hazard(800, -460, 2900, 90, 0.004, "hsla(160, 100%, 35%,0.75)") - const rotor = level.rotor(0, -725, 0.001) + // const rotor = level.rotor(0, -725, 0.001) + const rotor = level.rotor(-400, -725, 800, 50, 0.001, 0, 0.01, 0, 0.001) + + const portal = level.portal({ x: -135, y: 800 @@ -7718,6 +7859,8 @@ const level = { } }, "n-gon"() { //make by Oranger + simulation.makeTextLog(`"n-gon" by Oranger`); + document.body.style.backgroundColor = "#dcdcde"; let needGravity = []; let s = { //mech statue @@ -8121,6 +8264,8 @@ const level = { } }, tunnel() { // by Scarlettt + simulation.makeTextLog(`tunnel by Scarlettt`); + level.custom = () => { level.exit.drawAndCheck(); @@ -8593,6 +8738,8 @@ const level = { } }, run() { + simulation.makeTextLog(`run by iNoobBoi`); + addPartToMap = (len) => { //adds new map elements to the level while the level is already running //don't forget to run simulation.draw.setPaths() after you all the the elements so they show up visually map[len].collisionFilter.category = cat.map; map[len].collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet; @@ -8943,6 +9090,8 @@ const level = { } }, islands() { + simulation.makeTextLog(`islands by Richard0820`); + const boost1 = level.boost(58500, -18264, 1300); let portal2, portal3; // const removeIndex1 = map.length - 1; diff --git a/js/player.js b/js/player.js index ebe873d..6314461 100644 --- a/js/player.js +++ b/js/player.js @@ -522,7 +522,7 @@ const m = { if (tech.isAddBlockMass && m.isHolding) dmg *= 0.15 if (tech.isSpeedHarm) dmg *= 1 - Math.min(player.speed * 0.0165, 0.66) if (tech.isSlowFPS) dmg *= 0.8 - if (tech.isHarmReduce && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.4 + if (tech.isHarmReduce && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.34 if (tech.isNeutronium && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.1 if (tech.isBotArmor) dmg *= 0.93 ** b.totalBots() if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.33; @@ -956,7 +956,7 @@ const m = { m.calculateFieldThreshold(); //run calculateFieldThreshold after setting fieldArc, used for powerUp grab and mobPush with lookingAt(mob) m.isBodiesAsleep = true; m.wakeCheck(); - // m.setMaxEnergy(); + m.setMaxEnergy(); m.hole = { isOn: false, isReady: false, @@ -971,7 +971,7 @@ const m = { } }, setMaxEnergy() { - m.maxEnergy = (tech.isMaxEnergyTech ? 0.5 : 1) + tech.bonusEnergy + tech.healMaxEnergyBonus + tech.harmonicEnergy + 2 * tech.isGroundState + 3 * tech.isRelay * tech.isFlipFlopOn * tech.isRelayEnergy + m.maxEnergy = (tech.isMaxEnergyTech ? 0.5 : 1) + tech.bonusEnergy + tech.healMaxEnergyBonus + tech.harmonicEnergy + 2 * tech.isGroundState + 3 * tech.isRelay * tech.isFlipFlopOn * tech.isRelayEnergy + 0.5 * (m.fieldUpgrades[m.fieldMode].name === "standing wave") simulation.makeTextLog(`m.maxEnergy= ${(m.maxEnergy.toFixed(2))}`) }, fieldMeterColor: "#0cf", @@ -1336,7 +1336,7 @@ const m = { //draw electricity const step = 40 ctx.beginPath(); - for (let i = 0, len = 1.5 * tech.blockDmg; i < len; i++) { + for (let i = 0, len = 1.3 * tech.blockDmg; i < len; i++) { let x = m.pos.x - 20 * unit.x; let y = m.pos.y - 20 * unit.y; ctx.moveTo(x, y); @@ -1527,7 +1527,7 @@ const m = { }, { name: "standing wave", - description: "3 oscillating shields are permanently active
deflecting protects you in every direction
deflecting has 50% less recoil", //drains energy + description: "3 oscillating shields are permanently active
deflecting protects you in every direction
increase your maxenergy by 50", //drains energy //deflecting has 50% less recoil drainCD: 0, effect: () => { m.fieldBlockCD = 0; @@ -1560,7 +1560,7 @@ const m = { m.pushMass(mob[i]); this.drainCD = m.cycle + 10 } - if (mob[i].isShielded || mob[i].shield) m.fieldCDcycle = m.cycle + 30 + if (mob[i].isShielded || mob[i].shield) m.fieldCDcycle = m.cycle + 20 } } } @@ -1589,7 +1589,7 @@ const m = { m.pushMass(mob[i]); this.drainCD = m.cycle + 10 } - if (mob[i].isShielded || mob[i].shield) m.fieldCDcycle = m.cycle + 30 + if (mob[i].isShielded || mob[i].shield) m.fieldCDcycle = m.cycle + 20 } } } @@ -1660,7 +1660,7 @@ const m = { mob[i].damage(tech.blockDmg * m.dmgScale) const step = 40 ctx.beginPath(); - for (let i = 0, len = 1.5 * tech.blockDmg; i < len; i++) { + for (let i = 0, len = 1.3 * tech.blockDmg; i < len; i++) { let x = m.fieldPosition.x - 20 * unit.x; let y = m.fieldPosition.y - 20 * unit.y; ctx.moveTo(x, y); @@ -1967,6 +1967,11 @@ const m = { // m.eyeFillColor = m.fieldMeterColor m.hold = function() { if (m.energy > m.maxEnergy - 0.02 && m.fieldCDcycle < m.cycle && !input.field && bullet.length < 300 && (m.cycle % 2)) { + // if (tech.isBotField) { + // b.randomBot(this.position, false) + // bullet[bullet.length - 1].endCycle = simulation.cycle + 840 //14 seconds + // m.energy -= 0.35 + // } else if (tech.isSporeField) { if (tech.isSporeWorm) { const drain = 0.16 + (Math.max(bullet.length, 130) - 130) * 0.02 @@ -2111,9 +2116,9 @@ const m = { isPopping: false, isAttached: false, isOn: false, - drain: 0.0015, + drain: 0.0011, radiusLimit: 10, - damage: 0.7, + damage: 0.8, 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))); @@ -2355,7 +2360,6 @@ const m = { } m.plasmaBall.setPositionToNose() - //add friction for player when holding ball, more friction in vertical // const floatScale = Math.sqrt(m.plasmaBall.circleRadius) // const friction = 0.0002 * floatScale @@ -2380,10 +2384,6 @@ const m = { } else { player.force.y -= 0.5 * player.mass * simulation.g; } - - - - } else { m.fieldCDcycle = m.cycle + 90; m.plasmaBall.fire() @@ -2402,12 +2402,8 @@ const m = { } } m.drawFieldMeter("rgba(0, 0, 0, 0.2)") - m.plasmaBall.do() } - - - } else if (tech.isExtruder) { m.hold = function() { b.isExtruderOn = false @@ -2651,7 +2647,7 @@ const m = { } else { m.fieldFire = true; m.isBodiesAsleep = false; - m.drain = 0.0005 + m.drain = 0.0003 m.hold = function() { if (m.isHolding) { m.wakeCheck(); @@ -2662,7 +2658,7 @@ const m = { m.grabPowerUp(); m.lookForPickUp(); - m.drain += 0.0000025 //also increases inside tech.isTimeSkip + m.drain += 0.000002 //also increases inside tech.isTimeSkip if (m.energy > m.drain) { m.energy -= m.drain; if (m.energy < m.drain) { diff --git a/js/powerup.js b/js/powerup.js index 6b53eb3..ecac22c 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -736,7 +736,7 @@ const powerUps = { function cycle() { count++ - if (count < 600 && simulation.isChoosing) { + if (count < tech.brainStormDelay * 5 && simulation.isChoosing) { if (!(count % tech.brainStormDelay)) { powerUps.tech.effect(); document.getElementById("choose-grid").style.pointerEvents = "auto"; //turn off the normal 500ms delay diff --git a/js/simulation.js b/js/simulation.js index 50581cb..c9d9ca0 100644 --- a/js/simulation.js +++ b/js/simulation.js @@ -823,24 +823,29 @@ const simulation = { simulation.drawList = []; if (tech.isDronesTravel && m.alive) { - console.log('hi') //count drones let count = 0 + let sporeCount = 0 + let wormCount = 0 let deliveryCount = 0 for (let i = 0; i < bullet.length; ++i) { if (bullet[i].isDrone) { count++ if (bullet[i].isImproved) deliveryCount++ + } else if (bullet[i].isSpore) { + sporeCount++ + } else if (bullet[i].wormSize) { + wormCount++ } } - // count *= 2 + //respawn drones in animation frame let respawnDrones = () => { if (count > 0) { requestAnimationFrame(respawnDrones); if (!simulation.paused && !simulation.isChoosing) { - count-- const where = { x: level.enter.x + 50, y: level.enter.y - 60 } + count-- if (tech.isDroneRadioactive) { b.droneRadioactive({ x: where.x + 100 * (Math.random() - 0.5), y: where.y + 100 * (Math.random() - 0.5) }, 0) } else { @@ -859,6 +864,32 @@ const simulation = { } } requestAnimationFrame(respawnDrones); + + //respawn spores in animation frame + let respawnSpores = () => { + if (sporeCount > 0) { + requestAnimationFrame(respawnSpores); + if (!simulation.paused && !simulation.isChoosing) { + sporeCount-- + const where = { x: level.enter.x + 50, y: level.enter.y - 60 } + b.spore({ x: where.x + 100 * (Math.random() - 0.5), y: where.y + 120 * (Math.random() - 0.5) }) + } + } + } + requestAnimationFrame(respawnSpores); + + //respawn worms in animation frame + let respawnWorms = () => { + if (wormCount > 0) { + requestAnimationFrame(respawnWorms); + if (!simulation.paused && !simulation.isChoosing) { + wormCount-- + const where = { x: level.enter.x + 50, y: level.enter.y - 60 } + b.worm({ x: where.x + 100 * (Math.random() - 0.5), y: where.y + 120 * (Math.random() - 0.5) }) + } + } + } + requestAnimationFrame(respawnWorms); } function removeAll(array) { diff --git a/js/spawn.js b/js/spawn.js index 8f2bfef..1f51bc9 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -2988,6 +2988,7 @@ const spawn = { }, Vector.normalise(Vector.sub(this.fireTarget, this.position))); //distance between the target and the player's location if ( + m.isCloak || dot > 0.03 || // not looking at target Matter.Query.ray(map, this.fireTarget, this.position).length || Matter.Query.ray(body, this.fireTarget, this.position).length || //something blocking line of sight Vector.magnitude(Vector.sub(m.pos, this.fireTarget)) > 1000 // distance from player to target is very far, (this is because dot product can't tell if facing 180 degrees away) @@ -3542,6 +3543,10 @@ const spawn = { spawn.spawnOrbitals(me, radius + 50 + 200 * Math.random(), 1) Matter.Body.setDensity(me, 0.0022 + 0.0002 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger me.damageReduction = 0.09 / (tech.isScaleMobsWithDuplication ? 1 + tech.duplicationChance() : 1) + + me.startingDamageReduction = me.damageReduction + me.isInvulnerable = false + me.onDeath = function() { if (isSpawnBossPowerUp) powerUps.spawnBossPowerUp(this.position.x, this.position.y) }; @@ -3571,8 +3576,8 @@ const spawn = { if (this.speed < 0.01) { Matter.Body.setVelocity(this, Vector.mult(Vector.normalise(Vector.sub(player.position, this.position)), 0.1)); } else { - if (Math.abs(this.velocity.y) < 15) Matter.Body.setVelocity(this, { x: this.velocity.x, y: this.velocity.y * 1.07 }); - if (Math.abs(this.velocity.x) < 11) Matter.Body.setVelocity(this, { x: this.velocity.x * 1.07, y: this.velocity.y }); + if (Math.abs(this.velocity.y) < 13) Matter.Body.setVelocity(this, { x: this.velocity.x, y: this.velocity.y * 1.07 }); + if (Math.abs(this.velocity.x) < 10) Matter.Body.setVelocity(this, { x: this.velocity.x * 1.07, y: this.velocity.y }); } } me.noFire = function() { @@ -3582,18 +3587,32 @@ const spawn = { this.phaseCycle = -2 this.do = this.burstFire this.frictionAir = 1 - if (!this.isShielded) spawn.shield(this, this.position.x, this.position.y, 1); + this.isInvulnerable = true + this.damageReduction = 0 + // if (!this.isShielded) spawn.shield(this, this.position.x, this.position.y, 1); } }; me.burstFire = function() { this.normalDoStuff(); this.radialLines() + //draw invulnerable + ctx.beginPath(); + let vertices = this.vertices; + ctx.moveTo(vertices[0].x, vertices[0].y); + for (let j = 1; j < vertices.length; j++) ctx.lineTo(vertices[j].x, vertices[j].y); + ctx.lineTo(vertices[0].x, vertices[0].y); + ctx.lineWidth = 13 + 5 * Math.random(); + ctx.strokeStyle = `rgba(255,255,255,${0.5+0.2*Math.random()})`; + ctx.stroke(); + if (!(simulation.cycle % this.burstFireFreq)) { this.phaseCycle++ if (this.phaseCycle > this.burstTotalPhases) { //start spiral fire mode this.phaseCycle = -7 this.do = this.noFire this.frictionAir = 0; + this.isInvulnerable = false + this.damageReduction = this.startingDamageReduction Matter.Body.setVelocity(this, Vector.rotate({ x: 20, y: 0 }, 2 * Math.PI * Math.random())); if (this.isShielded) { //remove shield for (let i = 0; i < mob.length; i++) { diff --git a/js/tech.js b/js/tech.js index 666ce58..65acb1d 100644 --- a/js/tech.js +++ b/js/tech.js @@ -232,7 +232,7 @@ const tech = { if (tech.isDupDamage) dmg *= 1 + Math.min(1, tech.duplicationChance()) if (tech.isLowEnergyDamage) dmg *= 1 + 0.7 * Math.max(0, 1 - m.energy) if (tech.isMaxEnergyTech) dmg *= 1.5 - if (tech.isEnergyNoAmmo) dmg *= 1.70 + if (tech.isEnergyNoAmmo) dmg *= 1.88 if (tech.isDamageForGuns) dmg *= 1 + 0.12 * b.inventory.length if (tech.isLowHealthDmg) dmg *= 1 + Math.max(0, 1 - m.health) * 0.5 if (tech.isHarmDamage && m.lastHarmCycle + 600 > m.cycle) dmg *= 3; @@ -250,7 +250,7 @@ const tech = { return dmg * tech.slowFire * tech.aimDamage }, duplicationChance() { - return Math.max(0, (tech.isPowerUpsVanish ? 0.12 : 0) + (tech.isStimulatedEmission ? 0.15 : 0) + tech.cancelCount * 0.043 + tech.duplicateChance + m.duplicateChance + tech.wormDuplicate + tech.cloakDuplication + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.5 : 0)) + return Math.max(0, (tech.isPowerUpsVanish ? 0.12 : 0) + (tech.isStimulatedEmission ? 0.15 : 0) + tech.cancelCount * 0.043 + tech.duplicateChance + m.duplicateChance + tech.fieldDuplicate + tech.cloakDuplication + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.5 : 0)) }, isScaleMobsWithDuplication: false, maxDuplicationEvent() { @@ -312,7 +312,7 @@ const tech = { allowed() { return !tech.isSuperDeterminism }, - requires: "NOT EXPERIMENT MODE, not superdeterminism", + requires: "not superdeterminism", effect() { powerUps.spawn(m.pos.x, m.pos.y, "gun"); // this.count-- @@ -592,7 +592,7 @@ const tech = { }, { name: "exciton", - description: `increase damage by 70%, but
${powerUps.orb.ammo()} will no longer spawn`, + description: `increase damage by 88%, but
${powerUps.orb.ammo()} will no longer spawn`, maxCount: 1, count: 0, frequency: 1, @@ -671,7 +671,7 @@ const tech = { allowed() { return !m.isShipMode && !tech.isAlwaysFire, !tech.isGrapple }, - requires: "not ship mode, not automatic, grappling hook", + requires: "not ship mode, automatic, grappling hook", effect: () => { tech.isFireMoveLock = true; b.setFireCD(); @@ -2114,7 +2114,7 @@ const tech = { allowed() { //&& (m.fieldUpgrades[m.fieldMode].name !== "molecular assembler" || m.maxEnergy > 1) return m.maxEnergy > 0.99 && m.fieldUpgrades[m.fieldMode].name !== "standing wave" && !tech.isEnergyHealth && !tech.isRewindField //&& !tech.isRewindGun }, - requires: "not standing wave, mass-energy, max energy reduction", + requires: "not standing wave, mass-energy, max energy reduction, retrocausality", effect() { tech.isRewindAvoidDeath = true; }, @@ -2910,7 +2910,7 @@ const tech = { allowed() { return (powerUps.research.count > 3 || build.isExperimentSelection) && !tech.isSuperDeterminism }, - requires: "at least 4 research and not superdeterminism", + requires: "at least 4 research, not superdeterminism", effect() { tech.renormalization = true; }, @@ -3008,7 +3008,7 @@ const tech = { effect() { tech.isBrainstorm = true tech.isBrainstormActive = false - tech.brainStormDelay = 120 + tech.brainStormDelay = 145 - simulation.difficultyMode * 10 }, remove() { tech.isBrainstorm = false @@ -3134,7 +3134,7 @@ const tech = { allowed() { return true }, - requires: "not superdeterminism", + requires: "", effect() { tech.isPauseSwitchField = true; for (let i = 0; i < 6; i++) powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false); @@ -3148,7 +3148,7 @@ const tech = { }, { name: "paradigm shift", - description: `clickingtech while paused ejects them
10% chance to convert that tech into ${powerUps.orb.research(1)}`, + description: `clickingtech while paused ejects them
10% chance to convert that tech into ${powerUps.orb.research(1)}`, maxCount: 1, count: 0, frequency: 1, @@ -3193,7 +3193,7 @@ const tech = { allowed() { return (build.isExperimentSelection || powerUps.research.count > 3) && !tech.isDuplicateBoss }, - requires: "at least 4 research and not parthenogenesis", + requires: "at least 4 research, not parthenogenesis", effect() { tech.isResearchBoss = true; //abiogenesis }, @@ -3253,7 +3253,7 @@ const tech = { allowed() { return level.onLevel > 1 && !tech.isEnergyHealth }, - requires: "past levels 1, not mass-energy", + requires: "past level 1, not mass-energy", effect() { tech.isNoHeals = true; level.difficultyDecrease(simulation.difficultyMode * 2) @@ -3605,7 +3605,7 @@ const tech = { allowed() { return !tech.isSuperDeterminism }, - requires: "NOT EXPERIMENT MODE, not superdeterminism", + requires: "not superdeterminism", effect() { powerUps.spawn(m.pos.x, m.pos.y, "field"); for (let i = 0; i < 7; i++) powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false); @@ -3767,7 +3767,7 @@ const tech = { allowed() { return ((tech.haveGunCheck("nail gun") && tech.isNeedles) || (tech.isNeedles && tech.haveGunCheck("shotgun"))) && !tech.isNeedleIce }, - requires: "needle gun, not needle ice", + requires: "nail gun, needle gun, not needle ice", effect() { tech.needleTunnel = true }, @@ -3825,7 +3825,7 @@ const tech = { allowed() { return ((tech.haveGunCheck("nail gun") && !tech.nailInstantFireRate) || (tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isFoamShot && !tech.isSporeWorm)) && !tech.isNeedles && !tech.isIceCrystals && !tech.isIceShot }, - requires: "nail gun shot gun, not ice crystal, needles, or pneumatic actuator", + requires: "nail gun, shot gun, not ice crystal, needles, or pneumatic actuator", effect() { tech.isRivets = true for (i = 0, len = b.guns.length; i < len; i++) { //find which gun @@ -4040,7 +4040,7 @@ const tech = { allowed() { return (tech.isNailShot || tech.isNeedles || tech.nailBotCount > 1 || tech.haveGunCheck("nail gun") || tech.isRivets) && !tech.isIncendiary }, - requires: "needles, nails, rivets, not incendiary", + requires: "nail gun, needles, nails, rivets, not incendiary", effect() { tech.isNailCrit = true }, @@ -4060,7 +4060,7 @@ const tech = { allowed() { return tech.isMineDrop + tech.nailBotCount + tech.fragments + tech.nailsDeathMob / 2 + ((tech.haveGunCheck("mine") && !tech.isLaserMine) + (tech.haveGunCheck("nail gun") && !tech.isShieldPierce) + tech.isNeedles + tech.isNailShot) * 2 > 1 }, - requires: "nail gun, nails, rivets, not ceramic needles", + requires: "nail gun, nails, rivets, mine, not ceramic needles", effect() { tech.isNailRadiation = true; }, @@ -4080,7 +4080,7 @@ const tech = { allowed() { return tech.isNailRadiation && !tech.isFastRadiation }, - requires: "irradiated nails, not 1s half-life", + requires: "nail gun, mine, irradiated nails, not 1s half-life", effect() { tech.isSlowRadiation = true; }, @@ -4100,7 +4100,7 @@ const tech = { allowed() { return tech.isNailRadiation && !tech.isSlowRadiation }, - requires: "irradiated nails, not 6s half-life", + requires: "nail gun, mine, irradiated nails, not 6s half-life", effect() { tech.isFastRadiation = true; }, @@ -4249,16 +4249,16 @@ const tech = { }, { name: "incendiary ammunition", - description: "rivets, super balls, and drones
are loaded with explosives", + description: "shotgun, rivets, super balls, and drones
are loaded with explosives", isGunTech: true, maxCount: 1, count: 0, frequency: 1, frequencyDefault: 1, allowed() { - return tech.haveGunCheck("super balls") || (tech.isRivets && !tech.isNailCrit) || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && !(tech.isDroneTeleport || tech.isDroneRadioactive || tech.isSporeField || tech.isMissileField || tech.isIceField)) || (tech.haveGunCheck("drones") && !tech.isForeverDrones && !tech.isDroneRadioactive && !tech.isDroneTeleport) + return tech.haveGunCheck("shotgun") || tech.haveGunCheck("super balls") || (tech.isRivets && !tech.isNailCrit) || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && !(tech.isDroneTeleport || tech.isDroneRadioactive || tech.isSporeField || tech.isMissileField || tech.isIceField)) || (tech.haveGunCheck("drones") && !tech.isForeverDrones && !tech.isDroneRadioactive && !tech.isDroneTeleport) }, - requires: "super balls, rivets, drones, not irradiated drones or burst drones", + requires: "shotgun, super balls, rivets, drones, not irradiated drones or burst drones", effect() { tech.isIncendiary = true }, @@ -4581,7 +4581,7 @@ const tech = { isBot: true, isBotTech: true, allowed() { - return tech.haveGunCheck("missiles", false) + return tech.haveGunCheck("missiles", false) && tech.missileFireCD === 45 }, requires: "missiles", effect() { @@ -4778,7 +4778,7 @@ const tech = { }, { name: "MIRV", - description: "fire +1missile and grenade per shot
decrease explosionradius up to 10%", + description: "fire +1missile and grenade per shot
decrease explosionradius up to 12%", isGunTech: true, maxCount: 9, count: 0, @@ -5012,7 +5012,7 @@ const tech = { allowed() { return tech.haveGunCheck("spores") }, - requires: "spore gun", + requires: "spores", effect() { tech.isSporeGrowth = true }, @@ -5032,7 +5032,7 @@ const tech = { allowed() { return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField }, - requires: "spore gun, spores", + requires: "spores", effect() { tech.isFastSpores = true }, @@ -5052,7 +5052,7 @@ const tech = { allowed() { return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField || tech.isSporeWorm }, - requires: "spore gun, spores or worms", + requires: "spores", effect() { tech.isSporeFreeze = true }, @@ -5071,7 +5071,7 @@ const tech = { allowed() { return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField || tech.isSporeWorm }, - requires: "spore gun, spores or worms", + requires: "spores", effect() { tech.isSporeFollow = true }, @@ -5090,7 +5090,7 @@ const tech = { allowed() { return (tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField) && !tech.isEnergyHealth || tech.isSporeWorm }, - requires: "spore gun, spores, worms, not mass-energy", + requires: "spores, not mass-energy", effect() { tech.isMutualism = true }, @@ -5129,7 +5129,7 @@ const tech = { allowed() { return tech.haveGunCheck("spores") || tech.sporesOnDeath > 0 || tech.isSporeField || (tech.haveGunCheck("shotgun") && !tech.isIncendiary && !tech.isRivets && !tech.isIceShot && !tech.isFoamShot && !tech.isNeedles && !tech.isNailShot) }, - requires: "spore gun, spores", + requires: "spores", effect() { tech.isSporeWorm = true }, @@ -5148,7 +5148,7 @@ const tech = { allowed() { return tech.isSporeWorm }, - requires: "spore gun, shotgun, worms", + requires: "spores, shotgun, worms", effect() { tech.wormSize++ }, @@ -5156,6 +5156,25 @@ const tech = { tech.wormSize = 0 } }, + { + name: "path integration", + description: "drones, spores, and worms
travel with you through levels", + isGunTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return (tech.haveGunCheck("spores") && tech.isSporeFollow) || tech.haveGunCheck("drones") || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && !(tech.isMissileField || tech.isIceField)) + }, + requires: "spores, diplochory, drones", + effect() { + tech.isDronesTravel = true + }, + remove() { + tech.isDronesTravel = false + } + }, { name: "anti-shear topology", link: `anti-shear topology`, @@ -5218,7 +5237,7 @@ const tech = { allowed() { return !tech.isExtraMaxEnergy && (tech.haveGunCheck("drones") || tech.isForeverDrones || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && !(tech.isSporeField || tech.isMissileField || tech.isIceField))) }, - requires: "drones, not permittivity", + requires: "drones, not weak interaction", effect() { tech.isDroneGrab = true }, @@ -5247,25 +5266,6 @@ const tech = { tech.isDroneRespawn = false } }, - { - name: "autonomous navigation", - description: "drones travel with you through levels
and reset their durability", - isGunTech: true, - maxCount: 1, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return tech.haveGunCheck("drones") || (m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && !(tech.isSporeField || tech.isMissileField || tech.isIceField)) - }, - requires: "drones", - effect() { - tech.isDronesTravel = true - }, - remove() { - tech.isDronesTravel = false - } - }, { name: "brushless motor", description: "drones rapidly rush towards their target
increase drone collision damage by 33%", @@ -5351,7 +5351,7 @@ const tech = { allowed() { return tech.isDroneRadioactive }, - requires: "drones irradiated drones", + requires: "drones, irradiated drones", effect() { tech.droneRadioDamage = 2 }, @@ -5606,7 +5606,7 @@ const tech = { allowed() { return tech.haveGunCheck("harpoon") && !tech.isFilament && !tech.isHarpoonPowerUp && !tech.isGrapple }, - requires: "harpoon, not filament, toggling harpoon, grappling hook", + requires: "harpoon, not UHMWPE, induction furnace, grappling hook", ammoBonus: 8, effect() { tech.isRailGun = true; @@ -5730,7 +5730,7 @@ const tech = { allowed() { return tech.haveGunCheck("harpoon") && !tech.isImmuneGrapple }, - requires: "railgun, not Bose–Einstein statistics", + requires: "harpoon, not bulk modulus", effect() { tech.isRailEnergyGain = true; }, @@ -5749,7 +5749,7 @@ const tech = { allowed() { return (!tech.isLargeHarpoon && tech.haveGunCheck("harpoon")) || tech.isNeedles }, - requires: "nail gun, needle gun, needle, harpoon, not Bessemer process", + requires: "needle gun, harpoon, not Bessemer process", effect() { tech.isShieldPierce = true }, @@ -5768,7 +5768,7 @@ const tech = { allowed() { return tech.haveGunCheck("harpoon") && !tech.isShieldPierce }, - requires: "harpoon not ceramics", + requires: "harpoon, not ceramics", effect() { tech.isLargeHarpoon = true; }, @@ -5778,8 +5778,9 @@ const tech = { }, { name: "smelting", + // description: `forge 3ammo into a new harpoon
fire +1harpoon with each shot`, + descriptionFunction() { return `forge ${(tech.isRailGun ?5:3)*(2+this.count)}ammo into a new harpoon
fire +1harpoon with each shot` }, // description: `spend ${powerUps.orb.ammo(2)}to upgrade the harpoon
fire +1harpoon with each shot`, - description: `forge 3ammo into a new harpoon
fire +1harpoon with each shot`, // descriptionFunction() { return `forge ${tech.isRailGun? 10: 2}ammo into a new harpoon
fire +1harpoon with each shot` }, isGunTech: true, maxCount: 9, @@ -5787,28 +5788,28 @@ const tech = { frequency: 1, frequencyDefault: 1, allowed() { - return tech.haveGunCheck("harpoon") && b.returnGunAmmo('harpoon') > 2 + this.count * 3 + return tech.haveGunCheck("harpoon") && b.returnGunAmmo('harpoon') >= (tech.isRailGun ? 5 : 3) * (1 + this.count) }, requires: "harpoon", effect() { for (i = 0, len = b.guns.length; i < len; i++) { //find which gun if (b.guns[i].name === "harpoon") { - b.guns[i].ammo -= 3 + this.count * 3 - console.log(3 + this.count * 3) + b.guns[i].ammo -= (tech.isRailGun ? 5 : 3) * (1 + this.count) + // console.log(3 + this.count * 3) if (b.guns[i].ammo < 0) b.guns[i].ammo = 0 simulation.updateGunHUD(); tech.extraHarpoons++; break } } - this.description = `forge ${3+(this.count+1)*3}ammo into a new harpoon
fire +1harpoon with each shot` + // this.description = `forge ${3+(this.count+1)*3}ammo into a new harpoon
fire +1harpoon with each shot` }, remove() { if (tech.extraHarpoons) { - this.description = `forge ${2}ammo into a new harpoon
fire +1harpoon with each shot` + // this.description = `forge ${2}ammo into a new harpoon
fire +1harpoon with each shot` for (i = 0, len = b.guns.length; i < len; i++) { //find which gun if (b.guns[i].name === "harpoon") { - b.guns[i].ammo += 2 + b.guns[i].ammo += (tech.isRailGun ? 5 : 3) simulation.updateGunHUD(); break } @@ -6081,8 +6082,8 @@ const tech = { isGunTech: true, maxCount: 9, count: 0, - frequency: 2, - frequencyDefault: 2, + frequency: 1, + frequencyDefault: 1, allowed() { return tech.haveGunCheck("laser") && tech.laserReflections < 3 && !tech.beamSplitter && !tech.isWideLaser }, @@ -6239,7 +6240,7 @@ const tech = { }, requires: "standing wave, perfect diamagnetism", effect() { - tech.blockDmg += 1.75 //if you change this value also update the for loop in the electricity graphics in m.pushMass + tech.blockDmg += 2 //if you change this value also update the for loop in the electricity graphics in m.pushMass }, remove() { tech.blockDmg = 0; @@ -6354,7 +6355,7 @@ const tech = { frequency: 1, frequencyDefault: 1, allowed() { - return (m.fieldUpgrades[m.fieldMode].name === "pilot wave" || m.fieldUpgrades[m.fieldMode].name === "negative mass") && (build.isExperimentSelection || powerUps.research.count > 3) + return m.fieldUpgrades[m.fieldMode].name === "pilot wave" || m.fieldUpgrades[m.fieldMode].name === "negative mass" }, requires: "negative mass, pilot wave", effect() { @@ -6460,7 +6461,7 @@ const tech = { allowed() { return m.fieldUpgrades[m.fieldMode].name === "molecular assembler" || m.fieldUpgrades[m.fieldMode].name === "standing wave" || m.fieldUpgrades[m.fieldMode].name === "pilot wave" }, - requires: "molecular assembler or pilot wave", + requires: "molecular assembler, pilot wave, standing wave", effect: () => { tech.isMassEnergy = true // used in m.grabPowerUp m.energy += 2 @@ -6653,6 +6654,32 @@ const tech = { } }, // { + // name: "scrap-bot manufacturing", + // link: `manufacturing`, + // description: `use ${powerUps.orb.research(1)}to repurpose molecular assembler
excess energy used to condense scrap bot `, + // isFieldTech: true, + // maxCount: 1, + // count: 0, + // frequency: 3, + // frequencyDefault: 3, + // allowed() { + // return (build.isExperimentSelection || powerUps.research.count > 0) && m.fieldUpgrades[m.fieldMode].name === "molecular assembler" && !(tech.isIceField || tech.isSporeField || tech.isMissileField || tech.isFastDrones || tech.isDroneGrab || tech.isDroneRadioactive || tech.isDroneTeleport || tech.isDronesTravel) + // }, + // requires: "molecular assembler, no other manufacturing, no drone tech", + // effect() { + // if (!build.isExperimentSelection) { + // for (let i = 0; i < 1; i++) { + // if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) + // } + // } + // tech.isBotField = true; + // }, + // remove() { + // tech.isBotField = false; + // if (this.count > 0) powerUps.research.changeRerolls(1) + // } + // }, + // { // name: "thermal reservoir", // description: "increase your plasmadamage by 100%
plasma temporarily lowers health not energy", // isFieldTech: true, @@ -6672,7 +6699,7 @@ const tech = { // }, { name: "degenerate matter", - description: "reduce harm by 60% while your field is active", + description: "reduce harm by 66% while your field is active", isFieldTech: true, maxCount: 1, count: 0, @@ -6681,7 +6708,7 @@ const tech = { allowed() { return (m.fieldUpgrades[m.fieldMode].name === "plasma torch" || m.fieldUpgrades[m.fieldMode].name === "perfect diamagnetism" || m.fieldUpgrades[m.fieldMode].name === "pilot wave") && !tech.isEnergyHealth }, - requires: "perfect diamagnetism, pilot wave, plasma, not mass-energy", + requires: "plasma torch, perfect diamagnetism, pilot wave, not mass-energy", effect() { tech.isHarmReduce = true }, @@ -6722,7 +6749,7 @@ const tech = { allowed() { return m.fieldUpgrades[m.fieldMode].name === "plasma torch" && (build.isExperimentSelection || powerUps.research.count > 0) && !tech.isPlasmaBall && !tech.isExtruder }, - requires: "plasma torch", + requires: "plasma torch, not extruder, plasma ball", effect() { tech.plasmaBotCount++; b.plasmaBot(); @@ -6861,9 +6888,9 @@ const tech = { frequency: 2, frequencyDefault: 2, allowed() { - return m.fieldUpgrades[m.fieldMode].name === "time dilation" && !m.isShipMode && !tech.isRewindAvoidDeath && !tech.isEnergyHealth && !tech.isTimeSkip && !tech.isFreezeMobs + return m.fieldUpgrades[m.fieldMode].name === "time dilation" && !m.isShipMode && !tech.isRewindAvoidDeath && !tech.isEnergyHealth && !tech.isTimeSkip }, - requires: "time dilation, not CPT symmetry, mass-energy, timelike, Bose Einstein condensate", + requires: "time dilation, not CPT symmetry, mass-energy, timelike", effect() { tech.isRewindField = true; m.fieldUpgrades[m.fieldMode].set() @@ -7113,7 +7140,7 @@ const tech = { }, { name: "discrete optimization", - description: "increase damage by 40%
40% increased delay after firing", + description: "increase damage by 35%
35% increased delay after firing", isFieldTech: true, maxCount: 1, count: 0, @@ -7124,7 +7151,7 @@ const tech = { }, requires: "metamaterial cloaking, molecular assembler, plasma torch or pilot wave", effect() { - tech.aimDamage = 1.40 + tech.aimDamage = 1.35 b.setFireCD(); }, remove() { @@ -7174,18 +7201,18 @@ const tech = { }, { name: "virtual particles", - description: `use ${powerUps.orb.research(4)}to exploit your wormhole for a
12% chance to duplicate spawned power ups`, + description: `use ${powerUps.orb.research(4)}to exploit your field for a
12% chance to duplicate spawned power ups`, isFieldTech: true, maxCount: 1, count: 0, frequency: 3, frequencyDefault: 3, allowed() { - return m.fieldUpgrades[m.fieldMode].name === "wormhole" && (build.isExperimentSelection || powerUps.research.count > 3) + return (m.fieldUpgrades[m.fieldMode].name === "time dilation" || m.fieldUpgrades[m.fieldMode].name === "wormhole") && (build.isExperimentSelection || powerUps.research.count > 3) }, - requires: "wormhole", + requires: "wormhole, time dilation", effect() { - tech.wormDuplicate = 0.12 + tech.fieldDuplicate = 0.12 powerUps.setDupChance(); //needed after adjusting duplication chance if (!build.isExperimentSelection && !simulation.isTextLogOpen) simulation.circleFlare(0.13); for (let i = 0; i < 4; i++) { @@ -7193,7 +7220,7 @@ const tech = { } }, remove() { - tech.wormDuplicate = 0 + tech.fieldDuplicate = 0 powerUps.setDupChance(); //needed after adjusting duplication chance if (this.count > 0) powerUps.research.changeRerolls(4) } @@ -9748,7 +9775,7 @@ const tech = { isLongitudinal: null, is360Longitudinal: null, isShotgunReversed: null, - wormDuplicate: null, + fieldDuplicate: null, isCloakingDamage: null, harmonicEnergy: null, isFieldHarmReduction: null, @@ -9807,5 +9834,6 @@ const tech = { isFlipFlopHealth: null, isRelayEnergy: null, coyoteTime: null, - missileFireCD: null + missileFireCD: null, + isBotField: null } \ No newline at end of file diff --git a/todo.txt b/todo.txt index 5855d8f..e4ae920 100644 --- a/todo.txt +++ b/todo.txt @@ -1,30 +1,58 @@ ******************************************************** NEXT PATCH ************************************************** -nematodes now wiggle their tail. it's horrible -tech: transdimensional spores renamed transdimensional worms - spawns spores -> worms +automonous navigation -> path integration + sends spores and worms and drones to the next level with you +MIRV gives 10->12% smaller radius and damage +laser tech slow light has 33% less spacing +tech exciton gives 70%->88% damage +discrete optimization: 40%->35% damage and fire delay +degenerate matter 60->66% harm reduction while field is active +virtual particles 15% duplication is now allowed for time dilation +railgun no longer uses extra ammo when firing multiple bullets with smelting + smelting now costs more ammo with railgun +plasma torch, ball, extruder all use 33% less energy, do 15% more damage +bremsstrahlung does 15% more damage +standing wave field gives 50 energy + it's cooldown for blocking shields in now 0.5->0.33 s -missiles: - 20% more ammo - no longer fire rapidly on crouch - instead crouch gives missile initial forward velocity - no crouch makes the missiles recoil back before they accelerate forward - tech: launch system - fire missiles 500% more rapidly, gives 25% ammo - doesn't work with cruse missile - tech: ICBM - cruse missile is even bigger and slower +reactor + fight now starts when you press a button, so you can prep + spawns more ammo 4->7, heals 0->2 + will no longer show up on levels 2,3,4 + fewer bosses spawn at high difficulty levels + has a small chance to spawn all 3 boss types + sprayBoss is 25% slower, but it goes immune while spraying instead of shielding -pavilion has been added back to the map rotation - this will make the game end at 13 again, and feel harder - let me know if it's absence resulted in less NaN game crashes +community maps have a short message onload giving credit to the author +new level element balance - it's basically spinners and rotors combined + I'm replacing all rotors to fix potential BUGS + sewers, house, perplex, vats -reactor sprayBoss is now harder to kill - -bug fixes +requirement text bug fixes ******************************************************** TODO ******************************************************** -bugs: requirement text man discord messages - make sure guns are listed to work with gun tech randomization +make player collisions with mobs do no harm while standing wave is active + +Mobs bypass the [shrinking thing] on pavilion + either make this for all mobs or remove it + mobs only ignore it before it has been touched and returned + +fix issues with rotor + maybe fixes NaN + vats, sewers + replace with code powered spinner + +portal: + convert graphics to bitmaps + this seems to clip the edges + issues with + the end + platformer + player doesn't fling fast enough, unless arrows are held + player can't stand on blocks + but they can jump on blocks + bring back: the old phase decoherence field