diff --git a/.DS_Store b/.DS_Store index 108480a..17d0fc3 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/js/level.js b/js/level.js index dc2b9f8..2ab78fb 100644 --- a/js/level.js +++ b/js/level.js @@ -19,8 +19,8 @@ const level = { // b.giveGuns("harpoon") // tech.giveTech("toggling harpoon") // tech.giveTech("filament") - // tech.giveTech("isotropic radiator") - // tech.giveTech("necrophage") + // tech.giveTech("mouth") + // tech.giveTech("all-stars") // for (let i = 0; i < 3; i++) tech.giveTech("super sized") // for (let i = 0; i < 9; i++) tech.giveTech("MIRV") @@ -108,8 +108,9 @@ const level = { m.eyeFillColor = m.fieldMeterColor simulation.makeTextLog(`tech.isFlipFlopOn = true`); } - if (tech.removeMaxHealthOnKill > 0.01) { - 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) + if (tech.isSpawnExitTech) { + // 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 } }, custom() {}, @@ -2291,14 +2292,13 @@ const level = { spawn.mapRect(5300, -275, 50, 175); spawn.mapRect(5050, -100, 50, 150); spawn.mapRect(4850, -275, 50, 175); - level.difficultyIncrease(30) //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 spawn.starter(1900, -500, 200) //big boy // spawn.blockGroup(1900, -500) // for (let i = 0; i < 10; ++i) spawn.bodyRect(1600 + 5, -500, 30, 40); // spawn.laserBombingBoss(1900, -500) // for (let i = 0; i < 5; i++) spawn.focuser(1900, -500) - // spawn.snakeSuckBoss(1900, -500) // spawn.grenadier(1900, -500) // spawn.sneaker(1900, -500, 200) // spawn.shield(mob[mob.length - 1], 1900, -500, 1); @@ -2316,7 +2316,7 @@ const level = { // spawn.nodeGroup(1200, -500, "grenadier") // spawn.nodeGroup(1800, -500, "grenadier") // spawn.nodeGroup(1200, 0, "grenadier") - // spawn.snakeBoss(1200, -500) + spawn.snakeBoss(1200, -500) // spawn.suckerBoss(2900, -500) // spawn.randomMob(1600, -500) }, @@ -4365,15 +4365,15 @@ const level = { Composite.add(engine.world, cons[cons.length - 1]); spawn.bodyRect(-2700, 1150, 100, 160, 1, spawn.propsSlide); //weight - spawn.bodyRect(-2550, 1150, 200, 100, 1, spawn.propsSlide); //weight - spawn.bodyRect(-2775, 1300, 400, 100, 1, spawn.propsHoist); //hoist + spawn.bodyRect(-2550, 1200, 150, 150, 1, spawn.propsSlide); //weight + spawn.bodyRect(-2763, 1300, 350, 100, 1, spawn.propsHoist); //hoist cons[cons.length] = Constraint.create({ pointA: { x: -2575, y: 150 }, bodyB: body[body.length - 1], - stiffness: 0.0005, + stiffness: 0.0004, length: 566 }); Composite.add(engine.world, cons[cons.length - 1]); diff --git a/js/mob.js b/js/mob.js index 397eda6..5bf7caf 100644 --- a/js/mob.js +++ b/js/mob.js @@ -362,7 +362,7 @@ const mobs = { seePlayerByDistOrLOS() { if (!(simulation.cycle % this.seePlayerFreq)) { if ( - (this.distanceToPlayer2() < this.seeAtDistance2 || (Matter.Query.ray(map, this.position, this.playerPosRandomY()).length === 0 && Matter.Query.ray(body, this.position, this.playerPosRandomY()).length === 0)) && + (this.distanceToPlayer2() < this.seeAtDistance2 || (Matter.Query.ray(map, this.position, this.playerPosRandomY()).length === 0)) && //&& Matter.Query.ray(body, this.position, this.playerPosRandomY()).length === 0 !m.isCloak ) { this.foundPlayer(); @@ -1151,6 +1151,10 @@ const mobs = { m.setMaxHealth(); } } + if (tech.cloakDuplication) { + tech.cloakDuplication -= 0.01 + powerUps.setDupChance(); //needed after adjusting duplication chance + } } else if (tech.isShieldAmmo && this.shield && !this.isExtraShield) { let type = tech.isEnergyNoAmmo ? "heal" : "ammo" if (Math.random() < 0.4) { @@ -1242,29 +1246,67 @@ const mobs = { replace(i) { //if there are too many bodies don't turn into blocks to help performance if (this.leaveBody && body.length < 40 && this.mass < 200 && this.radius > 18) { - const len = body.length; - const v = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices)) //might help with vertex collision issue, not sure - body[len] = Matter.Bodies.fromVertices(this.position.x, this.position.y, v); - Matter.Body.setVelocity(body[len], Vector.mult(this.velocity, 0.5)); - Matter.Body.setAngularVelocity(body[len], this.angularVelocity); - body[len].collisionFilter.category = cat.body; - body[len].collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet; - // if (body[len].mass > 10 || 45 + 10 * Math.random() < body.length) { - // body[len].collisionFilter.mask = cat.player | cat.bullet | cat.mob | cat.mobBullet; - // } - body[len].classType = "body"; - Composite.add(engine.world, body[len]); //add to world + let v = Matter.Vertices.hull(Matter.Vertices.clockwiseSort(this.vertices)) //might help with vertex collision issue, not sure + if (v.length > 5 && body.length < 35 && Math.random() < 0.5) { + const cutPoint = 3 + Math.floor((v.length - 6) * Math.random()) //Math.floor(v.length / 2) + const v2 = v.slice(0, cutPoint + 1) + v = v.slice(cutPoint - 1) + const len = body.length; + body[len] = Matter.Bodies.fromVertices(this.position.x, this.position.y, v2); + Matter.Body.setVelocity(body[len], Vector.mult(this.velocity, 0.5)); + Matter.Body.setAngularVelocity(body[len], this.angularVelocity); + body[len].collisionFilter.category = cat.body; + body[len].collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet; + body[len].classType = "body"; + Composite.add(engine.world, body[len]); //add to world - //large mobs shrink so they don't block paths - if (body[len].mass > 9) { - const shrink = function(that, massLimit) { - if (that.mass > massLimit) { - const scale = 0.95; - Matter.Body.scale(that, scale, scale); - setTimeout(shrink, 20, that, massLimit); - } - }; - shrink(body[len], 7 + 4 * Math.random()) + const len2 = body.length; + body[len2] = Matter.Bodies.fromVertices(this.position.x, this.position.y, v); + Matter.Body.setVelocity(body[len2], Vector.mult(this.velocity, 0.5)); + Matter.Body.setAngularVelocity(body[len2], this.angularVelocity); + body[len2].collisionFilter.category = cat.body; + body[len2].collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet; + // if (body[len].mass > 10 || 45 + 10 * Math.random() < body.length) { + // body[len].collisionFilter.mask = cat.player | cat.bullet | cat.mob | cat.mobBullet; + // } + body[len2].classType = "body"; + Composite.add(engine.world, body[len2]); //add to world + + //large mobs shrink so they don't block paths + if (body[len].mass + body[len2].mass > 16) { + const massLimit = 8 + 6 * Math.random() + const shrink = function(that1, that2) { + if (that1.mass + that2.mass > massLimit) { + const scale = 0.95; + Matter.Body.scale(that1, scale, scale); + Matter.Body.scale(that2, scale, scale); + setTimeout(shrink, 20, that1, that2); + } + }; + shrink(body[len], body[len2]) + } + } else { + const len = body.length; + body[len] = Matter.Bodies.fromVertices(this.position.x, this.position.y, v); + Matter.Body.setVelocity(body[len], Vector.mult(this.velocity, 0.5)); + Matter.Body.setAngularVelocity(body[len], this.angularVelocity); + body[len].collisionFilter.category = cat.body; + body[len].collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet; + body[len].classType = "body"; + Composite.add(engine.world, body[len]); //add to world + + //large mobs shrink so they don't block paths + if (body[len].mass > 9) { + const massLimit = 7 + 4 * Math.random() + const shrink = function(that) { + if (that.mass > massLimit) { + const scale = 0.95; + Matter.Body.scale(that, scale, scale); + setTimeout(shrink, 20, that); + } + }; + shrink(body[len]) + } } Matter.Composite.remove(engine.world, this); mob.splice(i, 1); diff --git a/js/player.js b/js/player.js index afadcb0..b6b7d6a 100644 --- a/js/player.js +++ b/js/player.js @@ -948,7 +948,7 @@ const m = { m.fieldHarmReduction = 1; m.isSneakAttack = false m.duplicateChance = 0 - powerUps.setDo(); + powerUps.setDupChance(); m.grabPowerUpRange2 = 156000; m.blockingRecoil = 4; m.fieldRange = 155; @@ -2219,9 +2219,9 @@ const m = { for (let i = 0; i < inPlayer.length; i++) { if (m.energy > 0) { if (inPlayer[i].shield) { //shields drain player energy - m.energy -= 0.014; + m.energy -= 0.016; } else { - m.energy -= 0.004; + m.energy -= 0.006; } } } @@ -2590,7 +2590,7 @@ const m = { description: "use energy to tunnel through a wormhole
wormholes attract blocks and power ups
7% chance to duplicate spawned power ups", //
bullets may also traverse wormholes effect: function() { m.duplicateChance = 0.07 - powerUps.setDo(); //needed after adjusting duplication chance + powerUps.setDupChance(); //needed after adjusting duplication chance m.hold = function() { // m.hole = { //this is reset with each new field, but I'm leaving it here for reference diff --git a/js/powerup.js b/js/powerup.js index 3d76c15..e634c4c 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -89,7 +89,7 @@ const powerUps = { totalPowerUps: 0, //used for tech that count power ups at the end of a level lastTechIndex: null, do() {}, - setDo() { + setDupChance() { if (tech.duplicationChance() > 0 || tech.isAnthropicTech) { if (tech.isPowerUpsVanish) { powerUps.do = powerUps.doDuplicatesVanish @@ -319,16 +319,20 @@ const powerUps = { } } if (tech.isRerollBots) { + let delay = 0 for (const cost = 2 + Math.floor(0.2 * b.totalBots()); powerUps.research.count > cost - 1; powerUps.research.count -= cost) { - b.randomBot() - if (tech.renormalization) { - for (let i = 0; i < cost; i++) { - if (Math.random() < 0.4) { - m.fieldCDcycle = m.cycle + 20; - powerUps.spawn(m.pos.x, m.pos.y, "research"); + delay += 500 + setTimeout(() => { + b.randomBot() + if (tech.renormalization) { + for (let i = 0; i < cost; i++) { + if (Math.random() < 0.4) { + m.fieldCDcycle = m.cycle + 20; + powerUps.spawn(m.pos.x + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "research"); + } } } - } + }, delay); } for (let i = 0, len = tech.tech.length; i < len; i++) { if (tech.tech[i].name === "bot fabrication") tech.tech[i].description = `if you collect ${powerUps.orb.research(2 + Math.floor(0.2 * b.totalBots()))}use them to build a
random bot (+1 cost every 5 bots)` @@ -472,21 +476,39 @@ const powerUps = { } } } else { //give ammo to all guns in inventory + let textLog = "" for (let i = 0, len = b.inventory.length; i < len; i++) { const target = b.guns[b.inventory[i]] if (target.ammo !== Infinity) { if (tech.ammoCap) { const ammoAdded = Math.ceil(target.ammoPack * 0.45 * tech.ammoCap) //0.45 is average target.ammo = ammoAdded - simulation.makeTextLog(`${target.name}.ammo = ${ammoAdded}`) + textLog += `${target.name}.ammo = ${ammoAdded}
` } else { const ammoAdded = Math.ceil((0.45 * Math.random() + 0.45 * Math.random()) * target.ammoPack) //Math.ceil(Math.random() * target.ammoPack) target.ammo += ammoAdded - simulation.makeTextLog(`${target.name}.ammo += ${ammoAdded}`) + textLog += `${target.name}.ammo += ${ammoAdded}
` } } } + simulation.makeTextLog(textLog) } + // } else { //give ammo to all guns in inventory + // for (let i = 0, len = b.inventory.length; i < len; i++) { + // const target = b.guns[b.inventory[i]] + // if (target.ammo !== Infinity) { + // if (tech.ammoCap) { + // const ammoAdded = Math.ceil(target.ammoPack * 0.45 * tech.ammoCap) //0.45 is average + // target.ammo = ammoAdded + // simulation.makeTextLog(`${target.name}.ammo = ${ammoAdded}`) + // } else { + // const ammoAdded = Math.ceil((0.45 * Math.random() + 0.45 * Math.random()) * target.ammoPack) //Math.ceil(Math.random() * target.ammoPack) + // target.ammo += ammoAdded + // simulation.makeTextLog(`${target.name}.ammo += ${ammoAdded}`) + // } + // } + // } + // } simulation.updateGunHUD(); } }, diff --git a/js/spawn.js b/js/spawn.js index b40cf7f..ed660b2 100644 --- a/js/spawn.js +++ b/js/spawn.js @@ -917,7 +917,7 @@ const spawn = { me.onDamage = function(dmg) { if (Math.random() < 0.33 * dmg * Math.sqrt(this.mass) && this.health > dmg) this.split(); } - me.damageReduction = 0.2 //me.damageReductionGoal + me.damageReduction = 0.18 //me.damageReductionGoal me.do = function() { // // this.armor(); if (!m.isBodiesAsleep) { @@ -990,7 +990,7 @@ const spawn = { me.onHit = function() { //run this function on hitting player this.explode(); }; - me.damageReduction = 0.25 + me.damageReduction = 0.22 me.doAwake = function() { if (!m.isBodiesAsleep) { // this.armor(); @@ -1107,7 +1107,7 @@ const spawn = { if (!count % 2) powerUps.spawnRandomPowerUp(this.position.x, this.position.y) // higher then normal chance to drop heals and ammo } } - me.damageReduction = 0.25 + me.damageReduction = 0.22 me.do = function() { // this.armor(); this.alwaysSeePlayer(); @@ -3070,7 +3070,7 @@ const spawn = { let me = mob[mob.length - 1]; me.isBoss = true; - Matter.Body.setDensity(me, 0.002 + 0.0001 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger + Matter.Body.setDensity(me, 0.0025 + 0.00013 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger me.stroke = "transparent"; //used for drawGhost me.seeAtDistance2 = 1500000; @@ -3084,12 +3084,9 @@ const spawn = { me.friction = 0; me.frictionAir = 0.01; me.memory = Infinity; - // me.memory = 300; - // Matter.Body.setDensity(me, 0.0015); //extra dense //normal is 0.001 me.collisionFilter.mask = cat.player | cat.bullet //| cat.body spawn.shield(me, x, y, 1); - const len = Math.floor(Math.min(15, 3 + Math.sqrt(simulation.difficulty))) // simulation.difficulty = 40 on hard mode level 10 const speed = (0.007 + 0.003 * Math.random() + 0.004 * Math.sqrt(simulation.difficulty)) let radiusOrbitals = radius + 125 + 350 * Math.random() @@ -3100,7 +3097,7 @@ const spawn = { me.onDeath = function() { powerUps.spawnBossPowerUp(this.position.x, this.position.y) }; - me.damageReduction = 0.25 + me.damageReduction = 0.2 me.do = function() { // this.armor(); this.seePlayerCheckByDistance(); diff --git a/js/tech.js b/js/tech.js index 11bef4c..edec9db 100644 --- a/js/tech.js +++ b/js/tech.js @@ -194,26 +194,16 @@ return dmg * tech.slowFire * tech.aimDamage }, duplicationChance() { - return (tech.isPowerUpsVanish ? 0.13 : 0) + (tech.isStimulatedEmission ? 0.17 : 0) + tech.cancelCount * 0.045 + tech.duplicateChance + m.duplicateChance + tech.wormDuplicate + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.5 : 0) + return (tech.isPowerUpsVanish ? 0.13 : 0) + (tech.isStimulatedEmission ? 0.17 : 0) + tech.cancelCount * 0.045 + tech.duplicateChance + m.duplicateChance + tech.wormDuplicate + tech.cloakDuplication + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.5 : 0) }, maxDuplicationEvent() { if (tech.is100Duplicate && tech.duplicationChance() > 0.99) { tech.is100Duplicate = false - - const range = 550 + const range = 500 for (let i = 0, len = 8; i < len; i++) { const angle = 2 * Math.PI * i / len spawn.randomLevelBoss(m.pos.x + range * Math.cos(angle), m.pos.y + range * Math.sin(angle), spawn.nonCollideBossList); } - - // spawn.randomLevelBoss(m.pos.x + range, m.pos.y, spawn.nonCollideBossList); - // spawn.randomLevelBoss(m.pos.x, m.pos.y + range, spawn.nonCollideBossList); - // spawn.randomLevelBoss(m.pos.x - range, m.pos.y, spawn.nonCollideBossList); - // spawn.randomLevelBoss(m.pos.x, m.pos.y - range, spawn.nonCollideBossList); - // spawn.randomLevelBoss(m.pos.x + range, m.pos.y + range, spawn.nonCollideBossList); - // spawn.randomLevelBoss(m.pos.x + range, m.pos.y - range, spawn.nonCollideBossList); - // spawn.randomLevelBoss(m.pos.x - range, m.pos.y + range, spawn.nonCollideBossList); - // spawn.randomLevelBoss(m.pos.x - range, m.pos.y - range, spawn.nonCollideBossList); } }, setTechFrequency(name, frequency) { @@ -480,7 +470,7 @@ allowed() { return !tech.isEnergyNoAmmo && !tech.isEnergyHealth }, - requires: "exciton-lattice, not mass-energy", + requires: "not exciton-lattice, mass-energy", effect: () => { tech.isAmmoFromHealth = true; }, @@ -748,7 +738,7 @@ frequency: 2, frequencyDefault: 2, allowed() { - return m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" || tech.haveGunCheck("spores") || tech.haveGunCheck("drones") || tech.haveGunCheck("missiles") || tech.haveGunCheck("foam") || tech.haveGunCheck("wave beam") || tech.isNeutronBomb || tech.isIceField || tech.isIceShot || tech.relayIce || tech.blockingIce > 1 + return m.fieldUpgrades[m.fieldMode].name === "nano-scale manufacturing" || tech.haveGunCheck("spores") || tech.haveGunCheck("drones") || tech.haveGunCheck("missiles") || tech.haveGunCheck("foam") || tech.haveGunCheck("wave beam") || tech.isNeutronBomb || tech.isIceField || tech.isIceShot || tech.relayIce || tech.blockingIce > 1 || tech.isWormShot || tech.foamBotCount > 1 }, requires: "drones, spores, missiles, foam, wave beam, neutron bomb, ice IX", effect() { @@ -1634,7 +1624,7 @@ allowed() { return tech.throwChargeRate > 1 && m.fieldUpgrades[m.fieldMode].name !== "pilot wave" && m.fieldUpgrades[m.fieldMode].name !== "wormhole" && !tech.isTokamak }, - requires: "mass driver, not pilot wave not tokamak", + requires: "mass driver, not pilot wave, tokamak", effect() { tech.isAddBlockMass = true }, @@ -2620,7 +2610,7 @@ allowed() { return m.maxHealth > 1; }, - requires: "health above 100", + requires: "max health above 100", effect() { tech.isAcidDmg = true; }, @@ -2768,11 +2758,11 @@ requires: "anthropic principle, below 66% duplication chance", effect() { tech.isAnthropicTech = true - powerUps.setDo(); //needed after adjusting duplication chance + powerUps.setDupChance(); //needed after adjusting duplication chance }, remove() { tech.isAnthropicTech = false - powerUps.setDo(); //needed after adjusting duplication chance + powerUps.setDupChance(); //needed after adjusting duplication chance } }, { @@ -2821,7 +2811,7 @@ allowed() { return !tech.isResearchReality && !tech.isSwitchReality }, - requires: "Ψ(t) collapse, many-worlds", + requires: "not Ψ(t) collapse, many-worlds", effect() { tech.isCollisionRealitySwitch = true; level.difficultyDecrease(simulation.difficultyMode * 2) @@ -2862,7 +2852,7 @@ allowed() { return !tech.isSwitchReality && !tech.isCollisionRealitySwitch && !tech.isJunkResearch }, - requires: "many-worlds, non-unitary, not pseudoscience", + requires: "not many-worlds, non-unitary, pseudoscience", effect() { tech.isResearchReality = true; for (let i = 0; i < 16; i++) powerUps.spawn(m.pos.x + Math.random() * 60, m.pos.y + Math.random() * 60, "research", false); @@ -3088,12 +3078,12 @@ requires: "below 100% duplication chance", effect() { tech.duplicateChance += 0.1 - powerUps.setDo(); //needed after adjusting duplication chance + powerUps.setDupChance(); //needed after adjusting duplication chance tech.addJunkTechToPool(30) }, remove() { tech.duplicateChance = 0 - powerUps.setDo(); //needed after adjusting duplication chance + powerUps.setDupChance(); //needed after adjusting duplication chance if (this.count > 1) tech.removeJunkTechFromPool(30) } }, @@ -3110,11 +3100,11 @@ requires: "below 100% duplication chance", effect: () => { tech.isStimulatedEmission = true - powerUps.setDo(); //needed after adjusting duplication chance + powerUps.setDupChance(); //needed after adjusting duplication chance }, remove() { tech.isStimulatedEmission = false - powerUps.setDo(); //needed after adjusting duplication chance + powerUps.setDupChance(); //needed after adjusting duplication chance } }, { @@ -3130,11 +3120,11 @@ requires: "below 100% duplication chance", effect: () => { tech.isPowerUpsVanish = true - powerUps.setDo(); //needed after adjusting duplication chance + powerUps.setDupChance(); //needed after adjusting duplication chance }, remove() { tech.isPowerUpsVanish = false - powerUps.setDo(); //needed after adjusting duplication chance + powerUps.setDupChance(); //needed after adjusting duplication chance } }, { @@ -3150,11 +3140,11 @@ requires: "below 100% duplication chance, not determinism", effect() { tech.isCancelDuplication = true //search for tech.cancelCount to balance - powerUps.setDo(); //needed after adjusting duplication chance + powerUps.setDupChance(); //needed after adjusting duplication chance }, remove() { tech.isCancelDuplication = false - powerUps.setDo(); //needed after adjusting duplication chance + powerUps.setDupChance(); //needed after adjusting duplication chance } }, { @@ -3324,7 +3314,7 @@ allowed() { return !tech.isSuperDeterminism && tech.duplicationChance() > 0 && powerUps.research.count > 1 }, - requires: "at least 2 research, not super determinism", + requires: "some duplication, not super determinism", effect: () => { powerUps.research.changeRerolls(-2) simulation.makeTextLog(`m.research -= 2
${powerUps.research.count}`) @@ -3992,7 +3982,7 @@ allowed() { return tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIncendiary && !tech.isIceShot && !tech.isFoamShot && !tech.isWormShot && !tech.isNeedleShot }, - requires: "shotgun, not nail-shot, foam-shot, worm-shot, ice-shot", + requires: "shotgun, not nail-shot, foam-shot, worm-shot, ice-shot, needle-shot", effect() { tech.isSlugShot = true; }, @@ -4011,7 +4001,7 @@ allowed() { return tech.haveGunCheck("shotgun") && !tech.isIncendiary && !tech.isSlugShot && !tech.isIceShot && !tech.isFoamShot && !tech.isWormShot && !tech.isNeedleShot }, - requires: "shotgun, not incendiary, slug, foam-shot, worm-shot, ice-shot", + requires: "shotgun, not incendiary, slug, foam-shot, worm-shot, ice-shot, needle-shot", effect() { tech.isNailShot = true; }, @@ -4049,7 +4039,7 @@ allowed() { return tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIncendiary && !tech.isSlugShot && !tech.isIceShot && !tech.isFoamShot && !tech.isNeedleShot }, - requires: "shotgun, not incendiary, nail-shot, slug, foam-shot, ice-shot", + requires: "shotgun, not incendiary, nail-shot, slug, foam-shot, ice-shot, needle-shot", effect() { tech.isWormShot = true; }, @@ -4068,7 +4058,7 @@ allowed() { return tech.haveGunCheck("shotgun") && !tech.isNailShot && !tech.isIncendiary && !tech.isSlugShot && !tech.isIceShot && !tech.isWormShot && !tech.isNeedleShot }, - requires: "shotgun, not incendiary, nail-shot, slug, worm-shot, ice-shot", + requires: "shotgun, not incendiary, nail-shot, slug, worm-shot, ice-shot, needle-shot", effect() { tech.isFoamShot = true; }, @@ -4133,7 +4123,7 @@ allowed() { return tech.haveGunCheck("super balls") && tech.missileCount === 1 && !tech.superBallDelay }, - requires: "super balls, but not super duper or supertemporal", + requires: "super balls, but not MIRV or supertemporal", effect() { tech.oneSuperBall = true; for (i = 0, len = b.guns.length; i < len; i++) { //find which gun @@ -4352,7 +4342,7 @@ allowed() { return tech.haveGunCheck("missiles") }, - requires: "missiles", + requires: "missile gun", effect() { tech.missileBotCount++; b.missileBot(); @@ -4498,7 +4488,7 @@ allowed() { return tech.haveGunCheck("mine") }, - requires: "mines, not mine reclamation", + requires: "mines", effect() { tech.isMineDrop = true; if (tech.isMineDrop) b.mine(m.pos, { x: 0, y: 0 }, 0) @@ -4577,7 +4567,7 @@ allowed() { return tech.haveGunCheck("spores") }, - requires: "spores", + requires: "spore gun", effect() { tech.isSporeGrowth = true }, @@ -5007,7 +4997,7 @@ allowed() { return tech.haveGunCheck("harpoon") }, - requires: "harpoon, not spear", + requires: "harpoon", effect() { tech.isFilament = true; }, @@ -5227,7 +5217,7 @@ allowed() { return (tech.haveGunCheck("laser") || tech.isLaserMine || tech.laserBotCount > 1) && !tech.isWideLaser && !tech.isPulseLaser && !tech.historyLaser }, - requires: "laser, not wide beam, diffuse beam, pulse, or slow light", + requires: "laser, not diffuse beam, pulse, or slow light", effect() { tech.laserReflections += 2; }, @@ -6050,6 +6040,51 @@ m.fieldRegen = tech.energyRegen; } }, + { + name: "no-cloning theorem", + description: `42% chance to duplicate spawned power ups
if you kill a mob lose 1% duplication chance`, + isFieldTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return (m.fieldUpgrades[m.fieldMode].name === "time dilation" || m.fieldUpgrades[m.fieldMode].name === "metamaterial cloaking") && tech.duplicationChance() < 1 + }, + requires: "metamaterial cloaking, below 100% duplication chance", + effect() { + tech.cloakDuplication = 0.42 + powerUps.setDupChance(); //needed after adjusting duplication chance + + }, + remove() { + tech.cloakDuplication = 0 + powerUps.setDupChance(); //needed after adjusting duplication chance + } + }, + { + name: "symbiosis", + description: "if you kill a mob lose 2% max health
at the start of each level spawn 2 tech", + isFieldTech: true, + maxCount: 1, + count: 0, + frequency: 2, + frequencyDefault: 2, + allowed() { + return (m.fieldUpgrades[m.fieldMode].name === "time dilation" || m.fieldUpgrades[m.fieldMode].name === "metamaterial cloaking") && !tech.removeMaxHealthOnKill + }, + requires: "metamaterial cloaking, not -symbiosis-", + effect() { + tech.removeMaxHealthOnKill = 0.02 + tech.isSpawnExitTech = true + // 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 + // 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 + }, + remove() { + tech.removeMaxHealthOnKill = 0 + tech.isSpawnExitTech = false + } + }, { name: "boson composite", description: "intangible to blocks and mobs while cloaked
passing through mobs drains your energy", @@ -6091,26 +6126,6 @@ tech.isCloakStun = false; } }, - { - name: "pacifist", - description: "if you kill a mob lose 2% max health
spawn 2 tech at the end of every level", - isFieldTech: true, - maxCount: 1, - count: 0, - frequency: 2, - frequencyDefault: 2, - allowed() { - return m.fieldUpgrades[m.fieldMode].name === "metamaterial cloaking" && !tech.removeMaxHealthOnKill - }, - requires: "metamaterial cloaking, not -pacifist-", - effect() { - tech.removeMaxHealthOnKill = 0.02 - 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) - }, - remove() { - tech.removeMaxHealthOnKill = 0 - } - }, { name: "ambush", description: "metamaterial cloaking field damage effect
is increased from 300% to 600%", @@ -6245,17 +6260,17 @@ allowed() { return m.fieldUpgrades[m.fieldMode].name === "wormhole" && (build.isExperimentSelection || powerUps.research.count > 3) && tech.duplicationChance() < 1 }, - requires: "wormhole,below 100% duplication chance", + requires: "wormhole, below 100% duplication chance", effect() { tech.wormDuplicate = 0.14 - powerUps.setDo(); //needed after adjusting duplication chance + powerUps.setDupChance(); //needed after adjusting duplication chance for (let i = 0; i < 4; i++) { if (powerUps.research.count > 0) powerUps.research.changeRerolls(-1) } }, remove() { tech.wormDuplicate = 0 - powerUps.setDo(); //needed after adjusting duplication chance + powerUps.setDupChance(); //needed after adjusting duplication chance if (this.count > 0) powerUps.research.changeRerolls(4) } }, @@ -6493,8 +6508,8 @@ } }, { - name: "-pacifist-", - description: "experiment: if you kill a mob
lose 1% max health", + name: "-symbiosis-", + description: "experiment: if you kill a mob
lose 0.2% max health", maxCount: 1, count: 0, frequency: 0, @@ -6505,7 +6520,7 @@ }, requires: "", effect() { - tech.removeMaxHealthOnKill = 0.01 + tech.removeMaxHealthOnKill = 0.002 }, remove() { tech.removeMaxHealthOnKill = 0 @@ -6552,6 +6567,117 @@ if (this.count) player.restitution = 0 } }, + { + name: "mouth", + description: "mobs have a non functional mouth", + maxCount: 1, + count: 0, + frequency: 0, + isExperimentHide: true, + isJunk: true, + allowed() { + return true + }, + requires: "", + effect() { + mobs.draw = () => { + ctx.lineWidth = 2; + let i = mob.length; + while (i--) { + ctx.beginPath(); + const vertices = mob[i].vertices; + ctx.moveTo(vertices[0].x, vertices[0].y); + for (let j = 1, len = vertices.length; j < len; ++j) ctx.lineTo(vertices[j].x, vertices[j].y); + ctx.quadraticCurveTo(mob[i].position.x, mob[i].position.y, vertices[0].x, vertices[0].y); + ctx.fillStyle = mob[i].fill; + ctx.strokeStyle = mob[i].stroke; + ctx.fill(); + ctx.stroke(); + } + } + }, + remove() { + mobs.draw = () => { + ctx.lineWidth = 2; + let i = mob.length; + while (i--) { + ctx.beginPath(); + const vertices = mob[i].vertices; + ctx.moveTo(vertices[0].x, vertices[0].y); + for (let j = 1, len = vertices.length; j < len; ++j) ctx.lineTo(vertices[j].x, vertices[j].y); + ctx.lineTo(vertices[0].x, vertices[0].y); + ctx.fillStyle = mob[i].fill; + ctx.strokeStyle = mob[i].stroke; + ctx.fill(); + ctx.stroke(); + } + } + } + }, + { + name: "all-stars", + description: "make all mobs look like stars", + maxCount: 1, + count: 0, + frequency: 0, + isExperimentHide: true, + isJunk: true, + allowed() { + return true + }, + requires: "", + effect() { + mobs.draw = () => { + ctx.lineWidth = 2; + let i = mob.length; + while (i--) { + ctx.beginPath(); + const vertices = mob[i].vertices; + ctx.moveTo(vertices[0].x, vertices[0].y); + for (let j = 1, len = vertices.length; j < len; ++j) { + ctx.quadraticCurveTo(mob[i].position.x, mob[i].position.y, vertices[j].x, vertices[j].y); + } + ctx.quadraticCurveTo(mob[i].position.x, mob[i].position.y, vertices[0].x, vertices[0].y); + ctx.fillStyle = mob[i].fill; + ctx.strokeStyle = mob[i].stroke; + ctx.fill(); + ctx.stroke(); + } + } + }, + remove() { + mobs.draw = () => { + ctx.lineWidth = 2; + let i = mob.length; + while (i--) { + ctx.beginPath(); + const vertices = mob[i].vertices; + ctx.moveTo(vertices[0].x, vertices[0].y); + for (let j = 1, len = vertices.length; j < len; ++j) ctx.lineTo(vertices[j].x, vertices[j].y); + ctx.lineTo(vertices[0].x, vertices[0].y); + ctx.fillStyle = mob[i].fill; + ctx.strokeStyle = mob[i].stroke; + ctx.fill(); + ctx.stroke(); + } + } + } + }, + // draw() { + // ctx.lineWidth = 2; + // let i = mob.length; + // while (i--) { + // ctx.beginPath(); + // const vertices = mob[i].vertices; + // ctx.moveTo(vertices[0].x, vertices[0].y); + // for (let j = 1, len = vertices.length; j < len; ++j) ctx.lineTo(vertices[j].x, vertices[j].y); + // ctx.lineTo(vertices[0].x, vertices[0].y); + // ctx.fillStyle = mob[i].fill; + // ctx.strokeStyle = mob[i].stroke; + // ctx.fill(); + // ctx.stroke(); + // } + // }, { name: "true colors", description: `set all power ups to their real world colors`, @@ -8223,5 +8349,7 @@ ammoCap: null, isHarpoonPowerUp: null, harpoonDensity: null, - removeMaxHealthOnKill: null + removeMaxHealthOnKill: null, + isSpawnExitTech: null, + cloakDuplication: null } \ No newline at end of file diff --git a/todo.txt b/todo.txt index faff7d6..f4afbe0 100644 --- a/todo.txt +++ b/todo.txt @@ -1,12 +1,20 @@ ******************************************************** NEXT PATCH ************************************************** -tech: pacifist - if you kill a mob lose 2% max health, but gain 2 tech at the end of every level -junk tech: bounce - you bounce, it's kinda annoying +no cloning theorem - 42% duplication, but lose 1% dup if you kill a mob + requires cloaking or time dilation field +tech: symbiosis - if you kill a mob lose 2% max health, but gain 2 tech at the end of every level. + requires cloaking or time dilation field + +JUNK tech: all-stars - make mobs look like stars +JUNK tech: mouth - make mobs look like they have a mouth + +the nonCollideBosses have been made 10% harder to kill + these are the types of bosses that spawn from apomixis on 100% duplication + +7+ sided mobs may slice in two when they die ******************************************************** TODO ******************************************************** -experiment: like lose 1% max health every time you kill a mob? - JUNK tech: planetesimals game inside n-gon https://codepen.io/lilgreenland/pen/jrMvaB?editors=0010 @@ -46,8 +54,6 @@ harpoon tech tracking so good harpoon can hit a target, circle around and hit it again doesn't seem to be good physics -tech - explode after getting hit, but while you are immune to harm - "Interstellar Disturbance": Cosmic String applies to mobs who cross the wormhole's path, even after initial wormholing, but at reduced damage and stun time. on mouse down wormhole shows a possible wormhole @@ -67,28 +73,9 @@ make another boss with a tail stabbers maybe suckers maybe -tech remove all JUNK tech - but you can't research - maybe spend research - -tech missiles - move faster and more accurately, turn sharper - also some other bonus: - damage? or size which is basically damage - -experiment and understand vibe more obvious +make experiment and understand vibe more obvious mostly in early game or first time players -falling particle rain - what causes it? - after taking damage - mines - grenades - mines and grenades - once a second you just eject rain upwards - after collecting a power up - basically spores with no guidance - lag if too many particles? - look into 360 wave beam lag aoe effect pushes mobs away, then rapidly pulls them in @@ -108,10 +95,6 @@ make non moving bosses not move after getting hit buff rail gun -block shattering - get code from planetesimals - https://codepen.io/lilgreenland/pen/jrMvaB?editors=0010 - scrolling console history in pause menu? pause should at least show the last in game console message