diff --git a/img/collider.webp b/img/collider.webp new file mode 100644 index 0000000..ef6c55f Binary files /dev/null and b/img/collider.webp differ diff --git a/img/fluoroantimonic acid.webp b/img/fluoroantimonic acid.webp index 23918ed..99a3744 100644 Binary files a/img/fluoroantimonic acid.webp and b/img/fluoroantimonic acid.webp differ diff --git a/img/gun/mine.webp b/img/gun/mine.webp index dc49e3c..6f5e0e5 100644 Binary files a/img/gun/mine.webp and b/img/gun/mine.webp differ diff --git a/img/supercritical fission.webp b/img/supercritical fission.webp index f727d20..4e9c3c0 100644 Binary files a/img/supercritical fission.webp and b/img/supercritical fission.webp differ diff --git a/img/tungsten carbide.webp b/img/tungsten carbide.webp index ac6fda4..c41c4e0 100644 Binary files a/img/tungsten carbide.webp and b/img/tungsten carbide.webp differ diff --git a/js/level.js b/js/level.js index 8d6b81e..727f248 100644 --- a/js/level.js +++ b/js/level.js @@ -30,12 +30,12 @@ const level = { // m.setField("perfect diamagnetism") //molecular assembler standing wave time dilation perfect diamagnetism metamaterial cloaking wormhole negative mass pilot wave plasma torch // simulation.molecularMode = 2 // m.damage(0.1); - // b.giveGuns("shotgun") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser + // b.giveGuns("laser") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser // b.giveGuns("wave") //0 nail gun 1 shotgun 2 super balls 3 wave 4 missiles 5 grenades 6 spores 7 drones 8 foam 9 harpoon 10 mine 11 laser // b.guns[0].ammo = 10000 // tech.giveTech("vacuum bomb") - // tech.giveTech("time crystals") - // tech.giveTech("ice-shot") + // for (let i = 0; i < 3; ++i) tech.giveTech("collider") + // tech.giveTech("diffuse beam") // for (let i = 0; i < 1; ++i) tech.giveTech("super ball") // tech.isFoamBall = true // for (let i = 0; i < 3; ++i) tech.giveTech("repeater") @@ -421,7 +421,8 @@ const level = { player.position.y < level.exit.y - 0 && player.velocity.y < 0.15 ) { - level.exitCount += input.down ? 8 : 2 + // level.exitCount += input.down ? 8 : 2 + level.exitCount++ } else if (level.exitCount > 0) { level.exitCount -= 2 } @@ -3289,20 +3290,16 @@ const level = { spawn.mapRect(-1950, -3300, 8200, 1800); //roof spawn.mapRect(-250, -200, 1000, 300); // shelf spawn.mapRect(-250, -1700, 1000, 1250); // shelf roof - // spawn.blockDoor(710, -210); spawn.mapRect(705, -210, 25, 50); spawn.mapRect(725, -220, 25, 50); spawn.bodyRect(750, -125, 125, 125); spawn.bodyRect(875, -50, 50, 50); - spawn.mapRect(5400, -1700, 400, 1150); //right wall spawn.mapRect(5400, -300, 400, 400); //right wall spawn.mapRect(5700, -3300, 1800, 5100); //right wall spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 100); //exit bump spawn.mapRect(5403, -650, 400, 450); //blocking exit - // spawn.secondaryBossChance(4800, -500) //no bonus bosses on final level - if (mobs.mobDeaths < level.levelsCleared && !simulation.isCheating) { //pacifist run for (let i = 0; i < 250; i++) spawn.starter(1000 + 4000 * Math.random(), -1500 * Math.random()) } else { @@ -14703,7 +14700,7 @@ const level = { spawn.mapRect(133875, -1475, 475, 1775); spawn.mapRect(132025, -1925, 2325, 475); - simulation.enableConstructMode() //also remove when done + // simulation.enableConstructMode() //also remove when done coin(50165.9, -1090) coin(78725.4, -600) coin(103830.0, -1473) diff --git a/js/mob.js b/js/mob.js index 4fba9c7..6912b70 100644 --- a/js/mob.js +++ b/js/mob.js @@ -1187,6 +1187,7 @@ const mobs = { leaveBody: true, isDropPowerUp: true, death() { + if (tech.collidePowerUps && Math.random() < tech.collidePowerUps && this.isDropPowerUp) powerUps.randomize(this.position) //needs to run before onDeath spawns power ups this.onDeath(this); //custom death effects this.removeConsBB(); this.alive = false; //triggers mob removal in mob[i].replace(i) @@ -1207,9 +1208,6 @@ const mobs = { } requestAnimationFrame(cycle); } - - - if (tech.iceIXOnDeath && this.isSlowed) { for (let i = 0, len = 2 * Math.sqrt(Math.min(this.mass, 25)) * tech.iceIXOnDeath; i < len; i++) b.iceIX(3, Math.random() * 2 * Math.PI, this.position) } diff --git a/js/player.js b/js/player.js index 4f842db..24cc3bc 100644 --- a/js/player.js +++ b/js/player.js @@ -558,7 +558,7 @@ const m = { if (tech.isHarmReduceNoKill && m.lastKillCycle + 300 < m.cycle) dmg *= 0.33 if (tech.squirrelFx !== 1) dmg *= 1 + (tech.squirrelFx - 1) / 5 //cause more damage if (tech.isAddBlockMass && m.isHolding) dmg *= 0.15 - if (tech.isSpeedHarm) dmg *= 1 - Math.min(player.speed * 0.0165, 0.66) + if (tech.isSpeedHarm && player.speed > 0.1) dmg *= 1 - Math.min(player.speed * 0.0165, 0.66) if (tech.isHarmReduce && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.25 if (tech.isNeutronium && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.1 if (tech.isBotArmor) dmg *= 0.94 ** b.totalBots() @@ -1076,9 +1076,13 @@ const m = { }, setFieldRegen() { if (m.fieldMode === 6) { - m.fieldRegen = 0.0025 //15 energy per second + m.fieldRegen = 0.002333 //14 energy per second + } else if (m.fieldMode === 2) { + m.fieldRegen = 0.000833 //5 energy per second } else if (m.fieldMode === 4) { m.fieldRegen = 0.002 //12 energy per second + } else if (m.fieldMode === 5) { + m.fieldRegen = 0.001667 //10 energy per second } else { m.fieldRegen = 0.001 //6 energy per second } @@ -1828,7 +1832,7 @@ const m = { }, { name: "perfect diamagnetism", - description: "deflecting does not drain energy
maintains functionality while inactive
generate 6 energy per second", + description: "deflecting does not drain energy
maintains functionality while inactive
generate 5 energy per second", //
attract power ups from far away // description: "attract power ups from far away
deflecting doesn't drain energy
thrown blocks have", // description: "gain energy when blocking
no recoil when blocking", @@ -2396,7 +2400,7 @@ const m = { // }, { name: "plasma torch", - description: "use energy to emit short range plasma
damages and pushes mobs away
generate 6 energy per second", + description: "use energy to emit short range plasma
damages and pushes mobs away
generate 10 energy per second", set() { b.isExtruderOn = false // m.fieldCDcycleAlternate = 0 @@ -2785,7 +2789,7 @@ const m = { }, { name: "time dilation", - description: "use energy to stop time
+25% movement and fire rate
generate 15 energy per second", + description: "use energy to stop time
+25% movement and fire rate
generate 14 energy per second", set() { // m.fieldMeterColor = "#0fc" // m.fieldMeterColor = "#ff0" diff --git a/js/powerup.js b/js/powerup.js index a204fb5..9c5e6d7 100644 --- a/js/powerup.js +++ b/js/powerup.js @@ -1385,6 +1385,58 @@ const powerUps = { // } // return 0 // }, + randomize(where) { //makes a random power up convert into a random different power up + //put 10 power ups close together + const len = Math.min(10, powerUp.length) + for (let i = 0; i < len; i++) { //collide the first 10 power ups + const unit = Vector.rotate({ x: 1, y: 0 }, 6.28 * Math.random()) + Matter.Body.setPosition(powerUp[i], Vector.add(where, Vector.mult(unit, 20 + 25 * Math.random()))); + Matter.Body.setVelocity(powerUp[i], Vector.mult(unit, 20)); + } + + //count big power ups and small power ups + let options = ["heal", "research", "ammo"] + if (m.coupling) options.push("coupling") + if (tech.isBoostPowerUps) options.push("boost") + let bigIndexes = [] + let smallIndexes = [] + for (let i = 0; i < powerUp.length; i++) { + if (powerUp[i].name === "tech" || powerUp[i].name === "gun" || powerUp[i].name === "field") { + bigIndexes.push(i) + } else { + smallIndexes.push(i) + } + } + if (bigIndexes.length > 0) { + // console.log("at least 1 big will always spilt") + const index = bigIndexes[Math.floor(Math.random() * bigIndexes.length)] + for (let i = 0; i < 4; i++) powerUps.directSpawn(where.x, where.y, options[Math.floor(Math.random() * options.length)], false) + + Matter.Composite.remove(engine.world, powerUp[index]); + powerUp.splice(index, 1); + } else if (smallIndexes.length > 3 && Math.random() < 0.25) { + // console.log("no big, at least 4 small can combine") + for (let j = 0; j < 4; j++) { + for (let i = 0; i < powerUp.length; i++) { + if (powerUp[i].name === "heal" || powerUp[i].name === "research" || powerUp[i].name === "ammo" || powerUp[i].name === "coupling" || powerUp[i].name === "boost") { + Matter.Composite.remove(engine.world, powerUp[i]); + powerUp.splice(i, 1); + break + } + } + } + + options = ["tech", "gun", "field"] + powerUps.directSpawn(where.x, where.y, options[Math.floor(Math.random() * options.length)], false) + } else if (smallIndexes.length > 0) { + // console.log("no big, at least 1 small will swap flavors") + const index = Math.floor(Math.random() * powerUp.length) + options = options.filter(e => e !== powerUp[index].name); //don't repeat the current power up type + powerUps.directSpawn(where.x, where.y, options[Math.floor(Math.random() * options.length)], false) + Matter.Composite.remove(engine.world, powerUp[index]); + powerUp.splice(index, 1); + } + }, directSpawn(x, y, target, moving = true, mode = null, size = powerUps[target].size()) { let index = powerUp.length; target = powerUps[target]; diff --git a/js/tech.js b/js/tech.js index d4df66c..d5990b6 100644 --- a/js/tech.js +++ b/js/tech.js @@ -966,7 +966,7 @@ const tech = { name: "zoospore vector", link: `zoospore vector`, descriptionFunction() { - return `after mobs die
they have a +10% chance to grow ${b.guns[6].nameString('s')}` + return `after mobs die there is a +10% chance
they grow ${b.guns[6].nameString('s')}` }, // description: "after mobs die
they have a +10% chance to grow spores", maxCount: 9, @@ -1005,6 +1005,24 @@ const tech = { tech.deathSkipTime = 0 } }, + { + name: "collider", + descriptionFunction() { + return `after mobs die there is a +33% chance
to change a power up into a different flavor` + }, + maxCount: 3, + count: 0, + frequency: 1, + frequencyDefault: 1, + allowed: () => true, + requires: "", + effect() { + tech.collidePowerUps += 0.33333 + }, + remove() { + tech.collidePowerUps = 0 + } + }, { name: "bubble fusion", descriptionFunction() { @@ -3335,9 +3353,9 @@ const tech = { isNonRefundable: true, // isJunk: true, allowed() { - return !tech.isDeterminism + return !tech.isDeterminism && !tech.isBrainstorm }, - requires: "not determinism", + requires: "not determinism, brainstorm", effect() { tech.tooManyTechChoices = 1 // for (let i = 0; i < this.bonusResearch; i++) powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false); @@ -8574,6 +8592,22 @@ const tech = { }, remove() {} }, + // { + // name: "synchrotron", + // descriptionFunction() { + // return `power ups change into a different flavor after a boss dies` + // }, + // maxCount: 3, + // count: 0, + // frequency: 1, + // frequencyDefault: 1, + // allowed: () => true, + // requires: "", + // effect() { + // }, + // remove() { + // } + // }, { name: "return", description: "return to the introduction level
reduce combat difficulty by 2 levels", @@ -11387,4 +11421,5 @@ const tech = { isZombieMobs: null, isSuperMine: null, sentryAmmo: null, + collidePowerUps: null, } \ No newline at end of file diff --git a/todo.txt b/todo.txt index a40dab1..28b627a 100644 --- a/todo.txt +++ b/todo.txt @@ -1,20 +1,38 @@ ******************************************************** NEXT PATCH ************************************************** -level: lock - there is a way to escape the slime on the right side now +exit doors take longer to open + it's nice to take a few seconds to relax between levels + please don't submit a bug report about this -new community level! - stereoMadness by Richard0820 +plasma torch energy regen 6->10 +perfect diamagnetism energy regen 6->5 + +a few more new images + +tech: collider - after a mob dies smash power ups and change the flavor of one of them + powerUps.randomize(where) + if there is a tech,field,gun it will split into 4 small power ups + else if there are at least 4 small power ups they have a 1/4 chance to combine into a tech, field, gun + else a random small power up will change *********************************************************** TODO ***************************************************** +diagetic UI Elements + ammo number? + doesn't text look choppy when camera moves? + health bar could be rendered similarly to energy bar + what about 2 bezier curves on left and right of player head that looks like 1/3 circleRadiusScale + what about 2 bezier both above player + as the total energy and health increases the curses could asymptotically approach a maximum length as max energy/health goes to infinity + + level: lock - replace vanish elements with doors to fit theme better - can you do a sideways door? should there be something in the top part of the map? add alt versions of left and right sides make flipped L/R version (after everything else is done) +Tech: Drones always follow you mouse, never going to attack enemies or pick up power ups unless they are close to your mouse + tech: add an selection option to all tech, gun, fields to do something set all mobs to 30% health, and stun all mobs 50% chance to convert all power ups into research @@ -1149,9 +1167,8 @@ if pause is pressed while selecting power ups, display pause menu on top of sele subtractive sculpture kinetic sculpture quantum stuff -- Hypertorus, Glowing Opal Pearlescent, Physics, Hydro-Dipping Hydrodipped, Vija Celmins, Matt Molloy (photo of golden waves in the sky) -***major themes missing*** ***maybe redo*** - heuristics + laser supercritical fission ***past style themes*** field emitter - isometric, clean white robot spherical gun turret on bird legs, blender 3d, style of artstation and behance, Disney Pixar, cute