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