local metaphysicalSerum = 3 -- Value from 0 to 3 local clickDelay = 5 -- Delay between clicks and start of rounds local previousChestTitle = "" local currentExperiment = "NONE" local player = require("player") -- Chronomatron state local hasAdded = false local clicks = 1 local chronomatronOrder = {} local lastAdded = -1 local flashesSeenThisRound = 0 local lastFlashSlot = -1 local flashCooldown = 0 -- Ultrasequencer state local ultrasequencerOrder = {} -- General timer local clickTimer = 0 local lastCenterState = "NONE" local gridStateKey = {} local baselineGrid = {} -- Tracks the state of the grid at the start of the Clock phase local isClockPhaseActive = false local targetRound registerClientTick(function() -- Only proceed if a GUI is open if not player.inventory.isAnyScreenOpened() then if currentExperiment ~= "NONE" then -- Reset state when GUI is closed currentExperiment = "NONE" previousChestTitle = "" end return end local title = player.inventory.getChestTitle() if not title then return end -- Check if we entered a new experiment GUI if title ~= previousChestTitle then -- Find the experiment kind from the title stripping color codes if necessary local newExperiment = "NONE" if string.find(title, "Chronomatron") then newExperiment = "CHRONOMATRON" -- Check for Metaphysical variant if string.find(title, "Metaphysical") then targetRound = 12 - metaphysicalSerum else targetRound = 9 - metaphysicalSerum end elseif string.find(title, "Ultrasequencer") then newExperiment = "ULTRASEQUENCER" -- Check for variants if string.find(title, "Metaphysical") then targetRound = 9 - metaphysicalSerum else targetRound = 7 - metaphysicalSerum end end -- Only fully reset our state if the *type* of experiment has changed -- (This prevents the script from resetting when the title dynamically updates e.g., "Round 2") if currentExperiment ~= newExperiment then player.addMessage("§d[Exp] Detected: " .. newExperiment) hasAdded = false clicks = 1 chronomatronOrder = {} lastAdded = -1 flashesSeenThisRound = 0 ultrasequencerOrder = {} clickTimer = 3 currentExperiment = newExperiment end previousChestTitle = title end if currentExperiment == "NONE" then return end -- Ensure container has enough slots local slots = player.inventory.getContainerSlots() if not slots or slots < 54 then return end if clickTimer > 0 then clickTimer = clickTimer - 1 end if flashCooldown > 0 then flashCooldown = flashCooldown - 1 end -- Helper function to check variations of an item's name/ids robustly local function hasKeyword(item, keyword) if not item then return false end local nameStr = (item.name and string.lower(item.name) or "") .. " " .. (item.display_name and string.lower(item.display_name) or "") .. " " .. (item.skyblock_id and string.lower(item.skyblock_id) or "") .. " " .. (item.neu_id and string.lower(item.neu_id) or "") return string.find(nameStr, keyword) ~= nil end -- Process experiments if currentExperiment == "CHRONOMATRON" then local item49 = player.inventory.getStackFromContainer(49) local hasGlowstone = hasKeyword(item49, "glowstone") local hasClock = hasKeyword(item49, "clock") local currentCenterState = hasGlowstone and "GLOWSTONE" or (hasClock and "CLOCK" or "NONE") if currentCenterState ~= lastCenterState then lastCenterState = currentCenterState if currentCenterState == "CLOCK" then -- Round Start: Capture baseline and reset counters flashesSeenThisRound = 0 lastFlashSlot = -1 isClockPhaseActive = true hasAdded = false clicks = 1 clickTimer = clickDelay flashCooldown = 0 -- Capture what the grid looks like at the very start of the turn for i = 10, 43 do local slotItem = player.inventory.getStackFromContainer(i) if slotItem and slotItem.name then baselineGrid[i] = slotItem.name .. "_" .. tostring(slotItem.count) else baselineGrid[i] = "empty" end end else isClockPhaseActive = false end end -- In Chronomatron, we reset 'hasAdded' when it switches to Glowstone or when we manually want to start a new scan if hasGlowstone and (hasAdded or #chronomatronOrder == 0) then hasAdded = false end if not hasAdded and isClockPhaseActive then -- Monitoring for the flashes during the Clock (Computer display) phase for i = 10, 43 do local slotItem = player.inventory.getStackFromContainer(i) if slotItem and slotItem.name then -- 1. Create a fingerprint of CURRENT state local fingerprint = slotItem.name .. "_" .. tostring(slotItem.count) -- 2. Detect if it's currently "Active" (different from baseline) local isCurrentlyFlashed = (baselineGrid[i] and fingerprint ~= baselineGrid[i]) -- 3. Detect the START of a flash (transition from baseline to colored/enchanted) if isCurrentlyFlashed and i ~= lastFlashSlot and flashCooldown <= 0 then flashesSeenThisRound = flashesSeenThisRound + 1 lastFlashSlot = i flashCooldown = 2 -- Reduced from 8 to prevent cumulative lag -- If this is the NEW item in the sequence if flashesSeenThisRound > #chronomatronOrder then player.addMessage("§e[Chronomatron] " .. flashesSeenThisRound .. ": slot " .. i) table.insert(chronomatronOrder, i) hasAdded = true clickTimer = 0 break else -- Sequence flash was previously logged here end end -- Reset lastFlashSlot if the item returns to baseline, allowing it to be detected again if it flashes twice (unlikely in Chrono) if not isCurrentlyFlashed and i == lastFlashSlot then lastFlashSlot = -1 end end end end if hasClock and hasAdded and clicks <= #chronomatronOrder then if clickTimer <= 0 then local slotToClick = chronomatronOrder[clicks] player.addMessage("§a[Chronomatron] Clicking " .. clicks .. "/" .. #chronomatronOrder .. " (Slot " .. slotToClick .. ")") player.inventory.leftClick(slotToClick) clickTimer = clickDelay clicks = clicks + 1 if clicks > #chronomatronOrder and hasAdded then player.addMessage("§2[Chronomatron] Sequence complete. Waiting for next round...") if #chronomatronOrder >= targetRound then player.addMessage("§c[Chronomatron] Target Round " .. targetRound .. " reached! Closing GUI...") player.inventory.closeScreen() end end end end elseif currentExperiment == "ULTRASEQUENCER" then local item49 = player.inventory.getStackFromContainer(49) local hasGlowstone = hasKeyword(item49, "glowstone") local hasClock = hasKeyword(item49, "clock") local currentCenterState = hasGlowstone and "GLOWSTONE" or (hasClock and "CLOCK" or "NONE") if currentCenterState ~= lastCenterState then lastCenterState = currentCenterState if currentCenterState == "GLOWSTONE" then hasAdded = false -- Reset and wait to parse new sequence elseif currentCenterState == "CLOCK" then clicks = 1 clickTimer = clickDelay -- Consistent start delay end end if not hasAdded and hasGlowstone then local tempOrder = {} local maxFound = 0 -- Determine the correct play area based on level local startSlot, endSlot = 9, 44 local validSlots = {} if string.find(title, "Supreme") then -- 10-16, 19-25, 28-34 for r=0,2 do for c=10,16 do table.insert(validSlots, c + (r*9)) end end elseif string.find(title, "Transcendent") then -- 10-16, 19-25, 28-34, 37-43 for r=0,3 do for c=10,16 do table.insert(validSlots, c + (r*9)) end end else -- Metaphysical or Default: 9-44 for i=9,44 do table.insert(validSlots, i) end end -- Scan the determined valid slots for _, i in ipairs(validSlots) do local slotItem = player.inventory.getStackFromContainer(i) if slotItem and slotItem.name then local nameLow = string.lower(slotItem.name) local dispLow = slotItem.display_name and string.lower(slotItem.display_name) or "" local firstLore = (slotItem.lore and slotItem.lore[1]) and string.lower(slotItem.lore[1]) or "" -- Extremely aggressive check for anything glass-related local isGlass = string.find(nameLow, "glass") or string.find(dispLow, "glass") or string.find(firstLore, "glass") or (slotItem.skyblock_id and string.find(string.lower(slotItem.skyblock_id), "glass")) -- Debug check: only log if it's likely a real item (not glass) if not isGlass then local orderIndex = slotItem.count if orderIndex and orderIndex > 0 then tempOrder[orderIndex] = i maxFound = math.max(maxFound, orderIndex) end end end end if maxFound > 0 then ultrasequencerOrder = tempOrder player.addMessage("§e[Ultrasequencer] Parsed sequence of " .. maxFound .. " items") hasAdded = true clicks = 1 clickTimer = 10 end end if hasClock and ultrasequencerOrder[clicks] then if clickTimer <= 0 then local slotToClick = ultrasequencerOrder[clicks] player.addMessage("§a[Ultrasequencer] Clicking " .. clicks .. "/" .. #ultrasequencerOrder .. " (Slot " .. slotToClick .. ")") player.inventory.leftClick(slotToClick) clickTimer = clickDelay clicks = clicks + 1 if clicks > #ultrasequencerOrder then player.addMessage("§2[Ultrasequencer] Sequence complete.") if #ultrasequencerOrder >= targetRound then player.addMessage("§c[Ultrasequencer] Target Round " .. targetRound .. " reached! Closing GUI...") player.inventory.closeScreen() end end end end end end)