From 020e4017b068d61ec0a0f486261791a5b9a7a26f Mon Sep 17 00:00:00 2001 From: Alexthetransfem <124483815+theenchantedsword@users.noreply.github.com> Date: Fri, 18 Jul 2025 16:20:20 -0500 Subject: [PATCH 01/13] Update morechemistry.js updated morechemistry.js to the new version, 2.0.0 --- mods/morechemistry.js | 2058 +++++++---------------------------------- 1 file changed, 357 insertions(+), 1701 deletions(-) diff --git a/mods/morechemistry.js b/mods/morechemistry.js index 6dacbe57..8576022b 100644 --- a/mods/morechemistry.js +++ b/mods/morechemistry.js @@ -1,1726 +1,382 @@ -//This mod was made by Adora the transfem, https://discord.com/users/778753696804765696 on discord and https://www.tiktok.com/@alextheagenenby?_t=8hoCVI3NRhu&_r=1 on tiktok. -let version = "1.6.2"; -function pixelInRange(pixel, range){ - let i = 0; - while (i < range.length) { - if (pixel.x === range[i][0] && pixel.y === range[i][1]) { - i++; - return true; - } else { - i++; - } - - } - return false; - -} - -function customExplosion(pixel1, pixel2, radius, list) { - let x = pixel1.x; - let y = pixel1.y; - deletePixel(x, y); - deletePixel(pixel2.x, pixel2.y); - doFrame(); - focusGame(); - explodeAt(x, y, radius, list); -}; -function reactPixels(pixel1,pixel2) { - var r = elements[pixel1.element].reactions[pixel2.element]; - if (r.setting && settings[r.setting]===0) { - return false; - } - // r has the attribute "y" which is a range between two y values - // r.y example: [10,30] - // return false if y is defined and pixel1's y is not in the range - if (r.tempMin !== undefined && pixel1.temp < r.tempMin) { - return false; - } - if (r.tempMax !== undefined && pixel1.temp > r.tempMax) { - return false; - } - if (r.burning1 !== undefined && Boolean(pixel1.burning) !== r.burning1) { - return false; - } - if (r.burning2 !== undefined && Boolean(pixel2.burning) !== r.burning2) { - return false; - } - if (r.charged && !pixel1.charge) { - return false; - } - if (r.chance !== undefined && Math.random() > r.chance) { - return false; - } - if (r.y !== undefined && (pixel1.y < r.y[0] || pixel1.y > r.y[1])) { - return false; - } - if (r.explosion !== undefined){ - if (r.radius !== undefined){ - let radius = r.radius; - let list = r.explosion.split(","); - customExplosion(pixel1, pixel2, radius, list); - } - } - if (r.elem1 !== undefined) { - // if r.elem1 is an array, set elem1 to a random element from the array, otherwise set it to r.elem1 - if (Array.isArray(r.elem1)) { - var elem1 = r.elem1[Math.floor(Math.random() * r.elem1.length)]; - } else { var elem1 = r.elem1; } - - if (elem1 == null) { - deletePixel(pixel1.x,pixel1.y); - } - else { - changePixel(pixel1,elem1); - } - } - if (r.charge1) { pixel1.charge = r.charge1; } - if (r.temp1) { pixel1.temp += r.temp1; pixelTempCheck(pixel1); } - if (r.color1) { // if it's a list, use a random color from the list, else use the color1 attribute - pixel1.color = pixelColorPick(pixel1, Array.isArray(r.color1) ? r.color1[Math.floor(Math.random() * r.color1.length)] : r.color1); - } - if (r.attr1) { // add each attribute to pixel1 - for (var key in r.attr1) { - pixel1[key] = r.attr1[key]; - } - } - if (r.elem2 !== undefined) { - // if r.elem2 is an array, set elem2 to a random element from the array, otherwise set it to r.elem2 - if (Array.isArray(r.elem2)) { - var elem2 = r.elem2[Math.floor(Math.random() * r.elem2.length)]; - } else { var elem2 = r.elem2; } - - if (elem2 == null) { - deletePixel(pixel2.x,pixel2.y); - } - else { - changePixel(pixel2,elem2); - } - } - if (r.charge2) { pixel2.charge = r.charge2; } - if (r.temp2) { pixel2.temp += r.temp2; pixelTempCheck(pixel2); } - if (r.color2) { // if it's a list, use a random color from the list, else use the color2 attribute - pixel2.color = pixelColorPick(pixel2, Array.isArray(r.color2) ? r.color2[Math.floor(Math.random() * r.color2.length)] : r.color2); - } - if (r.attr2) { // add each attribute to pixel2 - for (var key in r.attr2) { - pixel2[key] = r.attr2[key]; - } - } - if (r.func) { r.func(pixel1,pixel2); } - return r.elem1!==undefined || r.elem2!==undefined; -} -function customExplosion(pixel1, pixel2, radius, list) { - let x = pixel1.x; - let y = pixel1.y; - deletePixel(x, y); - deletePixel(pixel2.x, pixel2.y); - explodeAt(x, y, radius, list); -}; -let obj = {}; -obj.items = ""; -elements.sodiumhydroxide = { - color: "#c9c5b1", - behavior: behaviors.LIQUID, - reactions: { - "acid": { "elem2":"water", }, - "acid": { "elem2":"smoke", }, - "acid": { "elem2":"fire", }, - "acid": { "elem2":"fire", }, - "acid": { "elem2":"fire", }, - "acid_gas": { "elem2":"water", }, - "acid_gas": { "elem2":"smoke", }, - "acid_gas": { "elem2":"fire", }, - "acid_gas": { "elem2":"fire", }, - "acid_gas": { "elem2":"fire", }, - "vinegar": { "elem1": ["sodium_acetate", "water"], }, - "aqua_regia": { "elem1": null, "elem2": ["fire", "fire", "hydrogen"], }, - "acidic_water": { "elem1": null, "elem2": ["water", "pop"], }, - "nitric_acid": { "elem1": null, "elem2": ["fire", "pop", "hydrogen"], }, - "chloroauric_acid": {"elem1": "gold", "elem2": ["fire", "fire", "pop"], }, - }, - viscosity: 0.56, - //tempHigh: 64.7, - fireColor: "#fba600", - category: "liquids", - state: "liquid", - density: 1.525, - stain: -0.25, - name: "SodiumHydroxide", - stateHigh: "sodiumhydroxidecrystals", - tempHigh: "1388", -} -elements.sodiumhydroxidecrystals = { - color: "#c9c5b1", +/* +Version 2.0.0 +*/ +function multiChoice(text, handler, title) { + let pause = false; + if (promptState) { pause = promptState.wasPaused } + else if (paused) { pause = true } + promptState = { + type: "confirm", + text: text, + handler: handler, + title: title || "Are you sure?", + wasPaused: pause + } + showPromptScreen(); + } +let xDown = false; +elements.copper_sulfate = { behavior: behaviors.POWDER, + color: ["#4391fd","#004cfe"], reactions: { - "acid": { "elem2":"smoke", }, - "acid": { "elem2":"fire", }, - "acid": { "elem2":"fire", }, - "acid": { "elem2":"fire", }, - "acid_gas": { "elem2":"smoke", }, - "acid_gas": { "elem2":"pop", }, - "acid_gas": { "elem2":"fire", }, - "acid_gas": { "elem2":"fire", }, - "water": { "elem1": null, "elem2": "sodiumhydroxide", }, - "vinegar": { "elem1": null, "elem2": "sodium_acetate", }, - "aqua_regia": { "elem1": null, "elem2": ["fire", "fire", "hydrogen"], }, - "acidic_water": { "elem1": null, "elem2": ["water", "pop"], }, - "nitric_acid": { "elem1": null, "elem2": ["fire", "pop", "hydrogen"], }, - "chloroauric_acid": {"elem1": "gold", "elem2": ["fire", "fire", "pop"], }, + ant: {"elem2": "dead_bug"}, + fly: {"elem2": "dead_bug"}, + firefly: {"elem2": "dead_bug"}, + stink_bug: {"elem2": "dead_bug"}, + bee: {"elem2": "dead_bug"}, + termite: {"elem2": "dead_bug"}, + spider: {"elem2": "dead_bug"}, + plant: {"elem2": "dead_plant"}, + grass: {"elem2": "dead_plant"}, + algae: {"elem2": null}, + kelp: {"elem2": "water"}, + coral: {"elem2": "water"}, + mushroom_cap: {"elem2": null}, + mushroom_stalk: {"elem2": null}, + mushroom_gill: {"elem2": null}, + mushroom_spore: {"elem2": null}, + zinc: {"stain2": "#2A1210"}, + fire: {"elem1": null,"elem2": "poison_gas","chance": 0.1}, + sugar: {"elem1": "oxidized_copper","elem2": null,"color1": ["#CB3D3D","#A6292B","#6E1B1B"]} }, - //tempHigh: 64.7, - fireColor: "#fba600", - category: "powders", + tempHigh: 110, + fireColor: [ + "#91d106", + "#feff97", + "#248e01" + ], state: "solid", - density: 2130, - name: "SodiumHydroxideCrystals", -} - -elements.sodium.reactions = { - "chlorine": { - "elem1": "salt", - "elem2": "pop" - }, - "vinegar": { - "elem1": "sodium_acetate", - "elem2": [ - null, - null, - null, - "hydrogen" - ], - "attr1": { - "foam": 15 - } - }, - "water": { - "elem1": [ - "sodiumhydroxide" - ], - "chance": 1, - "temp2": 299.6 - }, - "salt_water": { - "elem1": [ - "sodiumhydroxide", - "salt" - ], - "chance": 1, - "temp2": 299.6 - }, - "sugar_water": { - "elem1": [ - "sodiumhydroxide", - "sugar" - ], - "chance": 1, - "temp2": 299.6 - }, - "acid": { - "elem1": "explosion", - }, - "aqua_regia": { "elem1": null, "elem2": ["fire", "pop", "fire", "fire", "hydrogen"], }, - "acidic_water": { "elem1": null, "elem2": ["water", "pop", "pop"], }, - "nitric_acid": { "elem1": null, "elem2": ["fire", "pop", "pop", "hydrogen"], }, - "chloroauric_acid": { "elem1": "gold", "elem2": ["fire", "fire", "pop"], }, -}; -elements.magnesium = { - color: "#e6e6e6", - reactions: { - "acid": { "elem1": "hydrogen", "chance": 0.02, }, - "aqua_regia": { "elem1": "hydrogen", "chance": 0.2, "elem2": "pop", }, - - }, - behavior: behaviors.POWDER, - fireColor: "#ffffff", - category: "powders", - state: "solid", - density: 1740, - burnTime: 500, - name: "Magnesium", - stateHigh: "molten_magnesium", - tempHigh: "650", - burn: 50, - density: 1738, -} -elements.molten_magnesium = { - color: ["#fab298", "#f78157", "#ff9169", "#ff9e7a"], - behavior: behaviors.MOLTEN, - fireColor: "#ffffff", - category: "states", - state: "liquid", - density: 1740, - name: "MoltenMagnesium", - temp: 650, - stateLow: "magnesium", - tempLow: 600, - density: 1460, -} -elements.acidic_water = { - burn: 0, - behavior: behaviors.LIQUID, - reactions: { - "quicklime": {"elem2": ["hydrogen", "water", "water", "water", "water"], "elem1": null, }, - "slaked_lime": {"elem2": ["hydrogen", "water", "water", "water", "water"], "elem1": null, }, - "calcium": {"elem2": ["hydrogen", "fire", "water", "water", "water"], "elem1": null, }, - "sodium": {"elem2": ["hydrogen", "fire", "fire", "pop", "fire"], "elem1": null, }, - "sodiumhydroxide": {"elem2": ["hydrogen", "fire", "pop", "pop", "water"], "elem1": null, }, - "sodiumhydroxidecrystals": {"elem2": ["hydrogen", "pop", "water", "water"], "elem1": null, }, - }, - category: "liquids", - state: "liquid", - density: 1000, - name: "AcidWater", - density: 1100, -} -elements.acid.ignore.push("magnesium"); -elements.acid.ignore.push("sodiumhydroxide"); -elements.acid.ignore.push("sodiumhydroxidecrystals"); -elements.acid.ignore.push("rubidiumhydroxide"); -elements.acid.ignore.push("rubidiumhydroxidecrystals"); -elements.acid.ignore.push("rubidiumsalt"); -elements.acid.ignore.push("rubidium"); -elements.acid.ignore.push("moltenrubidium"); -elements.acid.ignore.push("potassium"); -elements.acid.ignore.push("MoltenPotassium"); -elements.acid.ignore.push("potassiumhydroxide"); -elements.acid.ignore.push("potassiumhydroxidecrystals"); -elements.acid.ignore.push("water"); -elements.acid.ignore.push("acidic_water"); -elements.acid.ignore.push("gold"); -elements.acid.ignore.push("chloroauric_acid"); -elements.acid.ignore.push("nitric_acid"); -elements.acid.ignore.push("aqua_regia"); -elements.cwall = { - "color": "rgb(128,128,128)", - "name": "Conductive Wall", - "behavior": [["XX", "XX", "XX"], ["XX", "XX", "XX"], ["XX", "XX", "XX"]], - "category": "solids", - "insulate": false, - "hardness": 1, - "noMix": true, - "colorObject": { - "r": 128, - "g": 128, - "b": 128 - }, - } -elements.acid.reactions = { - "ash": { - "elem1": "neutral_acid", - "elem2": null - }, - "limestone": { - "elem1": "neutral_acid", - "elem2": null - }, - "quicklime": { - "elem1": "neutral_acid", - "elem2": null - }, - "slaked_lime": { - "elem1": "neutral_acid", - "elem2": null - }, - "borax": { - "elem1": "neutral_acid", - "elem2": null - }, - "ammonia": { - "elem1": "neutral_acid", - "elem2": null - }, - "bleach": { - "elem1": "neutral_acid", - "elem2": null - }, - "water": { - "elem1": "acidic_water", - }, - "salt_water": { - "elem1": null, - "elem2": "water" - }, - "sugar_water": { - "elem1": null, - "elem2": "water" - }, - "charcoal": { - "elem1": null, - "elem2": "carbon_dioxide" - }, - "rock": { - "elem1": null, - "elem2": "sand", - "chance": 0.05 - }, - "baking_soda": { - "elem1": "salt_water", - "elem2": [ - "carbon_dioxide", - "foam" - ] - }, - "zinc": { "elem1": null, "elem2": "zinc_chloride", }, - "iron": { "elem1": null, "elem2": "iron_chloride", }, - "aluminum": { "elem1": null, "elem2": "aluminum_chloride", }, -} -elements.chloroauric_acid = { - behavior: behaviors.POWDER, - category: "powders", - state: "solid", - name: "ChloroauricAcid", - color: "#ba7b00", - tempHigh: 60, - stateHigh: "liquid_chloroauric_acid", - density: 4400, -} -elements.liquid_chloroauric_acid = { - behavior: behaviors.LIQUID, - category: "states", - state: "liquid", - name: "LiquidChloroauricAcid", - color: "#ba7b00", - reactions: { - "sodiumhydroxide": { "elem2": "gold", "elem1": ["water", "pop", "pop", "fire", "fire"], }, - "sodiumhydroxidecrystals": { "elem2": "gold", "elem1": ["water", "pop", "pop", "fire", "fire"], }, - "sodium": { "elem2": "gold", "elem1": ["fire", "pop", "pop", "fire", "fire"], }, - "calcium": { "elem2": "gold", "elem1": ["water", "pop", "water", "fire"], }, - }, - tempLow: 59, - stateLow: "chloroauric_acid", - tempHigh: 115, - stateHigh: "gold", - density: 2500, -} -elements.nitrogen_oxide = { - behavior: behaviors.GAS, - category: "gases", - state: "gas", - name: "NitrogenOxide", - color: "#961400", - reactions: { - "water": { "elem1": null, "elem2": "nitric_acid", }, - }, - density: 2.62, -} -elements.nitric_acid = { - behavior: behaviors.LIQUID, - category: "liquids", - state: "liquid", - name: "NitricAcid", - color: "#ffffff", - reactions: { "acid": { "elem1": null, "elem2": "aqua_regia",}, }, - density: 1.51, -} -elements.aqua_regia = { - "behavior": [ - [ - "XX", - "DB%5", - "XX" - ], - [ - "DB%5 AND M2", - "XX", - "DB%5 AND M2" - ], - [ - "DB%5 AND M2", - "DB%10 AND M1", - "DB%5 AND M2" - ] - ], - "ignore": [ - "glass", - "rad_glass", - "glass_shard", - "rad_shard", - "stained_glass", - "baked_clay", - "acid_gas", - "neutral_acid", - "acid_cloud", - "water", - "salt_water", - "sugar_water", - "dirty_water", - "copper", - "gold", - "porcelain", - "plastic", - "bead", - "microplastic", - "molten_plastic", - "pool_water", - "chlorine", - "hydrogen", - "magnesium", - "sodiumhydroxide", - "sodiumhydroxidecrystals", - "water", - "acidic_water", - "gold", - "chloroauric_acid", - "acid_ice", - "acid", - "nitric_acid", - "NaK", - ], - "reactions": { - "ash": { - "elem1": "neutral_acid", - "elem2": null - }, - "limestone": { - "elem1": "neutral_acid", - "elem2": null - }, - "quicklime": { - "elem1": "neutral_acid", - "elem2": null - }, - "slaked_lime": { - "elem1": "neutral_acid", - "elem2": null - }, - "borax": { - "elem1": "neutral_acid", - "elem2": null - }, - "ammonia": { - "elem1": "neutral_acid", - "elem2": null - }, - "bleach": { - "elem1": "neutral_acid", - "elem2": null - }, - "water": { - "elem1": "acidic_water" - }, - "salt_water": { - "elem1": null, - "elem2": "water" - }, - "sugar_water": { - "elem1": null, - "elem2": "water" - }, - "charcoal": { - "elem1": null, - "elem2": "carbon_dioxide" - }, - "rock": { - "elem1": null, - "elem2": "sand", - "chance": 0.05 - }, - "baking_soda": { - "elem1": "salt_water", - "elem2": [ - "carbon_dioxide", - "foam" - ] - }, - "gold": { - "elem1": null, "elem2": "chloroauric_acid", "temp2": 20, - }, - "gold_coin": { - "elem1": null, "elem2": "chloroauric_acid", "temp2": 20, - }, - }, - "category": "liquids", - "state": "liquid", - "density": 1049, - "stain": -0.1, - name: "AquaRegia", - "alias": "HCl + HN03", - "movable": true, - "color": "#ffdd9b", - density: 1.3, - } -elements.potassium = { - behavior: behaviors.POWDER, - color: ["#545454", "#737373", "#7d7d7d", "#8f8f8f"], - "category": "powders", - "state": "powder", - "alias": "K", - tempHigh: 63.65, - stateHigh: "MoltenPotassium", - reactions: { - "water": { "elem1": "potassiumhydroxide", "elem2": ["fire", "fire", "pop", "water"], }, - "acid": { "elem1": null, "elem2": ["water", "smoke", "fire"], }, - "acid": { "elem2":"fire", }, - "acid": { "elem2":"fire", }, - "acid_gas": { "elem1": null, "elem2": ["water", "smoke", "fire"], }, - "acid_gas": { "elem2":"fire", }, - "acid_gas": { "elem2":"fire", }, - "aqua_regia": { "elem1": null, "elem2": ["fire", "pop", "pop", "fire", "fire", "hydrogen"], }, - "acidic_water": { "elem1": null, "elem2": ["water", "pop", "pop"], }, - "nitric_acid": { "elem1": null, "elem2": ["fire", "pop", "fire", "pop", "hydrogen"], }, - "chloroauric_acid": {"elem1": "gold", "elem2": ["fire", "fire", "pop", "pop"], }, - "liquid_chloroauric_acid": {"elem1": "gold", "elem2": ["fire", "fire", "pop", "pop"], }, - }, - density: 862, -} -elements.MoltenPotassium = { - behavior: behaviors.LIQUID, - color: ["#9c9c9c", "#8c8b8b", "#7d7d7d", "#999797"], - state: "liquid", - name: "MoltenPotassium", - viscosity: 0.55, - reactions: { - water: { explosion: "fire,potassiumhydroxide,potassiumhydroxide,potassiumhydroxide,hydrogen,hydrogen,pop", radius: 3 }, - molten_sodium: { elem1: null, elem2: "NaK" }, - acid: { explosion: "fire,fire,hydrogen,pop,pop,hydrogen", radius: 5 }, - chloroauric_acid: { elem1: "gold", explosion: "fire,fire,gold_coin,hydrogen,hydrogen,pop", radius: 6}, - liquid_chloroauric_acid: { elem1: "gold", explosion: "fire,fire,gold_coin,hydrogen,hydrogen,pop", radius: 6 - }, - aqua_regia: { explosion: "fire,fire,fire,fire,hydrogen,pop,hydrogen,pop", radius: 7}, - nitric_acid: { explosion: "fire,fire,fire,hydrogen,pop", radius: 6}, - acidic_water: { explosion: "fire,potassiumhydroxide,hydrogen,hydrogen", radius: 4 }, - }, - temp: 70, - tempLow: 63.65, - stateLow: "potassium", - density: 862, -} -elements.potassiumhydroxide = { - color: "#c9c5b1", - behavior: behaviors.LIQUID, - reactions: { - "acid": { "elem1": null, "elem2": ["water", "smoke", "fire"], }, - "acid": { "elem2":"fire", }, - "acid": { "elem2":"fire", }, - "acid_gas": { "elem1": null, "elem2": ["water", "smoke", "fire"], }, - "acid_gas": { "elem2":"fire", }, - "acid_gas": { "elem2":"fire", }, - "aqua_regia": { "elem1": null, "elem2": ["fire", "pop", "pop", "fire", "fire", "hydrogen"], }, - "acidic_water": { "elem1": null, "elem2": ["water", "pop", "pop"], }, - "nitric_acid": { "elem1": null, "elem2": ["fire", "pop", "fire", "pop", "hydrogen"], }, - "chloroauric_acid": {"elem1": "gold", "elem2": ["fire", "pop"], } - }, - viscosity: 0.56, - //tempHigh: 64.7, - fireColor: "#fba600", - category: "liquids", - state: "liquid", - density: 2.12, - stain: -0.25, - name: "PotassiumHydroxide", - stateHigh: "potassiumhydroxidecrystals", - tempHigh: "1388", -} -elements.potassiumhydroxidecrystals = { - color: "#c9c5b1", - behavior: behaviors.POWDER, - reactions: { - "acid": { "elem2":"smoke", }, - "acid": { "elem2":"fire", }, - "acid": { "elem2":"fire", }, - "acid": { "elem2":"fire", }, - "acid_gas": { "elem2":"smoke", }, - "acid_gas": { "elem2":"pop", }, - "acid_gas": { "elem2":"fire", }, - "acid_gas": { "elem2":"fire", }, - "water": { "elem1": null, "elem2": "potassiumhydroxide", }, - "vinegar": { "elem1": null, "elem2": "sodium_acetate", }, - "aqua_regia": { "elem1": null, "elem2": ["fire", "pop", "pop", "fire", "fire", "hydrogen"], }, - "acidic_water": { "elem1": null, "elem2": ["water", "pop", "pop"], }, - "nitric_acid": { "elem1": null, "elem2": ["fire", "pop", "fire", "pop", "hydrogen"], }, - "chloroauric_acid": {"elem1": "gold", "elem2": ["fire", "fire", "pop", "pop"], }, - }, - //tempHigh: 64.7, - fireColor: "#fba600", + density: 3600, + hidden: true, category: "powders", - state: "solid", - density: 2040, - name: "PotassiumHydroxideCrystals", -} -let filterItems; -let direction; - -elements.iron_chloride = { - color: ["#010014", "#a2ff94"], - reactions: { - "dirty_water": { "elem1": "water", }, - "aluminum": { "elem1": "aluminum_chloride", "elem2": "iron" }, - }, - behavior: behaviors.POWDER, - category: "powders", - state: "solid", - density: 1740, - burnTime: 500, - name: "IronChloride", - density: 2900, -} -elements.aluminum_chloride = { - color: ["#faff61", "#f7f7e4", "#ffffb5"], - reactions: { - "dirty_water": { "elem1": "water", }, - }, - behavior: behaviors.POWDER, - category: "powders", - state: "solid", - density: 1740, - burnTime: 500, - name: "AluminumChloride", - density: 2440, -} - -elements.zinc_chloride = { - color: ["#faff61", "#f7f7e4", "#ffffb5"], - reactions: { - "dirty_water": { "elem1": "water", }, - "water": { "elem1": null, "chance": 0.2 }, - }, - behavior: behaviors.POWDER, - category: "powders", - state: "solid", - density: 1740, - burnTime: 500, - name: "ZincChloride", - density: 2910, -} -elements.acid.ignore.push("zinc"); -elements.acid.ignore.push("iron"); -elements.acid.ignore.push("aluminum"); -elements.acid.ignore.push("zinc_chloride"); -elements.acid.ignore.push("iron_chloride"); -elements.acid.ignore.push("aluminum_chloride"); -elements.kilonova = { - name: "Kilonova", - category: "energy", - maxSize: 1, - temp: 100000000, -} -elements.supernova.behavior = [ ["XX", "XX", "XX"], [ "XX", "EX:80>plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,plasma,molten_iron,molten_uranium,oxygen,molten_sodium,sulfur_gas,neon,chlorine,molten_calcium,molten_nickel,molten_copper,molten_zinc,gallium_gas,hydrogen,hydrogen,hydrogen,hydrogen,helium,helium,helium AND CH:NeutronStar", "XX" ], ["XX", "XX", "XX"] ] -elements.kilonova.behavior = [ ["XX", "XX", "XX"], [ "XX", "EX:200>plasma,plasma,molten_iron,molten_uranium,molten_lead,oxygen,molten_sodium,molten_gold,molten_tungsten,sulfur_gas,neon,chlorine,molten_calcium,molten_nickel,molten_copper,molten_zinc,gallium_gas,hydrogen,hydrogen,hydrogen,hydrogen,hydrogen,helium,helium,helium,helium AND CH:void", "XX" ], ["XX", "XX", "XX"] ] -elements.NeutronStar = { - behavior: [["XX", "XX", "XX"], ["CR:light", "XX", "CR:light"], ["XX", "XX", "XX"]], - name: "NeutronStar", - category: "energy", - maxSize: 1, - color: "#ffffff", - temp: 1000000000, - tempLow: -100, - insulate: true, - noMix: true, - movable: false, - stateLow: "kilonova", - reactions: { - "NeutronStar": { "elem1": "kilonova", "temp1": 100000000, }, - }, - density: 10**17, - hardness: 1, -} -elements.acid.ignore.push("pipe"); -elements.acid.ignore.push("gold"); -elements.acid.ignore.push("gold_coin"); -if(enabledMods.includes("mods/nousersthings.js")) { - elements.acid.ignore.push("filter"); -} -elements.acid.ignore.push("NaK"); -elements.NaK = { - behavior: behaviors.LIQUID, - category: "liquids", - state: "liquid", - alias: "Sodium-Potassium alloy", - color: "#848484", - viscosity: 9.4, - reactions: { - water: { - explosion: "fire,fire,pop,hydrogen,sodiumhydroxide,potassiumhydroxide,sodiumhydroxide,potassiumhydroxide,sodiumhydroxide,potassiumhydroxide", radius: 5,}, - acid: { - explosion: "fire,fire,pop,hydrogen,salt,potassium_salt,hydrogen,fire", radius: 6,}, - acidic_water: { - explosion: "fire,fire,pop,hydrogen,sodiumhydroxide,potassiumhydroxide,salt,potassium_salt", radius: 5,}, - nitric_acid: { - explosion: "fire,fire,fire,pop,hydrogen,sodiumhydroxide,potassiumhydroxide", radius: 6,}, - aqua_regia: { - explosion: "fire,fire,pop,hydrogen,sodiumhydroxide,potassiumhydroxide,salt,potassium_salt,fire,hydrogen,pop", radius: 7,}, - }, - density: 868, -}; -elements.rubidium = { - behavior: behaviors.POWDER, - category: "powders", - name: "Rubidium", - color: ["#9e9e9e", "#ababab", "#bababa", "#adadad"], - tempHigh: 39.5, - stateHigh: "moltenrubidium", - reactions: { - chlorine: { elem1: "rubidiumsalt" }, - acid: { explosion: "fire,rubidiumsalt,water", radius: 7, }, - aqua_regia: { explosion: "fire,rubidiumsalt,fire,water", radius: 8, }, - acidic_water: { explosion: "water,water,water,rubidiumsalt", radius: 3, }, - nitric_acid: { explosion: "fire,fire,hydrogen", radius: 7 }, - chloroauric_acid: { explosion: "fire,fire,hydrogen,gold_coin", radius: 7, }, - liquid_chloroauric_acid: { explosion: "fire,fire,hydrogen,gold_coin", radius: 7, }, - water: { explosion: "fire,rubidiumhydroxide", radius: 6 }, + id: 509, + movable: true, + properties: { + anhydrous: false }, - density: 1532, - fireColor: "#d91e1e", - tick: function(pixel) { - pixel.burning = true; - }, - state: "solid", -} -elements.moltenrubidium = { - density: 1532, - behavior: behaviors.LIQUID, - viscosity: 8, - name: "MoltenRubidium", - category: "liquids", - color: ["#adacac", "#adadad", "#c2c2c2", "#b8b8b8"], - reactions: { - chlorine: { elem1: "rubidiumsalt" }, - acid: { explosion: "fire,rubidiumsalt,water", radius: 7, }, - aqua_regia: { explosion: "fire,rubidiumsalt,fire,water", radius: 8, }, - acidic_water: { explosion: "water,water,water,rubidiumsalt", radius: 3, }, - nitric_acid: { explosion: "fire,fire,hydrogen", radius: 7 }, - chloroauric_acid: { explosion: "fire,fire,hydrogen,gold_coin", radius: 7, }, - liquid_chloroauric_acid: { explosion: "fire,fire,hydrogen,gold_coin", radius: 7, }, - water: { explosion: "fire,rubidiumhydroxide", radius: 6 }, - - }, - fireColor: "#d91e1e", - tick: function(pixel) { - pixel.burning = true; - }, - tempLow: 38, - stateLow: "rubidium", -} - -elements.rubidiumsalt = { - state: "solid", - name: "RubidiumSalt", - alias: "Rubidium Chloride or RbCl", - color: ["#e6e6e6", "#f5f5f5", "#fafafa", "#f0f0f0"], - behavior: behaviors.POWDER, - category: "powders", - density: 2800, -} - -elements.irradiate = { - "color": "rgb(25,150,25)", - "temp": 2, - "category": "tools", - "canPlace": false, - "desc": "Use on irradiatable pixels to turn them radioactive.", - "colorObject": { - "r": 25, - "g": 150, - "b": 25 - }, - tool: function(pixel) { - if (pixel.element == "lead") { - changePixel(pixel, "uranium"); - } else if(pixel.element == "glass"){ - changePixel(pixel, "rad_glass"); - } else if (pixel.element == "steam"){ - changePixel(pixel, "rad_steam"); - } else if (pixel.element == "cloud" || pixel.element == "rain_cloud"){ - changePixel(pixel, "rad_cloud"); - } else if (pixel.element == "water"){ - changePixel(pixel, "fallout"); + tick: function(pixel){ + if(pixelTicks-pixel.start == 2 && xDown){ + pixel.anhydrous = true; } - }, - } -elements.deradiate = { - name: "DE-radiate", - "color": "rgb(255,255,255)", - "temp": 2, - "category": "tools", - "canPlace": false, - "desc": "Use on irradiatable pixels to turn them radioactive.", - "colorObject": { - "r": 25, - "g": 150, - "b": 25 - }, -tool: function(pixel) { - if (pixel.element == "uranium") { - changePixel(pixel, "lead"); - } else if (pixel.element == "rad_glass") { - changePixel(pixel, "glass"); - } else if (pixel.element == "rad_steam"){ - changePixel(pixel, "steam"); - } else if (pixel.element == "rad_cloud"){ - changePixel(pixel, "cloud"); - } else if (pixel.element == "fallout"){ - changePixel(pixel, "water"); - } else if (pixel.element == "radiation"){ - deletePixel(pixel.x, pixel.y); - } - }, -}; -elements.rubidiumhydroxide = { - burn: 50, - color: "#c9c5b1", - behavior: behaviors.LIQUID, - reactions: { - chlorine: { elem1: "rubidiumsalt" }, - acid: { explosion: "fire,rubidiumsalt,water", radius: 7, }, - aqua_regia: { explosion: "fire,rubidiumsalt,fire,water", radius: 8, }, - acidic_water: { explosion: "water,water,water,rubidiumsalt", radius: 3, }, - nitric_acid: { explosion: "fire,fire,hydrogen", radius: 7 }, - chloroauric_acid: { explosion: "fire,fire,hydrogen,gold_coin", radius: 7, }, - liquid_chloroauric_acid: { explosion: "fire,fire,hydrogen,gold_coin", radius: 7, }, - }, - viscosity: 0.56, - //tempHigh: 64.7, - fireColor: "#d91e1e", - category: "liquids", - state: "liquid", - density: 2.12, - name: "RubidiumHydroxide", - stateHigh: "rubidiumhydroxidecrystals", - tempHigh: "1388", -} -elements.rubidiumhydroxidecrystals = { - burn: 50, - color: "#c9c5b1", - behavior: behaviors.POWDER, - reactions: { - water: { elem1: null, elem2: "rubidiumhydroxide", }, - chlorine: { elem1: "rubidiumsalt" }, - acid: { explosion: "fire,rubidiumsalt,water", radius: 7, }, - aqua_regia: { explosion: "fire,rubidiumsalt,fire,water", radius: 8, }, - acidic_water: { explosion: "water,water,water,rubidiumsalt", radius: 3, }, - nitric_acid: { explosion: "fire,fire,hydrogen", radius: 7 }, - chloroauric_acid: { explosion: "fire,fire,hydrogen,gold_coin", radius: 7, }, - liquid_chloroauric_acid: { explosion: "fire,fire,hydrogen,gold_coin", radius: 7, }, - }, - fireColor: "#d91e1e", - category: "powders", - state: "solid", - density: 2.12, - name: "RubidiumHydroxideCrystals", -} -elements.esuperheater = { - conduct: 1, - color: '#dd1111', - colorObject: { - "r": 221, - "g": 17, - "b": 17 - }, - behavior: behaviors.WALL, - behaviorOn: [ - [ - "XX", - "HT:10", - "XX" - ], - [ - "HT:10", - "XX", - "HT:10" - ], - [ - "XX", - "HT:10", - "XX" - ] - ], - category: "machines", - name: "e-superheater", -}, - elements.efreezer = { - conduct: 1, - color: '#ffffff', - colorObject: { - "r": 255, - "g": 255, - "b": 255 - }, - behavior: behaviors.WALL, - behaviorOn: [ - [ - "XX", - "CO:10", - "XX" - ], - [ - "CO:10", - "XX", - "CO:10" - ], - [ - "XX", - "CO:10", - "XX" - ] - ], - category: "machines", - name: "e-freezer", -} -let num = 0; -elements.morechemmixer = { - name: "MoreChemMixer", - behavior: behaviors.WALL, - category: "machines", - noMix: true, - onSelect: function(pixel) { - let item = prompt("enter range for mixing."); - if(/^\d+$/.test(item)){ - num = parseInt(item); - } else { - alert("that is not an integer."); - } - }, - tick: function(pixel) { - if(pixel.start == pixelTicks) { - pixel.range = num; - } - let range = mouseRange(pixel.x, pixel.y, pixel.range); - mix(range); - } - } -let num1 = 0; -elements.morechemsmasher = { - name: "MoreChemSmasher", - behavior: behaviors.WALL, - category: "machines", - noMix: true, - onSelect: function(pixel) { - let item = prompt("enter range for smashing."); - if(/^\d+$/.test(item)){ - num1 = parseInt(item); - } else { - alert("that is not an integer."); - } - }, - tick: function(pixel) { - if(pixel.start == pixelTicks) { - pixel.range = num1; - } - let range = mouseRange(pixel.x, pixel.y, pixel.range); - smash(range); - } - } -let num2 = 0; -let exclude = []; -elements.specialsmasher = { - name: "SpecialSmasher", - behavior: behaviors.WALL, - category: "machines", - noMix: true, - onSelect: function(pixel) { - let item = prompt("enter range for smashing."); - exclude = prompt("Enter elements to exclude, seperate them with commas.").replace(/\s/g, "").split(","); - if(/^\d+$/.test(item)){ - num2 = parseInt(item); - } else { - alert("that is not an integer."); - } - }, - tick: function(pixel) { - if(pixel.start + 1 == pixelTicks) { - pixel.range = num2; - pixel.exclude = exclude; - } - let range = mouseRange(pixel.x, pixel.y, pixel.range); - smash(range, pixel.exclude); - } - } -let num3 = 0; -let exclude1 = []; -elements.specialmixer = { - name: "SpecialMixer", - behavior: behaviors.WALL, - category: "machines", - noMix: true, - onSelect: function(pixel) { - let item = prompt("enter range for mixing."); - exclude1 = prompt("Enter elements to exclude, seperate them with commas.").replace(/\s/g, "").split(","); - if(/^\d+$/.test(item)){ - num3 = parseInt(item); - } else { - alert("that is not an integer."); - } - }, - tick: function(pixel) { - if(pixel.start + 1 == pixelTicks) { - pixel.range = num3; - pixel.exclude = exclude1; - } - let range = mouseRange(pixel.x, pixel.y, pixel.range); - mix(range, pixel.exclude); - } - } - -let num4 = 0; -let exclude2 = []; -let property1 = ""; -let value2 = ""; - -let item = ""; -elements.improvedsensor = { - behavior: behaviors.WALL, - color: "#bebfa3", - onSelect: function(){ - item = prompt("what item should it detect?"); - }, - tick: function(pixel) { - if(pixel.start == pixelTicks){ - pixel.clone = item; + let colour; + let num = Math.round(Math.random()*2); + if(pixel.anhydrous && !["rgb(235,247,250)","rgb(242,248,250)"].includes(pixel.color)){ + pixel.color = ["rgb(235,247,250)","rgb(242,248,250)"][num]; + } else if (!pixel.anhydrous && !['rgb(67,145,253)', 'rgb(0,76,254)'].includes(pixel.color)){ + pixel.color = ['rgb(67,145,253)', 'rgb(0,76,254)'][num]; } - - for (var i = 0; i < adjacentCoords.length; i++) { - var coords = adjacentCoords[i]; - var x = pixel.x + coords[0]; - var y = pixel.y + coords[1]; - if (!isEmpty(x,y,true)) { - var sensed = pixelMap[x][y]; - if (sensed.element == pixel.clone) { - pixel.charge = 5; - break; - } - } - } - doDefaults(pixel); - }, - conduct: 1, - movable: false, - category:"machines", - darkText: true, - hardness: 1, - - }; - -elements.eincinerator = { - conduct: 1, - color: 'rgb(255, 70, 0)', - colorObject: { - "r": 240, - "g": 10, - "b": 0 - }, - behavior: behaviors.WALL, - behaviorOn: [ - [ - "XX", - "HT:100000", - "XX" - ], - [ - "HT:100000", - "XX", - "HT:100000" - ], - [ - "XX", - "HT:100000", - "XX" - ] - ], - category: "machines", - name: "E-Incinerator", - noMix: true, -} -elements.incinerator = { - - behavior: [ - [ - "XX", - "HT:100000", - "XX" - ], - [ - "HT:100000", - "XX", - "HT:100000" - ], - [ - "XX", - "HT:100000", - "XX" - ] - ], - name: "Incinerator", - category: "machines", - colorObject: { - "r": 255, - "g": 50, - "b": 0 - }, - color: 'rgb(255, 50, 0)', - noMix: true, -} -function conditionTrue(condition, pixel){ - let p = pixel; - let string = ""; - condition = condition.split("!OR").join("||").split("&AND").join("&&").split("\"").join("") - - condition = eval(condition); - return condition; -} -let ifCondition = ""; -let currentProp = ""; -let currentPropValue = ""; -let Func = ""; -elements.propmachine = { - name: "PropMachine", - behavior: behaviors.WALL, - category: "machines", - noMix: true, -onSelect: function(pixel) { - - let item = prompt("enter range for prop changing."); - if(/^\d+$/.test(item)){ - num4 = parseInt(item); - } else { - alert("that is not an integer."); - } - exclude2 = prompt("Enter elements to exclude, seperate them with commas. You can also enter !IF if you wish to enter conditions for it to change the property and add the exclude elements.").replace(/\s/g, ""); - if(exclude2.includes("!IF")){ - exclude2.split("!IF").join(""); - ifCondition = prompt("Enter the condition for the property to change. A list of variables can be seen at the bottom of the page. you cannot use \"\" but you can use `` and ''."); - } else { ifCondition = '1 == 1'; } - exclude2.split(","); - if(exclude2.constructor == [].constructor){ - exclude2.push("propmachine"); - } else { - exclude2 += "propmachine"; - } - var answer1 = prompt("Warning - This tool may break the simulator if used incorrectly.\n\nEnter a pixel attribute to modify or enter !FUNC to execute a function on pixels.",(currentProp||undefined)); - if(answer1.includes("!FUNC")){ - alert("enter the function you wish to execute in the function textbox at the bottom of the page. if you have not before you get this alert, nothing will happen. make sure the function has \"function(){\" before it and \"}\" after it. an example is: \"function(){console.log(\"Hello World!\")}\""); - var answer2 = Func; - } - console.log(answer1) - if (!answer1) { return } - if(!answer2){ - var answer2 = prompt("Now, enter a value for "+answer1+":",(currentPropValue||undefined)); - if (!answer2) { return } - var valueL = answer2.toLowerCase(); - if (valueL === "true") { answer2 = true } - else if (valueL === "false") { answer2 = false } - else if (valueL === "null") { answer2 = null } - else if (valueL === "undefined") { answer2 = undefined } - else if (answer1 === "color" && valueL[0] === "#") { - var rgb = hexToRGB(valueL); - answer2 = "rgb("+rgb.r+","+rgb.g+","+rgb.b+")"; - } - currentProp = answer1; - currentPropValue = answer2; - console.log(answer1); - var num = parseFloat(answer2); - if (!isNaN(num)) { answer2 = num } - currentPropValue = answer2; - logMessage("Prop: "+currentProp); - logMessage("Value: "+currentPropValue); - } - }, - tick: function(pixel) { - if(pixel.start == pixelTicks) { - pixel.range = num4; - pixel.condition = ifCondition; - pixel.prop = currentProp; - pixel.val = currentPropValue; - pixel.func = Func; - } - let range = mouseRange(pixel.x, pixel.y, pixel.range); - prop({ property: pixel.prop, value: pixel.val },range, exclude2, pixel.condition, pixel.func); - } -} -function prop(obj, range, exclude = [], condition = "", func = undefined){ - let list = []; - for (var i = 0; i < range.length; i++) { - var x = range[i][0]; - var y = range[i][1]; - if (!isEmpty(x,y,true)) { - var pixel = pixelMap[x][y]; - list.push(pixel); - } - } - for (var i = 0; i < list.length; i++) { - if (!isEmpty(list[i].x, list[i].y, true)) { - var pixel = list[i]; - if(func){ - eval(func); - } - if (!exclude.includes(pixel.element) && conditionTrue(condition, pixel)){ - if(/^\d+$/.test(obj.value)){ - obj.value = parseInt(obj.value); - } - if (!obj.property) { return } - if (pixel[obj.property] !== undefined && typeof pixel[obj.property] !== typeof obj.value) { - logMessage("Error: "+obj.property+" type is "+typeof pixel[obj.property]+", not "+typeof obj.value+"."); - obj.property = null; - obj.value = null; - return; + let multi = (pixel.temp-70)/100; + multi = (multi < 0) ? 0 : ((multi > 1) ? 1 : multi); + if(Math.random() < 0.05*multi){ + pixel.anhydrous = true; } - if (obj.property === "element") { - changePixel(pixel, obj.value); - list.splice(list.indexOf(pixel),1); - return; - } - if (obj.property === "burning" && obj.value === "true") { - pixel.burnStart = pixelTicks; - list.splice(list.indexOf(pixel),1); - return; - } - pixel[obj.property] = obj.value; - list.splice(list.indexOf(pixel),1); - } - } - } -} -function mix(range, exclude = []){ - let mixlist = []; - for (var i = 0; i < range.length; i++) { - var x = range[i][0]; - var y = range[i][1]; - if (!isEmpty(x,y,true)) { - var pixel = pixelMap[x][y]; - if (elements[pixel.element].noMix !== true) { - mixlist.push(pixel); - } - } - } - for (var i = 0; i < mixlist.length; i++) { - var pixel1 = mixlist[Math.floor(Math.random()*mixlist.length)]; - var pixel2 = mixlist[Math.floor(Math.random()*mixlist.length)]; - if (exclude.includes(pixel1.element) || exclude.includes(pixel2.element)){ - mixlist.splice(mixlist.indexOf(pixel1),1); - mixlist.splice(mixlist.indexOf(pixel2),1); - } else { - swapPixels(pixel1,pixel2); - mixlist.splice(mixlist.indexOf(pixel1),1); - mixlist.splice(mixlist.indexOf(pixel2),1); - if (elements[pixel1.element].onMix) { - elements[pixel1.element].onMix(pixel1,pixel2); - } - if (elements[pixel2.element].onMix ) { - elements[pixel2.element].onMix(pixel2,pixel1); - } - } - } -} -function smash(range, exclude = []){ - let smashlist = []; - for (var i = 0; i < range.length; i++) { - var x = range[i][0]; - var y = range[i][1]; - if (!isEmpty(x,y,true)) { - var pixel = pixelMap[x][y]; - if (elements[pixel.element].noMix !== true) { - smashlist.push(pixel); - } - } - } - for (var i = 0; i < smashlist.length; i++) { - var pixel1 = smashlist[Math.floor(Math.random()*smashlist.length)]; - smashlist.splice(smashlist.indexOf(pixel1),1); - if (elements[pixel1.element].breakInto && !exclude.includes(pixel1.element)) { - if (Array.isArray(elements[pixel1.element].breakInto)){ - changePixel(pixelMap[pixel1.x][pixel1.y], elements[pixel1.element].breakInto[Math.floor(Math.random()*elements[pixel1.element].breakInto.length)]) - } else { - changePixel(pixelMap[pixel1.x][pixel1.y], elements[pixel1.element].breakInto) - } - } - } -} -function pull(range, pixel1, include = []){ - let pulllist = []; - for (var i = 0; i < range.length; i++) { - var x = range[i][0]; - var y = range[i][1]; - if (!isEmpty(x,y,true)) { - var pixel = pixelMap[x][y]; - if (elements[pixel.element].noMix !== true) { - pulllist.push(pixel); - } - } - } - for (var i = 0; i < pulllist.length; i++) { - var pixel = pulllist[Math.floor(Math.random()*pulllist.length)]; - pulllist.splice(pulllist.indexOf(pixel),1); - if (elements[pixel.element].movable != false && include.includes(pixel.element)) { - for (var i = 0; i < pulllist.length; i++) { - if (pixelInRange(pulllist[i], range)) { - let Xdistance = pixel1.x - pixel.x; - let Ydistance = pixel1.y - pixel.y; - let newX = (Xdistance > pixel.x ? pixel.x + 3 : pixel.x + 1); - let newY = (Ydistance > pixel.y ? pixel.y + 3 : pixel.y + 1); - tryMove(pixel, newX, newY, undefined, false); + if(pixel.anhydrous){ + let neighbors = []; + for(let coords of squareCoords){ + let x = pixel.x+coords[0], y = pixel.y+coords[1]; + neighbors[neighbors.length] = (isEmpty(x,y) && !outOfBounds(x,y)) ? "air" : (!outOfBounds(x,y)) ? pixelMap[x][y].element : undefined; } - } - } - } - } -function reduceToSign(num) { - if(num == 0){return 0;} - return num && num / Math.abs(num); -} -let prevNum; -elements.etemper = { - name: "E-Temper", - category: "machines", - conduct: 1, - insulate: true, - behavior: behaviors.WALL, - onSelect: function(pixel){ - prevNum = parseInt(prompt("Enter the temperature you want it set to.", (prevNum || undefined))); - }, - tick: function(pixel){ - if(pixel.start === pixelTicks){ - pixel.clone = `Temp: ${prevNum}`; - pixel.Temp = prevNum; - } - for (var i = 0; i < adjacentCoords.length; i++){ - let x = pixel.x + adjacentCoords[i][0]; - let y = pixel.y + adjacentCoords[i][1]; - if(outOfBounds(x,y)){ continue; } - if(isEmpty(x,y)){ continue; } - let pixel2 = pixelMap[x][y]; - if(reduceToSign(pixel.Temp) == -1){ - if (pixel2.temp > pixel.Temp && pixel.charge > 0 ){ - pixel2.temp += pixel.Temp / 6; - } - } else { - if (pixel2.temp < pixel.Temp && pixel.charge > 0 ){ - pixel2.temp += pixel.Temp / 6; - } - } - } - }, -} -let prevString; -elements.sign = { - name: "Sign", - category: "machines", - onSelect: function(){ - prevString = prompt("Enter the text you want it to say.", (prevString || undefined)); - }, - tick: function(pixel){ - if(pixel.start == pixelTicks){ - pixel.clone = prevString; - } - } -} -let attrElem = ""; -let magnetRange = 0; -let magnetElems = []; -let magnetPixels = []; -elements.magnet = { - category: "machines", - tick:function(pixel){ - if(pixelTicks == pixel.start){ - if(attrElem.includes(" ")){attrElem.replace(/s/g, "")} - pixel.elem = (attrElem.includes(",")) ? attrElem.split(",") : attrElem; - pixel.range = magnetRange; - } - let range = mouseRange(pixel.x, pixel.y, pixel.range) - for (var i = 0; i < currentPixels.length; i++){ - if(pixelInRange(currentPixels[i], range)){ - let pixel2 = currentPixels[i] - if(!magnetPixels.includes(pixel2)){ - magnetPixels.push(pixel2); - } - if(!pixel2.drag && pixel.elem.includes(pixel2.element)){pixel2.drag = true} - if(pixel2.drag && !pixel.elem.includes(pixel2.element) && !beamPixels.includes(pixel2) && ((draggingPixels && draggingPixels.includes(pixel2)) || !draggingPixels)){pixel2.drag = false;} - if(!magnetElems.includes(pixel2) && pixel.elem.includes(pixel2.element)){magnetElems.push(pixel2)} - if(pixel.elem.includes(pixel2.element)){ - (pixel2.x > pixel.x) ? tryMove(pixel2, pixel2.x - 1, pixel2.y, undefined, true) : tryMove(pixel2, pixel2.x + 1, pixel2.y, undefined, true); - (pixel2.y > pixel.y) ? tryMove(pixel2, pixel2.x, pixel2.y - 1, undefined, true) : tryMove(pixel2, pixel2.x, pixel2.y + 1, undefined, true); - } - } else if (draggingPixels && !draggingPixels.includes(currentPixels[i])){ - currentPixels[i].drag = false; - } - } - for(var i = 0; i < magnetPixels.length; i++){ - if(magnetPixels.length != 0){ - if(!pixel.elem.includes(magnetPixels[i].element)){ - magnetPixels[i].drag = false; - magnetPixels.splice(i, 1); - } - if(!pixelInRange(magnetPixels[i], range)){ - magnetPixels[i].drag = false; - magnetPixels.splice(i, 1); - } - } - } - }, - onSelect: function(){ - attrElem = prompt("Enter the element you want to attract.", (attrElem || undefined)); - magnetRange = parseInt(prompt("Enter the range you want to attract " + attrElem + " to.", (magnetRange || undefined))); - } -} -let move = false; -let moves = { - a: [-1,0], - d: [1,0], - s: [0,1], - w: [0,-1] -} -let UFOs = []; -let beamPixels = []; -let a = adjacentCoords; -function randomString(length){ - let str = ""; - let chars = "abcdefghijklmnopqrstuvwxyz"; - let charArr = chars.split(""); - for(var i = 0; i < length; i++){ - str += charrArr[Math.floor(Math.random() * charArr.length)]; - } - return str; -} -elements.ufo = { - category: "machines", - behavior: behaviors.WALL, - properties: { - cooldown: 0, - }, - tick: function(pixel){ - if(!UFOs.includes(pixel)){ UFOs = []; UFOs.push(pixel); } - if(move){ - tryMove(pixel, pixel.x + move[0], pixel.y + move[1]) - } - }, - hardness: 1, - insulate: true, -} -let keysDown = {}; -document.addEventListener("keydown", function(event){ - if(moves[event.key.toLowerCase()]){ - move = moves[event.key.toLowerCase()]; - } - keysDown[event.key.toLowerCase()] = true; - if(event.key.toLowerCase() == "b"){ - for(var i = 0; i < UFOs.length; i++){ - if(isEmpty(UFOs[i].x, UFOs[i].y+1) && !outOfBounds(UFOs[i].x, UFOs[i].y+1)){ - createPixel("heat_ray", UFOs[i].x, UFOs[i].y+1); - } - } - } - if(event.key.toLowerCase() == "q"){ - for(var i = 0; i < UFOs.length; i++){ - if(isEmpty(UFOs[i].x, UFOs[i].y+1) && !outOfBounds(UFOs[i].x, UFOs[i].y+1)){ - for(var ii = 0; ii < adjacentCoords.length; ii++){ - let x = UFOs[i].x + adjacentCoords[ii][0]; - let y = UFOs[i].y + adjacentCoords[ii][1]; - if(event.shiftKey){ - explodeAt(x, y, 10) - } else { - explodeAt(x, y, 4); - } - } - } - } - } - if(event.key.toLowerCase() == "x"){ - for(var i = 0; i < UFOs.length; i++){ - for(var ii = 0; ii < currentPixels.length; ii++){ - if([UFOs[i].x].includes(currentPixels[ii].x) && currentPixels[ii].y > UFOs[i].y){ - if(isEmpty(currentPixels[ii].x, currentPixels[ii].y - 1) && !outOfBounds(currentPixels[ii].x, currentPixels[ii].y - 1)){ - beamPixels.push(currentPixels[ii]); - currentPixels[ii].drag = true; - movePixel(currentPixels[ii], currentPixels[ii].x, currentPixels[ii].y - 1); + if(neighbors.includes("air") && pixel.temp < 50 && Math.random() < 0.00035){ + pixel.anhydrous = false; + } else if (neighbors.includes("steam") || neighbors.includes("water") || neighbors.includes("salt_water") || neighbors.includes("sugar_water") || neighbors.includes("dirty_water") || neighbors.includes("seltzer") || neighbors.includes("pool_water") || neighbors.includes("slush")){ + pixel.anhydrous = false; } - } - } - } - } - if(event.key.toLowerCase() == "g"){ - for(var i = 0; i < UFOs.length; i++){ - pixel = UFOs[i]; - for (var ii = 0; i < adjacentCoords.length; ii++){ - let x = pixel.x + a[ii][0]; - let y = pixel.y + a[ii][1]; - if(!isEmpty(x, y) && !outOfBounds(x, y)){ - let pixel2 = pixelMap[x][y]; - if(elements[pixel2.element].breakInto){ - if(typeof elements[pixel2.element].breakInto == "object"){ - changePixel(pixel2, elements[pixel2.element].breakInto[Math.floor(Math.random() * elements[pixel2.element].breakInto.length)]); + } +} +document.addEventListener("keydown", (e)=>{xDown = (e.key.toLowerCase() == "x") ? true : xDown;}); +document.addEventListener("keyup", (e)=>{xDown = (e.key.toLowerCase() == "x") ? false : xDown;}); + +elements.toggle_cloner = { + category: "machines", + active: "#fbff03", + inactive: "#333300", + color: "#333300", + name: "ToggleableCloner", + keyInput: "chance", + properties: { + clone: null, + toggle: false, + chance: 0.0166666667, + clickCd: 0, + }, + ignore: ["cloner", "toggle_cloner", "floating_cloner", "clone_powder", "slow_cloner", "ecloner", "destroyable_cloner", "destroyable_clone_powder", "ewall", "wall"], + onClicked: function(pixel,element){ + + if(pixel.clone == null && pixel.clickCd == 0 && dragStart == null){ + pixel.clone = (element == "unknown" || elements.toggle_cloner.ignore.includes(element)) ? pixel.clone : element; + } else if (pixel.clickCd == 0) { + pixel.toggle = !pixel.toggle; + if(pixel.toggle){ + let rgb = hexToRGB(elements.toggle_cloner.active); + let num = 5 - (Math.random()*10); + for(let key in rgb){ + rgb[key] += num; + rgb[key] = Math.round(Math.max(Math.min(rgb[key], 255), 0)); + } + pixel.color = `rgb(${rgb.r},${rgb.g},${rgb.b})`; } else { - changePixel(pixel2, elements[pixel2.element].breakInto); + let rgb = hexToRGB(elements.toggle_cloner.inactive); + let num = 5 - (Math.random()*10); + for(let key in rgb){ + rgb[key] += num; + rgb[key] = Math.round(Math.max(Math.min(rgb[key], 255), 0)); + } + pixel.color = `rgb(${rgb.r},${rgb.g},${rgb.b})`; } - } } - } - } - } - if(event.key.toLowerCase() == "j"){ - for(var i = 0; i < UFOs.length; i++){ - pixel = UFOs[i]; - for (var ii = 0; i < adjacentCoords.length; ii++){ - let x = pixel.x + a[ii][0]; - let y = pixel.y + a[ii][1]; - if(!isEmpty(x, y) && !outOfBounds(x, y) && elements[pixelMap[x][y].element].conduct > 0){ - pixelMap[x][y].charge = 1; + + if(pixel.clickCd == 0 && dragStart == null){ + pixel.clickCd = 20; + console.log(element); + }; + }, + onSelect: function(){ + logMessage("Click on the pixel while adjacent to a clonable pixel to set clone, then click on it to toggle on or off."); + }, + tick: function(pixel){ + if(pixel.clickCd > 0){pixel.clickCd--;} + if(![null, undefined].includes(pixel.clone) && pixel.toggle == true && Math.random() < pixel.chance){ + for(let coords of adjacentCoords){ + let x = pixel.x+coords[0], y = pixel.y+coords[1]; + if(isEmpty(x,y) && !outOfBounds(x,y)){ + createPixel(pixel.clone, x, y); + } + } } - } - } - } - if(event.key.toLowerCase() == "v"){ - for(var i = 0; i < UFOs.length; i++){ - let pixel = UFOs[i]; - let x = pixel.x - for (var y = pixel.y + 1; y < height; y++) { - if (outOfBounds(x, y)) { - break; - } - if (isEmpty(x, y)) { - if (Math.random() > 0.05) { continue } - createPixel("flash", x, y); - pixelMap[x][y].color = "#032dff"; - pixelMap[x][y].temp = -3500; - } - else { - if (elements[pixelMap[x][y].element].isGas) { continue } - if (elements[pixelMap[x][y].element].id === elements.heat_ray.id) { break } - pixelMap[x][y].temp -= 10; - pixelTempCheck(pixelMap[x][y]); - break; - } - } - } - } - if(event.key.toLowerCase() == "t"){ - for(var i = 0; i < UFOs.length; i++){ - for(var ii = 0; ii < adjacentCoords.length; ii++){ - let x = UFOs[i].x + adjacentCoords[ii][0]; - let y = UFOs[i].y + adjacentCoords[ii][1]; - if(x == pixel.x || y == pixel.y) {continue;} - if(!outOfBounds(x,y) && !isEmpty(x,y)){ - if(pixelMap[x][y].element == "ufo"){continue;} - deletePixel(x,y); - + for(let coords of adjacentCoords){ + let x = pixel.x+coords[0], y = pixel.y+coords[1]; + let p2 = getPixel(x,y); + if(p2 != null && p2.element == pixel.element && (p2.clone == null && pixel.clone != null)){ + p2.clone = pixel.clone; + } + } + } +}; + +elements.toggle = { + category: "machines", + active: "#b8b8b8", + inactive: "#2b2b2b", + color: "#2b2b2b", + properties: { + toggle: false, + clickCd: 0, + }, + onClicked: function(pixel){ + if(pixel.clickCd == 0 && dragStart == null){ + pixel.toggle = !pixel.toggle; + pixel.clickCd = 20; + if(pixel.toggle){ + let rgb = hexToRGB(elements.toggle.active); + let num = 5 - (Math.random()*10); + for(let key in rgb){ + rgb[key] += num; + rgb[key] = Math.round(Math.max(Math.min(rgb[key], 255), 0)); + } + pixel.color = `rgb(${rgb.r},${rgb.g},${rgb.b})`; + } else { + let rgb = hexToRGB(elements.toggle.inactive); + let num = 5 - (Math.random()*10); + for(let key in rgb){ + rgb[key] += num; + rgb[key] = Math.round(Math.max(Math.min(rgb[key], 255), 0)); + } + pixel.color = `rgb(${rgb.r},${rgb.g},${rgb.b})`; + } + }; + }, + tick: function(pixel){ + if(pixel.clickCd != 0){pixel.clickCd--;} + for(let coords of adjacentCoords){ + let x = pixel.x+coords[0], y = pixel.y+coords[1]; + let p2 = getPixel(x,y); + if(p2 != null && elements[p2.element].conduct == 1 && pixel.toggle){ + p2.charge = 1; + } } - } } - } -}) -function isArray(item) { - return Object.prototype.toString.call(item) === '[object Array]'; } -document.addEventListener("keyup", function(event){ - keysDown[event.key.toLowerCase()] = false; - if(moves[event.key.toLowerCase()] && move){ - move = false; - } - if(event.key.toLowerCase() == "x"){ - for(var i = 0; i < beamPixels.length; i++){ - beamPixels[i].drag = false; - } - beamPixels = []; - } -}) -function deletePixel(x,y) { - // remove pixelMap[x][y] from currentPixels - currentPixels.splice(currentPixels.indexOf(pixelMap[x][y]),1); - if(UFOs.includes(pixelMap[x][y])){ - UFOs.splice(UFOs.indexOf(pixelMap[x][y]),1) - } - if (pixelMap[x][y]) {pixelMap[x][y].del = true;} - delete pixelMap[x][y]; + + +elements.toggle_temper = { + active: "#ff7b00", + inactive: "#261200", + color: "#261200", + category: "machines", + targetTemp: 25, + keyInput: "targetTemp", + properties: { + toggle: false, + clickCd: 0, + targetTemp: null, + }, + onClicked: function(pixel){ + if(pixel.clickCd == 0 && dragStart == null){ + pixel.toggle = !pixel.toggle; + pixel.clickCd = 20; + if(pixel.toggle){ + let rgb = hexToRGB(elements.toggle_temper.active); + let num = 5 - (Math.random()*10); + for(let key in rgb){ + rgb[key] += num; + rgb[key] = Math.round(Math.max(Math.min(rgb[key], 255), 0)); + } + pixel.color = `rgb(${rgb.r},${rgb.g},${rgb.b})`; + } else { + let rgb = hexToRGB(elements.toggle_temper.inactive); + let num = 5 - (Math.random()*10); + for(let key in rgb){ + rgb[key] += num; + rgb[key] = Math.round(Math.max(Math.min(rgb[key], 255), 0)); + } + pixel.color = `rgb(${rgb.r},${rgb.g},${rgb.b})`; + } + }; + }, + onSelect: function(){ + promptInput("Enter the target temperature:", (In)=>{ + this.targetTemp = parseInt(In) || this.targetTemp; + }, "Temperature Selector", this.targetTemp); + }, + tick: function(pixel){ + if(pixel.targetTemp == null){ + pixel.targetTemp = this.targetTemp; + } + for(let coords of adjacentCoords){ + let x = pixel.x+coords[0], y = pixel.y+coords[1]; + let p2 = getPixel(x,y); + if(p2 != null && pixel.toggle){ + let difference = pixel.targetTemp-p2.temp; + p2.temp += difference/4; + } + } + if(pixel.clickCd > 0){pixel.clickCd--;}; + }, } -setInterval(function(){ - for(var i = 0; i < currentPixels.length; i++){ - for(var ii = 0; ii < UFOs.length; ii++){ - if(beamPixels.includes(currentPixels[i]) && currentPixels[i].x != UFOs[ii].x && !keysDown.x){ - beamPixels.splice(beamPixels.indexOf(currentPixels[i]), 1); - currentPixels[i].drag = false; - } - else if (currentPixels[i].x != UFOs[ii].x && beamPixels.includes(currentPixels[i])){ - (currentPixels[i].x > UFOs[ii].x) ? null : null; - } + +elements.multitool = { + category: "tools", + input: 0, + onSelect: function(){ + promptInput("Multitool for morechemistry.js, changes key values for different elements added in morechemistry.js, chance for toggleable cloner, and targetTemp for toggleable temper.", (In)=>{ + this.input = parseFloat(In) || 0; + }, "Multitool Input", this.input); + }, + tool: function(pixel){ + pixel[elements[pixel.element].keyInput] = this.input; + }, + canPlace: false, +} + +class rangeTool { + constructor(color, func, properties = false, onSelect = false, onClicked = false){ + this.category = "machines"; + this.properties = (properties == false) ? { range: null } : properties; + this.color = color; + this.range = 0; + this.onSelect = (onSelect == false) ? ()=>{promptInput("Enter the range for this tool: ", (range)=>{this.range = parseInt(range);}, "Tool Range", this.range)} : onSelect; + this.onClicked = (onClicked == false) ? undefined : onClicked; + this.func = func; } - if(currentPixels[i].drag && !beamPixels.includes(currentPixels[i])){ - if(draggingPixels && !draggingPixels.includes(currentPixels[i])){ - if(!magnetElems.includes(currentPixels[i])){ - currentPixels.drag = false; + tick = function(pixel){ + if(pixel.range == null){ + pixel.range = elements[pixel.element].range; + } else { + let pixelRange = mouseRange(pixel.x, pixel.y, pixel.range); + for(let coords of pixelRange){ + let p2 = getPixel(coords[0], coords[1]); + if(p2 != null){ + elements[pixel.element].func(p2); + } + } } - } else if(!draggingPixels){ - if(!magnetElems.includes(currentPixels[i])){ - currentPixels[i].drag = false; - } - } else if (draggingPixels && draggingPixels.includes(currentPixels[i])){ - continue; - } } - } -}, 1000/tps) -runAfterLoad(function(){ - document.body.insertAdjacentHTML("beforeend",` - these are all properties of the pixel. another way to find pixel properties is using debug on a pixel, it will tell you the property and the value, like x and y, or, in plants.js, fruit. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Variable - - Definition -
- p.color - - The color of the pixel. it is defined as an RGB value. -
- p.x and p.y - - The x and y positions of the pixel. -
- p.element - - The element of the pixel. -
- p.clone - - Specific to cloners, specifies what the cloner clones. -
- wc and lc - - Specific to saplings, specifies what colour the wood is (wc) and what colour the leaves are (lc). -
- p.start - - The start tick of the pixel. -
- p.tick - - the amount of ticks that have happened so far in the game. -
-

