diff --git a/mods/Neutronium Mod.js b/mods/Neutronium Mod.js
index 65993299..ffe8d9be 100644
--- a/mods/Neutronium Mod.js
+++ b/mods/Neutronium Mod.js
@@ -6,11 +6,51 @@ let rPOWDER = behaviors.POWDER
console.log("Welcome to the console.");
console.log(rPOWDER);
elements.test = {
+ name: "Testium",
color: "#ff0000",
behavior: behaviors.POWDER,
category: "land",
state: "solid",
+ density: 15,
+ temp: 22,
+ tempHigh: 35,
+ stateHigh: "molten_testium",
+ reactions: {
+ "ilitium": { "elem1":"tralphium", "elem2":null },
+ "nickel": { "elem1":"iron", "elem2":null },
+ }
+};
+elements.molten_testium = {
+ name:"Liquid Testium",
+ color:"#0000ff",
+ behavior: behaviors.LIQUID,
+ category: "liquids",
+ state: "liquid",
density: 10,
+ temp: 50,
+ tempHigh: 450,
+ stateHigh: "testium_gas",
+ tempLow: 35,
+ stateLow: "test",
+ reactions: {
+ "ilitium": { "elem1":"tralphium", "elem2":null },
+ "molten_nickel": { "elem1":"molten_iron", "elem2":null },
+ },
+};
+
+elements.testium_gas = {
+ name:"Liquid Testium",
+ color:"#00ff00",
+ behavior: behaviors.GAS,
+ category: "gases",
+ state: "gas",
+ density: 5,
+ temp: 525,
+ tempLow: 450,
+ stateLow: "molten_testium",
+ reactions: {
+ "ilitium": { "elem1":"helium", "elem2":null },
+ },
};
elements.neutronium = {
name: "Neutronium",
@@ -972,46 +1012,6 @@ tempLow: 1668,
temp: 2000,
viscosity: 10000
};
-elements.toxin = {
-color: "#07f71b",
-category: "liquids",
-state: "liquid",
-behavior: behaviors.LIQUID,
-stateLow: "toxic_ice",
-tempLow: -10,
-stateHigh: "toxic_gas",
-tempHigh: 115,
-reactions: {
- "water": { "elem1":null, "elem2":"toxic_water" },
-},
-};
-lifeArray = ["plant", "dead_plant", "frozen_plant", "grass", "algae", "cell", "cancer", "flea", "termite", "ant", "worm", "fly", "firefly", "bee", "human", "body", "head", "rat", "frog", "frozen_frog", "fish", "slug", "snail", "bone_marrow", "sapling", "seeds", "grass_seed", "wheat_seed", "wheat", "pollen", "flower_seed", "pistil", "petal", "vine", "bamboo", "bamboo_plant", "mushroom_spore", "mushroom_stalk", "mushroom_gills", "mushroom_cap", "hyphae", "lichen", "cellulose", "corn_seed", "potato_seed", "root", "berry_seed", "old_berry_leaf", "berry_leaf", "berry", "slime", "blood", "antibody", "infection", "meat", "rotten_meat", "frozen_meat", "yeast"]
-if(!elements.toxin.reactions) {
- elements.toxin.reactions = {}
-}
-for(i = 0; i < lifeArray.length; i++) {
- elements.toxin.reactions[lifeArray[i]] = { "elem1":null, "elem2":"dead" }
-};
-/*
-// (Ignore this comment if it's not in another comment anymore) this whole area is a comment only because I don't want the game to try using useless code and (possibly) error out.
-if(!elements.toxic_gas.reactions) {
- elements.toxic_gas.reactions = {}
-}
-for(i = 0; i < lifeArray.length; i++) {
- elements.toxic_gas.reactions[lifeArray[i]] = { "elem1":null, "elem2":"dead" }
-};
-if(!elements.toxic_ice.reactions) {
- elements.toxic_ice.reactions = {}
-}
-for(i = 0; i < lifeArray.length; i++) {
- elements.toxic_ice.reactions[lifeArray[i]] = { "elem1":null, "elem2":"dead" }
-};
-if(!elements.toxic_water.reactions) {
- elements.toxic_water.reactions = {}
-}
-for(i = 0; i < lifeArray.length; i++) {
- elements.toxic_water.reactions[lifeArray[i]] = { "elem1":null, "elem2":"dead" }
-}; */
elements.laser_emitter = {
color: "#8a8886",
category: "machines",
@@ -1032,13 +1032,6 @@ behavior: behaviors.WALL,
behaviorOn: behaviors.LASEREMITTER,
conduct: 1,
};
-elements.dead = {
-color: "#a5a683",
-category: "life",
-state: "solid",
-behavior: behaviors.POWDER,
-density: 10,
-};
elements.ilitium = {
color: "#97baa7",
category: "solids",
diff --git a/mods/betterMenuScreens.js b/mods/betterMenuScreens.js
new file mode 100644
index 00000000..0fa8977d
--- /dev/null
+++ b/mods/betterMenuScreens.js
@@ -0,0 +1,229 @@
+/**
+ * @typedef {object} MenuScreenLoader
+ * @property {string} name Name of the menu screen. Gets displayed on the button
+ * @property {string} parentDiv ID of the parent div. Should be the same as the ID provided in MenuScreen class via setParentDivId method
+ * @property {string} buttonDescription Description that is shown when the button is hovered
+ * @property {boolean} show Whether menu screen button should get shown on tool controls
+ * @property {() => void} [close] Closing method. Optional
+ * @property {() => void} [open] Opening method. Optional
+ * @property {() => void} [onClose] Method that gets called on close (except when menu is force closed, like when clicking on a different menu button). Optional
+ * @property {() => void} [loader] Method that injects the menu screen into HTML. Can be set to ModScreen build method. Optional
+ */
+var menuScreens = {
+ info: {
+ name: "Info",
+ parentDiv: "infoParent",
+ buttonDescription: "Brings up the element info screen",
+ show: true,
+ close: () => {
+ var infoParent = document.getElementById("infoParent");
+ var infoSearch = document.getElementById("infoSearch");
+ infoParent.style.display = "none";
+ infoSearch.value = "";
+ infoHistory = [];
+ },
+ open: showInfo
+ },
+ mods: {
+ name: "Mods",
+ parentDiv: "modParent",
+ buttonDescription: "Brings up the Mod Manager",
+ show: true,
+ close: () => {
+ var modParent = document.getElementById("modParent");
+ var modManagerUrl = document.getElementById("modManagerUrl");
+ modParent.style.display = "none";
+ modManagerUrl.value = "";
+ },
+ open: showModManager
+ },
+ settings: {
+ name: "Settings",
+ parentDiv: "settingsParent",
+ buttonDescription: "Brings up the settings screen",
+ show: true,
+ open: showSettings
+ }
+}
+
+closeMenu = (force) => {
+ if (!showingMenu) return;
+ const menu = menuScreens[showingMenu];
+ if (!menu) {
+ const menuParents = document.getElementsByClassName("menuParent");
+ for (const elem of menuParents) elem.style.display = "none";
+ showingMenu = false;
+ } else {
+ if (menu.close) menu.close();
+ else {
+ const menuParent = document.getElementById(menu.parentDiv);
+ menuParent.style.display = "none";
+ }
+ if (!force && menu.onClose) menu.onClose();
+ else showingMenu = false;
+ }
+}
+
+// injects into toolControls
+const inject = () => {
+ const toolControls = document.getElementById("toolControls");
+ const buttons = [];
+ for (const key in menuScreens) {
+ const element = menuScreens[key];
+ if (element.show) {
+ const button = document.createElement("button");
+ button.id = `betterMenuScreens_${key}Button`;
+ button.title = element.buttonDescription ?? "";
+ button.onclick = () => {
+ if (showingMenu != key) {
+ closeMenu(true);
+ if (element.open) element.open();
+ else {
+ const menuParent = document.getElementById(element.parentDiv);
+ menuParent.style.display = "block";
+ showingMenu = key;
+ }
+ } else {
+ closeMenu(true);
+ }
+ }
+ button.innerText = element.name;
+ button.className = "controlButton";
+ buttons.push(button);
+ }
+ if (element.loader) element.loader();
+ }
+ toolControls.removeChild(document.getElementById("infoButton"));
+ toolControls.removeChild(document.getElementById("modsButton"));
+ // replace the old settings button with new buttons
+ document.getElementById(`settingsButton`).replaceWith(...buttons);
+
+}
+
+class MenuScreen {
+ constructor () {
+ this.nodes = [];
+ this.innerHtml = "";
+ this.showCloseButton = true;
+ this.closeButtonText = "-";
+ }
+
+ /**
+ * Sets the screen title
+ * @param {string} [title] Screen title. "New Menu Screen" by default
+ */
+ setTitle(title = "New Menu Screen") {
+ this.title = title;
+ return this;
+ }
+
+ /**
+ * Sets close button visibility. When false the close button will not be added to the menu screen
+ * @param {boolean} show Visibility of the close button
+ */
+ setShowCloseButton(show) {
+ this.showCloseButton = show;
+ }
+
+ /**
+ * Sets the close button text
+ * @param {string} [text] Close button text. "-" by default
+ */
+ setCloseButtonText(text = "-") {
+ this.closeButtonText = text;
+ }
+
+ /**
+ * Sets the parent div ID. Has to be called at least once before build method is called
+ * @param {string} id Parent div ID
+ */
+ setParentDivId(id) {
+ this.parentDivId = id;
+ return this;
+ }
+
+ /**
+ * Sets the parent div class name. Changing the div class name is not recommended
+ * @param {string} [className] Parent div class name. "menuParent" by default
+ */
+ setParentDivClass(className = "menuParent") {
+ this.parentDivClass = className;
+ return this;
+ }
+
+ /**
+ * Sets the inner div ID. Has to be called at least once before build method is called
+ * @param {string} id Inner div ID
+ */
+ setInnerDivId(id) {
+ this.innerDivId = id;
+ return this;
+ }
+
+ /**
+ * Sets the inner div class name. Changing the div class name is not recommended
+ * @param {string} [className] Inner div class name. "menuScreen" by default
+ */
+ setInnerDivClass(className = "menuScreen") {
+ this.innerDivClass = className;
+ return this;
+ }
+
+ /**
+ * Adds a node to the menu screen content
+ * @param {Node|Node[]} node Any HTML node/element or array of HTML nodes/elements
+ */
+ addNode(node) {
+ if (node instanceof Array) this.nodes.push(...node);
+ else this.nodes.push(node);
+ return this;
+ }
+
+ /**
+ * Appends to menu screen contents inner html
+ * @param {string} html HTML code to append
+ */
+ appendInnerHtml(html) {
+ this.innerHtml += html;
+ return this;
+ }
+
+ /**
+ * Sets the menu screen contents inner html
+ * @param {string} html HTML code to set to
+ */
+ setInnerHtml(html) {
+ this.innerHtml = html;
+ return this;
+ }
+
+ /**
+ * Checks whether the menu screen is ready for build. That method should not be called outside of build method
+ * @private
+ */
+ _check() {
+ if (!this.parentDivId) throw "No parent div id specified";
+ if (!this.innerDivId) throw "No inner div id specified";
+ }
+
+ /**
+ * Builds the menu screen and appends it to chosen element
+ * @param {string} [id] Element id to append the menu screen to. Changing the id from default "gameDiv" is not recommended
+ */
+ build(id = "gameDiv") {
+ this._check();
+ const parent = document.createElement("div");
+ parent.className = this.parentDivClass ?? "menuParent";
+ parent.id = this.parentDivId;
+ parent.style.display = "none";
+ const inner = document.createElement("div");
+ inner.className = this.innerDivClass ?? "menuScreen";
+ inner.innerHTML = `${this.showCloseButton ? `
+