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 - } - } - } - } -}; -*/