diff --git a/js/level.js b/js/level.js
index 4a78987..8f5db5f 100644
--- a/js/level.js
+++ b/js/level.js
@@ -20,13 +20,14 @@ const level = {
// m.setField("time dilation")
// b.giveGuns("nail gun")
// b.giveGuns("mine")
- // tech.giveTech("needle gun")
- // tech.giveTech("stress concentration")
+ // tech.giveTech("cross disciplinary")
+ // tech.giveTech("determinism")
+ // tech.giveTech("pseudoscience")
// for (let i = 0; i < 100; ++i) tech.giveTech("nail-bot")
- // tech.giveTech("rivet gun")
- // tech.giveTech("needle ice")
- // tech.giveTech("flash freeze")
- // tech.giveTech("superfluidity")
+ // for (let i = 0; i < 9; ++i) tech.giveTech("emergence")
+ // tech.giveTech("decoherence")
+ // tech.giveTech("brainstorming")
+ // tech.giveTech("path integral")
// m.maxHealth = 100
// m.health = m.maxHealth
// for (let i = 0; i < 10; i++) tech.giveTech("tungsten carbide")
@@ -39,9 +40,12 @@ const level = {
// m.immuneCycle = Infinity //you can't take damage
// level.difficultyIncrease(40) //30 is near max on hard //60 is near max on why
// simulation.enableConstructMode() //used to build maps in testing mode
- // level.perplex();
+ // level.testChamber2();
// spawn.cellBossCulture(1900, -500)
// level.testing(); //not in rotation, used for testing
+ // for (let i = 0; i < 4; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "tech");
+ // for (let i = 0; i < 7; ++i) powerUps.directSpawn(m.pos.x + 50 * Math.random(), m.pos.y + 50 * Math.random(), "research");
+ // powerUps.research.changeRerolls(100)
// spawn.starter(1900, -500, 300)
// for (let i = 0; i < 50; ++i) spawn.starter(1900, -500)
// spawn.powerUpBoss(1900, -500)
@@ -4058,6 +4062,264 @@ const level = {
}, -2 * Math.PI / 3) //up left
}
+ },
+ testChamber2() {
+ level.setPosToSpawn(0, -50); //lower start
+ level.exit.y = level.enter.y - 550;
+ spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20);
+ level.exit.x = level.enter.x;
+ spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20);
+ level.defaultZoom = 2200
+ simulation.zoomTransition(level.defaultZoom)
+ document.body.style.backgroundColor = "#d0d5d5";
+ color.map = "#444"
+ spawn.mapRect(0, -1955, 175, 30);
+ const removeIndex1 = map.length - 1 //so much work to catch blocks caught at the bottom of the vertical portals
+ spawn.mapRect(1225, -1955, 175, 30);
+ const removeIndex2 = map.length - 1 //so much work to catch blocks caught at the bottom of the vertical portals
+ let portal, portal2, portal3
+ const hazard = level.hazard((simulation.isHorizontalFlipped ? -350 - 700 : 350), -2025, 700, 10, 0.4) //laser
+ spawn.mapRect(340, -2032.5, 20, 25); //laser nose
+ const hazard2 = level.hazard((simulation.isHorizontalFlipped ? -1775 - 150 : 1775), -2550, 150, 10, 0.4) //laser
+ spawn.mapRect(1920, -2557.5, 20, 25); //laser nose
+ const button = level.button(2100, -2600)
+ const buttonDoor = level.button(600, -550)
+ const door = level.door(312, -750, 25, 190, 185)
+
+ level.custom = () => {
+ if (!(m.cycle % 60)) { //so much work to catch blocks caught at the bottom of the vertical portals
+ let touching = Matter.Query.collides(map[removeIndex1], body)
+ if (touching.length) {
+ Matter.Composite.remove(engine.world, touching[0].bodyB);
+ for (let i = 0, len = body.length; i < len; i++) {
+ if (body[i].id === touching[0].bodyB.id) {
+ body.splice(i, 1);
+ break
+ }
+ }
+ }
+ touching = Matter.Query.collides(map[removeIndex2], body)
+ if (touching.length) {
+ Matter.Composite.remove(engine.world, touching[0].bodyB);
+ for (let i = 0, len = body.length; i < len; i++) {
+ if (body[i].id === touching[0].bodyB.id) {
+ body.splice(i, 1);
+ break
+ }
+ }
+ }
+ }
+
+ buttonDoor.query();
+ buttonDoor.draw();
+ if (buttonDoor.isUp) {
+ door.isClosing = true
+ } else {
+ door.isClosing = false
+ }
+ door.openClose();
+
+ portal[2].query()
+ portal[3].query()
+ portal2[2].query()
+ portal2[3].query()
+ portal3[2].query()
+ portal3[3].query()
+
+ if (button.isUp) {
+ hazard.isOn = false;
+ hazard2.isOn = false;
+ } else {
+ hazard.isOn = true;
+ hazard2.isOn = true;
+ }
+ button.query();
+ button.draw();
+
+ ctx.fillStyle = "#d4f4f4"
+ ctx.fillRect(-300, -1000, 650, 500)
+ level.exit.drawAndCheck();
+
+ level.enter.draw();
+ };
+ level.customTopLayer = () => {
+ door.draw();
+ hazard.opticalQuery();
+ hazard2.opticalQuery();
+ portal[0].draw();
+ portal[1].draw();
+ portal[2].draw();
+ portal[3].draw();
+ portal2[0].draw();
+ portal2[1].draw();
+ portal2[2].draw();
+ portal2[3].draw();
+ portal3[0].draw();
+ portal3[1].draw();
+ portal3[2].draw();
+ portal3[3].draw();
+ };
+ powerUps.spawnStartingPowerUps(1875, -3075);
+
+ const powerUpPos = shuffle([{ //no debris on this level but 2 random spawn instead
+ x: -150,
+ y: -1775
+ }, {
+ x: 2400,
+ y: -2650
+ }, {
+ x: -175,
+ y: -1375
+ }, {
+ x: 1325,
+ y: -150
+ }]);
+ powerUps.chooseRandomPowerUp(powerUpPos[0].x, powerUpPos[0].y);
+ powerUps.chooseRandomPowerUp(powerUpPos[1].x, powerUpPos[1].y);
+ //outer wall
+ spawn.mapRect(2500, -3700, 1200, 3800); //right map wall
+ spawn.mapRect(-1400, -3800, 1100, 3900); //left map wall
+ spawn.mapRect(-1400, -4800, 5100, 1200); //map ceiling
+ spawn.mapRect(-1400, 0, 5100, 1200); //floor
+ //lower entrance /exit
+ spawn.mapRect(300, -375, 50, 225);
+ spawn.bodyRect(312, -150, 25, 140);
+ spawn.mapRect(300, -10, 50, 50);
+ spawn.mapVertex(1555, 0, "625 0 75 0 200 -100 500 -100"); //entrance ramp
+ //upper entrance / exit
+ spawn.mapRect(-400, -1050, 750, 50);
+ spawn.mapRect(300, -1050, 50, 300);
+ // spawn.bodyRect(312, -750, 25, 190);
+ spawn.mapRect(300, -560, 50, 50);
+ spawn.bodyRect(750, -725, 125, 125);
+ spawn.mapRect(1150, -1050, 250, 575);
+ spawn.mapRect(1725, -550, 50, 200); //walls around portal 3
+ spawn.mapRect(1925, -550, 500, 200);
+ spawn.mapRect(1750, -390, 200, 40);
+ spawn.mapRect(-400, -550, 1800, 200);
+ spawn.mapRect(-200, -1700, 150, 25); //platform above exit room
+ spawn.mapRect(-200, -1325, 350, 25);
+ //portal 3 angled
+ spawn.mapRect(2425, -450, 100, 100);
+ //portal 1 bottom
+ spawn.mapRect(2290, -12, 375, 100);
+ spawn.mapRect(2350, -24, 375, 100);
+ spawn.mapRect(2410, -36, 375, 100);
+ //portal 1 top
+ spawn.mapRect(2290, -3012, 375, 50);
+ spawn.mapRect(2350, -3024, 375, 50);
+ spawn.mapRect(2410, -3036, 375, 50);
+ spawn.mapRect(1400, -3000, 1300, 50); //floor
+ spawn.mapRect(1750, -3050, 250, 75);
+ spawn.mapRect(1400, -3625, 50, 200);
+ spawn.mapRect(350, -3625, 50, 225);
+ spawn.mapRect(350, -3260, 50, 60);
+ spawn.mapRect(200, -3250, 1240, 50);
+ spawn.mapRect(1400, -3260, 50, 310);
+ spawn.bodyRect(1412, -3425, 25, 165);
+ spawn.mapRect(-150, -2925, 150, 25);
+ //portal 2
+ spawn.mapRect(-300, -2600, 300, 675); //left platform
+ spawn.mapRect(1400, -2600, 375, 675); //right platform
+ spawn.mapRect(1925, -2600, 775, 675); //far right platform
+ spawn.bodyRect(2130, -2660, 50, 50); //button's block
+ spawn.mapRect(150, -2100, 200, 175);
+ spawn.mapRect(1050, -2100, 200, 175);
+ //mobs
+ spawn.randomMob(1075, -3500, -0.3);
+ spawn.randomMob(2175, -700, -0.2);
+ spawn.randomMob(-75, -850, -0.1);
+ spawn.randomMob(550, -3400, 0);
+ spawn.randomMob(0, -1175, 0.5);
+ spawn.randomMob(-75, -1150, 0.5);
+ spawn.randomMob(1075, -625, 0.5);
+ spawn.randomMob(800, -3400, -0.3);
+ spawn.randomMob(1225, -3375, -0.2);
+ spawn.randomMob(1200, -1125, -0.1);
+ spawn.randomMob(2050, -950, 0.5);
+ if (simulation.difficulty > 40) {
+ spawn.randomMob(2300, -2775, -0.5);
+ spawn.randomMob(600, -925, -0.5);
+ spawn.randomMob(1550, -2750, -0.5);
+ spawn.randomMob(1350, -1150, -0.5);
+ spawn.randomMob(-75, -1475, 0);
+ spawn.randomGroup(600, -2600, 0);
+ }
+ if (simulation.difficulty > 1) {
+ if (Math.random() < 0.5) {
+ spawn.randomLevelBoss(700, -1550);
+ } else {
+ spawn.randomLevelBoss(675, -2775); //["shooterBoss", "launcherBoss", "laserTargetingBoss", "streamBoss", "shieldingBoss", "pulsarBoss", "grenadierBoss"]
+ }
+ }
+ powerUps.addResearchToLevel() //needs to run after mobs are spawned
+ spawn.secondaryBossChance(1925, -1250)
+
+ if (simulation.isHorizontalFlipped) { //flip the map horizontally
+ level.flipHorizontal(); //only flips map,body,mob,powerUp,cons,consBB, exit
+ // level.setPosToSpawn(0, -50); //-x // no need since 0
+ button.min.x = -button.min.x - 126 // flip the button horizontally
+ button.max.x = -button.max.x + 126 // flip the button horizontally
+ buttonDoor.min.x = -buttonDoor.min.x - 126 // flip the button horizontally
+ buttonDoor.max.x = -buttonDoor.max.x + 126 // flip the button horizontally
+
+ //this makes the hazard draw, but not collide for reasons I don't understand
+ //so don't use it, instead just call the hazard differently based on this flip flag
+ // hazard.min.x = -hazard.min.x - hazard.width //-x-width
+ // hazard.max.x = -hazard.max.x - hazard.width //-x-width
+ // hazard2.min.x = -hazard2.min.x - hazard2.width //-x-width
+ // hazard2.max.x = -hazard2.max.x - hazard2.width //-x-width
+ portal = level.portal({
+ x: -2475,
+ y: -140
+ }, 2 * Math.PI, { //right
+ x: -2475,
+ y: -3140
+ }, 2 * Math.PI) //right
+
+ portal2 = level.portal({
+ x: -75,
+ y: -2150
+ }, -Math.PI / 2, { //up
+ x: -1325,
+ y: -2150
+ }, -Math.PI / 2) //up
+
+ portal3 = level.portal({
+ x: -1850,
+ y: -585
+ }, -Math.PI / 2, { //up
+ x: -2425,
+ y: -600
+ }, -1 * Math.PI / 3) //up left
+
+ // level.custom = () => { };
+ // level.customTopLayer = () => {};
+
+ } else {
+ portal = level.portal({
+ x: 2475,
+ y: -140
+ }, Math.PI, { //left
+ x: 2475,
+ y: -3140
+ }, Math.PI) //left
+ portal2 = level.portal({
+ x: 75,
+ y: -2150
+ }, -Math.PI / 2, { //up
+ x: 1325,
+ y: -2150
+ }, -Math.PI / 2) //up
+ portal3 = level.portal({
+ x: 1850,
+ y: -585
+ }, -Math.PI / 2, { //up
+ x: 2425,
+ y: -600
+ }, -2 * Math.PI / 3) //up left
+ }
+
},
sewers() {
const button1 = level.button(6600, 2675)
@@ -4075,7 +4337,10 @@ const level = {
button1.query();
button1.draw();
ctx.fillStyle = "hsl(175, 15%, 76%)"
- ctx.fillRect(9300, 2200, 600, 400)
+ ctx.fillRect(9100, 2200, 800, 400)
+ ctx.fillStyle = "rgba(0,0,0,0.03)" //shadows
+ ctx.fillRect(6250, 2025, 700, 650)
+ ctx.fillRect(8000, 2025, 600, 575)
level.exit.drawAndCheck();
level.enter.draw();
};
@@ -4121,7 +4386,7 @@ const level = {
spawn.bodyRect(1450, -300, 150, 50);
const xPos = shuffle([600, 1250, 2000]);
- spawn.mapRect(xPos[0], -200, 400, 100);
+ spawn.mapRect(xPos[0], -200, 300, 100);
spawn.mapRect(xPos[1], -250, 300, 300);
spawn.mapRect(xPos[2], -150, 300, 200);
@@ -4228,7 +4493,10 @@ const level = {
rotor.rotate();
ctx.fillStyle = "hsl(175, 15%, 76%)"
- ctx.fillRect(-9300 - 600, 2200, 600, 400)
+ ctx.fillRect(-9900, 2200, 800, 400)
+ ctx.fillStyle = "rgba(0,0,0,0.03)" //shadows
+ ctx.fillRect(-6950, 2025, 700, 650)
+ ctx.fillRect(-8600, 2025, 600, 575)
level.exit.drawAndCheck();
level.enter.draw();
diff --git a/js/player.js b/js/player.js
index 08bd892..e2272e5 100644
--- a/js/player.js
+++ b/js/player.js
@@ -3367,7 +3367,7 @@ const m = {
const drain = m.fieldRegen + 0.0004
if (m.energy > drain) {
m.energy -= drain
- if (m.immuneCycle < m.cycle + 1) m.immuneCycle = m.cycle + 1; //player is immune to damage for 1/4 seconds // and can't regen
+ if (m.immuneCycle < m.cycle + 1) m.immuneCycle = m.cycle + 1; //player is immune to damage for 1 cycle
m.isBodiesAsleep = true;
function sleep(who) {
@@ -3469,7 +3469,7 @@ const m = {
x: velocity.x,
y: velocity.y - 4 //an extra vertical kick so the player hangs in place longer
});
- if (m.immuneCycle < m.cycle + 15) m.immuneCycle = m.cycle + 15; //player is immune to damage for 1/4 seconds
+ if (m.immuneCycle < m.cycle + 5) m.immuneCycle = m.cycle + 5; //player is immune to damage for 1/4 seconds
// move bots to player
for (let i = 0; i < bullet.length; i++) {
if (bullet[i].botType) {
diff --git a/js/powerup.js b/js/powerup.js
index 92333b2..a41bae3 100644
--- a/js/powerup.js
+++ b/js/powerup.js
@@ -248,6 +248,7 @@ const powerUps = {
} else if (type === "field") {
m.setField(index)
} else if (type === "tech") {
+ if (tech.isBanish && tech.tech[index].isBanished) tech.tech[index].isBanished = false
setTimeout(() => { powerUps.lastTechIndex = index }, 10);
simulation.makeTextLog(`tech.giveTech("${tech.tech[index].name}")`);
tech.giveTech(index)
@@ -270,7 +271,7 @@ const powerUps = {
document.getElementById("choose-grid").style.transitionDuration = "0s";
}, 500);
- // if (tech.isExtraChoice) {
+ // if (tech.extraChoices) {
// document.body.style.overflowY = "scroll";
// document.body.style.overflowX = "hidden";
// }
@@ -304,7 +305,7 @@ const powerUps = {
},
endDraft(type, isCanceled = false) { //type should be a gun, tech, or field
if (isCanceled) {
- if (tech.isCancelTech && Math.random() < 0.94) {
+ if (tech.isCancelTech && Math.random() < 0.96) {
// powerUps.research.use('tech')
powerUps[type].effect();
return
@@ -330,16 +331,16 @@ const powerUps = {
// powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "tech", false);
// simulation.makeTextLog(`options exchange: returns 1 tech`)
// }
- if (tech.isBanish && type === 'tech') { // banish researched tech by adding them to the list of banished tech
- const banishLength = tech.isDeterminism ? 1 : 3 + tech.isExtraChoice * 2
- for (let i = 0; i < banishLength; i++) {
- const index = powerUps.tech.choiceLog.length - i - 1
- if (powerUps.tech.choiceLog[index] && tech.tech[powerUps.tech.choiceLog[index]]) {
- tech.tech[powerUps.tech.choiceLog[index]].isBanished = true
- }
- }
- simulation.makeTextLog(`powerUps.tech.length: ${Math.max(0,powerUps.tech.lastTotalChoices - banishLength)}`)
- }
+ // if (tech.isBanish && type === 'tech') { // banish researched tech by adding them to the list of banished tech
+ // const banishLength = tech.isDeterminism ? 1 : 3 + tech.extraChoices * 2
+ // for (let i = 0; i < banishLength; i++) {
+ // const index = powerUps.tech.choiceLog.length - i - 1
+ // if (powerUps.tech.choiceLog[index] && tech.tech[powerUps.tech.choiceLog[index]]) {
+ // tech.tech[powerUps.tech.choiceLog[index]].isBanished = true
+ // }
+ // }
+ // simulation.makeTextLog(`powerUps.tech.length: ${Math.max(0,powerUps.tech.lastTotalChoices - banishLength)}`)
+ // }
}
if (tech.isAnsatz && powerUps.research.count === 0) {
for (let i = 0; i < 2; i++) powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false);
@@ -425,14 +426,14 @@ const powerUps = {
powerUps.research.changeRerolls(-1)
}
powerUps.research.currentRerollCount++
- if (tech.isBanish && type === 'tech') { // banish researched tech
- const banishLength = tech.isDeterminism ? 1 : 3 + tech.isExtraChoice * 2
- for (let i = 0; i < banishLength; i++) {
- const index = powerUps.tech.choiceLog.length - i - 1
- if (powerUps.tech.choiceLog[index] && tech.tech[powerUps.tech.choiceLog[index]]) tech.tech[powerUps.tech.choiceLog[index]].isBanished = true
- }
- simulation.makeTextLog(`powerUps.tech.length: ${Math.max(0,powerUps.tech.lastTotalChoices - banishLength)}`)
- }
+ // if (tech.isBanish && type === 'tech') { // banish researched tech
+ // const banishLength = tech.isDeterminism ? 1 : 3 + tech.extraChoices * 2
+ // for (let i = 0; i < banishLength; i++) {
+ // const index = powerUps.tech.choiceLog.length - i - 1
+ // if (powerUps.tech.choiceLog[index] && tech.tech[powerUps.tech.choiceLog[index]]) tech.tech[powerUps.tech.choiceLog[index]].isBanished = true
+ // }
+ // simulation.makeTextLog(`powerUps.tech.length: ${Math.max(0,powerUps.tech.lastTotalChoices - banishLength)}`)
+ // }
if (tech.isResearchReality) {
m.switchWorlds()
simulation.trails()
@@ -572,81 +573,261 @@ const powerUps = {
}
}
},
+ gun: {
+ name: "gun",
+ color: "#26a",
+ size() {
+ return 35;
+ },
+ effect() {
+ if (m.alive) {
+ let text = ""
+ if (!tech.isSuperDeterminism) text += `
${tech.isCancelTech ? "?":"✕"}
`
+ text += `gun
`
+
+ let options = [];
+ for (let i = 0; i < b.guns.length; i++) {
+ if (!b.guns[i].have) options.push(i);
+ }
+ let totalChoices = Math.min(options.length, tech.isDeterminism ? 1 : 3 + tech.extraChoices)
+ if (tech.isFlipFlopChoices) totalChoices += tech.isRelay ? (tech.isFlipFlopOn ? -1 : 7) : (tech.isFlipFlopOn ? 7 : -1) //flip the order for relay
+
+
+ function removeOption(index) {
+ for (let i = 0; i < options.length; i++) {
+ if (options[i] === index) {
+ options.splice(i, 1) //remove a previous choice from option pool
+ return
+ }
+ }
+ }
+
+ //check for guns that were a choice last time and remove them
+ for (let i = 0; i < b.guns.length; i++) {
+ if (options.length - 1 < totalChoices) break //you have to repeat choices if there are not enough choices left to display
+ if (b.guns[i].isRecentlyShown) removeOption(i)
+ }
+ for (let i = 0; i < b.guns.length; i++) b.guns[i].isRecentlyShown = false //reset recently shown back to zero
+
+ if (options.length > 0) {
+ for (let i = 0; i < totalChoices; i++) {
+ const choose = options[Math.floor(Math.seededRandom(0, options.length))] //pick an element from the array of options
+ text += ` ${b.guns[choose].description}
`
+ b.guns[choose].isRecentlyShown = true
+ removeOption(choose)
+ if (options.length < 1) break
+ }
+ if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
+ tech.junkResearchNumber = Math.floor(5 * Math.random())
+ text += ` `
+ for (let i = 0; i < tech.junkResearchNumber; i++) text += ``
+ text += ` pseudoscience `
+ } else if (powerUps.research.count) {
+ text += ` `
+ for (let i = 0, len = Math.min(powerUps.research.count, 30); i < len; i++) text += ``
+ text += ` ${tech.isResearchReality?"alternate reality": "research"} `
+ }
+ if (tech.isOneGun && b.inventory.length > 0) text += `replaces your current gun
`
+ document.getElementById("choose-grid").innerHTML = text
+ powerUps.showDraft();
+ }
+ }
+ },
+ // pick(who, skip1 = -1, skip2 = -1, skip3 = -1, skip4 = -1) {
+ // let options = [];
+ // for (let i = 0; i < who.length; i++) {
+ // if (!who[i].have && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4) {
+ // options.push(i);
+ // }
+ // }
+ // //remove repeats from last selection
+ // const totalChoices = tech.isDeterminism ? 1 : 3 + tech.extraChoices * 2
+ // if (powerUps.gun.choiceLog.length > totalChoices || powerUps.gun.choiceLog.length === totalChoices) { //make sure this isn't the first time getting a power up and there are previous choices to remove
+ // for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection
+ // if (options.length > totalChoices) {
+ // for (let j = 0, len = options.length; j < len; j++) {
+ // if (powerUps.gun.choiceLog[powerUps.gun.choiceLog.length - 1 - i] === options[j]) {
+ // options.splice(j, 1) //remove previous choice from option pool
+ // break
+ // }
+ // }
+ // }
+ // }
+ // }
+ // if (options.length > 0) {
+ // return options[Math.floor(Math.seededRandom(0, options.length))]
+ // }
+ // },
+ // effectOld() {
+ // let choice1 = powerUps.gun.pick(b.guns)
+ // let choice2 = -1
+ // let choice3 = -1
+ // if (choice1 > -1) {
+ // let text = ""
+ // if (!tech.isSuperDeterminism) text += `${tech.isCancelTech ? "?":"✕"}
`
+ // text += `gun
`
+ // text += ` ${b.guns[choice1].description}
`
+ // if (!tech.isDeterminism) {
+ // choice2 = powerUps.gun.pick(b.guns, choice1)
+ // if (choice2 > -1) text += ` ${b.guns[choice2].description}
`
+ // choice3 = powerUps.gun.pick(b.guns, choice1, choice2)
+ // if (choice3 > -1) text += ` ${b.guns[choice3].description}
`
+ // }
+ // if (tech.extraChoices) {
+ // let choice4 = powerUps.gun.pick(b.guns, choice1, choice2, choice3)
+ // if (choice4 > -1) text += ` ${b.guns[choice4].description}
`
+ // let choice5 = powerUps.gun.pick(b.guns, choice1, choice2, choice3, choice4)
+ // if (choice5 > -1) text += `
+ //
${b.guns[choice5].description}
`
+ // powerUps.gun.choiceLog.push(choice4)
+ // powerUps.gun.choiceLog.push(choice5)
+ // }
+ // powerUps.gun.choiceLog.push(choice1)
+ // powerUps.gun.choiceLog.push(choice2)
+ // powerUps.gun.choiceLog.push(choice3)
+ // // if (powerUps.research.count) text += ` research
${powerUps.research.count} `
+
+ // if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
+ // tech.junkResearchNumber = Math.floor(5 * Math.random())
+ // text += ` `
+ // for (let i = 0; i < tech.junkResearchNumber; i++) text += ``
+ // text += ` pseudoscience `
+ // } else if (powerUps.research.count) {
+ // text += ` `
+ // for (let i = 0, len = Math.min(powerUps.research.count, 30); i < len; i++) text += ``
+ // text += ` ${tech.isResearchReality?"alternate reality": "research"} `
+ // }
+ // if (tech.isOneGun && b.inventory.length > 0) text += `replaces your current gun
`
+ // document.getElementById("choose-grid").innerHTML = text
+ // powerUps.showDraft();
+ // }
+ // }
+ },
field: {
name: "field",
color: "#0cf",
size() {
return 45;
},
- pick(who, skip1 = -1, skip2 = -1, skip3 = -1, skip4 = -1) {
- let options = [];
- for (let i = 1; i < who.length; i++) {
- if (i !== m.fieldMode && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4) options.push(i);
- }
- //remove repeats from last selection
- const totalChoices = tech.isDeterminism ? 1 : 3 + tech.isExtraChoice * 2
- if (powerUps.field.choiceLog.length > totalChoices || powerUps.field.choiceLog.length === totalChoices) { //make sure this isn't the first time getting a power up and there are previous choices to remove
- for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection
- if (options.length > totalChoices) {
- for (let j = 0, len = options.length; j < len; j++) {
- if (powerUps.field.choiceLog[powerUps.field.choiceLog.length - 1 - i] === options[j]) {
- options.splice(j, 1) //remove previous choice from option pool
- break
- }
- }
- }
- }
- }
- if (options.length > 0) {
- // return options[Math.floor(Math.random() * options.length)]
- return options[Math.floor(Math.seededRandom(0, options.length))]
- }
- },
- choiceLog: [], //records all previous choice options
effect() {
- let choice1 = powerUps.field.pick(m.fieldUpgrades)
- let choice2 = -1
- let choice3 = -1
- if (choice1 > -1) {
+ if (m.alive) {
let text = ""
if (!tech.isSuperDeterminism) text += `${tech.isCancelTech ? "?":"✕"}
`
text += `field
`
- text += ` ${m.fieldUpgrades[choice1].name}
${m.fieldUpgrades[choice1].description}
`
- powerUps.field.choiceLog.push(choice1)
- if (!tech.isDeterminism) {
- choice2 = powerUps.field.pick(m.fieldUpgrades, choice1)
- if (choice2 > -1) text += ` ${m.fieldUpgrades[choice2].name}
${m.fieldUpgrades[choice2].description}
`
- choice3 = powerUps.field.pick(m.fieldUpgrades, choice1, choice2)
- if (choice3 > -1) text += ` ${m.fieldUpgrades[choice3].name}
${m.fieldUpgrades[choice3].description}
`
- powerUps.field.choiceLog.push(choice2)
- powerUps.field.choiceLog.push(choice3)
- }
- if (tech.isExtraChoice) {
- let choice4 = powerUps.field.pick(m.fieldUpgrades, choice1, choice2, choice3)
- if (choice4 > -1) text += ` ${m.fieldUpgrades[choice4].name}
${m.fieldUpgrades[choice4].description}
`
- let choice5 = powerUps.field.pick(m.fieldUpgrades, choice1, choice2, choice3, choice4)
- if (choice5 > -1) text += ` ${m.fieldUpgrades[choice5].name}
${m.fieldUpgrades[choice5].description}
`
- powerUps.field.choiceLog.push(choice4)
- powerUps.field.choiceLog.push(choice5)
- }
- if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
- tech.junkResearchNumber = Math.floor(4 * Math.random())
- text += ` `
- for (let i = 0; i < tech.junkResearchNumber; i++) text += ``
- text += ` pseudoscience `
- } else if (powerUps.research.count) {
- text += ` `
- for (let i = 0, len = Math.min(powerUps.research.count, 30); i < len; i++) text += ``
- // text += ` research `
- text += ` ${tech.isResearchReality?"alternate reality": "research"}`
+ let options = [];
+ for (let i = 1; i < m.fieldUpgrades.length; i++) { //skip field emitter
+ if (i !== m.fieldMode) options.push(i);
+ }
+ let totalChoices = Math.min(options.length, tech.isDeterminism ? 1 : 3 + tech.extraChoices)
+ if (tech.isFlipFlopChoices) totalChoices += tech.isRelay ? (tech.isFlipFlopOn ? -1 : 7) : (tech.isFlipFlopOn ? 7 : -1) //flip the order for relay
+
+ function removeOption(index) {
+ for (let i = 0; i < options.length; i++) {
+ if (options[i] === index) {
+ options.splice(i, 1) //remove a previous choice from option pool
+ return
+ }
+ }
+ }
+ //check for fields that were a choice last time and remove them
+ for (let i = 0; i < m.fieldUpgrades.length; i++) {
+ if (options.length - 1 < totalChoices) break //you have to repeat choices if there are not enough choices left to display
+ if (m.fieldUpgrades[i].isRecentlyShown) removeOption(i)
+ }
+ for (let i = 0; i < m.fieldUpgrades.length; i++) m.fieldUpgrades[i].isRecentlyShown = false //reset recently shown back to zero
+
+ if (options.length > 0) {
+ for (let i = 0; i < totalChoices; i++) {
+ const choose = options[Math.floor(Math.seededRandom(0, options.length))] //pick an element from the array of options
+ text += ` ${m.fieldUpgrades[choose].name}
${m.fieldUpgrades[choose].description}
`
+ m.fieldUpgrades[choose].isRecentlyShown = true
+ removeOption(choose)
+ if (options.length < 1) break
+ }
+ if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
+ tech.junkResearchNumber = Math.floor(5 * Math.random())
+ text += ` `
+ for (let i = 0; i < tech.junkResearchNumber; i++) text += ``
+ text += ` pseudoscience `
+ } else if (powerUps.research.count) {
+ text += ` `
+ for (let i = 0, len = Math.min(powerUps.research.count, 30); i < len; i++) text += ``
+ text += ` ${tech.isResearchReality?"alternate reality": "research"} `
+ }
+ document.getElementById("choose-grid").innerHTML = text
+ powerUps.showDraft();
}
- //(${powerUps.research.count})
- // text += `${simulation.SVGrightMouse} activate the shield with the right mouse
fields shield you from damage
and let you pick up and throw blocks
`
- document.getElementById("choose-grid").innerHTML = text
- powerUps.showDraft();
}
- }
+ },
+ // pick(who, skip1 = -1, skip2 = -1, skip3 = -1, skip4 = -1) {
+ // let options = [];
+ // for (let i = 1; i < who.length; i++) {
+ // if (i !== m.fieldMode && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4) options.push(i);
+ // }
+ // //remove repeats from last selection
+ // const totalChoices = tech.isDeterminism ? 1 : 3 + tech.extraChoices * 2
+ // if (powerUps.field.choiceLog.length > totalChoices || powerUps.field.choiceLog.length === totalChoices) { //make sure this isn't the first time getting a power up and there are previous choices to remove
+ // for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection
+ // if (options.length > totalChoices) {
+ // for (let j = 0, len = options.length; j < len; j++) {
+ // if (powerUps.field.choiceLog[powerUps.field.choiceLog.length - 1 - i] === options[j]) {
+ // options.splice(j, 1) //remove previous choice from option pool
+ // break
+ // }
+ // }
+ // }
+ // }
+ // }
+ // if (options.length > 0) {
+ // // return options[Math.floor(Math.random() * options.length)]
+ // return options[Math.floor(Math.seededRandom(0, options.length))]
+ // }
+ // },
+ // effectOld() {
+ // let choice1 = powerUps.field.pick(m.fieldUpgrades)
+ // let choice2 = -1
+ // let choice3 = -1
+ // if (choice1 > -1) {
+ // let text = ""
+ // if (!tech.isSuperDeterminism) text += `${tech.isCancelTech ? "?":"✕"}
`
+ // text += `field
`
+ // text += ` ${m.fieldUpgrades[choice1].name}
${m.fieldUpgrades[choice1].description}
`
+ // powerUps.field.choiceLog.push(choice1)
+ // if (!tech.isDeterminism) {
+ // choice2 = powerUps.field.pick(m.fieldUpgrades, choice1)
+ // if (choice2 > -1) text += ` ${m.fieldUpgrades[choice2].name}
${m.fieldUpgrades[choice2].description}
`
+ // choice3 = powerUps.field.pick(m.fieldUpgrades, choice1, choice2)
+ // if (choice3 > -1) text += ` ${m.fieldUpgrades[choice3].name}
${m.fieldUpgrades[choice3].description}
`
+ // powerUps.field.choiceLog.push(choice2)
+ // powerUps.field.choiceLog.push(choice3)
+ // }
+ // if (tech.extraChoices) {
+ // let choice4 = powerUps.field.pick(m.fieldUpgrades, choice1, choice2, choice3)
+ // if (choice4 > -1) text += ` ${m.fieldUpgrades[choice4].name}
${m.fieldUpgrades[choice4].description}
`
+ // let choice5 = powerUps.field.pick(m.fieldUpgrades, choice1, choice2, choice3, choice4)
+ // if (choice5 > -1) text += ` ${m.fieldUpgrades[choice5].name}
${m.fieldUpgrades[choice5].description}
`
+ // powerUps.field.choiceLog.push(choice4)
+ // powerUps.field.choiceLog.push(choice5)
+ // }
+
+ // if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
+ // tech.junkResearchNumber = Math.floor(4 * Math.random())
+ // text += ` `
+ // for (let i = 0; i < tech.junkResearchNumber; i++) text += ``
+ // text += ` pseudoscience `
+ // } else if (powerUps.research.count) {
+ // text += ` `
+ // for (let i = 0, len = Math.min(powerUps.research.count, 30); i < len; i++) text += ``
+ // // text += ` research `
+ // text += ` ${tech.isResearchReality?"alternate reality": "research"}`
+ // }
+ // //(${powerUps.research.count})
+ // // text += `${simulation.SVGrightMouse} activate the shield with the right mouse
fields shield you from damage
and let you pick up and throw blocks
`
+ // document.getElementById("choose-grid").innerHTML = text
+ // powerUps.showDraft();
+ // }
+ // }
},
tech: {
name: "tech",
@@ -654,53 +835,98 @@ const powerUps = {
size() {
return 42;
},
- choiceLog: [], //records all previous choice options
- lastTotalChoices: 0, //tracks how many tech were available for random selection last time a tech was picked up
- // banishLog: [], //records all tech permanently removed from the selection pool
effect() {
if (m.alive) {
- function pick(skip1 = null, skip2 = null, skip3 = null, skip4 = null) {
- let options = [];
+ let text = ""
+ if (!tech.isSuperDeterminism) text += `${tech.isCancelTech ? "?":"✕"}
`
+ text += `tech
`
+
+ let options = []; //generate all options
+ optionLengthNoDuplicates = 0
+ for (let i = 0; i < tech.tech.length; i++) {
+ if (tech.tech[i].count < tech.tech[i].maxCount && tech.tech[i].allowed() && !tech.tech[i].isBanished) {
+ if (tech.tech[i].frequency > 0) optionLengthNoDuplicates++
+ for (let j = 0, len = tech.tech[i].frequency; j < len; j++) options.push(i);
+ }
+ }
+ // console.log(optionLengthNoDuplicates, options.length)
+
+ function removeOption(index) {
+ for (let i = options.length; i > -1; i--) {
+ if (index === options[i]) {
+ options.splice(i, 1) //remove all copies of that option form the options array (some tech are in the options array multiple times because of frequency)
+ optionLengthNoDuplicates--
+ }
+ if (options.length < 1) return;
+ }
+ }
+
+ //set total choices
+ let totalChoices = tech.isDeterminism ? 1 : 3 + tech.extraChoices
+ if (tech.isFlipFlopChoices) totalChoices += tech.isRelay ? (tech.isFlipFlopOn ? -1 : 7) : (tech.isFlipFlopOn ? 7 : -1) //flip the order for relay
+ if (optionLengthNoDuplicates < totalChoices + 1) { //if not enough options for all the choices
+ // console.log('if not enough options for all the choices')
+ totalChoices = optionLengthNoDuplicates
+ if (tech.isBanish) { //when you run out of options eject banish
+ for (let i = 0, len = tech.tech.length; i < len; i++) {
+ if (tech.tech[i].name === "decoherence") powerUps.ejectTech(i, true)
+ }
+ simulation.makeTextLog(`decoherence tech ejected`)
+ simulation.makeTextLog(`options reset`)
+ }
+ }
+ if (tech.tooManyTechChoices) {
+ tech.tooManyTechChoices = false
+ totalChoices = optionLengthNoDuplicates
+ }
+
+
+
+ //check for tech that were a choice last time and remove them
+ if (optionLengthNoDuplicates > totalChoices) {
+ // console.log('check for tech that were a choice last time and remove them', optionLengthNoDuplicates, options.length)
for (let i = 0; i < tech.tech.length; i++) {
- if (tech.tech[i].count < tech.tech[i].maxCount && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4 && tech.tech[i].allowed() && !tech.tech[i].isBanished) {
- for (let j = 0, len = tech.tech[i].frequency; j < len; j++) options.push(i);
- }
- }
- powerUps.tech.lastTotalChoices = options.length //this is recorded so that banish can know how many tech were available
-
- const totalChoices = tech.isDeterminism ? 1 : 3 + tech.isExtraChoice * 2
- if (powerUps.tech.choiceLog.length > totalChoices || powerUps.tech.choiceLog.length === totalChoices) { //make sure this isn't the first time getting a power up and there are previous choices to remove
- for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection
- if (options.length > totalChoices) {
- for (let j = 0, len = options.length; j < len; j++) {
- if (powerUps.tech.choiceLog[powerUps.tech.choiceLog.length - 1 - i] === options[j]) {
- options.splice(j, 1) //remove previous choice from option pool
- break;
- }
- }
+ if (optionLengthNoDuplicates > totalChoices) {
+ if (tech.tech[i].isRecentlyShown) {
+ // console.log(i)
+ removeOption(i)
}
+ } else {
+ break //you have to repeat choices if there are not enough choices left to display
}
+
}
+ }
+ for (let i = 0; i < tech.tech.length; i++) tech.tech[i].isRecentlyShown = false //reset recently shown back to zero
+ // powerUps.tech.lastTotalChoices = options.length //this is recorded so that banish can know how many tech were available
+ // console.log(optionLengthNoDuplicates, options.length)
+ if (options.length > 0) {
+ for (let i = 0; i < totalChoices; i++) {
+ if (options.length < 1) break
+ const choose = options[Math.floor(Math.seededRandom(0, options.length))] //pick an element from the array of options
+ if (tech.isBanish) {
+ tech.tech[choose].isBanished = true
+ if (i === 0) simulation.makeTextLog(`options.length = ${optionLengthNoDuplicates}`)
+ }
+ //avoid displaying repeated tech options at the same time
+ removeOption(choose)
+ tech.tech[choose].isRecentlyShown = true
- if (options.length > 0) {
- // const choose = options[Math.floor(Math.random() * options.length)]
- const choose = options[Math.floor(Math.seededRandom(0, options.length))]
const isCount = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count+1}x)` : "";
-
if (tech.tech[choose].isFieldTech) {
text += `
-
-
-
-
- ${tech.tech[choose].name} ${isCount}
${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() :tech.tech[choose].description}
`
+
+
+
+
+ ${tech.tech[choose].name} ${isCount}${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() :tech.tech[choose].description}`
} else if (tech.tech[choose].isGunTech) {
text += `
-
-
-
-
- ${tech.tech[choose].name} ${isCount}
${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() :tech.tech[choose].description}
`
+
+
+
+
+ ${tech.tech[choose].name} ${isCount}${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() :tech.tech[choose].description}`
} else if (tech.tech[choose].isLore) {
text += ` ${tech.tech[choose].name} ${isCount}
${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}
`
} else if (tech.tech[choose].isJunk) {
@@ -708,65 +934,28 @@ const powerUps = {
} else {
text += ` ${tech.tech[choose].name} ${isCount}
${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}
`
}
-
- // text += ` ${tech.tech[choose].name}
${tech.tech[choose].description}
`
- return choose
- } else if (tech.isBanish) { //if no tech options available eject banish tech
- for (let i = 0, len = tech.tech.length; i < len; i++) {
- if (tech.tech[i].name === "decoherence") powerUps.ejectTech(i)
- }
+ if (options.length < 1) break
}
- }
-
- let text = ""
- if (!tech.isSuperDeterminism) text += `${tech.isCancelTech ? "?":"✕"}
`
- text += `tech
`
- let choice1 = pick()
- // console.log(choice1)
- let choice2 = null
- let choice3 = null
- if (choice1 !== null) {
- powerUps.tech.choiceLog.push(choice1)
- if (!tech.isDeterminism) {
- choice2 = pick(choice1)
- // if (choice2 > -1) text += ` ${tech.tech[choice2].name}
${tech.tech[choice2].description}
`
- choice3 = pick(choice1, choice2)
- // if (choice3 > -1) text += ` ${tech.tech[choice3].name}
${tech.tech[choice3].description}
`
- powerUps.tech.choiceLog.push(choice2)
- powerUps.tech.choiceLog.push(choice3)
- }
- if (tech.isExtraChoice) {
- let choice4 = pick(choice1, choice2, choice3)
- // if (choice4 > -1) text += ` ${tech.tech[choice4].name}
${tech.tech[choice4].description}
`
- let choice5 = pick(choice1, choice2, choice3, choice4)
- // if (choice5 > -1) text += ` ${tech.tech[choice5].name}
${tech.tech[choice5].description}
`
- powerUps.tech.choiceLog.push(choice4)
- powerUps.tech.choiceLog.push(choice5)
- }
- // if (powerUps.research.count) text += ` research
${powerUps.research.count} `
-
if (tech.isExtraGunField) {
if (Math.random() > 0.5 && b.inventory.length < b.guns.length) {
- //bonus gun in tech menu
- let choiceGun = powerUps.gun.pick(b.guns)
- powerUps.gun.choiceLog.push(choiceGun)
- text += ` ${b.guns[choiceGun].name}
${b.guns[choiceGun].description}
`
+ let gunOptions = [];
+ for (let i = 0; i < b.guns.length; i++) {
+ if (!b.guns[i].have) gunOptions.push(i);
+ }
+ const pick = gunOptions[Math.floor(Math.seededRandom(0, gunOptions.length))] //pick an element from the array of options
+ text += ` ${b.guns[pick].description}
`
} else {
- //bonus field in tech menu
- let choiceField = powerUps.field.pick(m.fieldUpgrades)
- powerUps.field.choiceLog.push(choiceField)
- text += ` ${m.fieldUpgrades[choiceField].name}
${m.fieldUpgrades[choiceField].description}
`
+ let fieldOptions = [];
+ for (let i = 1; i < m.fieldUpgrades.length; i++) { //skip field emitter
+ if (i !== m.fieldMode) fieldOptions.push(i);
+ }
+ const pick = options[Math.floor(Math.seededRandom(0, fieldOptions.length))] //pick an element from the array of options
+ text += ` ${m.fieldUpgrades[pick].name}
${m.fieldUpgrades[pick].description}
`
}
}
- if (tech.tooManyTechChoices) {
- tech.tooManyTechChoices--
- for (let i = 0; i < powerUps.tech.lastTotalChoices; i++) pick()
- }
-
if (tech.isBrainstorm && !tech.isBrainstormActive && !simulation.isChoosing) {
tech.isBrainstormActive = true
let count = 0
- requestAnimationFrame(cycle);
function cycle() {
count++
@@ -782,8 +971,8 @@ const powerUps = {
tech.isBrainstormActive = false
}
}
+ requestAnimationFrame(cycle);
}
-
//add in research button or pseudoscience button
if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
tech.junkResearchNumber = Math.floor(5 * Math.random())
@@ -796,115 +985,160 @@ const powerUps = {
// text += ` research`
text += ` ${tech.isResearchReality?"alternate reality": "research"}`
}
-
- // if (tech.isBrainstorm && tech.isBrainstormActive < 4) {
- // setTimeout(() => {
- // if (simulation.isChoosing) {
- // tech.isBrainstormActive++
- // powerUps.tech.effect();
- // //turn off the normal 500ms delay
- // document.getElementById("choose-grid").style.pointerEvents = "auto";
- // document.body.style.cursor = "auto";
- // document.getElementById("choose-grid").style.transitionDuration = "0s";
- // } else {
- // tech.isBrainstormActive = 0;
- // }
- // }, 1000);
- // } else {
- // tech.isBrainstormActive = 0;
- // }
-
document.getElementById("choose-grid").innerHTML = text
powerUps.showDraft();
-
}
}
- }
- },
- gun: {
- name: "gun",
- color: "#26a",
- size() {
- return 35;
- },
- pick(who, skip1 = -1, skip2 = -1, skip3 = -1, skip4 = -1) {
- let options = [];
- for (let i = 0; i < who.length; i++) {
- if (!who[i].have && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4) {
- options.push(i);
- }
- }
-
- //remove repeats from last selection
- const totalChoices = tech.isDeterminism ? 1 : 3 + tech.isExtraChoice * 2
- if (powerUps.gun.choiceLog.length > totalChoices || powerUps.gun.choiceLog.length === totalChoices) { //make sure this isn't the first time getting a power up and there are previous choices to remove
- for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection
- if (options.length > totalChoices) {
- for (let j = 0, len = options.length; j < len; j++) {
- if (powerUps.gun.choiceLog[powerUps.gun.choiceLog.length - 1 - i] === options[j]) {
- options.splice(j, 1) //remove previous choice from option pool
- break
- }
- }
- }
- }
- }
- if (options.length > 0) {
- // console.log(`random: ${Math.seededRandom(0, options.length)}`)
-
- return options[Math.floor(Math.seededRandom(0, options.length))]
- // return options[Math.floor(Math.random() * options.length)]
- }
},
- choiceLog: [], //records all previous choice options
- effect() {
- let choice1 = powerUps.gun.pick(b.guns)
- let choice2 = -1
- let choice3 = -1
- if (choice1 > -1) {
- let text = ""
- if (!tech.isSuperDeterminism) text += `${tech.isCancelTech ? "?":"✕"}
`
- text += `gun
`
- text += ` ${b.guns[choice1].description}
`
- if (!tech.isDeterminism) {
- choice2 = powerUps.gun.pick(b.guns, choice1)
- if (choice2 > -1) text += ` ${b.guns[choice2].description}
`
- choice3 = powerUps.gun.pick(b.guns, choice1, choice2)
- if (choice3 > -1) text += ` ${b.guns[choice3].description}
`
- }
- if (tech.isExtraChoice) {
- let choice4 = powerUps.gun.pick(b.guns, choice1, choice2, choice3)
- if (choice4 > -1) text += ` ${b.guns[choice4].description}
`
- let choice5 = powerUps.gun.pick(b.guns, choice1, choice2, choice3, choice4)
- if (choice5 > -1) text += `
-
${b.guns[choice5].description}
`
- powerUps.gun.choiceLog.push(choice4)
- powerUps.gun.choiceLog.push(choice5)
- }
- powerUps.gun.choiceLog.push(choice1)
- powerUps.gun.choiceLog.push(choice2)
- powerUps.gun.choiceLog.push(choice3)
- // if (powerUps.research.count) text += ` research
${powerUps.research.count} `
+ // effectOld() {
+ // if (m.alive) {
+ // function pick(skip1 = null, skip2 = null, skip3 = null, skip4 = null) {
+ // let options = [];
+ // for (let i = 0; i < tech.tech.length; i++) {
+ // if (tech.tech[i].count < tech.tech[i].maxCount && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4 && tech.tech[i].allowed() && !tech.tech[i].isBanished) {
+ // for (let j = 0, len = tech.tech[i].frequency; j < len; j++) options.push(i);
+ // }
+ // }
+ // powerUps.tech.lastTotalChoices = options.length //this is recorded so that banish can know how many tech were available
- if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
- tech.junkResearchNumber = Math.floor(5 * Math.random())
- text += ` `
- for (let i = 0; i < tech.junkResearchNumber; i++) text += ``
- text += ` pseudoscience `
- } else if (powerUps.research.count) {
- text += ` `
- for (let i = 0, len = Math.min(powerUps.research.count, 30); i < len; i++) text += ``
- text += ` ${tech.isResearchReality?"alternate reality": "research"} `
- }
- if (tech.isOneGun && b.inventory.length > 0) text += `replaces your current gun
`
- document.getElementById("choose-grid").innerHTML = text
- powerUps.showDraft();
- }
- }
+ // const totalChoices = tech.isDeterminism ? 1 : 3 + tech.extraChoices * 2
+ // if (powerUps.tech.choiceLog.length > totalChoices || powerUps.tech.choiceLog.length === totalChoices) { //make sure this isn't the first time getting a power up and there are previous choices to remove
+ // for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection
+ // if (options.length > totalChoices) {
+ // for (let j = 0, len = options.length; j < len; j++) {
+ // if (powerUps.tech.choiceLog[powerUps.tech.length - 1 - i] === options[j]) {
+ // options.splice(j, 1) //remove previous choice from option pool
+ // break;
+ // }
+ // }
+ // }
+ // }
+ // }
+
+ // if (options.length > 0) {
+ // // const choose = options[Math.floor(Math.random() * options.length)]
+ // const choose = options[Math.floor(Math.seededRandom(0, options.length))]
+ // const isCount = tech.tech[choose].count > 0 ? `(${tech.tech[choose].count+1}x)` : "";
+
+ // if (tech.tech[choose].isFieldTech) {
+ // text += `
+ //
+ //
+ //
+ //
+ // ${tech.tech[choose].name} ${isCount}
${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() :tech.tech[choose].description}
`
+ // } else if (tech.tech[choose].isGunTech) {
+ // text += `
+ //
+ //
+ //
+ //
+ // ${tech.tech[choose].name} ${isCount}
${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() :tech.tech[choose].description}
`
+ // } else if (tech.tech[choose].isLore) {
+ // text += ` ${tech.tech[choose].name} ${isCount}
${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}
`
+ // } else if (tech.tech[choose].isJunk) {
+ // text += ` ${tech.tech[choose].name} ${isCount}
${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}
`
+ // } else {
+ // text += ` ${tech.tech[choose].name} ${isCount}
${tech.tech[choose].descriptionFunction ? tech.tech[choose].descriptionFunction() : tech.tech[choose].description}
`
+ // }
+
+ // // text += ` ${tech.tech[choose].name}
${tech.tech[choose].description}
`
+ // return choose
+ // } else if (tech.isBanish) { //if no tech options available eject banish tech
+ // for (let i = 0, len = tech.tech.length; i < len; i++) {
+ // if (tech.tech[i].name === "decoherence") powerUps.ejectTech(i)
+ // }
+ // }
+ // }
+
+
+ // let text = ""
+ // if (!tech.isSuperDeterminism) text += `${tech.isCancelTech ? "?":"✕"}
`
+ // text += `tech
`
+ // let choice1 = pick()
+ // // console.log(choice1)
+ // let choice2 = null
+ // let choice3 = null
+ // if (choice1 !== null) {
+ // powerUps.tech.choiceLog.push(choice1)
+ // if (!tech.isDeterminism) {
+ // choice2 = pick(choice1)
+ // // if (choice2 > -1) text += ` ${tech.tech[choice2].name}
${tech.tech[choice2].description}
`
+ // choice3 = pick(choice1, choice2)
+ // // if (choice3 > -1) text += ` ${tech.tech[choice3].name}
${tech.tech[choice3].description}
`
+ // powerUps.tech.choiceLog.push(choice2)
+ // powerUps.tech.choiceLog.push(choice3)
+ // }
+ // if (tech.extraChoices) {
+ // let choice4 = pick(choice1, choice2, choice3)
+ // // if (choice4 > -1) text += ` ${tech.tech[choice4].name}
${tech.tech[choice4].description}
`
+ // let choice5 = pick(choice1, choice2, choice3, choice4)
+ // // if (choice5 > -1) text += ` ${tech.tech[choice5].name}
${tech.tech[choice5].description}
`
+ // powerUps.tech.choiceLog.push(choice4)
+ // powerUps.tech.choiceLog.push(choice5)
+ // }
+ // // if (powerUps.research.count) text += ` research
${powerUps.research.count} `
+
+ // if (tech.isExtraGunField) {
+ // if (Math.random() > 0.5 && b.inventory.length < b.guns.length) {
+ // //bonus gun in tech menu
+ // let choiceGun = powerUps.gun.pick(b.guns)
+ // powerUps.gun.choiceLog.push(choiceGun)
+ // text += ` ${b.guns[choiceGun].name}
${b.guns[choiceGun].description}
`
+ // } else {
+ // //bonus field in tech menu
+ // let choiceField = powerUps.field.pick(m.fieldUpgrades)
+ // powerUps.field.choiceLog.push(choiceField)
+ // text += ` ${m.fieldUpgrades[choiceField].name}
${m.fieldUpgrades[choiceField].description}
`
+ // }
+ // }
+ // if (tech.tooManyTechChoices) {
+ // tech.tooManyTechChoices--
+ // for (let i = 0; i < powerUps.tech.lastTotalChoices; i++) pick()
+ // }
+
+ // if (tech.isBrainstorm && !tech.isBrainstormActive && !simulation.isChoosing) {
+ // tech.isBrainstormActive = true
+ // let count = 0
+ // requestAnimationFrame(cycle);
+
+ // function cycle() {
+ // count++
+ // 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
+ // document.body.style.cursor = "auto";
+ // document.getElementById("choose-grid").style.transitionDuration = "0s";
+ // }
+ // requestAnimationFrame(cycle);
+ // } else {
+ // tech.isBrainstormActive = false
+ // }
+ // }
+ // }
+
+ // //add in research button or pseudoscience button
+ // if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
+ // tech.junkResearchNumber = Math.floor(5 * Math.random())
+ // text += ` `
+ // for (let i = 0; i < tech.junkResearchNumber; i++) text += ``
+ // text += ` pseudoscience `
+ // } else if (powerUps.research.count) {
+ // text += ` `
+ // for (let i = 0, len = Math.min(powerUps.research.count, 30); i < len; i++) text += ``
+ // // text += ` research `
+ // text += ` ${tech.isResearchReality?"alternate reality": "research"}`
+ // }
+ // document.getElementById("choose-grid").innerHTML = text
+ // powerUps.showDraft();
+ // }
+ // }
+ // }
},
onPickUp(who) {
powerUps.research.currentRerollCount = 0
- if (tech.isTechDamage && who.name === "tech") m.damage(0.11)
+ if (tech.isTechDamage && who.name === "tech") m.damage(0.11 + 0.11 * tech.isEnergyHealth)
if (tech.isMassEnergy) m.energy += 2;
if (tech.isMineDrop && bullet.length < 150 && Math.random() < 0.6) {
if (tech.isLaserMine && input.down) {
@@ -1027,10 +1261,8 @@ const powerUps = {
for (let i = 0; i < 3; i++) powerUps.spawnRandomPowerUp(x, y);
}
},
- ejectTech(choose = 'random') {
- if (!simulation.isChoosing)
-
-
+ ejectTech(choose = 'random', isOverride = false) {
+ if (!simulation.isChoosing || isOverride) {
//find which tech you have
if (choose === 'random') {
const have = []
@@ -1063,22 +1295,23 @@ const powerUps = {
return false
}
} else if (tech.tech[choose].count) {
- // simulation.makeTextLog(` ${tech.tech[choose].name} was ejected`, 600) //message about what tech was lost
- simulation.makeTextLog(`tech.remove("${tech.tech[choose].name}")`)
+ // simulation.makeTextLog(` ${tech.tech[choose].name} was ejected`, 600) //message about what tech was lost
+ simulation.makeTextLog(`tech.remove("${tech.tech[choose].name}")`)
- for (let i = 0; i < tech.tech[choose].count; i++) {
- powerUps.directSpawn(m.pos.x, m.pos.y, "tech");
- powerUp[powerUp.length - 1].isDuplicated = true
+ for (let i = 0; i < tech.tech[choose].count; i++) {
+ powerUps.directSpawn(m.pos.x, m.pos.y, "tech");
+ powerUp[powerUp.length - 1].isDuplicated = true
+ }
+ // remove a random tech from the list of tech you have
+ tech.tech[choose].remove();
+ tech.tech[choose].count = 0;
+ tech.tech[choose].isLost = true;
+ simulation.updateTechHUD();
+ m.fieldCDcycle = m.cycle + 30; //disable field so you can't pick up the ejected tech
+ return true
+ } else {
+ return false
}
- // remove a random tech from the list of tech you have
- tech.tech[choose].remove();
- tech.tech[choose].count = 0;
- tech.tech[choose].isLost = true;
- simulation.updateTechHUD();
- m.fieldCDcycle = m.cycle + 30; //disable field so you can't pick up the ejected tech
- return true
- } else {
- return false
}
},
pauseEjectTech(index) {
diff --git a/js/simulation.js b/js/simulation.js
index d73b16f..d196a85 100644
--- a/js/simulation.js
+++ b/js/simulation.js
@@ -105,7 +105,7 @@ const simulation = {
simulation.isTimeSkipping = true;
for (let i = 0; i < cycles; i++) {
simulation.cycle++;
- // m.walk_cycle += (m.flipLegs * m.Vx) * 0.5; //makes the legs look like they are moving fast (it's times 0.5 because when they move too fast it's a blur)
+ // m.walk_cycle += (m.flipLegs * m.Vx) * 0.5; //makes the legs look like they are moving fast this is just gonna run for each method call since it needs some tweaking
simulation.gravity();
Engine.update(engine, simulation.delta);
// level.custom();
diff --git a/js/spawn.js b/js/spawn.js
index 48e0fa4..ac13490 100644
--- a/js/spawn.js
+++ b/js/spawn.js
@@ -1,7 +1,7 @@
//main object for spawning things in a level
const spawn = {
nonCollideBossList: ["cellBossCulture", "bomberBoss", "powerUpBoss", "growBossCulture"],
- // other bosses: suckerBoss, laserBoss, tetherBoss, bounceBoss, sprayBoss //these need a particular level to work so they are not included in the random pool
+ // other bosses: suckerBoss, laserBoss, tetherBoss, bounceBoss, sprayBoss, mineBoss //these need a particular level to work so they are not included in the random pool
randomBossList: [
"orbitalBoss", "historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss",
"powerUpBoss", "powerUpBossBaby", "streamBoss", "pulsarBoss", "spawnerBossCulture", "grenadierBoss", "growBossCulture", "blinkBoss",
@@ -3576,7 +3576,7 @@ const spawn = {
ctx.setLineDash([]);
}
},
- sprayBoss(x, y, radius = 35, isSpawnBossPowerUp = true) {
+ sprayBoss(x, y, radius = 40, isSpawnBossPowerUp = true) {
mobs.spawn(x, y, 16, radius, "rgb(255,255,255)");
let me = mob[mob.length - 1];
me.isBoss = true;
@@ -3588,7 +3588,7 @@ const spawn = {
me.frictionAir = 0;
me.restitution = 1
spawn.spawnOrbitals(me, radius + 50 + 125 * Math.random(), 1)
- Matter.Body.setDensity(me, 0.0022 + 0.0001 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
+ Matter.Body.setDensity(me, 0.002 + 0.0001 * 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
@@ -3630,8 +3630,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) < 11) Matter.Body.setVelocity(this, { x: this.velocity.x, y: this.velocity.y * 1.07 });
- if (Math.abs(this.velocity.x) < 8) Matter.Body.setVelocity(this, { x: this.velocity.x * 1.07, y: this.velocity.y });
+ if (Math.abs(this.velocity.y) < 10) Matter.Body.setVelocity(this, { x: this.velocity.x, y: this.velocity.y * 1.05 });
+ if (Math.abs(this.velocity.x) < 8) Matter.Body.setVelocity(this, { x: this.velocity.x * 1.05, y: this.velocity.y });
}
}
me.burstFire = function() {
@@ -4816,8 +4816,8 @@ const spawn = {
me.collisionFilter.mask = cat.player | cat.map | cat.body | cat.bullet;
me.onDeath = function() {
if (simulation.difficulty > 11) { //explode AoE
- const radius = 100 + simulation.difficulty + 60 * Math.random()
- if (m.immuneCycle < m.cycle && Vector.magnitude(Vector.sub(this.position, player.position)) < radius) m.damage(0.0004 * radius * simulation.dmgScale);
+ const radius = 100 + 0.5 * simulation.difficulty + 50 * Math.random()
+ if (m.immuneCycle < m.cycle && Vector.magnitude(Vector.sub(this.position, player.position)) < radius) m.damage(0.0003 * radius * simulation.dmgScale);
simulation.drawList.push({ //add dmg to draw queue
x: this.position.x,
y: this.position.y,
diff --git a/js/tech.js b/js/tech.js
index b174b70..7109ddc 100644
--- a/js/tech.js
+++ b/js/tech.js
@@ -4,6 +4,7 @@ const tech = {
for (let i = 0, len = tech.tech.length; i < len; i++) {
tech.tech[i].count = 0
tech.tech[i].isLost = false
+ tech.tech[i].isBanished = false
tech.tech[i].remove();
if (tech.tech[i].isJunk) {
tech.tech[i].frequency = 0
@@ -224,7 +225,7 @@ const tech = {
damageFromTech() {
let dmg = 1 //m.fieldDamage
if (tech.isDeathSkipTime) dmg *= 1.67
- if (tech.isNoDraftPause) dmg *= 1.4
+ if (tech.isNoDraftPause) dmg *= 1.34
if (tech.isCloakingDamage) dmg *= 1.35
if (tech.isTechDamage) dmg *= 1.9
if (tech.isMaxEnergyTech) dmg *= 1.5
@@ -1794,6 +1795,24 @@ const tech = {
tech.isFlipFlopDamage = false;
}
},
+ {
+ name: "integrated circuit",
+ description: "if ON +7 power up choices
if OFF -1 power up choices",
+ maxCount: 1,
+ count: 0,
+ frequency: 4,
+ frequencyDefault: 4,
+ allowed() {
+ return (tech.isFlipFlop || tech.isRelay) && !tech.isDeterminism
+ },
+ requires: "ON/OFF tech not determinism",
+ effect() {
+ tech.isFlipFlopChoices = true //do you have this tech
+ },
+ remove() {
+ tech.isFlipFlopChoices = false
+ }
+ },
{
name: "transistor",
description: "if ON generate 20 energy per second
if OFF drain 1 energy per second",
@@ -2107,7 +2126,7 @@ const tech = {
frequency: 1,
frequencyDefault: 1,
allowed() {
- return !tech.isZeno && !tech.isNoHeals && !tech.isPiezo && !tech.isRewindAvoidDeath && !tech.isTechDamage && !tech.isMutualism //&& !tech.isAmmoFromHealth && !tech.isRewindGun
+ return !tech.isZeno && !tech.isNoHeals && !tech.isPiezo && !tech.isRewindAvoidDeath && !tech.isMutualism //&& !tech.isAmmoFromHealth && !tech.isRewindGun
},
requires: "not Zeno, ergodicity, piezoelectricity, CPT, antiscience, mutualism",
effect: () => {
@@ -2494,10 +2513,8 @@ const tech = {
count: 0,
frequency: 1,
frequencyDefault: 1,
- allowed() {
- return !tech.isEnergyHealth
- },
- requires: "not mass-energy",
+ allowed() { return true },
+ requires: "",
effect() {
tech.isTechDamage = true;
},
@@ -2776,7 +2793,7 @@ const tech = {
{
name: "Ψ(t) collapse",
link: `Ψ(t) collapse`,
- description: `after you research enter an alternate reality
spawn ${powerUps.orb.research(14)}`,
+ description: `after you research enter an alternate reality
spawn ${powerUps.orb.research(17)}`,
maxCount: 1,
count: 0,
frequency: 1,
@@ -2785,7 +2802,7 @@ const tech = {
return !tech.isSwitchReality && !tech.isCollisionRealitySwitch && !tech.isJunkResearch
},
requires: "not many-worlds, non-unitary, pseudoscience",
- bonusResearch: 14,
+ bonusResearch: 17,
effect() {
tech.isResearchReality = true;
for (let i = 0; i < this.bonusResearch; i++) powerUps.spawn(m.pos.x + Math.random() * 60, m.pos.y + Math.random() * 60, "research", false);
@@ -2958,8 +2975,8 @@ const tech = {
},
{
name: "emergence",
- description: "tech, fields, and guns have 5 choices
+5% JUNK to tech pool",
- maxCount: 1,
+ description: "tech, fields, and guns have +2 choices
+4% JUNK to tech pool",
+ maxCount: 9,
count: 0,
frequency: 1,
frequencyDefault: 1,
@@ -2968,21 +2985,41 @@ const tech = {
},
requires: "not determinism",
effect: () => {
- tech.isExtraChoice = true;
- this.refundAmount += tech.addJunkTechToPool(0.05)
+ tech.extraChoices += 2;
+ this.refundAmount += tech.addJunkTechToPool(0.04)
},
refundAmount: 0,
remove() {
- tech.isExtraChoice = false;
+ tech.extraChoices = 0;
if (this.count > 0 && this.refundAmount > 0) {
tech.removeJunkTechFromPool(this.refundAmount)
this.refundAmount = 0
}
}
},
+ {
+ name: "path integral",
+ link: `path integral`,
+ description: "your next tech choice
presents every possible option",
+ maxCount: 1,
+ count: 0,
+ frequency: 1,
+ frequencyDefault: 1,
+ isNonRefundable: true,
+ // isJunk: true,
+ allowed() { return true },
+ requires: "",
+ 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);
+ },
+ remove() {
+ tech.tooManyTechChoices = 0
+ }
+ },
{
name: "determinism",
- description: "spawn 5 tech, but you have only
1 choice for tech, fields, and guns",
+ description: "spawn 5 tech
only 1 choice for tech, fields, and guns",
maxCount: 1,
count: 0,
frequency: 1,
@@ -2990,9 +3027,9 @@ const tech = {
isBadRandomOption: true,
isNonRefundable: true,
allowed() {
- return !tech.isExtraChoice && !tech.isExtraGunField
+ return !tech.extraChoices && !tech.isExtraGunField && !tech.isFlipFlopChoices
},
- requires: "NOT EXPERIMENT MODE, not emergence, cross disciplinary",
+ requires: "NOT EXPERIMENT MODE, not emergence, cross disciplinary, integrated circuit",
effect: () => {
tech.isDeterminism = true;
//if you change the number spawned also change it in Born rule
@@ -3019,7 +3056,7 @@ const tech = {
},
{
name: "superdeterminism",
- description: `spawn 5 tech, but you have no cancel
and ${powerUps.orb.research(1)}, no longer spawn`,
+ description: `spawn 5 tech
you have no cancel and ${powerUps.orb.research(1)}, no longer spawn`,
maxCount: 1,
count: 0,
frequency: 4,
@@ -3106,7 +3143,7 @@ const tech = {
{
name: "eternalism",
// description: `increase damage by 60%, but time doesn't pause
while choosing a choosing a field, tech, or gun`, //${powerUps.orb.heal()} or
- description: "+40% damage
time can't be paused (time can be dilated)",
+ description: "+34% damage
time can't be paused (time can be dilated)",
maxCount: 1,
count: 0,
frequency: 1,
@@ -3253,7 +3290,7 @@ const tech = {
{
name: "options exchange",
link: `options exchange`,
- description: `clicking × for a field, tech, or gun has a 94%
chance to randomize choices and not cancel`,
+ description: `clicking × for a field, tech, or gun has a 96%
chance to randomize choices and not cancel`,
maxCount: 1,
count: 0,
frequency: 1,
@@ -3564,7 +3601,7 @@ const tech = {
allowed() {
return !tech.isSuperDeterminism && tech.duplicationChance() > 0 && powerUps.research.count > 1
},
- requires: "NOT EXPERIMENT MODE, some duplication, not super determinism",
+ requires: "NOT EXPERIMENT MODE, some duplication, not superdeterminism",
effect: () => {
powerUps.research.changeRerolls(-2)
simulation.makeTextLog(`m.research -= 2`)
@@ -3602,7 +3639,7 @@ const tech = {
// text = ``
// let num = 3
- // if (tech.isExtraChoice) num = 5
+ // if (tech.extraChoices) num = 5
// if (tech.isDeterminism) num = 1
// for (let i = 0; i < num; i++) {
// const index = powerUps.tech.choiceLog[powerUps.tech.choiceLog.length - i - 1]
@@ -3627,7 +3664,7 @@ const tech = {
// effect: () => {
// powerUps.research.changeRerolls(-2)
// let num = 3
- // if (tech.isExtraChoice) num = 5
+ // if (tech.extraChoices) num = 5
// if (tech.isDeterminism) num = 1
// for (let i = 0; i < num; i++) {
// const index = powerUps.tech.choiceLog[powerUps.tech.choiceLog.length - i - 1]
@@ -9570,7 +9607,7 @@ const tech = {
remove() {}
},
// {
- // name: "JUNKie", //just crashes the game
+ // name: "JUNKie", //just crashes the game
// description: "all junk",
// maxCount: 1,
// count: 0,
@@ -9591,27 +9628,6 @@ const tech = {
// tech.tooManyTechChoices = 0
// }
// },
- {
- name: "path integral",
- link: `path integral`,
- // description: "your next 3 tech choices
present almost every possible option",
- description: "your next tech choice
presents almost every possible option",
- maxCount: 1,
- count: 0,
- frequency: 1,
- frequencyDefault: 1,
- isNonRefundable: true,
- isJunk: true,
- allowed() { return true },
- requires: "",
- 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);
- },
- remove() {
- tech.tooManyTechChoices = 0
- }
- },
{
name: "rule 30",
maxCount: 1,
@@ -9625,7 +9641,7 @@ const tech = {
effect() {},
remove() {},
state: [
- [false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false]
+ [Math.random() > 0.8, false, false, false, Math.random() > 0.8, false, false, false, false, false, false, false, false, false, true, false, false, false, Math.random() > 0.8, false, false, false, Math.random() > 0.8, false, false, false, false, Math.random() > 0.8, false]
],
rule(state, a, b, c) {
//30
@@ -9640,25 +9656,68 @@ const tech = {
},
id: 0,
descriptionFunction() {
-
- if (this.id === 0 && Math.random() < 0.5) {
- // for (let i = 0; i < 29; i++) this.state[0][i] = Math.random() < 0.5 //randomize seed
- this.name = "rule 90"
- this.link = `${this.name}`
- // console.log(this.name)
- this.state[0] = [false, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, false, false, false, false, false, false, false, false, false, false, false, false, false]
- this.rule = function(state, a, b, c) {
- if (state[a] && state[b] && state[c]) return false; // TTT => F
- if (state[a] && state[b] && !state[c]) return true; // TTF => T
- if (state[a] && !state[b] && state[c]) return false; //TFT => F
- if (state[a] && !state[b] && !state[c]) return true; //TFF => T
- if (!state[a] && state[b] && state[c]) return true; //FTT => T
- if (!state[a] && state[b] && !state[c]) return false; //FTF => F
- if (!state[a] && !state[b] && state[c]) return true; //FFT => T
- if (!state[a] && !state[b] && !state[c]) return false; //FFF => F
+ const loop = () => {
+ if ((simulation.paused || simulation.isChoosing) && m.alive && !build.isExperimentSelection) { //&& (!simulation.isChoosing || this.count === 0)
+ let b = []; //produce next row
+ b.push(this.rule(this.state[this.state.length - 1], this.state[this.state.length - 1].length - 1, 0, 1)); //left edge wrap around
+ for (let i = 1; i < this.state[this.state.length - 1].length - 1; i++) { //apply rule to the rest of the array
+ b.push(this.rule(this.state[this.state.length - 1], i - 1, i, i + 1));
+ }
+ b.push(this.rule(this.state[this.state.length - 1], this.state[this.state.length - 1].length - 2, this.state[this.state.length - 1].length - 1, 0)); //right edge wrap around
+ this.state.push(b)
+ if (document.getElementById(`cellular-rule-id${this.id}`)) document.getElementById(`cellular-rule-id${this.id}`).innerHTML = this.outputText() //convert to squares and send HTML
+ if (this.count && this.state.length < 120 && !(this.state.length % 10)) powerUps.spawn(m.pos.x - 50 + 100 * (Math.random() - 0.5), m.pos.y + 100 * (Math.random() - 0.5), "research");
+ setTimeout(() => { loop() }, 400);
}
}
-
+ setTimeout(() => { loop() }, 400);
+ this.id++
+ return `${this.outputText()}`
+ },
+ outputText() {
+ let text = ""
+ for (let j = 0; j < this.state.length; j++) {
+ text += ""
+ for (let i = 0; i < this.state[j].length; i++) {
+ if (this.state[j][i]) {
+ text += "⬛" //"█" //"■"
+ } else {
+ text += "⬜" //" " //"□"
+ }
+ }
+ text += "
"
+ }
+ return text
+ },
+ },
+ {
+ name: "rule 90",
+ maxCount: 1,
+ count: 0,
+ frequency: 0,
+ isJunk: true,
+ allowed() {
+ return true
+ },
+ requires: "",
+ effect() {},
+ remove() {},
+ state: [
+ [false, false, false, false, Math.random() > 0.8, false, false, false, false, Math.random() > 0.8, false, false, false, Math.random() > 0.8, true, true, false, false, false, false, Math.random() > 0.8, Math.random() > 0.8, false, false, false, false, false, false, Math.random() > 0.8]
+ ],
+ rule(state, a, b, c) { //90
+ if (state[a] && state[b] && state[c]) return false; // TTT => F
+ if (state[a] && state[b] && !state[c]) return true; // TTF => T
+ if (state[a] && !state[b] && state[c]) return false; //TFT => F
+ if (state[a] && !state[b] && !state[c]) return true; //TFF => T
+ if (!state[a] && state[b] && state[c]) return true; //FTT => T
+ if (!state[a] && state[b] && !state[c]) return false; //FTF => F
+ if (!state[a] && !state[b] && state[c]) return true; //FFT => T
+ if (!state[a] && !state[b] && !state[c]) return false; //FFF => F
+ },
+ id: 90,
+ descriptionFunction() {
+ // this.link = `${this.name}`
const loop = () => {
if ((simulation.paused || simulation.isChoosing) && m.alive && !build.isExperimentSelection) { //&& (!simulation.isChoosing || this.count === 0)
let b = []; //produce next row
@@ -9955,7 +10014,7 @@ const tech = {
isFarAwayDmg: null,
isEntanglement: null,
isMassEnergy: null,
- isExtraChoice: null,
+ extraChoices: null,
laserBotCount: null,
dynamoBotCount: null,
nailBotCount: null,
@@ -10134,6 +10193,7 @@ const tech = {
// isFlipFlopLevelReset: null,
isFlipFlopDamage: null,
isFlipFlopEnergy: null,
+ isFlipFlopChoices: null,
isRelay: null,
relayIce: null,
isMetaAnalysis: null,
diff --git a/lib/matter.min.js b/lib/matter.min.js
index da8f1e1..29d25db 100644
--- a/lib/matter.min.js
+++ b/lib/matter.min.js
@@ -1,6 +1,6 @@
/*!
- * matter-js 0.17.1 by @liabru
+ * matter-js 0.18.0 by @liabru
* http://brm.io/matter-js/
* License MIT
*/
-!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("Matter",[],t):"object"==typeof exports?exports.Matter=t():e.Matter=t()}(this,(function(){return function(e){var t={};function n(i){if(t[i])return t[i].exports;var o=t[i]={i:i,l:!1,exports:{}};return e[i].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(i,o,function(t){return e[t]}.bind(null,o));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=22)}([function(e,t){var n={};e.exports=n,function(){n._nextId=0,n._seed=0,n._nowStartTime=+new Date,n._warnedOnce={},n._decomp=null,n.extend=function(e,t){var i,o;"boolean"==typeof t?(i=2,o=t):(i=1,o=!0);for(var r=i;r0;t--){var i=Math.floor(n.random()*(t+1)),o=e[t];e[t]=e[i],e[i]=o}return e},n.choose=function(e){return e[Math.floor(n.random()*e.length)]},n.isElement=function(e){return"undefined"!=typeof HTMLElement?e instanceof HTMLElement:!!(e&&e.nodeType&&e.nodeName)},n.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)},n.isFunction=function(e){return"function"==typeof e},n.isPlainObject=function(e){return"object"==typeof e&&e.constructor===Object},n.isString=function(e){return"[object String]"===toString.call(e)},n.clamp=function(e,t,n){return en?n:e},n.sign=function(e){return e<0?-1:1},n.now=function(){if("undefined"!=typeof window&&window.performance){if(window.performance.now)return window.performance.now();if(window.performance.webkitNow)return window.performance.webkitNow()}return Date.now?Date.now():new Date-n._nowStartTime},n.random=function(t,n){return n=void 0!==n?n:1,(t=void 0!==t?t:0)+e()*(n-t)};var e=function(){return n._seed=(9301*n._seed+49297)%233280,n._seed/233280};n.colorToNumber=function(e){return 3==(e=e.replace("#","")).length&&(e=e.charAt(0)+e.charAt(0)+e.charAt(1)+e.charAt(1)+e.charAt(2)+e.charAt(2)),parseInt(e,16)},n.logLevel=1,n.log=function(){console&&n.logLevel>0&&n.logLevel<=3&&console.log.apply(console,["matter-js:"].concat(Array.prototype.slice.call(arguments)))},n.info=function(){console&&n.logLevel>0&&n.logLevel<=2&&console.info.apply(console,["matter-js:"].concat(Array.prototype.slice.call(arguments)))},n.warn=function(){console&&n.logLevel>0&&n.logLevel<=3&&console.warn.apply(console,["matter-js:"].concat(Array.prototype.slice.call(arguments)))},n.warnOnce=function(){var e=Array.prototype.slice.call(arguments).join(" ");n._warnedOnce[e]||(n.warn(e),n._warnedOnce[e]=!0)},n.deprecated=function(e,t,i){e[t]=n.chain((function(){n.warnOnce("🔅 deprecated 🔅",i)}),e[t])},n.nextId=function(){return n._nextId++},n.indexOf=function(e,t){if(e.indexOf)return e.indexOf(t);for(var n=0;ne.max.x&&(e.max.x=o.x),o.xe.max.y&&(e.max.y=o.y),o.y0?e.max.x+=n.x:e.min.x+=n.x,n.y>0?e.max.y+=n.y:e.min.y+=n.y)},n.contains=function(e,t){return t.x>=e.min.x&&t.x<=e.max.x&&t.y>=e.min.y&&t.y<=e.max.y},n.overlaps=function(e,t){return e.min.x<=t.max.x&&e.max.x>=t.min.x&&e.max.y>=t.min.y&&e.min.y<=t.max.y},n.translate=function(e,t){e.min.x+=t.x,e.max.x+=t.x,e.min.y+=t.y,e.max.y+=t.y},n.shift=function(e,t){var n=e.max.x-e.min.x,i=e.max.y-e.min.y;e.min.x=t.x,e.max.x=t.x+n,e.min.y=t.y,e.max.y=t.y+i}},function(e,t){var n={};e.exports=n,n.create=function(e,t){return{x:e||0,y:t||0}},n.clone=function(e){return{x:e.x,y:e.y}},n.magnitude=function(e){return Math.sqrt(e.x*e.x+e.y*e.y)},n.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},n.rotate=function(e,t,n){var i=Math.cos(t),o=Math.sin(t);n||(n={});var r=e.x*i-e.y*o;return n.y=e.x*o+e.y*i,n.x=r,n},n.rotateAbout=function(e,t,n,i){var o=Math.cos(t),r=Math.sin(t);i||(i={});var a=n.x+((e.x-n.x)*o-(e.y-n.y)*r);return i.y=n.y+((e.x-n.x)*r+(e.y-n.y)*o),i.x=a,i},n.normalise=function(e){var t=n.magnitude(e);return 0===t?{x:0,y:0}:{x:e.x/t,y:e.y/t}},n.dot=function(e,t){return e.x*t.x+e.y*t.y},n.cross=function(e,t){return e.x*t.y-e.y*t.x},n.cross3=function(e,t,n){return(t.x-e.x)*(n.y-e.y)-(t.y-e.y)*(n.x-e.x)},n.add=function(e,t,n){return n||(n={}),n.x=e.x+t.x,n.y=e.y+t.y,n},n.sub=function(e,t,n){return n||(n={}),n.x=e.x-t.x,n.y=e.y-t.y,n},n.mult=function(e,t){return{x:e.x*t,y:e.y*t}},n.div=function(e,t){return{x:e.x/t,y:e.y/t}},n.perp=function(e,t){return{x:(t=!0===t?-1:1)*-e.y,y:t*e.x}},n.neg=function(e){return{x:-e.x,y:-e.y}},n.angle=function(e,t){return Math.atan2(t.y-e.y,t.x-e.x)},n._temp=[n.create(),n.create(),n.create(),n.create(),n.create(),n.create()]},function(e,t,n){var i={};e.exports=i;var o=n(2),r=n(0);i.create=function(e,t){for(var n=[],i=0;i0)return!1}return!0},i.scale=function(e,t,n,r){if(1===t&&1===n)return e;var a,s;r=r||i.centre(e);for(var l=0;l=0?l-1:e.length-1],u=e[l],d=e[(l+1)%e.length],p=t[l0&&(r|=2),3===r)return!1;return 0!==r||null},i.hull=function(e){var t,n,i=[],r=[];for((e=e.slice(0)).sort((function(e,t){var n=e.x-t.x;return 0!==n?n:e.y-t.y})),n=0;n=2&&o.cross3(r[r.length-2],r[r.length-1],t)<=0;)r.pop();r.push(t)}for(n=e.length-1;n>=0;n-=1){for(t=e[n];i.length>=2&&o.cross3(i[i.length-2],i[i.length-1],t)<=0;)i.pop();i.push(t)}return i.pop(),r.pop(),i.concat(r)}},function(e,t,n){var i={};e.exports=i;var o=n(0);i.on=function(e,t,n){for(var i,o=t.split(" "),r=0;r0){n||(n={}),i=t.split(" ");for(var c=0;c0&&r.rotateAbout(a.position,n,e.position,a.position)}},i.setVelocity=function(e,t){e.positionPrev.x=e.position.x-t.x,e.positionPrev.y=e.position.y-t.y,e.velocity.x=t.x,e.velocity.y=t.y,e.speed=r.magnitude(e.velocity)},i.setAngularVelocity=function(e,t){e.anglePrev=e.angle-t,e.angularVelocity=t,e.angularSpeed=Math.abs(e.angularVelocity)},i.translate=function(e,t){i.setPosition(e,r.add(e.position,t))},i.rotate=function(e,t,n){if(n){var o=Math.cos(t),r=Math.sin(t),a=e.position.x-n.x,s=e.position.y-n.y;i.setPosition(e,{x:n.x+(a*o-s*r),y:n.y+(a*r+s*o)}),i.setAngle(e,e.angle+t)}else i.setAngle(e,e.angle+t)},i.scale=function(e,t,n,r){var a=0,s=0;r=r||e.position;for(var u=0;u0&&(a+=d.area,s+=d.inertia),d.position.x=r.x+(d.position.x-r.x)*t,d.position.y=r.y+(d.position.y-r.y)*n,l.update(d.bounds,d.vertices,e.velocity)}e.parts.length>1&&(e.area=a,e.isStatic||(i.setMass(e,e.density*a),i.setInertia(e,s))),e.circleRadius&&(t===n?e.circleRadius*=t:e.circleRadius=null)},i.update=function(e,t,n,i){var a=Math.pow(t*n*e.timeScale,2),s=1-e.frictionAir*n*e.timeScale,u=e.position.x-e.positionPrev.x,d=e.position.y-e.positionPrev.y;e.velocity.x=u*s*i+e.force.x/e.mass*a,e.velocity.y=d*s*i+e.force.y/e.mass*a,e.positionPrev.x=e.position.x,e.positionPrev.y=e.position.y,e.position.x+=e.velocity.x,e.position.y+=e.velocity.y,e.angularVelocity=(e.angle-e.anglePrev)*s*i+e.torque/e.inertia*a,e.anglePrev=e.angle,e.angle+=e.angularVelocity,e.speed=r.magnitude(e.velocity),e.angularSpeed=Math.abs(e.angularVelocity);for(var p=0;p0&&(f.position.x+=e.velocity.x,f.position.y+=e.velocity.y),0!==e.angularVelocity&&(o.rotate(f.vertices,e.angularVelocity,e.position),c.rotate(f.axes,e.angularVelocity),p>0&&r.rotateAbout(f.position,e.angularVelocity,e.position,f.position)),l.update(f.bounds,f.vertices,e.velocity)}},i.applyForce=function(e,t,n){e.force.x+=n.x,e.force.y+=n.y;var i=t.x-e.position.x,o=t.y-e.position.y;e.torque+=i*n.y-o*n.x},i._totalProperties=function(e){for(var t={mass:0,area:0,inertia:0,centre:{x:0,y:0}},n=1===e.parts.length?0:1;n0&&r.motion=r.sleepThreshold&&i.set(r,!0)):r.sleepCounter>0&&(r.sleepCounter-=1)}else i.set(r,!1)}},i.afterCollisions=function(e,t){for(var n=t*t*t,o=0;oi._motionWakeThreshold*n&&i.set(c,!1)}}}},i.set=function(e,t){var n=e.isSleeping;t?(e.isSleeping=!0,e.sleepCounter=e.sleepThreshold,e.positionImpulse.x=0,e.positionImpulse.y=0,e.positionPrev.x=e.position.x,e.positionPrev.y=e.position.y,e.anglePrev=e.angle,e.speed=0,e.angularSpeed=0,e.motion=0,n||o.trigger(e,"sleepStart")):(e.isSleeping=!1,e.sleepCounter=0,n&&o.trigger(e,"sleepEnd"))}},function(e,t,n){var i={};e.exports=i;var o=n(3),r=n(2),a=n(7),s=n(1),l=n(10),c=n(0);i._warming=.4,i._torqueDampen=1,i._minLength=1e-6,i.create=function(e){var t=e;t.bodyA&&!t.pointA&&(t.pointA={x:0,y:0}),t.bodyB&&!t.pointB&&(t.pointB={x:0,y:0});var n=t.bodyA?r.add(t.bodyA.position,t.pointA):t.pointA,i=t.bodyB?r.add(t.bodyB.position,t.pointB):t.pointB,o=r.magnitude(r.sub(n,i));t.length=void 0!==t.length?t.length:o,t.id=t.id||c.nextId(),t.label=t.label||"Constraint",t.type="constraint",t.stiffness=t.stiffness||(t.length>0?1:.7),t.damping=t.damping||0,t.angularStiffness=t.angularStiffness||0,t.angleA=t.bodyA?t.bodyA.angle:t.angleA,t.angleB=t.bodyB?t.bodyB.angle:t.angleB,t.plugin={};var a={visible:!0,lineWidth:2,strokeStyle:"#ffffff",type:"line",anchors:!0};return 0===t.length&&t.stiffness>.1?(a.type="pin",a.anchors=!1):t.stiffness<.9&&(a.type="spring"),t.render=c.extend(a,t.render),t},i.preSolveAll=function(e){for(var t=0;t0&&(d.position.x+=c.x,d.position.y+=c.y),0!==c.angle&&(o.rotate(d.vertices,c.angle,n.position),l.rotate(d.axes,c.angle),u>0&&r.rotateAbout(d.position,c.angle,n.position,d.position)),s.update(d.bounds,d.vertices,n.velocity)}c.angle*=i._warming,c.x*=i._warming,c.y*=i._warming}}},i.pointAWorld=function(e){return{x:(e.bodyA?e.bodyA.position.x:0)+e.pointA.x,y:(e.bodyA?e.bodyA.position.y:0)+e.pointA.y}},i.pointBWorld=function(e){return{x:(e.bodyB?e.bodyB.position.x:0)+e.pointB.x,y:(e.bodyB?e.bodyB.position.y:0)+e.pointB.y}}},function(e,t,n){var i={};e.exports=i;var o=n(17);i.create=function(e,t){var n=e.bodyA,o=e.bodyB,r=e.parentA,a=e.parentB,s={id:i.id(n,o),bodyA:n,bodyB:o,contacts:{},activeContacts:[],separation:0,isActive:!0,confirmedActive:!0,isSensor:n.isSensor||o.isSensor,timeCreated:t,timeUpdated:t,inverseMass:r.inverseMass+a.inverseMass,friction:Math.min(r.friction,a.friction),frictionStatic:Math.max(r.frictionStatic,a.frictionStatic),restitution:Math.max(r.restitution,a.restitution),slop:Math.max(r.slop,a.slop)};return i.update(s,e,t),s},i.update=function(e,t,n){var r=e.contacts,a=t.supports,s=e.activeContacts,l=t.parentA,c=t.parentB;if(e.collision=t,e.inverseMass=l.inverseMass+c.inverseMass,e.friction=Math.min(l.friction,c.friction),e.frictionStatic=Math.max(l.frictionStatic,c.frictionStatic),e.restitution=Math.max(l.restitution,c.restitution),e.slop=Math.max(l.slop,c.slop),s.length=0,t.collided){for(var u=0;u0&&o.area(C)1?(v=a.create(r.extend({parts:m.slice(0)},i)),a.setPosition(v,{x:e,y:t}),v):m[0]}},function(e,t,n){var i={};e.exports=i;var o=n(0);i.create=function(e){var t={};return e||o.log("Mouse.create: element was undefined, defaulting to document.body","warn"),t.element=e||document.body,t.absolute={x:0,y:0},t.position={x:0,y:0},t.mousedownPosition={x:0,y:0},t.mouseupPosition={x:0,y:0},t.offset={x:0,y:0},t.scale={x:1,y:1},t.wheelDelta=0,t.button=-1,t.pixelRatio=parseInt(t.element.getAttribute("data-pixel-ratio"),10)||1,t.sourceEvents={mousemove:null,mousedown:null,mouseup:null,mousewheel:null},t.mousemove=function(e){var n=i._getRelativeMousePosition(e,t.element,t.pixelRatio);e.changedTouches&&(t.button=0,e.preventDefault()),t.absolute.x=n.x,t.absolute.y=n.y,t.position.x=t.absolute.x*t.scale.x+t.offset.x,t.position.y=t.absolute.y*t.scale.y+t.offset.y,t.sourceEvents.mousemove=e},t.mousedown=function(e){var n=i._getRelativeMousePosition(e,t.element,t.pixelRatio);e.changedTouches?(t.button=0,e.preventDefault()):t.button=e.button,t.absolute.x=n.x,t.absolute.y=n.y,t.position.x=t.absolute.x*t.scale.x+t.offset.x,t.position.y=t.absolute.y*t.scale.y+t.offset.y,t.mousedownPosition.x=t.position.x,t.mousedownPosition.y=t.position.y,t.sourceEvents.mousedown=e},t.mouseup=function(e){var n=i._getRelativeMousePosition(e,t.element,t.pixelRatio);e.changedTouches&&e.preventDefault(),t.button=-1,t.absolute.x=n.x,t.absolute.y=n.y,t.position.x=t.absolute.x*t.scale.x+t.offset.x,t.position.y=t.absolute.y*t.scale.y+t.offset.y,t.mouseupPosition.x=t.position.x,t.mouseupPosition.y=t.position.y,t.sourceEvents.mouseup=e},t.mousewheel=function(e){t.wheelDelta=Math.max(-1,Math.min(1,e.wheelDelta||-e.detail)),e.preventDefault()},i.setElement(t,t.element),t},i.setElement=function(e,t){e.element=t,t.addEventListener("mousemove",e.mousemove),t.addEventListener("mousedown",e.mousedown),t.addEventListener("mouseup",e.mouseup),t.addEventListener("mousewheel",e.mousewheel),t.addEventListener("DOMMouseScroll",e.mousewheel),t.addEventListener("touchmove",e.mousemove),t.addEventListener("touchstart",e.mousedown),t.addEventListener("touchend",e.mouseup)},i.clearSourceEvents=function(e){e.sourceEvents.mousemove=null,e.sourceEvents.mousedown=null,e.sourceEvents.mouseup=null,e.sourceEvents.mousewheel=null,e.wheelDelta=0},i.setOffset=function(e,t){e.offset.x=t.x,e.offset.y=t.y,e.position.x=e.absolute.x*e.scale.x+e.offset.x,e.position.y=e.absolute.y*e.scale.y+e.offset.y},i.setScale=function(e,t){e.scale.x=t.x,e.scale.y=t.y,e.position.x=e.absolute.x*e.scale.x+e.offset.x,e.position.y=e.absolute.y*e.scale.y+e.offset.y},i._getRelativeMousePosition=function(e,t,n){var i,o,r=t.getBoundingClientRect(),a=document.documentElement||document.body.parentNode||document.body,s=void 0!==window.pageXOffset?window.pageXOffset:a.scrollLeft,l=void 0!==window.pageYOffset?window.pageYOffset:a.scrollTop,c=e.changedTouches;return c?(i=c[0].pageX-r.left-s,o=c[0].pageY-r.top-l):(i=e.pageX-r.left-s,o=e.pageY-r.top-l),{x:i/(t.clientWidth/(t.width||t.clientWidth)*n),y:o/(t.clientHeight/(t.height||t.clientHeight)*n)}}},function(e,t,n){var i={};e.exports=i;var o=n(14),r=n(9),a=n(1);i.collisions=function(e,t){for(var n=[],s=t.pairs.table,l=0;l1?1:0;d1?1:0;f0:0!=(e.mask&t.category)&&0!=(t.mask&e.category)}},function(e,t,n){var i={};e.exports=i;var o=n(3),r=n(2);i.collides=function(e,t,n){var a,s,l,c,u=!1;if(n){var d=e.parent,p=t.parent,f=d.speed*d.speed+d.angularSpeed*d.angularSpeed+p.speed*p.speed+p.angularSpeed*p.angularSpeed;u=n&&n.collided&&f<.2,c=n}else c={collided:!1,bodyA:e,bodyB:t};if(n&&u){var v=c.axisBody,m=v===e?t:e,y=[v.axes[n.axisNumber]];if(l=i._overlapAxes(v.vertices,m.vertices,y),c.reused=!0,l.overlap<=0)return c.collided=!1,c}else{if((a=i._overlapAxes(e.vertices,t.vertices,e.axes)).overlap<=0)return c.collided=!1,c;if((s=i._overlapAxes(t.vertices,e.vertices,t.axes)).overlap<=0)return c.collided=!1,c;a.overlapo?o=s:s=0?a.index-1:u.length-1],c.x=o.x-d.x,c.y=o.y-d.y,l=-r.dot(n,c),s=o,o=u[(a.index+1)%u.length],c.x=o.x-d.x,c.y=o.y-d.y,(i=-r.dot(n,c))r?(o.warn("Plugin.register:",i.toString(t),"was upgraded to",i.toString(e)),i._registry[e.name]=e):n-1},i.isFor=function(e,t){var n=e.for&&i.dependencyParse(e.for);return!e.for||t.name===n.name&&i.versionSatisfies(t.version,n.range)},i.use=function(e,t){if(e.uses=(e.uses||[]).concat(t||[]),0!==e.uses.length){for(var n=i.dependencies(e),r=o.topologicalSort(n),a=[],s=0;s0&&o.info(a.join(" "))}else o.warn("Plugin.use:",i.toString(e),"does not specify any dependencies to install.")},i.dependencies=function(e,t){var n=i.dependencyParse(e),r=n.name;if(!(r in(t=t||{}))){e=i.resolve(e)||e,t[r]=o.map(e.uses||[],(function(t){i.isPlugin(t)&&i.register(t);var r=i.dependencyParse(t),a=i.resolve(t);return a&&!i.versionSatisfies(a.version,r.range)?(o.warn("Plugin.dependencies:",i.toString(a),"does not satisfy",i.toString(r),"used by",i.toString(n)+"."),a._warned=!0,e._warned=!0):a||(o.warn("Plugin.dependencies:",i.toString(t),"used by",i.toString(n),"could not be resolved."),e._warned=!0),r.name}));for(var a=0;a=|>)?\s*((\d+)\.(\d+)\.(\d+))(-[0-9A-Za-z-]+)?$/;t.test(e)||o.warn("Plugin.versionParse:",e,"is not a valid version or range.");var n=t.exec(e),i=Number(n[4]),r=Number(n[5]),a=Number(n[6]);return{isRange:Boolean(n[1]||n[2]),version:n[3],range:e,operator:n[1]||n[2]||"",major:i,minor:r,patch:a,parts:[i,r,a],prerelease:n[7],number:1e8*i+1e4*r+a}},i.versionSatisfies=function(e,t){t=t||"*";var n=i.versionParse(t),o=i.versionParse(e);if(n.isRange){if("*"===n.operator||"*"===e)return!0;if(">"===n.operator)return o.number>n.number;if(">="===n.operator)return o.number>=n.number;if("~"===n.operator)return o.major===n.major&&o.minor===n.minor&&o.patch>=n.patch;if("^"===n.operator)return n.major>0?o.major===n.major&&o.number>=n.number:n.minor>0?o.minor===n.minor&&o.patch>=n.patch:o.patch===n.patch}return e===t||"*"===e}},function(e,t,n){var i={};e.exports=i;var o=n(0),r=n(5),a=n(1),s=n(4),l=n(2),c=n(12);!function(){var e,t;"undefined"!=typeof window&&(e=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.msRequestAnimationFrame||function(e){window.setTimeout((function(){e(o.now())}),1e3/60)},t=window.cancelAnimationFrame||window.mozCancelAnimationFrame||window.webkitCancelAnimationFrame||window.msCancelAnimationFrame),i._goodFps=30,i._goodDelta=1e3/60,i.create=function(e){var t={controller:i,engine:null,element:null,canvas:null,mouse:null,frameRequestId:null,timing:{historySize:60,delta:0,deltaHistory:[],lastTime:0,lastTimestamp:0,lastElapsed:0,timestampElapsed:0,timestampElapsedHistory:[],engineDeltaHistory:[],engineElapsedHistory:[],elapsedHistory:[]},options:{width:800,height:600,pixelRatio:1,background:"#14151f",wireframeBackground:"#14151f",hasBounds:!!e.bounds,enabled:!0,wireframes:!0,showSleeping:!0,showDebug:!1,showStats:!1,showPerformance:!1,showBroadphase:!1,showBounds:!1,showVelocity:!1,showCollisions:!1,showSeparations:!1,showAxes:!1,showPositions:!1,showAngleIndicator:!1,showIds:!1,showVertexNumbers:!1,showConvexHulls:!1,showInternalEdges:!1,showMousePosition:!1}},n=o.extend(t,e);return n.canvas&&(n.canvas.width=n.options.width||n.canvas.width,n.canvas.height=n.options.height||n.canvas.height),n.mouse=e.mouse,n.engine=e.engine,n.canvas=n.canvas||d(n.options.width,n.options.height),n.context=n.canvas.getContext("2d"),n.textures={},n.bounds=n.bounds||{min:{x:0,y:0},max:{x:n.canvas.width,y:n.canvas.height}},1!==n.options.pixelRatio&&i.setPixelRatio(n,n.options.pixelRatio),o.isElement(n.element)?n.element.appendChild(n.canvas):n.canvas.parentNode||o.log("Render.create: options.element was undefined, render.canvas was created but not appended","warn"),n},i.run=function(t){!function o(r){t.frameRequestId=e(o),n(t,r),i.world(t,r),(t.options.showStats||t.options.showDebug)&&i.stats(t,t.context,r),(t.options.showPerformance||t.options.showDebug)&&i.performance(t,t.context,r)}()},i.stop=function(e){t(e.frameRequestId)},i.setPixelRatio=function(e,t){var n=e.options,i=e.canvas;"auto"===t&&(t=p(i)),n.pixelRatio=t,i.setAttribute("data-pixel-ratio",t),i.width=n.width*t,i.height=n.height*t,i.style.width=n.width+"px",i.style.height=n.height+"px"},i.lookAt=function(e,t,n,i){i=void 0===i||i,t=o.isArray(t)?t:[t],n=n||{x:0,y:0};for(var r={min:{x:1/0,y:1/0},max:{x:-1/0,y:-1/0}},a=0;ar.max.x&&(r.max.x=u.x),l.yr.max.y&&(r.max.y=u.y))}var d=r.max.x-r.min.x+2*n.x,p=r.max.y-r.min.y+2*n.y,f=e.canvas.height,v=e.canvas.width/f,m=d/p,y=1,g=1;m>v?g=m/v:y=v/m,e.options.hasBounds=!0,e.bounds.min.x=r.min.x,e.bounds.max.x=r.min.x+d*y,e.bounds.min.y=r.min.y,e.bounds.max.y=r.min.y+p*g,i&&(e.bounds.min.x+=.5*d-d*y*.5,e.bounds.max.x+=.5*d-d*y*.5,e.bounds.min.y+=.5*p-p*g*.5,e.bounds.max.y+=.5*p-p*g*.5),e.bounds.min.x-=n.x,e.bounds.max.x-=n.x,e.bounds.min.y-=n.y,e.bounds.max.y-=n.y,e.mouse&&(c.setScale(e.mouse,{x:(e.bounds.max.x-e.bounds.min.x)/e.canvas.width,y:(e.bounds.max.y-e.bounds.min.y)/e.canvas.height}),c.setOffset(e.mouse,e.bounds.min))},i.startViewTransform=function(e){var t=e.bounds.max.x-e.bounds.min.x,n=e.bounds.max.y-e.bounds.min.y,i=t/e.options.width,o=n/e.options.height;e.context.setTransform(e.options.pixelRatio/i,0,0,e.options.pixelRatio/o,0,0),e.context.translate(-e.bounds.min.x,-e.bounds.min.y)},i.endViewTransform=function(e){e.context.setTransform(e.options.pixelRatio,0,0,e.options.pixelRatio,0,0)},i.world=function(e,t){var n,u=o.now(),d=e.engine,p=d.world,f=e.canvas,m=e.context,y=e.options,g=e.timing,x=r.allBodies(p),h=r.allConstraints(p),b=y.wireframes?y.wireframeBackground:y.background,S=[],w=[],A={timestamp:d.timing.timestamp};if(s.trigger(e,"beforeRender",A),e.currentBackground!==b&&v(e,b),m.globalCompositeOperation="source-in",m.fillStyle="transparent",m.fillRect(0,0,f.width,f.height),m.globalCompositeOperation="source-over",y.hasBounds){for(n=0;n1?1:0;a1?1:0;s1?1:0;r1?1:0;s1?1:0;r1?1:0;r1?1:0;o0)){var u=i.activeContacts[0].vertex.x,d=i.activeContacts[0].vertex.y;2===i.activeContacts.length&&(u=(i.activeContacts[0].vertex.x+i.activeContacts[1].vertex.x)/2,d=(i.activeContacts[0].vertex.y+i.activeContacts[1].vertex.y)/2),o.bodyB===o.supports[0].body||!0===o.bodyA.isStatic?s.moveTo(u-8*o.normal.x,d-8*o.normal.y):s.moveTo(u+8*o.normal.x,d+8*o.normal.y),s.lineTo(u,d)}l.wireframes?s.strokeStyle="rgba(255,165,0,0.7)":s.strokeStyle="orange",s.lineWidth=1,s.stroke()},i.separations=function(e,t,n){var i,o,r,a,s,l=n,c=e.options;for(l.beginPath(),s=0;s0&&c.trigger(e,"collisionStart",{pairs:A.collisionStart}),r.preSolvePosition(A.list),m=0;m0&&c.trigger(e,"collisionActive",{pairs:A.collisionActive}),A.collisionEnd.length>0&&c.trigger(e,"collisionEnd",{pairs:A.collisionEnd}),i._bodiesClearForces(b),c.trigger(e,"afterUpdate",h),e.timing.lastElapsed=p.now()-f,e},i.merge=function(e,t){if(p.extend(e,t),t.world){e.world=t.world,i.clear(e);for(var n=u.allBodies(e.world),r=0;rf.friction*f.frictionStatic*L*n&&(O=T,V=a.clamp(f.friction*R*n,-O,O));var F=r.cross(P,g),D=r.cross(M,g),H=b/(m.inverseMass+y.inverseMass+m.inverseInertia*F*F+y.inverseInertia*D*D);if(E*=H,V*=H,k<0&&k*k>i._restingThresh*n)w.normalImpulse=0;else{var j=w.normalImpulse;w.normalImpulse=Math.min(w.normalImpulse+E,0),E=w.normalImpulse-j}if(I*I>i._restingThreshTangent*n)w.tangentImpulse=0;else{var W=w.tangentImpulse;w.tangentImpulse=a.clamp(w.tangentImpulse+V,-O,O),V=w.tangentImpulse-W}o.x=g.x*E+x.x*V,o.y=g.y*E+x.y*V,m.isStatic||m.isSleeping||(m.positionPrev.x+=o.x*m.inverseMass,m.positionPrev.y+=o.y*m.inverseMass,m.anglePrev+=r.cross(P,o)*m.inverseInertia),y.isStatic||y.isSleeping||(y.positionPrev.x-=o.x*y.inverseMass,y.positionPrev.y-=o.y*y.inverseMass,y.anglePrev-=r.cross(M,o)*y.inverseInertia)}}}}},function(e,t,n){var i={};e.exports=i;var o=n(9),r=n(0);i._pairMaxIdleLife=1e3,i.create=function(e){return r.extend({table:{},list:[],collisionStart:[],collisionActive:[],collisionEnd:[]},e)},i.update=function(e,t,n){var i,r,a,s,l=e.list,c=e.table,u=e.collisionStart,d=e.collisionEnd,p=e.collisionActive;for(u.length=0,d.length=0,p.length=0,s=0;si._pairMaxIdleLife&&c.push(a);for(a=0;au.bounds.max.x||f.bounds.max.yu.bounds.max.y))){var v=i._getRegion(e,f);if(!f.region||v.id!==f.region.id||o){f.region&&!o||(f.region=v);var m=i._regionUnion(v,f.region);for(a=m.startCol;a<=m.endCol;a++)for(s=m.startRow;s<=m.endRow;s++){l=d[c=i._getBucketId(a,s)];var y=a>=v.startCol&&a<=v.endCol&&s>=v.startRow&&s<=v.endRow,g=a>=f.region.startCol&&a<=f.region.endCol&&s>=f.region.startRow&&s<=f.region.endRow;!y&&g&&g&&l&&i._bucketRemoveBody(e,l,f),(f.region===v||y&&!g||o)&&(l||(l=i._createBucket(d,c)),i._bucketAddBody(e,l,f))}f.region=v,p=!0}}}p&&(e.pairsList=i._createActivePairsList(e))},i.clear=function(e){e.buckets={},e.pairs={},e.pairsList=[]},i._regionUnion=function(e,t){var n=Math.min(e.startCol,t.startCol),o=Math.max(e.endCol,t.endCol),r=Math.min(e.startRow,t.startRow),a=Math.max(e.endRow,t.endRow);return i._createRegion(n,o,r,a)},i._getRegion=function(e,t){var n=t.bounds,o=Math.floor(n.min.x/e.bucketWidth),r=Math.floor(n.max.x/e.bucketWidth),a=Math.floor(n.min.y/e.bucketHeight),s=Math.floor(n.max.y/e.bucketHeight);return i._createRegion(o,r,a,s)},i._createRegion=function(e,t,n,i){return{id:e+","+t+","+n+","+i,startCol:e,endCol:t,startRow:n,endRow:i}},i._getBucketId=function(e,t){return"C"+e+"R"+t},i._createBucket=function(e,t){return e[t]=[]},i._bucketAddBody=function(e,t,n){for(var i=0;i0?i.push(n):delete e.pairs[t[o]];return i}},function(e,t,n){var i=e.exports=n(23);i.Axes=n(10),i.Bodies=n(11),i.Body=n(6),i.Bounds=n(1),i.Common=n(0),i.Composite=n(5),i.Composites=n(24),i.Constraint=n(8),i.Contact=n(17),i.Detector=n(13),i.Engine=n(18),i.Events=n(4),i.Grid=n(21),i.Mouse=n(12),i.MouseConstraint=n(25),i.Pair=n(9),i.Pairs=n(20),i.Plugin=n(15),i.Query=n(26),i.Render=n(16),i.Resolver=n(19),i.Runner=n(27),i.SAT=n(14),i.Sleeping=n(7),i.Svg=n(28),i.Vector=n(2),i.Vertices=n(3),i.World=n(29),i.Engine.run=i.Runner.run,i.Common.deprecated(i.Engine,"run","Engine.run ➤ use Matter.Runner.run(engine) instead")},function(e,t,n){var i={};e.exports=i;var o=n(15),r=n(0);i.name="matter-js",i.version="0.17.1",i.uses=[],i.used=[],i.use=function(){o.use(i,Array.prototype.slice.call(arguments))},i.before=function(e,t){return e=e.replace(/^Matter./,""),r.chainPathBefore(i,e,t)},i.after=function(e,t){return e=e.replace(/^Matter./,""),r.chainPathAfter(i,e,t)}},function(e,t,n){var i={};e.exports=i;var o=n(5),r=n(8),a=n(0),s=n(6),l=n(11),c=a.deprecated;i.stack=function(e,t,n,i,r,a,l){for(var c,u=o.create({label:"Stack"}),d=e,p=t,f=0,v=0;vm&&(m=x),s.translate(g,{x:.5*h,y:.5*x}),d=g.bounds.max.x+r,o.addBody(u,g),c=g,f+=1}else d+=r}p+=m+a,d=e}return u},i.chain=function(e,t,n,i,s,l){for(var c=e.bodies,u=1;u0)for(c=0;c0&&(p=f[c-1+(l-1)*t],o.addConstraint(e,r.create(a.extend({bodyA:p,bodyB:d},s)))),i&&cp||a<(c=p-c)||a>n-1-c))return 1===d&&s.translate(u,{x:(a+(n%2==1?1:-1))*f,y:0}),l(e+(u?a*f:0)+a*r,i,a,c,u,d)}))},i.newtonsCradle=function(e,t,n,i,a){for(var s=o.create({label:"Newtons Cradle"}),c=0;c1?1:0;ue.deltaMax?e.deltaMax:i)/e.delta,e.delta=i),0!==e.timeScalePrev&&(s*=a.timeScale/e.timeScalePrev),0===a.timeScale&&(s=0),e.timeScalePrev=a.timeScale,e.correction=s,e.frameCounter+=1,n-e.counterTimestamp>=1e3&&(e.fps=e.frameCounter*((n-e.counterTimestamp)/1e3),e.counterTimestamp=n,e.frameCounter=0),o.trigger(e,"tick",l),o.trigger(e,"beforeUpdate",l),r.update(t,i,s),o.trigger(e,"afterUpdate",l),o.trigger(e,"afterTick",l)},i.stop=function(e){t(e.frameRequestId)},i.start=function(e,t){i.run(e,t)}}()},function(e,t,n){var i={};e.exports=i;n(1);var o=n(0);i.pathToVertices=function(e,t){"undefined"==typeof window||"SVGPathSeg"in window||o.warn("Svg.pathToVertices: SVGPathSeg not defined, a polyfill is required.");var n,r,a,s,l,c,u,d,p,f,v,m=[],y=0,g=0,x=0;t=t||15;var h=function(e,t,n){var i=n%2==1&&n>1;if(!p||e!=p.x||t!=p.y){p&&i?(f=p.x,v=p.y):(f=0,v=0);var o={x:f+e,y:v+t};!i&&p||(p=o),m.push(o),g=f+e,x=v+t}},b=function(e){var t=e.pathSegTypeAsLetter.toUpperCase();if("Z"!==t){switch(t){case"M":case"L":case"T":case"C":case"S":case"Q":g=e.x,x=e.y;break;case"H":g=e.x;break;case"V":x=e.y}h(g,x,e.pathSegType)}};for(i._svgPathToAbsolute(e),a=e.getTotalLength(),c=[],n=0;n0;t--){var i=Math.floor(n.random()*(t+1)),o=e[t];e[t]=e[i],e[i]=o}return e},n.choose=function(e){return e[Math.floor(n.random()*e.length)]},n.isElement=function(e){return"undefined"!=typeof HTMLElement?e instanceof HTMLElement:!!(e&&e.nodeType&&e.nodeName)},n.isArray=function(e){return"[object Array]"===Object.prototype.toString.call(e)},n.isFunction=function(e){return"function"==typeof e},n.isPlainObject=function(e){return"object"==typeof e&&e.constructor===Object},n.isString=function(e){return"[object String]"===toString.call(e)},n.clamp=function(e,t,n){return en?n:e},n.sign=function(e){return e<0?-1:1},n.now=function(){if("undefined"!=typeof window&&window.performance){if(window.performance.now)return window.performance.now();if(window.performance.webkitNow)return window.performance.webkitNow()}return Date.now?Date.now():new Date-n._nowStartTime},n.random=function(t,n){return n=void 0!==n?n:1,(t=void 0!==t?t:0)+e()*(n-t)};var e=function(){return n._seed=(9301*n._seed+49297)%233280,n._seed/233280};n.colorToNumber=function(e){return 3==(e=e.replace("#","")).length&&(e=e.charAt(0)+e.charAt(0)+e.charAt(1)+e.charAt(1)+e.charAt(2)+e.charAt(2)),parseInt(e,16)},n.logLevel=1,n.log=function(){console&&n.logLevel>0&&n.logLevel<=3&&console.log.apply(console,["matter-js:"].concat(Array.prototype.slice.call(arguments)))},n.info=function(){console&&n.logLevel>0&&n.logLevel<=2&&console.info.apply(console,["matter-js:"].concat(Array.prototype.slice.call(arguments)))},n.warn=function(){console&&n.logLevel>0&&n.logLevel<=3&&console.warn.apply(console,["matter-js:"].concat(Array.prototype.slice.call(arguments)))},n.warnOnce=function(){var e=Array.prototype.slice.call(arguments).join(" ");n._warnedOnce[e]||(n.warn(e),n._warnedOnce[e]=!0)},n.deprecated=function(e,t,i){e[t]=n.chain((function(){n.warnOnce("🔅 deprecated 🔅",i)}),e[t])},n.nextId=function(){return n._nextId++},n.indexOf=function(e,t){if(e.indexOf)return e.indexOf(t);for(var n=0;ne.max.x&&(e.max.x=o.x),o.xe.max.y&&(e.max.y=o.y),o.y0?e.max.x+=n.x:e.min.x+=n.x,n.y>0?e.max.y+=n.y:e.min.y+=n.y)},n.contains=function(e,t){return t.x>=e.min.x&&t.x<=e.max.x&&t.y>=e.min.y&&t.y<=e.max.y},n.overlaps=function(e,t){return e.min.x<=t.max.x&&e.max.x>=t.min.x&&e.max.y>=t.min.y&&e.min.y<=t.max.y},n.translate=function(e,t){e.min.x+=t.x,e.max.x+=t.x,e.min.y+=t.y,e.max.y+=t.y},n.shift=function(e,t){var n=e.max.x-e.min.x,i=e.max.y-e.min.y;e.min.x=t.x,e.max.x=t.x+n,e.min.y=t.y,e.max.y=t.y+i}},function(e,t){var n={};e.exports=n,n.create=function(e,t){return{x:e||0,y:t||0}},n.clone=function(e){return{x:e.x,y:e.y}},n.magnitude=function(e){return Math.sqrt(e.x*e.x+e.y*e.y)},n.magnitudeSquared=function(e){return e.x*e.x+e.y*e.y},n.rotate=function(e,t,n){var i=Math.cos(t),o=Math.sin(t);n||(n={});var r=e.x*i-e.y*o;return n.y=e.x*o+e.y*i,n.x=r,n},n.rotateAbout=function(e,t,n,i){var o=Math.cos(t),r=Math.sin(t);i||(i={});var a=n.x+((e.x-n.x)*o-(e.y-n.y)*r);return i.y=n.y+((e.x-n.x)*r+(e.y-n.y)*o),i.x=a,i},n.normalise=function(e){var t=n.magnitude(e);return 0===t?{x:0,y:0}:{x:e.x/t,y:e.y/t}},n.dot=function(e,t){return e.x*t.x+e.y*t.y},n.cross=function(e,t){return e.x*t.y-e.y*t.x},n.cross3=function(e,t,n){return(t.x-e.x)*(n.y-e.y)-(t.y-e.y)*(n.x-e.x)},n.add=function(e,t,n){return n||(n={}),n.x=e.x+t.x,n.y=e.y+t.y,n},n.sub=function(e,t,n){return n||(n={}),n.x=e.x-t.x,n.y=e.y-t.y,n},n.mult=function(e,t){return{x:e.x*t,y:e.y*t}},n.div=function(e,t){return{x:e.x/t,y:e.y/t}},n.perp=function(e,t){return{x:(t=!0===t?-1:1)*-e.y,y:t*e.x}},n.neg=function(e){return{x:-e.x,y:-e.y}},n.angle=function(e,t){return Math.atan2(t.y-e.y,t.x-e.x)},n._temp=[n.create(),n.create(),n.create(),n.create(),n.create(),n.create()]},function(e,t,n){var i={};e.exports=i;var o=n(2),r=n(0);i.create=function(e,t){for(var n=[],i=0;i0)return!1;a=n}return!0},i.scale=function(e,t,n,r){if(1===t&&1===n)return e;var a,s;r=r||i.centre(e);for(var l=0;l=0?l-1:e.length-1],u=e[l],d=e[(l+1)%e.length],p=t[l0&&(r|=2),3===r)return!1;return 0!==r||null},i.hull=function(e){var t,n,i=[],r=[];for((e=e.slice(0)).sort((function(e,t){var n=e.x-t.x;return 0!==n?n:e.y-t.y})),n=0;n=2&&o.cross3(r[r.length-2],r[r.length-1],t)<=0;)r.pop();r.push(t)}for(n=e.length-1;n>=0;n-=1){for(t=e[n];i.length>=2&&o.cross3(i[i.length-2],i[i.length-1],t)<=0;)i.pop();i.push(t)}return i.pop(),r.pop(),i.concat(r)}},function(e,t,n){var i={};e.exports=i;var o=n(0);i.on=function(e,t,n){for(var i,o=t.split(" "),r=0;r0){n||(n={}),i=t.split(" ");for(var c=0;c0&&r.rotateAbout(a.position,n,e.position,a.position)}},i.setVelocity=function(e,t){e.positionPrev.x=e.position.x-t.x,e.positionPrev.y=e.position.y-t.y,e.velocity.x=t.x,e.velocity.y=t.y,e.speed=r.magnitude(e.velocity)},i.setAngularVelocity=function(e,t){e.anglePrev=e.angle-t,e.angularVelocity=t,e.angularSpeed=Math.abs(e.angularVelocity)},i.translate=function(e,t){i.setPosition(e,r.add(e.position,t))},i.rotate=function(e,t,n){if(n){var o=Math.cos(t),r=Math.sin(t),a=e.position.x-n.x,s=e.position.y-n.y;i.setPosition(e,{x:n.x+(a*o-s*r),y:n.y+(a*r+s*o)}),i.setAngle(e,e.angle+t)}else i.setAngle(e,e.angle+t)},i.scale=function(e,t,n,r){var a=0,s=0;r=r||e.position;for(var u=0;u0&&(a+=d.area,s+=d.inertia),d.position.x=r.x+(d.position.x-r.x)*t,d.position.y=r.y+(d.position.y-r.y)*n,l.update(d.bounds,d.vertices,e.velocity)}e.parts.length>1&&(e.area=a,e.isStatic||(i.setMass(e,e.density*a),i.setInertia(e,s))),e.circleRadius&&(t===n?e.circleRadius*=t:e.circleRadius=null)},i.update=function(e,t,n,i){var a=Math.pow(t*n*e.timeScale,2),s=1-e.frictionAir*n*e.timeScale,u=e.position.x-e.positionPrev.x,d=e.position.y-e.positionPrev.y;e.velocity.x=u*s*i+e.force.x/e.mass*a,e.velocity.y=d*s*i+e.force.y/e.mass*a,e.positionPrev.x=e.position.x,e.positionPrev.y=e.position.y,e.position.x+=e.velocity.x,e.position.y+=e.velocity.y,e.angularVelocity=(e.angle-e.anglePrev)*s*i+e.torque/e.inertia*a,e.anglePrev=e.angle,e.angle+=e.angularVelocity,e.speed=r.magnitude(e.velocity),e.angularSpeed=Math.abs(e.angularVelocity);for(var p=0;p0&&(f.position.x+=e.velocity.x,f.position.y+=e.velocity.y),0!==e.angularVelocity&&(o.rotate(f.vertices,e.angularVelocity,e.position),c.rotate(f.axes,e.angularVelocity),p>0&&r.rotateAbout(f.position,e.angularVelocity,e.position,f.position)),l.update(f.bounds,f.vertices,e.velocity)}},i.applyForce=function(e,t,n){e.force.x+=n.x,e.force.y+=n.y;var i=t.x-e.position.x,o=t.y-e.position.y;e.torque+=i*n.y-o*n.x},i._totalProperties=function(e){for(var t={mass:0,area:0,inertia:0,centre:{x:0,y:0}},n=1===e.parts.length?0:1;n0&&r.motion=r.sleepThreshold&&i.set(r,!0)):r.sleepCounter>0&&(r.sleepCounter-=1)}else i.set(r,!1)}},i.afterCollisions=function(e,t){for(var n=t*t*t,o=0;oi._motionWakeThreshold*n&&i.set(c,!1)}}}},i.set=function(e,t){var n=e.isSleeping;t?(e.isSleeping=!0,e.sleepCounter=e.sleepThreshold,e.positionImpulse.x=0,e.positionImpulse.y=0,e.positionPrev.x=e.position.x,e.positionPrev.y=e.position.y,e.anglePrev=e.angle,e.speed=0,e.angularSpeed=0,e.motion=0,n||o.trigger(e,"sleepStart")):(e.isSleeping=!1,e.sleepCounter=0,n&&o.trigger(e,"sleepEnd"))}},function(e,t,n){var i={};e.exports=i;var o,r,a,s=n(3),l=n(9);o=[],r={overlap:0,axis:null},a={overlap:0,axis:null},i.create=function(e,t){return{pair:null,collided:!1,bodyA:e,bodyB:t,parentA:e.parent,parentB:t.parent,depth:0,normal:{x:0,y:0},tangent:{x:0,y:0},penetration:{x:0,y:0},supports:[]}},i.collides=function(e,t,n){if(i._overlapAxes(r,e.vertices,t.vertices,e.axes),r.overlap<=0)return null;if(i._overlapAxes(a,t.vertices,e.vertices,t.axes),a.overlap<=0)return null;var o,c,u=n&&n.table[l.id(e,t)];u?o=u.collision:((o=i.create(e,t)).collided=!0,o.bodyA=e.idP?P=s:sC?C=s:so?o=a:al.frictionStatic?s.frictionStatic:l.frictionStatic,e.restitution=s.restitution>l.restitution?s.restitution:l.restitution,e.slop=s.slop>l.slop?s.slop:l.slop,t.pair=e,a.length=0;for(var u=0;u0?1:.7),t.damping=t.damping||0,t.angularStiffness=t.angularStiffness||0,t.angleA=t.bodyA?t.bodyA.angle:t.angleA,t.angleB=t.bodyB?t.bodyB.angle:t.angleB,t.plugin={};var a={visible:!0,lineWidth:2,strokeStyle:"#ffffff",type:"line",anchors:!0};return 0===t.length&&t.stiffness>.1?(a.type="pin",a.anchors=!1):t.stiffness<.9&&(a.type="spring"),t.render=c.extend(a,t.render),t},i.preSolveAll=function(e){for(var t=0;t0&&(d.position.x+=c.x,d.position.y+=c.y),0!==c.angle&&(o.rotate(d.vertices,c.angle,n.position),l.rotate(d.axes,c.angle),u>0&&r.rotateAbout(d.position,c.angle,n.position,d.position)),s.update(d.bounds,d.vertices,n.velocity)}c.angle*=i._warming,c.x*=i._warming,c.y*=i._warming}}},i.pointAWorld=function(e){return{x:(e.bodyA?e.bodyA.position.x:0)+e.pointA.x,y:(e.bodyA?e.bodyA.position.y:0)+e.pointA.y}},i.pointBWorld=function(e){return{x:(e.bodyB?e.bodyB.position.x:0)+e.pointB.x,y:(e.bodyB?e.bodyB.position.y:0)+e.pointB.y}}},function(e,t,n){var i={};e.exports=i;var o=n(2),r=n(0);i.fromVertices=function(e){for(var t={},n=0;n0&&o.area(M)1?(v=a.create(r.extend({parts:y.slice(0)},i)),a.setPosition(v,{x:e,y:t}),v):y[0]}},function(e,t,n){var i={};e.exports=i;var o=n(0);i.create=function(e){var t={};return e||o.log("Mouse.create: element was undefined, defaulting to document.body","warn"),t.element=e||document.body,t.absolute={x:0,y:0},t.position={x:0,y:0},t.mousedownPosition={x:0,y:0},t.mouseupPosition={x:0,y:0},t.offset={x:0,y:0},t.scale={x:1,y:1},t.wheelDelta=0,t.button=-1,t.pixelRatio=parseInt(t.element.getAttribute("data-pixel-ratio"),10)||1,t.sourceEvents={mousemove:null,mousedown:null,mouseup:null,mousewheel:null},t.mousemove=function(e){var n=i._getRelativeMousePosition(e,t.element,t.pixelRatio);e.changedTouches&&(t.button=0,e.preventDefault()),t.absolute.x=n.x,t.absolute.y=n.y,t.position.x=t.absolute.x*t.scale.x+t.offset.x,t.position.y=t.absolute.y*t.scale.y+t.offset.y,t.sourceEvents.mousemove=e},t.mousedown=function(e){var n=i._getRelativeMousePosition(e,t.element,t.pixelRatio);e.changedTouches?(t.button=0,e.preventDefault()):t.button=e.button,t.absolute.x=n.x,t.absolute.y=n.y,t.position.x=t.absolute.x*t.scale.x+t.offset.x,t.position.y=t.absolute.y*t.scale.y+t.offset.y,t.mousedownPosition.x=t.position.x,t.mousedownPosition.y=t.position.y,t.sourceEvents.mousedown=e},t.mouseup=function(e){var n=i._getRelativeMousePosition(e,t.element,t.pixelRatio);e.changedTouches&&e.preventDefault(),t.button=-1,t.absolute.x=n.x,t.absolute.y=n.y,t.position.x=t.absolute.x*t.scale.x+t.offset.x,t.position.y=t.absolute.y*t.scale.y+t.offset.y,t.mouseupPosition.x=t.position.x,t.mouseupPosition.y=t.position.y,t.sourceEvents.mouseup=e},t.mousewheel=function(e){t.wheelDelta=Math.max(-1,Math.min(1,e.wheelDelta||-e.detail)),e.preventDefault()},i.setElement(t,t.element),t},i.setElement=function(e,t){e.element=t,t.addEventListener("mousemove",e.mousemove),t.addEventListener("mousedown",e.mousedown),t.addEventListener("mouseup",e.mouseup),t.addEventListener("mousewheel",e.mousewheel),t.addEventListener("DOMMouseScroll",e.mousewheel),t.addEventListener("touchmove",e.mousemove),t.addEventListener("touchstart",e.mousedown),t.addEventListener("touchend",e.mouseup)},i.clearSourceEvents=function(e){e.sourceEvents.mousemove=null,e.sourceEvents.mousedown=null,e.sourceEvents.mouseup=null,e.sourceEvents.mousewheel=null,e.wheelDelta=0},i.setOffset=function(e,t){e.offset.x=t.x,e.offset.y=t.y,e.position.x=e.absolute.x*e.scale.x+e.offset.x,e.position.y=e.absolute.y*e.scale.y+e.offset.y},i.setScale=function(e,t){e.scale.x=t.x,e.scale.y=t.y,e.position.x=e.absolute.x*e.scale.x+e.offset.x,e.position.y=e.absolute.y*e.scale.y+e.offset.y},i._getRelativeMousePosition=function(e,t,n){var i,o,r=t.getBoundingClientRect(),a=document.documentElement||document.body.parentNode||document.body,s=void 0!==window.pageXOffset?window.pageXOffset:a.scrollLeft,l=void 0!==window.pageYOffset?window.pageYOffset:a.scrollTop,c=e.changedTouches;return c?(i=c[0].pageX-r.left-s,o=c[0].pageY-r.top-l):(i=e.pageX-r.left-s,o=e.pageY-r.top-l),{x:i/(t.clientWidth/(t.width||t.clientWidth)*n),y:o/(t.clientHeight/(t.height||t.clientHeight)*n)}}},function(e,t,n){var i={};e.exports=i;var o=n(0),r=n(8);i.create=function(e){return o.extend({bodies:[],pairs:null},e)},i.setBodies=function(e,t){e.bodies=t.slice(0)},i.clear=function(e){e.bodies=[]},i.collisions=function(e){var t,n,o=[],a=e.pairs,s=e.bodies,l=s.length,c=i.canCollide,u=r.collides;for(s.sort(i._compareBoundsX),t=0;tf)break;if(!(vB.max.y)&&(!m||!h.isStatic&&!h.isSleeping)&&c(d.collisionFilter,h.collisionFilter)){var b=h.parts.length;if(x&&1===b)(C=u(d,h,a))&&o.push(C);else for(var S=b>1?1:0,w=g>1?1:0;wB.max.x||p.max.xB.max.y||(C=u(A,M,a))&&o.push(C)}}}}return o},i.canCollide=function(e,t){return e.group===t.group&&0!==e.group?e.group>0:0!=(e.mask&t.category)&&0!=(t.mask&e.category)},i._compareBoundsX=function(e,t){return e.bounds.min.x-t.bounds.min.x}},function(e,t,n){var i={};e.exports=i;var o=n(0);i._registry={},i.register=function(e){if(i.isPlugin(e)||o.warn("Plugin.register:",i.toString(e),"does not implement all required fields."),e.name in i._registry){var t=i._registry[e.name],n=i.versionParse(e.version).number,r=i.versionParse(t.version).number;n>r?(o.warn("Plugin.register:",i.toString(t),"was upgraded to",i.toString(e)),i._registry[e.name]=e):n-1},i.isFor=function(e,t){var n=e.for&&i.dependencyParse(e.for);return!e.for||t.name===n.name&&i.versionSatisfies(t.version,n.range)},i.use=function(e,t){if(e.uses=(e.uses||[]).concat(t||[]),0!==e.uses.length){for(var n=i.dependencies(e),r=o.topologicalSort(n),a=[],s=0;s0&&o.info(a.join(" "))}else o.warn("Plugin.use:",i.toString(e),"does not specify any dependencies to install.")},i.dependencies=function(e,t){var n=i.dependencyParse(e),r=n.name;if(!(r in(t=t||{}))){e=i.resolve(e)||e,t[r]=o.map(e.uses||[],(function(t){i.isPlugin(t)&&i.register(t);var r=i.dependencyParse(t),a=i.resolve(t);return a&&!i.versionSatisfies(a.version,r.range)?(o.warn("Plugin.dependencies:",i.toString(a),"does not satisfy",i.toString(r),"used by",i.toString(n)+"."),a._warned=!0,e._warned=!0):a||(o.warn("Plugin.dependencies:",i.toString(t),"used by",i.toString(n),"could not be resolved."),e._warned=!0),r.name}));for(var a=0;a=|>)?\s*((\d+)\.(\d+)\.(\d+))(-[0-9A-Za-z-+]+)?$/;t.test(e)||o.warn("Plugin.versionParse:",e,"is not a valid version or range.");var n=t.exec(e),i=Number(n[4]),r=Number(n[5]),a=Number(n[6]);return{isRange:Boolean(n[1]||n[2]),version:n[3],range:e,operator:n[1]||n[2]||"",major:i,minor:r,patch:a,parts:[i,r,a],prerelease:n[7],number:1e8*i+1e4*r+a}},i.versionSatisfies=function(e,t){t=t||"*";var n=i.versionParse(t),o=i.versionParse(e);if(n.isRange){if("*"===n.operator||"*"===e)return!0;if(">"===n.operator)return o.number>n.number;if(">="===n.operator)return o.number>=n.number;if("~"===n.operator)return o.major===n.major&&o.minor===n.minor&&o.patch>=n.patch;if("^"===n.operator)return n.major>0?o.major===n.major&&o.number>=n.number:n.minor>0?o.minor===n.minor&&o.patch>=n.patch:o.patch===n.patch}return e===t||"*"===e}},function(e,t,n){var i={};e.exports=i;var o=n(0),r=n(5),a=n(1),s=n(4),l=n(2),c=n(13);!function(){var e,t;"undefined"!=typeof window&&(e=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.msRequestAnimationFrame||function(e){window.setTimeout((function(){e(o.now())}),1e3/60)},t=window.cancelAnimationFrame||window.mozCancelAnimationFrame||window.webkitCancelAnimationFrame||window.msCancelAnimationFrame),i._goodFps=30,i._goodDelta=1e3/60,i.create=function(e){var t={controller:i,engine:null,element:null,canvas:null,mouse:null,frameRequestId:null,timing:{historySize:60,delta:0,deltaHistory:[],lastTime:0,lastTimestamp:0,lastElapsed:0,timestampElapsed:0,timestampElapsedHistory:[],engineDeltaHistory:[],engineElapsedHistory:[],elapsedHistory:[]},options:{width:800,height:600,pixelRatio:1,background:"#14151f",wireframeBackground:"#14151f",hasBounds:!!e.bounds,enabled:!0,wireframes:!0,showSleeping:!0,showDebug:!1,showStats:!1,showPerformance:!1,showBounds:!1,showVelocity:!1,showCollisions:!1,showSeparations:!1,showAxes:!1,showPositions:!1,showAngleIndicator:!1,showIds:!1,showVertexNumbers:!1,showConvexHulls:!1,showInternalEdges:!1,showMousePosition:!1}},n=o.extend(t,e);return n.canvas&&(n.canvas.width=n.options.width||n.canvas.width,n.canvas.height=n.options.height||n.canvas.height),n.mouse=e.mouse,n.engine=e.engine,n.canvas=n.canvas||d(n.options.width,n.options.height),n.context=n.canvas.getContext("2d"),n.textures={},n.bounds=n.bounds||{min:{x:0,y:0},max:{x:n.canvas.width,y:n.canvas.height}},n.options.showBroadphase=!1,1!==n.options.pixelRatio&&i.setPixelRatio(n,n.options.pixelRatio),o.isElement(n.element)?n.element.appendChild(n.canvas):n.canvas.parentNode||o.log("Render.create: options.element was undefined, render.canvas was created but not appended","warn"),n},i.run=function(t){!function o(r){t.frameRequestId=e(o),n(t,r),i.world(t,r),(t.options.showStats||t.options.showDebug)&&i.stats(t,t.context,r),(t.options.showPerformance||t.options.showDebug)&&i.performance(t,t.context,r)}()},i.stop=function(e){t(e.frameRequestId)},i.setPixelRatio=function(e,t){var n=e.options,i=e.canvas;"auto"===t&&(t=p(i)),n.pixelRatio=t,i.setAttribute("data-pixel-ratio",t),i.width=n.width*t,i.height=n.height*t,i.style.width=n.width+"px",i.style.height=n.height+"px"},i.lookAt=function(e,t,n,i){i=void 0===i||i,t=o.isArray(t)?t:[t],n=n||{x:0,y:0};for(var r={min:{x:1/0,y:1/0},max:{x:-1/0,y:-1/0}},a=0;ar.max.x&&(r.max.x=u.x),l.yr.max.y&&(r.max.y=u.y))}var d=r.max.x-r.min.x+2*n.x,p=r.max.y-r.min.y+2*n.y,f=e.canvas.height,v=e.canvas.width/f,y=d/p,m=1,g=1;y>v?g=y/v:m=v/y,e.options.hasBounds=!0,e.bounds.min.x=r.min.x,e.bounds.max.x=r.min.x+d*m,e.bounds.min.y=r.min.y,e.bounds.max.y=r.min.y+p*g,i&&(e.bounds.min.x+=.5*d-d*m*.5,e.bounds.max.x+=.5*d-d*m*.5,e.bounds.min.y+=.5*p-p*g*.5,e.bounds.max.y+=.5*p-p*g*.5),e.bounds.min.x-=n.x,e.bounds.max.x-=n.x,e.bounds.min.y-=n.y,e.bounds.max.y-=n.y,e.mouse&&(c.setScale(e.mouse,{x:(e.bounds.max.x-e.bounds.min.x)/e.canvas.width,y:(e.bounds.max.y-e.bounds.min.y)/e.canvas.height}),c.setOffset(e.mouse,e.bounds.min))},i.startViewTransform=function(e){var t=e.bounds.max.x-e.bounds.min.x,n=e.bounds.max.y-e.bounds.min.y,i=t/e.options.width,o=n/e.options.height;e.context.setTransform(e.options.pixelRatio/i,0,0,e.options.pixelRatio/o,0,0),e.context.translate(-e.bounds.min.x,-e.bounds.min.y)},i.endViewTransform=function(e){e.context.setTransform(e.options.pixelRatio,0,0,e.options.pixelRatio,0,0)},i.world=function(e,t){var n,u=o.now(),d=e.engine,p=d.world,f=e.canvas,y=e.context,m=e.options,g=e.timing,x=r.allBodies(p),h=r.allConstraints(p),b=m.wireframes?m.wireframeBackground:m.background,S=[],w=[],A={timestamp:d.timing.timestamp};if(s.trigger(e,"beforeRender",A),e.currentBackground!==b&&v(e,b),y.globalCompositeOperation="source-in",y.fillStyle="transparent",y.fillRect(0,0,f.width,f.height),y.globalCompositeOperation="source-over",m.hasBounds){for(n=0;n1?1:0;a1?1:0;s1?1:0;r1?1:0;s1?1:0;r1?1:0;r1?1:0;o0)){var u=i.activeContacts[0].vertex.x,d=i.activeContacts[0].vertex.y;2===i.activeContacts.length&&(u=(i.activeContacts[0].vertex.x+i.activeContacts[1].vertex.x)/2,d=(i.activeContacts[0].vertex.y+i.activeContacts[1].vertex.y)/2),o.bodyB===o.supports[0].body||!0===o.bodyA.isStatic?s.moveTo(u-8*o.normal.x,d-8*o.normal.y):s.moveTo(u+8*o.normal.x,d+8*o.normal.y),s.lineTo(u,d)}l.wireframes?s.strokeStyle="rgba(255,165,0,0.7)":s.strokeStyle="orange",s.lineWidth=1,s.stroke()},i.separations=function(e,t,n){var i,o,r,a,s,l=n,c=e.options;for(l.beginPath(),s=0;s0&&l.trigger(e,"collisionStart",{pairs:m.collisionStart}),r.preSolvePosition(m.list),f=0;f0&&l.trigger(e,"collisionActive",{pairs:m.collisionActive}),m.collisionEnd.length>0&&l.trigger(e,"collisionEnd",{pairs:m.collisionEnd}),i._bodiesClearForces(b),l.trigger(e,"afterUpdate",h),e.timing.lastElapsed=d.now()-p,e},i.merge=function(e,t){if(d.extend(e,t),t.world){e.world=t.world,i.clear(e);for(var n=c.allBodies(e.world),r=0;rW||-H>W?(o=H>0?H:-H,(n=f.friction*(H>0?1:-1)*s)<-o?n=-o:n>o&&(n=o)):(n=H,o=d);var G=I*b-T*h,N=R*b-E*h,U=C/(M+y.inverseInertia*G*G+m.inverseInertia*N*N),z=(1+f.restitution)*F*U;if(n*=U,F*F>l&&F<0)k.normalImpulse=0;else{var X=k.normalImpulse;k.normalImpulse+=z,k.normalImpulse=Math.min(k.normalImpulse,0),z=k.normalImpulse-X}if(H*H>u)k.tangentImpulse=0;else{var Q=k.tangentImpulse;k.tangentImpulse+=n,k.tangentImpulse<-o&&(k.tangentImpulse=-o),k.tangentImpulse>o&&(k.tangentImpulse=o),n=k.tangentImpulse-Q}var Y=h*z+S*n,Z=b*z+w*n;y.isStatic||y.isSleeping||(y.positionPrev.x+=Y*y.inverseMass,y.positionPrev.y+=Z*y.inverseMass,y.anglePrev+=(I*Z-T*Y)*y.inverseInertia),m.isStatic||m.isSleeping||(m.positionPrev.x-=Y*m.inverseMass,m.positionPrev.y-=Z*m.inverseMass,m.anglePrev-=(R*Z-E*Y)*m.inverseInertia)}}}}},function(e,t,n){var i={};e.exports=i;var o=n(9),r=n(0);i.create=function(e){return r.extend({table:{},list:[],collisionStart:[],collisionActive:[],collisionEnd:[]},e)},i.update=function(e,t,n){var i,r,a,s,l=e.list,c=l.length,u=e.table,d=t.length,p=e.collisionStart,f=e.collisionEnd,v=e.collisionActive;for(p.length=0,f.length=0,v.length=0,s=0;sy&&(y=x),s.translate(g,{x:.5*h,y:.5*x}),d=g.bounds.max.x+r,o.addBody(u,g),c=g,f+=1}else d+=r}p+=y+a,d=e}return u},i.chain=function(e,t,n,i,s,l){for(var c=e.bodies,u=1;u0)for(c=0;c0&&(p=f[c-1+(l-1)*t],o.addConstraint(e,r.create(a.extend({bodyA:p,bodyB:d},s)))),i&&cp||a<(c=p-c)||a>n-1-c))return 1===d&&s.translate(u,{x:(a+(n%2==1?1:-1))*f,y:0}),l(e+(u?a*f:0)+a*r,i,a,c,u,d)}))},i.newtonsCradle=function(e,t,n,i,a){for(var s=o.create({label:"Newtons Cradle"}),c=0;cu.bounds.max.x||f.bounds.max.yu.bounds.max.y))){var v=i._getRegion(e,f);if(!f.region||v.id!==f.region.id||o){f.region&&!o||(f.region=v);var y=i._regionUnion(v,f.region);for(a=y.startCol;a<=y.endCol;a++)for(s=y.startRow;s<=y.endRow;s++){l=d[c=i._getBucketId(a,s)];var m=a>=v.startCol&&a<=v.endCol&&s>=v.startRow&&s<=v.endRow,g=a>=f.region.startCol&&a<=f.region.endCol&&s>=f.region.startRow&&s<=f.region.endRow;!m&&g&&g&&l&&i._bucketRemoveBody(e,l,f),(f.region===v||m&&!g||o)&&(l||(l=i._createBucket(d,c)),i._bucketAddBody(e,l,f))}f.region=v,p=!0}}}p&&(e.pairsList=i._createActivePairsList(e))},a(i,"update","Grid.update ➤ replaced by Matter.Detector"),i.clear=function(e){e.buckets={},e.pairs={},e.pairsList=[]},a(i,"clear","Grid.clear ➤ replaced by Matter.Detector"),i._regionUnion=function(e,t){var n=Math.min(e.startCol,t.startCol),o=Math.max(e.endCol,t.endCol),r=Math.min(e.startRow,t.startRow),a=Math.max(e.endRow,t.endRow);return i._createRegion(n,o,r,a)},i._getRegion=function(e,t){var n=t.bounds,o=Math.floor(n.min.x/e.bucketWidth),r=Math.floor(n.max.x/e.bucketWidth),a=Math.floor(n.min.y/e.bucketHeight),s=Math.floor(n.max.y/e.bucketHeight);return i._createRegion(o,r,a,s)},i._createRegion=function(e,t,n,i){return{id:e+","+t+","+n+","+i,startCol:e,endCol:t,startRow:n,endRow:i}},i._getBucketId=function(e,t){return"C"+e+"R"+t},i._createBucket=function(e,t){return e[t]=[]},i._bucketAddBody=function(e,t,n){var i,r=e.pairs,a=o.id,s=t.length;for(i=0;i0?s.push(t):delete i[o[n]];return s}},function(e,t,n){var i={};e.exports=i;var o=n(3),r=n(7),a=n(13),s=n(4),l=n(14),c=n(10),u=n(5),d=n(0),p=n(1);i.create=function(e,t){var n=(e?e.mouse:null)||(t?t.mouse:null);n||(e&&e.render&&e.render.canvas?n=a.create(e.render.canvas):t&&t.element?n=a.create(t.element):(n=a.create(),d.warn("MouseConstraint.create: options.mouse was undefined, options.element was undefined, may not function as expected")));var o={type:"mouseConstraint",mouse:n,element:null,body:null,constraint:c.create({label:"Mouse Constraint",pointA:n.position,pointB:{x:0,y:0},length:.01,stiffness:.1,angularStiffness:1,render:{strokeStyle:"#90EE90",lineWidth:3}}),collisionFilter:{category:1,mask:4294967295,group:0}},r=d.extend(o,t);return s.on(e,"beforeUpdate",(function(){var t=u.allBodies(e.world);i.update(r,t),i._triggerEvents(r)})),r},i.update=function(e,t){var n=e.mouse,i=e.constraint,a=e.body;if(0===n.button){if(i.bodyB)r.set(i.bodyB,!1),i.pointA=n.position;else for(var c=0;c1?1:0;ue.deltaMax?e.deltaMax:i)/e.delta,e.delta=i),0!==e.timeScalePrev&&(s*=a.timeScale/e.timeScalePrev),0===a.timeScale&&(s=0),e.timeScalePrev=a.timeScale,e.correction=s,e.frameCounter+=1,n-e.counterTimestamp>=1e3&&(e.fps=e.frameCounter*((n-e.counterTimestamp)/1e3),e.counterTimestamp=n,e.frameCounter=0),o.trigger(e,"tick",l),o.trigger(e,"beforeUpdate",l),r.update(t,i,s),o.trigger(e,"afterUpdate",l),o.trigger(e,"afterTick",l)},i.stop=function(e){t(e.frameRequestId)},i.start=function(e,t){i.run(e,t)}}()},function(e,t,n){var i={};e.exports=i;var o=n(8),r=n(0).deprecated;i.collides=function(e,t){return o.collides(e,t)},r(i,"collides","SAT.collides ➤ replaced by Collision.collides")},function(e,t,n){var i={};e.exports=i;n(1);var o=n(0);i.pathToVertices=function(e,t){"undefined"==typeof window||"SVGPathSeg"in window||o.warn("Svg.pathToVertices: SVGPathSeg not defined, a polyfill is required.");var n,r,a,s,l,c,u,d,p,f,v,y=[],m=0,g=0,x=0;t=t||15;var h=function(e,t,n){var i=n%2==1&&n>1;if(!p||e!=p.x||t!=p.y){p&&i?(f=p.x,v=p.y):(f=0,v=0);var o={x:f+e,y:v+t};!i&&p||(p=o),y.push(o),g=f+e,x=v+t}},b=function(e){var t=e.pathSegTypeAsLetter.toUpperCase();if("Z"!==t){switch(t){case"M":case"L":case"T":case"C":case"S":case"Q":g=e.x,x=e.y;break;case"H":g=e.x;break;case"V":x=e.y}h(g,x,e.pathSegType)}};for(i._svgPathToAbsolute(e),a=e.getTotalLength(),c=[],n=0;n25% nail, needle, rivet size/damage
-combined tech: flagella - spores move +50% faster
- spores follow you if they can't find a target
-shock wave stun also applies to sporangium
- no longer reduces explosion size
+tech: integrated circuit - if ON +7 power up choices if OFF -1
-JUNK tech: reincarnation - kill all mobs and spawn new ones
- (also spawn a few extra mobs for fun)
-
-updated pause menu and fields descriptions to new wording style
-
-bug fixes
+update matter.js engine 0.17.1 -> 0.18.0
+ shouldn't change anything
+big fixes
*********************************************************** TODO *****************************************************
-Tech: florescence
+
+wormhole tech: entropic gravity - gain defense for each research
+ requires wormhole or negative mass field or pilot wave
+
+shrapnel: a new bullet type: a very small bullet with no targeting that has a high gravity arc
+ maybe 1 bounce or no bounce before it ends on map or mob collision
+ often spawns in groups
+
+testChamber2
+ mechanics
+ companion cube
+ bring cube to the end and use it to unlock research
+ level draws on the block to show it's different
+ only this block can trigger a button
+ if cube no longer exists or is off the map spawn a new one
+ double portal fling chain
+ for player?
+ for cube
+ button that activates a laser beam that hits a target and opens a door
+ in order to enter the door you need to place the cube on the button to activate the laser
+ cube has to fly through a portal in oder to get to the button
+ you can't use your body
+ story:
+ you pick up the cube early on and have to get it to a button
+ you run through the level to get the cube, clearing the level of mobs
+ picking up the cube spawns the boss
+ maybe an extra hard boss that is designed for that level
+ blockBoss?
+ you must get the cube to a button near the start of the level
+ the button opens a door
+ normal blocks don't work
+ normal blocks spawn into mobs like blockBoss
+ or mobs don't spawn blocks
+ or just the code looks for the cube
+ or the cube is resting on a button, and when you take the cube off the button the laser fires
+
+mitosis: after needle,bullets or rivets hit a surface split off into two smaller less damaging versions that have their velocity reset -firerate
+
+tech: florescence
Hitting a mob makes it emit lasers from its vertices
all laser but pulse?
should trigger a global cd so it can't occur more then once per cycle
@@ -68,6 +103,9 @@ super balls do more damage after bouncing?
how to check for bounce?
maybe just increases damage after hitting a mob
+Make environmental damages also damage mobs
+So if a mob passes through laser, it gets damaged
+
dark mode:
look at Tinyfolks, 20 minutes till dawn