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 ? ` + ${this.title ?? "Menu Screen"}

"; + inner.append(this.nodes); + parent.appendChild(inner); + document.getElementById(id).appendChild(parent); + } +} + +runAfterLoadList.push(inject); \ No newline at end of file diff --git a/mods/chem.js b/mods/chem.js index aabc4c21..c1e3b9a1 100644 --- a/mods/chem.js +++ b/mods/chem.js @@ -1903,8 +1903,10 @@ trueAcids.push("hexafluorosilicic_acid"); trueAcidGases.push("hexafluorosilicic_acid_gas"); -elements.hydrofluoric_acid.ignore.push("sand","hexafluorosilicic_acid","hexafluorosilicic_acid_gas","potassium_carbonate","potassium_fluoride"); -elements.hydrofluoric_acid_gas.ignore.push("sand","hexafluorosilicic_acid","hexafluorosilicic_acid_gas","potassium_carbonate","potassium_fluoride"); +elements.hydrofluoric_acid.ignore.push("sand","hexafluorosilicic_acid","hexafluorosilicic_acid_gas","potassium_carbonate","potassium_fluoride","carbon_dioxide","hydrogen"); +elements.hydrofluoric_acid_gas.ignore.push("sand","hexafluorosilicic_acid","hexafluorosilicic_acid_gas","potassium_carbonate","potassium_fluoride","carbon_dioxide","hydrogen"); +elements.hydrogen_fluoride.ignore.push("sand","hexafluorosilicic_acid","hexafluorosilicic_acid_gas","potassium_carbonate","potassium_fluoride","carbon_dioxide","hydrogen"); +elements.liquid_hydrogen_fluoride.ignore.push("sand","hexafluorosilicic_acid","hexafluorosilicic_acid_gas","potassium_carbonate","potassium_fluoride","carbon_dioxide","hydrogen"); elements.hexafluorosilicic_acid.ignore.push("sand"); elements.hexafluorosilicic_acid_gas.ignore.push("sand"); @@ -1912,9 +1914,14 @@ elements.hydrofluoric_acid.reactions.sand = { elem1:"hexafluorosilicic_acid", el elements.hydrofluoric_acid_gas.reactions.sand = { elem1:"hexafluorosilicic_acid", elem2: null}; elements.hydrofluoric_acid.reactions.potassium_carbonate = { elem1:"potassium_fluoride", elem2: "carbon_dioxide"}; elements.hydrofluoric_acid_gas.reactions.potassium_carbonate = { elem1:"potassium_fluoride", elem2: "carbon_dioxide"}; +elements.hydrogen_fluoride.reactions.potassium_carbonate = { elem1:"potassium_fluoride", elem2: "carbon_dioxide"}; +elements.liquid_hydrogen_fluoride.reactions.potassium_carbonate = { elem1:"potassium_fluoride", elem2: "carbon_dioxide"}; elements.hydrofluoric_acid.reactions.potassium_fluoride = { elem1:["hydrogen","fluorine"], elem2: "potassium_fluoride"}; elements.hydrofluoric_acid_gas.reactions.potassium_fluoride = { elem1:["hydrogen","fluorine"], elem2: "potassium_fluoride"}; +elements.fluorine.ignore.push("sand","potassium_fluoride","carbon_dioxide"); +elements.liquid_fluorine.ignore.push("sand","potassium_fluoride","carbon_dioxide"); + elements.potassium_carbonate = { color: "#e2e1e8", behavior: behaviors.POWDER, @@ -2314,7 +2321,6 @@ elements.bless.reactions["hydrogen_fluoride"] = {elem2: "hydrogen"}; elements.bless.reactions["liquid_hydrogen_fluoride"] = {elem2: "hydrogen"}; elements.bless.reactions["hydrogen_fluoride_ice"] = {elem2: "hydrogen"}; elements.bless.reactions["hydrofluoric_acid"] = {elem2: "hydrogen"}; -elements.bless.reactions["liquid_hydrofluoric_acid"] = {elem2: "hydrogen"}; elements.bless.reactions["hydrofluoric_acid_ice"] = {elem2: "hydrogen"}; elements.bless.reactions["francium"] = {elem2: null}; elements.bless.reactions["molten_francium"] = {elem2: null}; diff --git a/mods/infLiqLight.js b/mods/infLiqLight.js new file mode 100644 index 00000000..6661f886 --- /dev/null +++ b/mods/infLiqLight.js @@ -0,0 +1,8 @@ +let oldLiqLightTick = elements.liquid_light.tick; +let oldDelPixel = deletePixel; +elements.liquid_light.tick = (pixel)=>{ + deletePixel = ()=>{}; + oldLiqLightTick(pixel); + deletePixel = oldDelPixel; +} +window.addEventListener("load", ()=>{}); diff --git a/mods/oldTooltip.js b/mods/oldTooltip.js new file mode 100644 index 00000000..abb3bc03 --- /dev/null +++ b/mods/oldTooltip.js @@ -0,0 +1,23 @@ +const defaultTooltip = "---"; +let tooltipEle; +window.addEventListener("load", ()=>{ + tooltipEle = document.createElement("p"); + tooltipEle.innerHTML = defaultTooltip; + setTimeout(()=>{ + document.getElementById("extraInfo").children[1].appendChild(tooltipEle); + let buttons = document.getElementsByClassName("elementButton"); + [...buttons].forEach(button=>{ + let ele = button.getAttribute("element"); + button.addEventListener("mouseenter", e=>{ + if(elements.hasOwnProperty(ele)) { + if(elements[ele].hasOwnProperty("desc")) { + tooltipEle.innerHTML = elements[ele].desc; + } + } + }); + button.addEventListener("mouseleave", e=>{ + tooltipEle.innerHTML = defaultTooltip; + }); + }); + }); +}); diff --git a/mods/tooltip.js b/mods/tooltip.js index ee98a11d..ddd4708e 100644 --- a/mods/tooltip.js +++ b/mods/tooltip.js @@ -1,21 +1,32 @@ -const defaultTooltip = "---"; -let tooltipEle; +const devMode = false; +// Tippy depends on popper +const popperUrl = devMode ? "https://unpkg.com/@popperjs/core@2/dist/umd/popper.min.js" : "https://unpkg.com/@popperjs/core@2"; +const tippyUrl = devMode ? "https://unpkg.com/tippy.js@6/dist/tippy-bundle.umd.js" : "https://unpkg.com/tippy.js@6"; window.addEventListener("load", ()=>{ - tooltipEle = document.createElement("p"); - tooltipEle.innerHTML = defaultTooltip; - document.getElementById("extraInfo").children[1].appendChild(tooltipEle); - let buttons = document.getElementsByClassName("elementButton"); - [...buttons].forEach(button=>{ - let ele = button.getAttribute("element"); - button.addEventListener("mouseenter", e=>{ - if(elements.hasOwnProperty(ele)) { - if(elements[ele].hasOwnProperty("desc")) { - tooltipEle.innerHTML = elements[ele].desc; - } + let popper = document.createElement("script"); + popper.src = popperUrl; + popper.addEventListener("load", () => { + let tippyScr = document.createElement("script"); + tippyScr.src = tippyUrl; + tippyScr.addEventListener("load", ()=>main(), {passive: true}); + document.body.appendChild(tippyScr); + }, {passive: true}); + document.body.appendChild(popper); +}, {passive: true}); +function main() { + [...document.getElementsByClassName("elementButton")].forEach(button=>{ + let ele = elements[button.getAttribute("element")]; + // if(ele === undefined || ele === null) return; + if(ele.desc) { + button.setAttribute("data-tippy-content", `
${ele.desc}
`); + if(ele.desc.includes("")) { + button.setAttribute("data-tippy-interactive", true); } - }); - button.addEventListener("mouseleave", e=>{ - tooltipEle.innerHTML = defaultTooltip; - }); + } }); -}); + tippy("[data-tippy-content]", { + allowHTML: true, + duration: 0, + placement: "bottom" + }); +} diff --git a/mods/vibranium.js b/mods/vibranium.js deleted file mode 100644 index e29faf4d..00000000 --- a/mods/vibranium.js +++ /dev/null @@ -1,19 +0,0 @@ -}; -elements.vibranium - color:"#455357", - behavior: behaviors.WALL, - category: "solids", - state: "solid", - tempHigh: 1000000000, - conduct: Infinity, - hardness: 1, -}; -elements.uru - color: "#719aa6", - behavior: behaviors.WALL, - catagory: "solids", - state: "solid", - tempHigh: 1000000000, - conduct: 0, - Hardness: 1, -}; diff --git a/mods/world_gen_test.js b/mods/world_gen_test.js index af279f17..dc214aba 100644 --- a/mods/world_gen_test.js +++ b/mods/world_gen_test.js @@ -138,6 +138,84 @@ if (enabledMods.includes("mods/chem.js")) { }; } +if (enabledMods.includes("mods/structure_test.js")) { + elements.smooth_tungsten = { + color: "#bcbaae", + behavior: behaviors.WALL, + tempHigh: 3422, + stateHigh: "molten_tungsten", + category: "solids", + hidden: true, + density: 19300, + conduct: 0.65, + hardness: 0.75 +}, + elements.francium_reactor = { + tick: function(pixel) { + for(cx = -4; cx <= 4; cx++) { + for(cy = -4; cy <= 4; cy++) { + if(cx === 0 && cy === 0) { + continue; + }; + var finalCoords = [pixel.x+cx,pixel.y+cy]; + if(isEmpty(...finalCoords,true)) { + continue; + } else { + var otherPixel = pixelMap[finalCoords[0]][finalCoords[1]]; + if(otherPixel.element === pixel.element) { + deletePixel(...finalCoords); + }; + }; + }; + }; + if(!isEmpty(pixel.x,pixel.y-1,true)) { + swapPixels(pixel,pixelMap[pixel.x][pixel.y-1]); + return; + }; + if(!tryMove(pixel,pixel.x,pixel.y+1)) { + let width = 10 + Math.floor(Math.random() * (8 + 1)); + let randomHeight = 2 + Math.floor(Math.random() * (2 + 1)); + var heights = []; + for(let i = 1; i <= randomHeight; i++) + { + heights.push(Math.floor(i)); + } + var currentHeight = pixel.y + 100; + while(currentHeight > pixel.y) + { + loadPixelRowFromArray(Array((width)*2-1).fill("tungsten"),pixel.x,currentHeight,true,true); + currentHeight--; + } + for(let i = 0; i < heights.length; i++) + { + for(let j = 0; j < heights[i]; j++) + { + loadPixelRowFromArray(Array((width-i)*2+1).fill("smooth_tungsten"),pixel.x,currentHeight,true,true); + currentHeight--; + } + } + + for(let i = heights.length-1; i >= 0; i--) + { + for(let j = 0; j < heights[i]; j++) + { + loadPixelRowFromArray(Array((width-i)*2+1).fill("smooth_tungsten"),pixel.x,currentHeight,true,true); + currentHeight--; + } + } + }; + }, + excludeRandom: true, + desc: "Creates a francium reactor for the francium lake worldgen.", + cooldown: 6, + state: "solid", + hardness: 1, + category: "structures", + color: ["#adadad", "#70b8ba", "#adadad", "#70b8ba", "#adadad"], + }; + elements.francium_height_map = newHeightMap(Array(5000).fill("tungsten").concat(["francium_reactor"]), "francium_height", 0.125, 1, 0.2, 2.5, 20); +} + //override function until fix worldGen = function (worldtype) { diff --git a/mods/yumcherries.js. b/mods/yumcherries.js similarity index 100% rename from mods/yumcherries.js. rename to mods/yumcherries.js