-- RSWarehouse.lua -- Construction: https://cdn.domekologe.eu/gameserver/minecraft/cc/Minecolonies_RefinedStorage_Integration.png -- IMPORTANT: Entangled Block MUST be on left Side of Computer, if not, change direction variable! --[[ Changelog: - Change Domum Items, that only items from architects cutter are excluded ]]-- local time_between_runs = 15 local MAX_EXPORT = 256 local direction = "left" ------------------------------------------------------------------------------- -- INIT ------------------------------------------------------------------------------- local monitor = peripheral.find("monitor") if not monitor then error("Monitor not found") end monitor.setTextScale(0.5) local bridge = peripheral.find("rs_bridge") if not bridge then error("RS Bridge not found") end local colony = peripheral.find("colony_integrator") if not colony then error("Colony Integrator not found") end local deliveredRequests = {} local craftingRequests = {} local ARCHITECTS_CUTTER_ITEMS = { ["domum_ornamentum:panel"] = true, ["domum_ornamentum:plain"] = true, ["domum_ornamentum:post"] = true, ["domum_ornamentum:fancy_door"] = true, ["domum_ornamentum:fancy_light"] = true, ["domum_ornamentum:fancy_trapdoor"] = true, ["domum_ornamentum:blockpaperwall"] = true, ["domum_ornamentum:blockpillar"] = true, ["domum_ornamentum:blocktiledpaperwall"] = true, ["domum_ornamentum:blockypillar"] = true, ["domum_ornamentum:centerlight"] = true, ["domum_ornamentum:shingle"] = true, ["domum_ornamentum:shingle_slab"] = true, ["domum_ornamentum:shingle_stairs"] = true, ["domum_ornamentum:vanilla_fence_gate_compat"] = true, ["domum_ornamentum:vanilla_fence_compat"] = true, ["domum_ornamentum:vanilla_wall_compat"] = true, ["domum_ornamentum:vanilla_stairs_compat"] = true, ["domum_ornamentum:vanilla_slab_compat"] = true, ["domum_ornamentum:vanilla_trapdoors_compat"] = true, ["domum_ornamentum:framed"] = true, ["domum_ornamentum:framed_light"] = true, ["domum_ornamentum:four_light"] = true, ["domum_ornamentum:extra"] = true, ["domum_ornamentum:extra_slab"] = true, ["domum_ornamentum:extra_stairs"] = true } ------------------------------------------------------------------------------- -- HELPERS ------------------------------------------------------------------------------- local function isBuilder(colonistName) return string.find(colonistName, "Builder") ~= nil end local function isEquipmentRequest(desc) return desc and string.find(desc, "level") end local function makeRequestId(data) return string.format( "%s|%s|%s|%d|%s", data.item.name, textutils.serialize(data.item.nbt), data.colonist, data.needed, data.building or "" ) end local function getDomumVariant(nbt) if not nbt then return "Unknown" end if nbt.variant then return tostring(nbt.variant) end if nbt.block then return tostring(nbt.block) end if nbt.material then return tostring(nbt.material) end if nbt.texture then return tostring(nbt.texture) end if nbt.state then return tostring(nbt.state) end return "Unspecified. Check Requester" end local function isArchitectCutterItem(item) if not item or not item.name then return false end return ARCHITECTS_CUTTER_ITEMS[item.name] == true end ------------------------------------------------------------------------------- -- MONITOR UI ------------------------------------------------------------------------------- local function drawHeader(mon, remaining) local w, _ = mon.getSize() local now = os.time() local cycle = "day" local color = colors.lightBlue if now >= 18.5 or now < 5 then cycle = "night" color = colors.red elseif now >= 18 then cycle = "sunset" color = colors.orange elseif now < 6 then cycle = "sunrise" color = colors.yellow end mon.setCursorPos(1,1) mon.setTextColor(color) mon.write("Time: "..textutils.formatTime(now, false).." ["..cycle.."]") mon.setCursorPos(w - 16, 1) mon.setTextColor(colors.green) mon.write(string.format("Remaining: %02ds", remaining)) end local function drawSectionTitle(mon, row, title) local w, _ = mon.getSize() mon.setCursorPos(math.floor((w - #title) / 2), row) mon.setTextColor(colors.white) mon.write(title) return row + 1 end local function drawLine(mon, row, left, right, color) local w, _ = mon.getSize() mon.setCursorPos(1, row) mon.setTextColor(color) mon.write(left) mon.setCursorPos(w - #right, row) mon.write(right) return row + 1 end ------------------------------------------------------------------------------- -- REQUEST FETCH ------------------------------------------------------------------------------- local function getRequests() local list = {} for _, r in pairs(colony.getRequests()) do if r.items and r.items[1] and r.items[1].name then table.insert(list, { name = r.name, desc = r.desc, needed = r.count or 0, item = { name = r.items[1].name, count = math.min(r.count or 0, MAX_EXPORT), nbt = r.items[1].nbt }, colonist = r.target, building = r.building or r.target }) end end return list end ------------------------------------------------------------------------------- -- MAIN SCAN ------------------------------------------------------------------------------- local function scan(monitor, remaining) local builder = {} local nonBuilder = {} local equipment = {} local activeRequests = {} local missingDomum = {} for _, data in ipairs(getRequests()) do local requestId = makeRequestId(data) activeRequests[requestId] = true local provided = 0 local color = colors.blue -- default: not deliverable local isDomum = isArchitectCutterItem(data.item) local hasNBT = data.item and type(data.item.nbt) == "table" and next(data.item.nbt) ~= nil -- ====================================================== -- DELIVERY FIRST (never blocked by crafting) -- ====================================================== if not isDomum or hasNBT then -- Normal items OR Domum items with NBT provided = bridge.exportItem(data.item, direction) else -- Domum item without NBT -> never export provided = 0 end -- Fully delivered if provided >= data.needed then deliveredRequests[requestId] = true craftingRequests[requestId] = nil color = colors.green -- Partially delivered elseif provided > 0 then color = colors.yellow -- Nothing delivered -> check / start crafting else -- Domum item without NBT must NEVER be crafted if isDomum and not hasNBT then color = colors.blue else -- Craft already running if craftingRequests[requestId] then color = colors.pink -- Try to start crafting else local craftItem = { name = data.item.name, count = data.needed, nbt = data.item.nbt } local ok = bridge.craftItem(craftItem) if ok then craftingRequests[requestId] = { started = os.epoch("utc") } color = colors.pink else color = colors.blue end end end end -- ====================================================== -- Donum Ornamentum Missing Items -- ====================================================== if isDomum and color == colors.blue then local variant = getDomumVariant(data.item.nbt) local key = data.item.name .. "|" .. variant missingDomum[key] = { name = data.name:gsub("^[%d%-]+%s*", ""), variant = variant } end -- ====================================================== -- UI ENTRY -- ====================================================== local variant = "" if isDomum then local v = getDomumVariant(data.item.nbt) if v ~= "unknown" then variant = " [" .. v .. "]" end end local entry = { left = string.format( "%d %s%s (%d)", provided, data.name:gsub("^[%d%-]+%s*", ""), variant, data.needed ), provided = provided, needed = data.needed, color = color } -- Equipment requests always show colonist if isEquipmentRequest(data.desc) then entry.right = data.colonist table.insert(equipment, entry) -- Builder requests show building / hut elseif isBuilder(data.colonist) then entry.right = data.building or "Builder" table.insert(builder, entry) -- Non-builder requests show colonist name else entry.right = data.colonist table.insert(nonBuilder, entry) end -- ====================================================== -- TERMINAL OUTPUT -- ====================================================== if color == colors.pink then print(string.format( "[CRAFTING] %s%s x%d -> %s", data.item.name, variant, data.needed, entry.right )) elseif color == colors.blue then if isDomum and not hasNBT then print(string.format( "[SKIP] %s x%d -> %s (missing NBT)", data.item.name, data.needed, entry.right )) else print(string.format( "[MISSING] %s x%d -> %s (no pattern)", data.item.name, data.needed, entry.right )) end elseif color == colors.green then print(string.format( "[DONE] %s%s x%d -> %s", data.item.name, variant, data.needed, entry.right )) else print(string.format( "[PARTIAL] %s%s x%d -> %s", data.item.name, variant, provided, entry.right )) end end -- ====================================================== -- CLEANUP: remove state for vanished requests -- ====================================================== for requestId, _ in pairs(deliveredRequests) do if not activeRequests[requestId] then deliveredRequests[requestId] = nil craftingRequests[requestId] = nil end end -- ====================================================== -- MONITOR UI -- ====================================================== monitor.clear() drawHeader(monitor, remaining) local row = 3 if #builder > 0 then row = drawSectionTitle(monitor, row, "Builder Requests") for _, r in ipairs(builder) do row = drawLine(monitor, row, r.left, r.right, r.color) end row = row + 1 end if #nonBuilder > 0 then row = drawSectionTitle(monitor, row, "Non Builder Requests") for _, r in ipairs(nonBuilder) do row = drawLine(monitor, row, r.left, r.right, r.color) end row = row + 1 end if #equipment > 0 then row = drawSectionTitle(monitor, row, "Equipment Requests") for _, r in ipairs(equipment) do row = drawLine(monitor, row, r.left, r.right, r.color) end end -- ====================================================== -- MISSING DOMUM ORNAMENTUM SUMMARY -- ====================================================== if next(missingDomum) ~= nil then row = row + 1 row = drawSectionTitle(monitor, row, "Missing Domum Ornamentum Items") for _, entry in pairs(missingDomum) do local text = "- " .. entry.name .. " [" .. entry.variant .. "]" row = drawLine( monitor, row, text, "", colors.blue ) end end end ------------------------------------------------------------------------------- -- LOOP ------------------------------------------------------------------------------- local counter = time_between_runs scan(monitor, counter) local timer = os.startTimer(1) while true do local e = { os.pullEvent() } if e[1] == "timer" and e[2] == timer then counter = counter - 1 if counter <= 0 then scan(monitor, time_between_runs) counter = time_between_runs else drawHeader(monitor, counter) end timer = os.startTimer(1) end end