From fb147d585c92ab2c3b71af3b6c2a08c3b1c49a08 Mon Sep 17 00:00:00 2001 From: Cube14yt Date: Sat, 19 Jul 2025 14:22:58 +0800 Subject: [PATCH 1/6] 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 2/6] 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 3/6] 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 4/6] 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 5/6] 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 6/6] 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 + } + } + } + } +}; +*/