Paste function code for the prop machine in the text area below, typing doesnt work well.

- - - `); +} + +elements.toggle_mixer = new rangeTool("#212420", (pixel)=>{ + let range = mouseRange(pixel.x, pixel.y, pixel.range); + let pixels = []; + for(let coords of range){ + let p2 = getPixel(coords[0], coords[1]); + if(p2 != null && pixel.toggle){ + pixels.push(p2); + } + } + for(let p of pixels){ + if(Math.random() < pixel.chance){ + let p2 = pixels[Math.round(Math.random()*pixels.length)]; + if(p != undefined && p2 != undefined && elements[p.element].movable && elements[p2.element].movable){ + swapPixels(p, p2); + if(elements[p.element].onMix != undefined){ + elements[p.element].onMix(p); + } + if(elements[p2.element].onMix != undefined){ + elements[p2.element].onMix(p2); + } + } + } + } + if(pixel.clickCd > 0){pixel.clickCd--;} +}, {range: null, toggle: false, clickCd: 0, chance: 0.35}, false, (pixel)=>{ + if(pixel.clickCd == 0 && dragStart == null){ + pixel.toggle = !pixel.toggle; + pixel.clickCd = 20; + if(pixel.toggle){ + let rgb = hexToRGB(elements.toggle_mixer.active); + let num = 5 - (Math.random()*10); + for(let key in rgb){ + rgb[key] += num; + rgb[key] = Math.round(Math.max(Math.min(rgb[key], 255), 0)); + } + pixel.color = `rgb(${rgb.r},${rgb.g},${rgb.b})`; + } else { + let rgb = hexToRGB(elements.toggle_mixer.inactive); + let num = 5 - (Math.random()*10); + for(let key in rgb){ + rgb[key] += num; + rgb[key] = Math.round(Math.max(Math.min(rgb[key], 255), 0)); + } + pixel.color = `rgb(${rgb.r},${rgb.g},${rgb.b})`; + } + }; }); +elements.toggle_mixer.inactive = "#212420", elements.toggle_mixer.active = "#93a390", elements.toggle_mixer.movable = false, elements.toggle_mixer.keyInput = "chance"; + +elements.toggle_smasher = new rangeTool("#2e2726", (pixel)=>{ + let range = mouseRange(pixel.x, pixel.y, pixel.range); + for(let coords of range){ + let p2 = getPixel(coords[0], coords[1]); + if(p2 != null && pixel.toggle && Math.random() < pixel.chance && elements[p2.element].breakInto != undefined){ + let elem = (Array.isArray(elements[p2.element].breakInto)) ? elements[p2.element].breakInto[Math.round(Math.random()*elements[p2.element].breakInto.length)] : elements[p2.element].breakInto; + if(elem != undefined){ + changePixel(p2, elem); + } + } + } + if(pixel.clickCd > 0){pixel.clickCd--;} +}, {range: null, toggle: false, clickCd: 0, chance: 0.35}, false, (pixel)=>{ + if(pixel.clickCd == 0 && dragStart == null){ + pixel.toggle = !pixel.toggle; + pixel.clickCd = 20; + if(pixel.toggle){ + let rgb = hexToRGB(elements.toggle_smasher.active); + let num = 5 - (Math.random()*10); + for(let key in rgb){ + rgb[key] += num; + rgb[key] = Math.round(Math.max(Math.min(rgb[key], 255), 0)); + } + pixel.color = `rgb(${rgb.r},${rgb.g},${rgb.b})`; + } else { + let rgb = hexToRGB(elements.toggle_smasher.inactive); + let num = 5 - (Math.random()*10); + for(let key in rgb){ + rgb[key] += num; + rgb[key] = Math.round(Math.max(Math.min(rgb[key], 255), 0)); + } + pixel.color = `rgb(${rgb.r},${rgb.g},${rgb.b})`; + } + }; +}); +elements.toggle_smasher.inactive = "#2e2726", elements.toggle_smasher.active = "#bf9e9b", elements.toggle_smasher.movable = false, elements.toggle_smasher.keyInput = "chance"; From 0d5b1e899c1ff8c46eeb9d22d46a40b3e6dc9c0d Mon Sep 17 00:00:00 2001 From: Alexthetransfem <124483815+theenchantedsword@users.noreply.github.com> Date: Fri, 18 Jul 2025 16:23:15 -0500 Subject: [PATCH 02/13] Update worldgenlibrary.js --- mods/worldgenlibrary.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mods/worldgenlibrary.js b/mods/worldgenlibrary.js index 5fe60643..11d22465 100644 --- a/mods/worldgenlibrary.js +++ b/mods/worldgenlibrary.js @@ -1,3 +1,6 @@ +/* +Version 1.1.0 +*/ Array.prototype.getClosest = function(num){ let arr = []; for(value of this){ @@ -129,7 +132,7 @@ elements.generate = { b[b.length] = key; } } - promptInput("There are the following biomes available: \n"+ b.join(", "), (out)=>{ + promptChoose("", b, (out)=>{ if(biomes[out] == undefined){ alert("Invalid Selection."); } else { @@ -138,7 +141,7 @@ elements.generate = { elements.generate.default = out; selectElement("dirt"); } - }, "Enter biome to generate: ", elements.generate.default); + }, "Select a biome to generate: "); } } for(item of enabledMods){ From 7f55db27d7fffc97880a9c75e043dd7e4aa5904f Mon Sep 17 00:00:00 2001 From: Alexthetransfem <124483815+theenchantedsword@users.noreply.github.com> Date: Fri, 18 Jul 2025 16:24:59 -0500 Subject: [PATCH 03/13] Update plants.js --- mods/plants.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mods/plants.js b/mods/plants.js index 89a5992b..1921fc97 100644 --- a/mods/plants.js +++ b/mods/plants.js @@ -1,3 +1,6 @@ +/* +Version 2.1.0 +*/ let is2d = (arr)=>{ return arr.some(item => Array.isArray(item)); } From fb147d585c92ab2c3b71af3b6c2a08c3b1c49a08 Mon Sep 17 00:00:00 2001 From: Cube14yt Date: Sat, 19 Jul 2025 14:22:58 +0800 Subject: [PATCH 04/13] new mods --- cubesstuff.js | 160 ++++++++++++++++++++++++++++++++++++++ fans.js | 211 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 371 insertions(+) create mode 100644 cubesstuff.js create mode 100644 fans.js diff --git a/cubesstuff.js b/cubesstuff.js new file mode 100644 index 00000000..b7765d6f --- /dev/null +++ b/cubesstuff.js @@ -0,0 +1,160 @@ +//broken rn dont know how to fix it yet +/* +elements.button = { + color: "#970000", + conduct: 1, + charge: 0, + category: "machines", + onSelect: function () { + logMessage("Click the button with no elements equipped to charge the button.") + }, + properties: { + clicked: false, + clickTime: 1, + }, + onClicked: function (pixel) { + pixel.clicked = true + pixel.clickTime = 1 + }, + tick: function (pixel) { + if (pixel.clicked == true && pixel.clickTime > 0) { + pixel.charge = 1 + pixel.clickTime-- + } + else if (pixel.clicked == true && pixel.clickTime <= 0) { + pixel.clicked = false + pixel.charge = 0 + } + } +} +*/ +elements.aerogel = { + color: "#79ffff", + category: "solids", + behavior: behaviors.WALL, + state: "solid", + tempHigh: 1200, + stateHigh: "ash", + insulate: true, + density: 0.2, + hardness: 0.1, + breakInto: "dust", + onPlace: function (pixel) { + if (pixel.alpha === undefined) { pixel.alpha = Math.random() * (0.5 - 0.4) + 0.4 } + } +} + +let oldCopperReactions = elements.copper.reactions +elements.molten_copper.reactions.molten_aluminum = { elem1: "molten_nordic_gold", elem2: null, chance: 0.5 } +elements.acid.ignore.push("nordic_gold") +elements.acid.ignore.push("nordic_gold_coin") + +elements.nordic_gold = { + color: ["#f1db7c", "#e5c34b", "#d2a742", "#b98c31", "#a47320"], + tempHigh: 1060, + behavior: behaviors.WALL, + category: "solids", + state: "solid", + density: 8800, + conduct: 0.90, + breakInto: "nordic_gold_coin" +} + +elements.nordic_gold_coin = { + color: ["#f1db7c", "#e5c34b", "#d2a742", "#b98c31", "#a47320"], + tempHigh: 1060, + stateHigh: "molten_nordic_gold", + behavior: behaviors.POWDER, + category: "powders", + state: "solid", + density: 8800, + conduct: 0.90, + alias: "euro_coin", + reactions: { + "glue": { elem1: "nordic_gold", elem2: null } + } +} + +function randomColor() { + const letters = "0123456789ABCDEF"; + let color = "#"; + for (let i = 0; i < 6; i++) { + color += letters[Math.floor(Math.random() * 16)]; + } + return color; +} + +elements.disco_ball = { + color: "#ebebc3", + buttonColor: ["#ff0000", "#ff8800", "#ffff00", "#00ff00", "#00ffff", "#0000ff", "#ff00ff"], + renderer: renderPresets.LED, + behavior: behaviors.WALL, + category: "machines", + tempHigh: 1500, + stateHigh: ["molten_glass", "molten_glass", "molten_copper"], + conduct: 1, + breakInto: "glass_shard", + forceSaveColor: true, + tick: function (pixel) { + for (var i = 0; i < squareCoords.length; i++) { + var coord = squareCoords[i]; + var x = pixel.x + coord[0]; + var y = pixel.y + coord[1]; + if (pixel.charge > 0) { + pixel.color = randomColor() + if (isEmpty(x, y)) { + createPixel("light", x, y) + let p = getPixel(x, y) + if (p !== null && p.element == "light") { + p.color = pixel.color + } + } + } + else { pixel.color = "#ebebc3" } + } + } +} + +elements.molten_iron.reactions.sulfur = { elem1: "pyrite", elem2: null, chance: 0.25 } +elements.molten_iron.reactions.molten_sulfur = { elem1: "pyrite", elem2: null, chance: 0.25 } +elements.molten_iron.reactions.sulfur_gas = { elem1: "pyrite", elem2: null, chance: 0.25 } + +elements.pyrite = { + color: ["#d8c25e", "#bbaa49", "#998f3e"], + alias: ["fools_gold", "Iron Disulfide"], + density: 5000, + tempHigh: 1177, + stateHigh: ["iron", "molten_sulfur"], + grain: 0.4, + state: "solid", + behavior: behaviors.WALL, + category: "solids" +} + +elements.fire_extinguisher_powder = { + color: "#ececec", + behavior: [ + "XX|XX|XX", + "XX|DL%1|XX", + "M2%30|M1%30|M2%30" + ], + extinguish: true, + tick: function (pixel) { + for (var i = 0; i < adjacentCoords.length; i++) { + var coords = adjacentCoords[i]; + var x = pixel.x + coords[0]; + var y = pixel.y + coords[1]; + if (getPixel(x, y)?.burning === true) { + let elem = getPixel(x, y) + elem.burning = false + } + } + }, + tool: function(pixel) { + if(pixel.burning === true){ + delete pixel.burning; + delete pixel.burnStart; + } + }, + canPlace: true +} \ No newline at end of file diff --git a/fans.js b/fans.js new file mode 100644 index 00000000..a3bf07ad --- /dev/null +++ b/fans.js @@ -0,0 +1,211 @@ +function getSelfMovingBehaviorFunctionNames() { + return Object.entries(behaviors) + .filter(([name, func]) => { + if (typeof func !== "function") return false; + if (["SEEDRISE"].includes(name)) return false; + + const code = func.toString(); + + // Only allow if it's moving its own pixel + const selfMove = /movePixel\s*\(\s*pixel\s*,/.test(code) || /tryMove\s*\(\s*pixel\s*,/.test(code) + || /pixel\.(x|y)\s*[\+\-]=/.test(code); + + return selfMove; + }) + .map(([name]) => name); +} + +const builtInMovementBehaviors = [ + "M1", "M2","BO", "SP", "XX|M1", "M1|M2", "M1%", "M2%", "M1%|M2", + "M1|M2%", "M1%|M2%", 'XX|M1%', 'M1%|XX', 'XX|M2%', 'M2%|XX' +]; + +function behaviorIncludesMovement(behaviorMatrix, movementFunctionNames) { + if (!Array.isArray(behaviorMatrix)) return false; + + for (const row of behaviorMatrix) { + if (!Array.isArray(row)) continue; + + for (const cell of row) { + if (typeof cell !== "string") continue; + + // Handle "AND" logic: multiple behaviors in one cell + const andParts = cell.split("AND"); + + for (const andPart of andParts) { + const parts = andPart.trim().split("|").map(p => p.trim()); + if (parts.some(p => builtInMovementBehaviors.includes(p) || movementFunctionNames.includes(p))) { + return true; + } + } + } + } + + return false; +} + + +runAfterAutogen(function () { + const movementFunctionNames = getSelfMovingBehaviorFunctionNames(); + + const movableElements = Object.entries(elements).filter(([name, elem]) => { + const behavior = elem.behavior; + const tick = elem.tick || elem.tickFunc; + + let movesSelf = false; + + // Check behavior matrix + if (Array.isArray(behavior)) { + movesSelf = behaviorIncludesMovement(behavior, movementFunctionNames); + } + + // Check single string + else if (typeof behavior === "string") { + const parts = behavior.split("|").map(p => p.trim()); + movesSelf = parts.some(p => builtInMovementBehaviors.includes(p) || movementFunctionNames.includes(p)); + } + + // Check function-type behavior + else if (typeof behavior === "function") { + movesSelf = movementFunctionNames.includes(behavior.name); + } + + // Check tick function + if (!movesSelf && typeof tick === "function") { + const code = tick.toString(); + if (/movePixel\s*\(\s*pixel\s*,/.test(code) || /tryMove\s*\(\s*pixel\s*,/.test(code) || /pixel\.(x|y)\s*[\+\-]=/.test(code)) { + movesSelf = true; + } + } + + return movesSelf; + }).map(([name]) => name); + + console.log("🚶 Self-Moving Elements:", movableElements); + window.movableElementsByBehavior = movableElements; +}); + + + + + + +runAfterAutogen(function () { + console.log(behaviors) +}) + +// Create a global map to track delay for each position +if (!window.fanPushDelays) { + window.fanPushDelays = new Map(); +} + +elements.fan_right = { + behavior: behaviors.WALL, + color: "#c5c5c5", + tick: function (pixel) { + const fan_strength = 10; + const delay_ticks = 2; + + for (let i = 1; i <= fan_strength; i++) { + const x = pixel.x + i; + const y = pixel.y; + + // SKIP if position is empty + if (isEmpty(x, y)) continue; + + const delem = pixelMap[x]?.[y]; + if (!delem) continue; + + // Skip non-movable elements + if (!window.movableElementsByBehavior.includes(delem.element)) continue; + + // Use position key for delay tracking + const key = `${x},${y}`; + const currentDelay = window.fanPushDelays.get(key) || 0; + + if (currentDelay >= delay_ticks) { + window.fanPushDelays.set(key, 0); + + const newX = x + 1; + if (isEmpty(newX, y)) { + movePixel(delem, newX, y); + } + } else { + window.fanPushDelays.set(key, currentDelay + 1); + } + } + }, + category: "machines" +}; + +elements.fan_left = { + behavior: behaviors.WALL, + color: "#c5c5c5", + tick: function (pixel) { + const fan_strength = 10; + const delay_ticks = 2; + + for (let i = 0; i >= -fan_strength; i--) { + const x = pixel.x + i; + const y = pixel.y; + + // SKIP if position is empty + if (isEmpty(x, y)) continue; + + const delem = pixelMap[x]?.[y]; + if (!delem) continue; + + // Skip non-movable elements + if (!window.movableElementsByBehavior.includes(delem.element)) continue; + + // Use position key for delay tracking + const key = `${x},${y}`; + const currentDelay = window.fanPushDelays.get(key) || 0; + + if (currentDelay >= delay_ticks) { + window.fanPushDelays.set(key, 0); + + const newX = x - 1; + if (isEmpty(newX, y)) { + movePixel(delem, newX, y); + } + } else { + window.fanPushDelays.set(key, currentDelay + 1); + } + } + }, + category: "machines" +}; +/* +elements.fan_up = { + behavior: behaviors.WALL, + tick: function (pixel) { + let fan_strength = 10; + let delay_ticks = 0; // delay between pushes per pixel row + if (!pixel._fan_delay) pixel._fan_delay = 0; + + if (pixel._fan_delay > 0) { + pixel._fan_delay--; + return; + } + + for (let i = 1; i <= fan_strength; i++) { + const tx = pixel.x; + const ty = pixel.y - i; + + if (!isEmpty(tx, ty)) { + const delem = pixelMap[tx]?.[ty]; + + if (!delem || !window.movableElementsByBehavior.includes(delem.element)) break; + + const above = ty - 1; + if (isEmpty(tx, above)) { + movePixel(delem, tx, above); + pixel._fan_delay = delay_ticks; + break; // only move one per tick + } + } + } + } +}; +*/ From 4cba583da6ba4bfb57d7268d02daa853059355f6 Mon Sep 17 00:00:00 2001 From: Cube14yt Date: Sat, 19 Jul 2025 14:40:53 +0800 Subject: [PATCH 05/13] add mods to mod list --- mod-list.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mod-list.html b/mod-list.html index 0141dd98..1a600cc9 100644 --- a/mod-list.html +++ b/mod-list.html @@ -246,6 +246,7 @@ conveyance.jsConveyors, operated with and without electricityMelecie drill.jsDrills made out of several materialsSuss ExtraMachines.jsSensors, energy resources, materials, and moreMecoolnotcool +fans.jsFansCube14yt fine_tuned_cloner.jsCloner that can spawn at different rates and prevent unwanted cloningBatteRaquette58 flipflop.jsToggleable switches [More Info]Flix fueled_generators.jsFuel powered generatorsguzzo86 @@ -356,6 +357,7 @@ bfdi.jsSeveral references to Battle for Dream IslandTaterbob citybuilding.jsSeeds that create miniature buildings and other city-related itemsSquareScreamYT collab_mod.jsCreated by multiple people, adds random thingsmrapple, ilikepizza, stefanblox +cubesstuff.jsSome random stuff like disco ball, pyrite, and nordic gold.Cube14yt doom.jsAs seen on TikTok - Select the Doom element to start [WASD to move]ggod elem3.jsAll elements and combinations from Elemental 3 [Very Large]Sophie explosionsound.jsSound effects for explosionsnousernamefound From 6dc479a733b42db5faee9ba20e4dd4ce31c10229 Mon Sep 17 00:00:00 2001 From: Cube14yt Date: Sat, 19 Jul 2025 14:42:09 +0800 Subject: [PATCH 06/13] moves fire extinguisher powder to powder category --- cubesstuff.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cubesstuff.js b/cubesstuff.js index b7765d6f..7fc272ba 100644 --- a/cubesstuff.js +++ b/cubesstuff.js @@ -156,5 +156,6 @@ elements.fire_extinguisher_powder = { delete pixel.burnStart; } }, - canPlace: true -} \ No newline at end of file + canPlace: true, + category: "powders" +} From 11c9dce3d4af13b4d614edb93d1b0b41570533c9 Mon Sep 17 00:00:00 2001 From: Cube14yt Date: Sun, 20 Jul 2025 10:48:58 +0800 Subject: [PATCH 07/13] Delete fans.js --- fans.js | 211 -------------------------------------------------------- 1 file changed, 211 deletions(-) delete mode 100644 fans.js diff --git a/fans.js b/fans.js deleted file mode 100644 index a3bf07ad..00000000 --- a/fans.js +++ /dev/null @@ -1,211 +0,0 @@ -function getSelfMovingBehaviorFunctionNames() { - return Object.entries(behaviors) - .filter(([name, func]) => { - if (typeof func !== "function") return false; - if (["SEEDRISE"].includes(name)) return false; - - const code = func.toString(); - - // Only allow if it's moving its own pixel - const selfMove = /movePixel\s*\(\s*pixel\s*,/.test(code) || /tryMove\s*\(\s*pixel\s*,/.test(code) - || /pixel\.(x|y)\s*[\+\-]=/.test(code); - - return selfMove; - }) - .map(([name]) => name); -} - -const builtInMovementBehaviors = [ - "M1", "M2","BO", "SP", "XX|M1", "M1|M2", "M1%", "M2%", "M1%|M2", - "M1|M2%", "M1%|M2%", 'XX|M1%', 'M1%|XX', 'XX|M2%', 'M2%|XX' -]; - -function behaviorIncludesMovement(behaviorMatrix, movementFunctionNames) { - if (!Array.isArray(behaviorMatrix)) return false; - - for (const row of behaviorMatrix) { - if (!Array.isArray(row)) continue; - - for (const cell of row) { - if (typeof cell !== "string") continue; - - // Handle "AND" logic: multiple behaviors in one cell - const andParts = cell.split("AND"); - - for (const andPart of andParts) { - const parts = andPart.trim().split("|").map(p => p.trim()); - if (parts.some(p => builtInMovementBehaviors.includes(p) || movementFunctionNames.includes(p))) { - return true; - } - } - } - } - - return false; -} - - -runAfterAutogen(function () { - const movementFunctionNames = getSelfMovingBehaviorFunctionNames(); - - const movableElements = Object.entries(elements).filter(([name, elem]) => { - const behavior = elem.behavior; - const tick = elem.tick || elem.tickFunc; - - let movesSelf = false; - - // Check behavior matrix - if (Array.isArray(behavior)) { - movesSelf = behaviorIncludesMovement(behavior, movementFunctionNames); - } - - // Check single string - else if (typeof behavior === "string") { - const parts = behavior.split("|").map(p => p.trim()); - movesSelf = parts.some(p => builtInMovementBehaviors.includes(p) || movementFunctionNames.includes(p)); - } - - // Check function-type behavior - else if (typeof behavior === "function") { - movesSelf = movementFunctionNames.includes(behavior.name); - } - - // Check tick function - if (!movesSelf && typeof tick === "function") { - const code = tick.toString(); - if (/movePixel\s*\(\s*pixel\s*,/.test(code) || /tryMove\s*\(\s*pixel\s*,/.test(code) || /pixel\.(x|y)\s*[\+\-]=/.test(code)) { - movesSelf = true; - } - } - - return movesSelf; - }).map(([name]) => name); - - console.log("🚶 Self-Moving Elements:", movableElements); - window.movableElementsByBehavior = movableElements; -}); - - - - - - -runAfterAutogen(function () { - console.log(behaviors) -}) - -// Create a global map to track delay for each position -if (!window.fanPushDelays) { - window.fanPushDelays = new Map(); -} - -elements.fan_right = { - behavior: behaviors.WALL, - color: "#c5c5c5", - tick: function (pixel) { - const fan_strength = 10; - const delay_ticks = 2; - - for (let i = 1; i <= fan_strength; i++) { - const x = pixel.x + i; - const y = pixel.y; - - // SKIP if position is empty - if (isEmpty(x, y)) continue; - - const delem = pixelMap[x]?.[y]; - if (!delem) continue; - - // Skip non-movable elements - if (!window.movableElementsByBehavior.includes(delem.element)) continue; - - // Use position key for delay tracking - const key = `${x},${y}`; - const currentDelay = window.fanPushDelays.get(key) || 0; - - if (currentDelay >= delay_ticks) { - window.fanPushDelays.set(key, 0); - - const newX = x + 1; - if (isEmpty(newX, y)) { - movePixel(delem, newX, y); - } - } else { - window.fanPushDelays.set(key, currentDelay + 1); - } - } - }, - category: "machines" -}; - -elements.fan_left = { - behavior: behaviors.WALL, - color: "#c5c5c5", - tick: function (pixel) { - const fan_strength = 10; - const delay_ticks = 2; - - for (let i = 0; i >= -fan_strength; i--) { - const x = pixel.x + i; - const y = pixel.y; - - // SKIP if position is empty - if (isEmpty(x, y)) continue; - - const delem = pixelMap[x]?.[y]; - if (!delem) continue; - - // Skip non-movable elements - if (!window.movableElementsByBehavior.includes(delem.element)) continue; - - // Use position key for delay tracking - const key = `${x},${y}`; - const currentDelay = window.fanPushDelays.get(key) || 0; - - if (currentDelay >= delay_ticks) { - window.fanPushDelays.set(key, 0); - - const newX = x - 1; - if (isEmpty(newX, y)) { - movePixel(delem, newX, y); - } - } else { - window.fanPushDelays.set(key, currentDelay + 1); - } - } - }, - category: "machines" -}; -/* -elements.fan_up = { - behavior: behaviors.WALL, - tick: function (pixel) { - let fan_strength = 10; - let delay_ticks = 0; // delay between pushes per pixel row - if (!pixel._fan_delay) pixel._fan_delay = 0; - - if (pixel._fan_delay > 0) { - pixel._fan_delay--; - return; - } - - for (let i = 1; i <= fan_strength; i++) { - const tx = pixel.x; - const ty = pixel.y - i; - - if (!isEmpty(tx, ty)) { - const delem = pixelMap[tx]?.[ty]; - - if (!delem || !window.movableElementsByBehavior.includes(delem.element)) break; - - const above = ty - 1; - if (isEmpty(tx, above)) { - movePixel(delem, tx, above); - pixel._fan_delay = delay_ticks; - break; // only move one per tick - } - } - } - } -}; -*/ From 431c702315b70aeb897ff8b7883eca44e634a69a Mon Sep 17 00:00:00 2001 From: Cube14yt Date: Sun, 20 Jul 2025 10:49:51 +0800 Subject: [PATCH 08/13] Delete cubesstuff.js --- cubesstuff.js | 161 -------------------------------------------------- 1 file changed, 161 deletions(-) delete mode 100644 cubesstuff.js diff --git a/cubesstuff.js b/cubesstuff.js deleted file mode 100644 index 7fc272ba..00000000 --- a/cubesstuff.js +++ /dev/null @@ -1,161 +0,0 @@ -//broken rn dont know how to fix it yet -/* -elements.button = { - color: "#970000", - conduct: 1, - charge: 0, - category: "machines", - onSelect: function () { - logMessage("Click the button with no elements equipped to charge the button.") - }, - properties: { - clicked: false, - clickTime: 1, - }, - onClicked: function (pixel) { - pixel.clicked = true - pixel.clickTime = 1 - }, - tick: function (pixel) { - if (pixel.clicked == true && pixel.clickTime > 0) { - pixel.charge = 1 - pixel.clickTime-- - } - else if (pixel.clicked == true && pixel.clickTime <= 0) { - pixel.clicked = false - pixel.charge = 0 - } - } -} -*/ -elements.aerogel = { - color: "#79ffff", - category: "solids", - behavior: behaviors.WALL, - state: "solid", - tempHigh: 1200, - stateHigh: "ash", - insulate: true, - density: 0.2, - hardness: 0.1, - breakInto: "dust", - onPlace: function (pixel) { - if (pixel.alpha === undefined) { pixel.alpha = Math.random() * (0.5 - 0.4) + 0.4 } - } -} - -let oldCopperReactions = elements.copper.reactions -elements.molten_copper.reactions.molten_aluminum = { elem1: "molten_nordic_gold", elem2: null, chance: 0.5 } -elements.acid.ignore.push("nordic_gold") -elements.acid.ignore.push("nordic_gold_coin") - -elements.nordic_gold = { - color: ["#f1db7c", "#e5c34b", "#d2a742", "#b98c31", "#a47320"], - tempHigh: 1060, - behavior: behaviors.WALL, - category: "solids", - state: "solid", - density: 8800, - conduct: 0.90, - breakInto: "nordic_gold_coin" -} - -elements.nordic_gold_coin = { - color: ["#f1db7c", "#e5c34b", "#d2a742", "#b98c31", "#a47320"], - tempHigh: 1060, - stateHigh: "molten_nordic_gold", - behavior: behaviors.POWDER, - category: "powders", - state: "solid", - density: 8800, - conduct: 0.90, - alias: "euro_coin", - reactions: { - "glue": { elem1: "nordic_gold", elem2: null } - } -} - -function randomColor() { - const letters = "0123456789ABCDEF"; - let color = "#"; - for (let i = 0; i < 6; i++) { - color += letters[Math.floor(Math.random() * 16)]; - } - return color; -} - -elements.disco_ball = { - color: "#ebebc3", - buttonColor: ["#ff0000", "#ff8800", "#ffff00", "#00ff00", "#00ffff", "#0000ff", "#ff00ff"], - renderer: renderPresets.LED, - behavior: behaviors.WALL, - category: "machines", - tempHigh: 1500, - stateHigh: ["molten_glass", "molten_glass", "molten_copper"], - conduct: 1, - breakInto: "glass_shard", - forceSaveColor: true, - tick: function (pixel) { - for (var i = 0; i < squareCoords.length; i++) { - var coord = squareCoords[i]; - var x = pixel.x + coord[0]; - var y = pixel.y + coord[1]; - if (pixel.charge > 0) { - pixel.color = randomColor() - if (isEmpty(x, y)) { - createPixel("light", x, y) - let p = getPixel(x, y) - if (p !== null && p.element == "light") { - p.color = pixel.color - } - } - } - else { pixel.color = "#ebebc3" } - } - } -} - -elements.molten_iron.reactions.sulfur = { elem1: "pyrite", elem2: null, chance: 0.25 } -elements.molten_iron.reactions.molten_sulfur = { elem1: "pyrite", elem2: null, chance: 0.25 } -elements.molten_iron.reactions.sulfur_gas = { elem1: "pyrite", elem2: null, chance: 0.25 } - -elements.pyrite = { - color: ["#d8c25e", "#bbaa49", "#998f3e"], - alias: ["fools_gold", "Iron Disulfide"], - density: 5000, - tempHigh: 1177, - stateHigh: ["iron", "molten_sulfur"], - grain: 0.4, - state: "solid", - behavior: behaviors.WALL, - category: "solids" -} - -elements.fire_extinguisher_powder = { - color: "#ececec", - behavior: [ - "XX|XX|XX", - "XX|DL%1|XX", - "M2%30|M1%30|M2%30" - ], - extinguish: true, - tick: function (pixel) { - for (var i = 0; i < adjacentCoords.length; i++) { - var coords = adjacentCoords[i]; - var x = pixel.x + coords[0]; - var y = pixel.y + coords[1]; - if (getPixel(x, y)?.burning === true) { - let elem = getPixel(x, y) - elem.burning = false - } - } - }, - tool: function(pixel) { - if(pixel.burning === true){ - delete pixel.burning; - delete pixel.burnStart; - } - }, - canPlace: true, - category: "powders" -} From 2d68bf9f48a472b7e69704f77d0cb552606c8100 Mon Sep 17 00:00:00 2001 From: Cube14yt Date: Sun, 20 Jul 2025 10:52:04 +0800 Subject: [PATCH 09/13] Add files via upload --- mods/cubesstuff.js | 161 ++++++++++++++++++++++++++++++++++ mods/fans.js | 211 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 372 insertions(+) create mode 100644 mods/cubesstuff.js create mode 100644 mods/fans.js diff --git a/mods/cubesstuff.js b/mods/cubesstuff.js new file mode 100644 index 00000000..0421591c --- /dev/null +++ b/mods/cubesstuff.js @@ -0,0 +1,161 @@ +//broken rn dont know how to fix it yet +/* +elements.button = { + color: "#970000", + conduct: 1, + charge: 0, + category: "machines", + onSelect: function () { + logMessage("Click the button with no elements equipped to charge the button.") + }, + properties: { + clicked: false, + clickTime: 1, + }, + onClicked: function (pixel) { + pixel.clicked = true + pixel.clickTime = 1 + }, + tick: function (pixel) { + if (pixel.clicked == true && pixel.clickTime > 0) { + pixel.charge = 1 + pixel.clickTime-- + } + else if (pixel.clicked == true && pixel.clickTime <= 0) { + pixel.clicked = false + pixel.charge = 0 + } + } +} +*/ +elements.aerogel = { + color: "#79ffff", + category: "solids", + behavior: behaviors.WALL, + state: "solid", + tempHigh: 1200, + stateHigh: "ash", + insulate: true, + density: 0.2, + hardness: 0.1, + breakInto: "dust", + onPlace: function (pixel) { + if (pixel.alpha === undefined) { pixel.alpha = Math.random() * (0.5 - 0.4) + 0.4 } + } +} + +let oldCopperReactions = elements.copper.reactions +elements.molten_copper.reactions.molten_aluminum = { elem1: "molten_nordic_gold", elem2: null, chance: 0.5 } +elements.acid.ignore.push("nordic_gold") +elements.acid.ignore.push("nordic_gold_coin") + +elements.nordic_gold = { + color: ["#f1db7c", "#e5c34b", "#d2a742", "#b98c31", "#a47320"], + tempHigh: 1060, + behavior: behaviors.WALL, + category: "solids", + state: "solid", + density: 8800, + conduct: 0.90, + breakInto: "nordic_gold_coin" +} + +elements.nordic_gold_coin = { + color: ["#f1db7c", "#e5c34b", "#d2a742", "#b98c31", "#a47320"], + tempHigh: 1060, + stateHigh: "molten_nordic_gold", + behavior: behaviors.POWDER, + category: "powders", + state: "solid", + density: 8800, + conduct: 0.90, + alias: "euro_coin", + reactions: { + "glue": { elem1: "nordic_gold", elem2: null } + } +} + +function randomColor() { + const letters = "0123456789ABCDEF"; + let color = "#"; + for (let i = 0; i < 6; i++) { + color += letters[Math.floor(Math.random() * 16)]; + } + return color; +} + +elements.disco_ball = { + color: "#ebebc3", + buttonColor: ["#ff0000", "#ff8800", "#ffff00", "#00ff00", "#00ffff", "#0000ff", "#ff00ff"], + renderer: renderPresets.LED, + behavior: behaviors.WALL, + category: "machines", + tempHigh: 1500, + stateHigh: ["molten_glass", "molten_glass", "molten_copper"], + conduct: 1, + breakInto: "glass_shard", + forceSaveColor: true, + tick: function (pixel) { + for (var i = 0; i < squareCoords.length; i++) { + var coord = squareCoords[i]; + var x = pixel.x + coord[0]; + var y = pixel.y + coord[1]; + if (pixel.charge > 0) { + pixel.color = randomColor() + if (isEmpty(x, y)) { + createPixel("light", x, y) + let p = getPixel(x, y) + if (p !== null && p.element == "light") { + p.color = pixel.color + } + } + } + else { pixel.color = "#ebebc3" } + } + } +} + +elements.molten_iron.reactions.sulfur = { elem1: "pyrite", elem2: null, chance: 0.25 } +elements.molten_iron.reactions.molten_sulfur = { elem1: "pyrite", elem2: null, chance: 0.25 } +elements.molten_iron.reactions.sulfur_gas = { elem1: "pyrite", elem2: null, chance: 0.25 } + +elements.pyrite = { + color: ["#d8c25e", "#bbaa49", "#998f3e"], + alias: ["fools_gold", "Iron Disulfide"], + density: 5000, + tempHigh: 1177, + stateHigh: ["iron", "molten_sulfur"], + grain: 0.4, + state: "solid", + behavior: behaviors.WALL, + category: "solids" +} + +elements.fire_extinguisher_powder = { + color: "#ececec", + behavior: [ + "XX|XX|XX", + "XX|DL%1|XX", + "M2%30|M1%30|M2%30" + ], + extinguish: true, + tick: function (pixel) { + for (var i = 0; i < adjacentCoords.length; i++) { + var coords = adjacentCoords[i]; + var x = pixel.x + coords[0]; + var y = pixel.y + coords[1]; + if (getPixel(x, y)?.burning === true) { + let elem = getPixel(x, y) + elem.burning = false + } + } + }, + tool: function(pixel) { + if(pixel.burning === true){ + delete pixel.burning; + delete pixel.burnStart; + } + }, + canPlace: true, + category: "powders" +} \ No newline at end of file diff --git a/mods/fans.js b/mods/fans.js new file mode 100644 index 00000000..a3bf07ad --- /dev/null +++ b/mods/fans.js @@ -0,0 +1,211 @@ +function getSelfMovingBehaviorFunctionNames() { + return Object.entries(behaviors) + .filter(([name, func]) => { + if (typeof func !== "function") return false; + if (["SEEDRISE"].includes(name)) return false; + + const code = func.toString(); + + // Only allow if it's moving its own pixel + const selfMove = /movePixel\s*\(\s*pixel\s*,/.test(code) || /tryMove\s*\(\s*pixel\s*,/.test(code) + || /pixel\.(x|y)\s*[\+\-]=/.test(code); + + return selfMove; + }) + .map(([name]) => name); +} + +const builtInMovementBehaviors = [ + "M1", "M2","BO", "SP", "XX|M1", "M1|M2", "M1%", "M2%", "M1%|M2", + "M1|M2%", "M1%|M2%", 'XX|M1%', 'M1%|XX', 'XX|M2%', 'M2%|XX' +]; + +function behaviorIncludesMovement(behaviorMatrix, movementFunctionNames) { + if (!Array.isArray(behaviorMatrix)) return false; + + for (const row of behaviorMatrix) { + if (!Array.isArray(row)) continue; + + for (const cell of row) { + if (typeof cell !== "string") continue; + + // Handle "AND" logic: multiple behaviors in one cell + const andParts = cell.split("AND"); + + for (const andPart of andParts) { + const parts = andPart.trim().split("|").map(p => p.trim()); + if (parts.some(p => builtInMovementBehaviors.includes(p) || movementFunctionNames.includes(p))) { + return true; + } + } + } + } + + return false; +} + + +runAfterAutogen(function () { + const movementFunctionNames = getSelfMovingBehaviorFunctionNames(); + + const movableElements = Object.entries(elements).filter(([name, elem]) => { + const behavior = elem.behavior; + const tick = elem.tick || elem.tickFunc; + + let movesSelf = false; + + // Check behavior matrix + if (Array.isArray(behavior)) { + movesSelf = behaviorIncludesMovement(behavior, movementFunctionNames); + } + + // Check single string + else if (typeof behavior === "string") { + const parts = behavior.split("|").map(p => p.trim()); + movesSelf = parts.some(p => builtInMovementBehaviors.includes(p) || movementFunctionNames.includes(p)); + } + + // Check function-type behavior + else if (typeof behavior === "function") { + movesSelf = movementFunctionNames.includes(behavior.name); + } + + // Check tick function + if (!movesSelf && typeof tick === "function") { + const code = tick.toString(); + if (/movePixel\s*\(\s*pixel\s*,/.test(code) || /tryMove\s*\(\s*pixel\s*,/.test(code) || /pixel\.(x|y)\s*[\+\-]=/.test(code)) { + movesSelf = true; + } + } + + return movesSelf; + }).map(([name]) => name); + + console.log("🚶 Self-Moving Elements:", movableElements); + window.movableElementsByBehavior = movableElements; +}); + + + + + + +runAfterAutogen(function () { + console.log(behaviors) +}) + +// Create a global map to track delay for each position +if (!window.fanPushDelays) { + window.fanPushDelays = new Map(); +} + +elements.fan_right = { + behavior: behaviors.WALL, + color: "#c5c5c5", + tick: function (pixel) { + const fan_strength = 10; + const delay_ticks = 2; + + for (let i = 1; i <= fan_strength; i++) { + const x = pixel.x + i; + const y = pixel.y; + + // SKIP if position is empty + if (isEmpty(x, y)) continue; + + const delem = pixelMap[x]?.[y]; + if (!delem) continue; + + // Skip non-movable elements + if (!window.movableElementsByBehavior.includes(delem.element)) continue; + + // Use position key for delay tracking + const key = `${x},${y}`; + const currentDelay = window.fanPushDelays.get(key) || 0; + + if (currentDelay >= delay_ticks) { + window.fanPushDelays.set(key, 0); + + const newX = x + 1; + if (isEmpty(newX, y)) { + movePixel(delem, newX, y); + } + } else { + window.fanPushDelays.set(key, currentDelay + 1); + } + } + }, + category: "machines" +}; + +elements.fan_left = { + behavior: behaviors.WALL, + color: "#c5c5c5", + tick: function (pixel) { + const fan_strength = 10; + const delay_ticks = 2; + + for (let i = 0; i >= -fan_strength; i--) { + const x = pixel.x + i; + const y = pixel.y; + + // SKIP if position is empty + if (isEmpty(x, y)) continue; + + const delem = pixelMap[x]?.[y]; + if (!delem) continue; + + // Skip non-movable elements + if (!window.movableElementsByBehavior.includes(delem.element)) continue; + + // Use position key for delay tracking + const key = `${x},${y}`; + const currentDelay = window.fanPushDelays.get(key) || 0; + + if (currentDelay >= delay_ticks) { + window.fanPushDelays.set(key, 0); + + const newX = x - 1; + if (isEmpty(newX, y)) { + movePixel(delem, newX, y); + } + } else { + window.fanPushDelays.set(key, currentDelay + 1); + } + } + }, + category: "machines" +}; +/* +elements.fan_up = { + behavior: behaviors.WALL, + tick: function (pixel) { + let fan_strength = 10; + let delay_ticks = 0; // delay between pushes per pixel row + if (!pixel._fan_delay) pixel._fan_delay = 0; + + if (pixel._fan_delay > 0) { + pixel._fan_delay--; + return; + } + + for (let i = 1; i <= fan_strength; i++) { + const tx = pixel.x; + const ty = pixel.y - i; + + if (!isEmpty(tx, ty)) { + const delem = pixelMap[tx]?.[ty]; + + if (!delem || !window.movableElementsByBehavior.includes(delem.element)) break; + + const above = ty - 1; + if (isEmpty(tx, above)) { + movePixel(delem, tx, above); + pixel._fan_delay = delay_ticks; + break; // only move one per tick + } + } + } + } +}; +*/ From cc66e8f68f87c52371c7ce89af01b21c5e89299f Mon Sep 17 00:00:00 2001 From: Suss <167750109+therealsuss@users.noreply.github.com> Date: Mon, 21 Jul 2025 10:26:02 +1000 Subject: [PATCH 10/13] petal dye yeah --- mods/petal_dye.js | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 mods/petal_dye.js diff --git a/mods/petal_dye.js b/mods/petal_dye.js new file mode 100644 index 00000000..38a06353 --- /dev/null +++ b/mods/petal_dye.js @@ -0,0 +1,8 @@ +elements.water.reactions.petal = { + func: function(pixel1, pixel2) { + if (pixel1.temp > 64) { + deletePixel(pixel1.x, pixel1.y); + pixel2.element = "dye"; + } + } +} From 34cc49b56396962be8aa44361f682535de334afc Mon Sep 17 00:00:00 2001 From: redbirdly <155550833+redbirdly@users.noreply.github.com> Date: Mon, 21 Jul 2025 11:33:28 +0800 Subject: [PATCH 11/13] Update and rename hexagon_test.js to hexagon.js --- mods/{hexagon_test.js => hexagon.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename mods/{hexagon_test.js => hexagon.js} (100%) diff --git a/mods/hexagon_test.js b/mods/hexagon.js similarity index 100% rename from mods/hexagon_test.js rename to mods/hexagon.js From fcc5cc35ea4b94bd1a9f4c4cae6f4160c4c99096 Mon Sep 17 00:00:00 2001 From: Suss <167750109+therealsuss@users.noreply.github.com> Date: Wed, 23 Jul 2025 10:43:16 +1000 Subject: [PATCH 12/13] fix --- mods/petal_dye.js | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/mods/petal_dye.js b/mods/petal_dye.js index 38a06353..137032a3 100644 --- a/mods/petal_dye.js +++ b/mods/petal_dye.js @@ -6,3 +6,35 @@ elements.water.reactions.petal = { } } } +elements.salt_water.reactions.petal = { + func: function(pixel1, pixel2) { + if (pixel1.temp > 64) { + deletePixel(pixel1.x, pixel1.y); + pixel2.element = "dye"; + } + } +} +elements.sugar_water.reactions.petal = { + func: function(pixel1, pixel2) { + if (pixel1.temp > 64) { + deletePixel(pixel1.x, pixel1.y); + pixel2.element = "dye"; + } + } +} +elements.seltzer.reactions.petal = { + func: function(pixel1, pixel2) { + if (pixel1.temp > 64) { + deletePixel(pixel1.x, pixel1.y); + pixel2.element = "dye"; + } + } +} +elements.pool_water.reactions.petal = { + func: function(pixel1, pixel2) { + if (pixel1.temp > 64) { + deletePixel(pixel1.x, pixel1.y); + pixel2.element = "dye"; + } + } +} From af28e7bbd1a687b72509db7db8c5f86f70e04757 Mon Sep 17 00:00:00 2001 From: Suss <167750109+therealsuss@users.noreply.github.com> Date: Wed, 23 Jul 2025 10:46:12 +1000 Subject: [PATCH 13/13] Update mod-list.html --- mod-list.html | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mod-list.html b/mod-list.html index 0141dd98..ebaaf7de 100644 --- a/mod-list.html +++ b/mod-list.html @@ -231,6 +231,7 @@ neutronium_compressor.jsCompressor from Minecraft's Avaritia mod that compresses 10,000 pixels of an element into a singularityAlice noblegas.jsThe missing noble gasesnousernamefound nousersthings.jsMany chemical elements, compounds, and morenousernamefound +petal_dye.jsBoil petals to make dyeSuss radioactive.jsRadioactive elements on the periodic table [WIP]kaeud random_rocks.jsRandomly generates rocks on game loadAlice roseyiede.jsSeveral variants of a substance called roseyiedeAlice @@ -339,6 +340,7 @@ nograssgrow.jsPrevents Grass from growingmollthecoder ocean.jsMarine lifeSquareScreamYT ores.jsOre generation along with tools to mine themnousernamefound +petal_dye.jsBoil petals to make dyeSuss pizzasstuff.jsNew animals, foods, and plants_ilikepizza_ plants.jsWide variety of new plants and fruitsAdora primordial_birthpool.jsCross between Primordial Soup and Birthpool. Requires fey_and_more.jsAlice