Domekologe

minecolonies_refinedstorage_1.21.1.lua

Jan 17th, 2026 (edited)
3,001
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 12.45 KB | None | 0 0
  1. -- RSWarehouse.lua
  2. -- Construction: https://cdn.domekologe.eu/gameserver/minecraft/cc/Minecolonies_RefinedStorage_Integration.png
  3. -- IMPORTANT: Entangled Block MUST be on left Side of Computer, if not, change direction variable!
  4. --[[
  5. Changelog:
  6. - Change Domum Items, that only items from architects cutter are excluded
  7.  
  8. ]]--
  9.  
  10. local time_between_runs = 15
  11. local MAX_EXPORT = 256
  12. local direction = "left"
  13.  
  14.  
  15. -------------------------------------------------------------------------------
  16. -- INIT
  17. -------------------------------------------------------------------------------
  18.  
  19. local monitor = peripheral.find("monitor")
  20. if not monitor then error("Monitor not found") end
  21. monitor.setTextScale(0.5)
  22.  
  23. local bridge = peripheral.find("rs_bridge")
  24. if not bridge then error("RS Bridge not found") end
  25.  
  26. local colony = peripheral.find("colony_integrator")
  27. if not colony then error("Colony Integrator not found") end
  28.  
  29. local deliveredRequests = {}
  30. local craftingRequests = {}
  31.  
  32.  
  33.  
  34. local ARCHITECTS_CUTTER_ITEMS = {
  35.   ["domum_ornamentum:panel"] = true,
  36.   ["domum_ornamentum:plain"] = true,
  37.   ["domum_ornamentum:post"] = true,
  38.   ["domum_ornamentum:fancy_door"] = true,
  39.   ["domum_ornamentum:fancy_light"] = true,
  40.   ["domum_ornamentum:fancy_trapdoor"] = true,
  41.   ["domum_ornamentum:blockpaperwall"] = true,
  42.   ["domum_ornamentum:blockpillar"] = true,
  43.   ["domum_ornamentum:blocktiledpaperwall"] = true,
  44.   ["domum_ornamentum:blockypillar"] = true,
  45.   ["domum_ornamentum:centerlight"] = true,
  46.   ["domum_ornamentum:shingle"] = true,
  47.   ["domum_ornamentum:shingle_slab"] = true,
  48.   ["domum_ornamentum:shingle_stairs"] = true,
  49.   ["domum_ornamentum:vanilla_fence_gate_compat"] = true,
  50.   ["domum_ornamentum:vanilla_fence_compat"] = true,
  51.   ["domum_ornamentum:vanilla_wall_compat"] = true,
  52.   ["domum_ornamentum:vanilla_stairs_compat"] = true,
  53.   ["domum_ornamentum:vanilla_slab_compat"] = true,
  54.   ["domum_ornamentum:vanilla_trapdoors_compat"] = true,
  55.   ["domum_ornamentum:framed"] = true,
  56.   ["domum_ornamentum:framed_light"] = true,
  57.   ["domum_ornamentum:four_light"] = true,
  58.   ["domum_ornamentum:extra"] = true,
  59.   ["domum_ornamentum:extra_slab"] = true,
  60.   ["domum_ornamentum:extra_stairs"] = true
  61. }
  62.  
  63.  
  64. -------------------------------------------------------------------------------
  65. -- HELPERS
  66. -------------------------------------------------------------------------------
  67.  
  68. local function isBuilder(colonistName)
  69.   return string.find(colonistName, "Builder") ~= nil
  70. end
  71.  
  72. local function isEquipmentRequest(desc)
  73.   return desc and string.find(desc, "level")
  74. end
  75.  
  76. local function makeRequestId(data)
  77.   return string.format(
  78.     "%s|%s|%s|%d|%s",
  79.     data.item.name,
  80.     textutils.serialize(data.item.nbt),
  81.     data.colonist,
  82.     data.needed,
  83.     data.building or ""
  84.   )
  85. end
  86.  
  87.  
  88. local function getDomumVariant(nbt)
  89.   if not nbt then return "Unknown" end
  90.  
  91.   if nbt.variant then
  92.     return tostring(nbt.variant)
  93.   end
  94.  
  95.   if nbt.block then
  96.     return tostring(nbt.block)
  97.   end
  98.  
  99.   if nbt.material then
  100.     return tostring(nbt.material)
  101.   end
  102.  
  103.   if nbt.texture then
  104.     return tostring(nbt.texture)
  105.   end
  106.  
  107.   if nbt.state then
  108.     return tostring(nbt.state)
  109.   end
  110.  
  111.   return "Unspecified. Check Requester"
  112. end
  113.  
  114. local function isArchitectCutterItem(item)
  115.   if not item or not item.name then return false end
  116.   return ARCHITECTS_CUTTER_ITEMS[item.name] == true
  117. end
  118.  
  119.  
  120.  
  121. -------------------------------------------------------------------------------
  122. -- MONITOR UI
  123. -------------------------------------------------------------------------------
  124.  
  125. local function drawHeader(mon, remaining)
  126.   local w, _ = mon.getSize()
  127.   local now = os.time()
  128.  
  129.   local cycle = "day"
  130.   local color = colors.lightBlue
  131.   if now >= 18.5 or now < 5 then
  132.     cycle = "night"
  133.     color = colors.red
  134.   elseif now >= 18 then
  135.     cycle = "sunset"
  136.     color = colors.orange
  137.   elseif now < 6 then
  138.     cycle = "sunrise"
  139.     color = colors.yellow
  140.   end
  141.  
  142.   mon.setCursorPos(1,1)
  143.   mon.setTextColor(color)
  144.   mon.write("Time: "..textutils.formatTime(now, false).." ["..cycle.."]")
  145.  
  146.   mon.setCursorPos(w - 16, 1)
  147.   mon.setTextColor(colors.green)
  148.   mon.write(string.format("Remaining: %02ds", remaining))
  149. end
  150.  
  151. local function drawSectionTitle(mon, row, title)
  152.   local w, _ = mon.getSize()
  153.   mon.setCursorPos(math.floor((w - #title) / 2), row)
  154.   mon.setTextColor(colors.white)
  155.   mon.write(title)
  156.   return row + 1
  157. end
  158.  
  159. local function drawLine(mon, row, left, right, color)
  160.   local w, _ = mon.getSize()
  161.   mon.setCursorPos(1, row)
  162.   mon.setTextColor(color)
  163.   mon.write(left)
  164.  
  165.   mon.setCursorPos(w - #right, row)
  166.   mon.write(right)
  167.  
  168.   return row + 1
  169. end
  170.  
  171. -------------------------------------------------------------------------------
  172. -- REQUEST FETCH
  173. -------------------------------------------------------------------------------
  174.  
  175. local function getRequests()
  176.   local list = {}
  177.   for _, r in pairs(colony.getRequests()) do
  178.     if r.items and r.items[1] and r.items[1].name then
  179.       table.insert(list, {
  180.         name = r.name,
  181.         desc = r.desc,
  182.         needed = r.count or 0,
  183.         item = {
  184.           name  = r.items[1].name,
  185.           count = math.min(r.count or 0, MAX_EXPORT),
  186.           nbt   = r.items[1].nbt
  187.         },
  188.         colonist = r.target,
  189.         building = r.building or r.target
  190.       })
  191.     end
  192.   end
  193.   return list
  194. end
  195.  
  196. -------------------------------------------------------------------------------
  197. -- MAIN SCAN
  198. -------------------------------------------------------------------------------
  199.  
  200. local function scan(monitor, remaining)
  201.   local builder = {}
  202.   local nonBuilder = {}
  203.   local equipment = {}
  204.   local activeRequests = {}
  205.   local missingDomum = {}
  206.   for _, data in ipairs(getRequests()) do
  207.     local requestId = makeRequestId(data)
  208.     activeRequests[requestId] = true
  209.  
  210.     local provided = 0
  211.     local color = colors.blue -- default: not deliverable
  212.  
  213.     local isDomum = isArchitectCutterItem(data.item)
  214.  
  215.     local hasNBT = data.item
  216.       and type(data.item.nbt) == "table"
  217.       and next(data.item.nbt) ~= nil
  218.  
  219.     -- ======================================================
  220.     -- DELIVERY FIRST (never blocked by crafting)
  221.     -- ======================================================
  222.  
  223.     if not isDomum or hasNBT then
  224.       -- Normal items OR Domum items with NBT
  225.       provided = bridge.exportItem(data.item, direction)
  226.     else
  227.       -- Domum item without NBT -> never export
  228.       provided = 0
  229.     end
  230.  
  231.     -- Fully delivered
  232.     if provided >= data.needed then
  233.       deliveredRequests[requestId] = true
  234.       craftingRequests[requestId] = nil
  235.       color = colors.green
  236.  
  237.     -- Partially delivered
  238.     elseif provided > 0 then
  239.       color = colors.yellow
  240.  
  241.     -- Nothing delivered -> check / start crafting
  242.     else
  243.       -- Domum item without NBT must NEVER be crafted
  244.       if isDomum and not hasNBT then
  245.         color = colors.blue
  246.  
  247.       else
  248.         -- Craft already running
  249.         if craftingRequests[requestId] then
  250.           color = colors.pink
  251.  
  252.         -- Try to start crafting
  253.         else
  254.           local craftItem = {
  255.             name  = data.item.name,
  256.             count = data.needed,
  257.             nbt   = data.item.nbt
  258.           }
  259.  
  260.           local ok = bridge.craftItem(craftItem)
  261.  
  262.           if ok then
  263.             craftingRequests[requestId] = {
  264.               started = os.epoch("utc")
  265.             }
  266.             color = colors.pink
  267.           else
  268.             color = colors.blue
  269.           end
  270.         end
  271.       end
  272.     end
  273.    
  274.     -- ======================================================
  275.     -- Donum Ornamentum Missing Items
  276.     -- ======================================================
  277.    
  278.     if isDomum and color == colors.blue then
  279.       local variant = getDomumVariant(data.item.nbt)
  280.    
  281.       local key = data.item.name .. "|" .. variant
  282.       missingDomum[key] = {
  283.         name = data.name:gsub("^[%d%-]+%s*", ""),
  284.         variant = variant
  285.       }
  286.     end
  287.     -- ======================================================
  288.     -- UI ENTRY
  289.     -- ======================================================
  290.     local variant = ""
  291.     if isDomum then
  292.       local v = getDomumVariant(data.item.nbt)
  293.       if v ~= "unknown" then
  294.         variant = " [" .. v .. "]"
  295.       end
  296.     end
  297.  
  298.  
  299.     local entry = {
  300.       left = string.format(
  301.         "%d %s%s (%d)",
  302.         provided,
  303.         data.name:gsub("^[%d%-]+%s*", ""),
  304.         variant,
  305.         data.needed
  306.       ),
  307.       provided = provided,
  308.       needed = data.needed,
  309.       color = color
  310.     }
  311.  
  312.     -- Equipment requests always show colonist
  313.     if isEquipmentRequest(data.desc) then
  314.       entry.right = data.colonist
  315.       table.insert(equipment, entry)
  316.  
  317.     -- Builder requests show building / hut
  318.     elseif isBuilder(data.colonist) then
  319.       entry.right = data.building or "Builder"
  320.       table.insert(builder, entry)
  321.  
  322.     -- Non-builder requests show colonist name
  323.     else
  324.       entry.right = data.colonist
  325.       table.insert(nonBuilder, entry)
  326.     end
  327.  
  328.     -- ======================================================
  329.     -- TERMINAL OUTPUT
  330.     -- ======================================================
  331.     if color == colors.pink then
  332.       print(string.format(
  333.         "[CRAFTING] %s%s x%d -> %s",
  334.         data.item.name,
  335.         variant,
  336.         data.needed,
  337.         entry.right
  338.       ))
  339.     elseif color == colors.blue then
  340.       if isDomum and not hasNBT then
  341.         print(string.format(
  342.           "[SKIP]     %s x%d -> %s (missing NBT)",
  343.           data.item.name,
  344.           data.needed,
  345.           entry.right
  346.         ))
  347.       else
  348.         print(string.format(
  349.           "[MISSING]  %s x%d -> %s (no pattern)",
  350.           data.item.name,
  351.           data.needed,
  352.           entry.right
  353.         ))
  354.       end
  355.     elseif color == colors.green then
  356.       print(string.format(
  357.         "[DONE]     %s%s x%d -> %s",
  358.         data.item.name,
  359.         variant,
  360.         data.needed,
  361.         entry.right
  362.       ))
  363.     else
  364.       print(string.format(
  365.         "[PARTIAL]  %s%s x%d -> %s",
  366.         data.item.name,
  367.         variant,
  368.         provided,
  369.         entry.right
  370.       ))
  371.     end
  372.   end
  373.  
  374.   -- ======================================================
  375.   -- CLEANUP: remove state for vanished requests
  376.   -- ======================================================
  377.   for requestId, _ in pairs(deliveredRequests) do
  378.     if not activeRequests[requestId] then
  379.       deliveredRequests[requestId] = nil
  380.       craftingRequests[requestId] = nil
  381.     end
  382.   end
  383.  
  384.   -- ======================================================
  385.   -- MONITOR UI
  386.   -- ======================================================
  387.   monitor.clear()
  388.   drawHeader(monitor, remaining)
  389.  
  390.   local row = 3
  391.  
  392.   if #builder > 0 then
  393.     row = drawSectionTitle(monitor, row, "Builder Requests")
  394.     for _, r in ipairs(builder) do
  395.       row = drawLine(monitor, row, r.left, r.right, r.color)
  396.     end
  397.     row = row + 1
  398.   end
  399.  
  400.   if #nonBuilder > 0 then
  401.     row = drawSectionTitle(monitor, row, "Non Builder Requests")
  402.     for _, r in ipairs(nonBuilder) do
  403.       row = drawLine(monitor, row, r.left, r.right, r.color)
  404.     end
  405.     row = row + 1
  406.   end
  407.  
  408.   if #equipment > 0 then
  409.     row = drawSectionTitle(monitor, row, "Equipment Requests")
  410.     for _, r in ipairs(equipment) do
  411.       row = drawLine(monitor, row, r.left, r.right, r.color)
  412.     end
  413.   end
  414.  
  415.   -- ======================================================
  416.   -- MISSING DOMUM ORNAMENTUM SUMMARY
  417.   -- ======================================================
  418.   if next(missingDomum) ~= nil then
  419.     row = row + 1
  420.     row = drawSectionTitle(monitor, row, "Missing Domum Ornamentum Items")
  421.  
  422.     for _, entry in pairs(missingDomum) do
  423.       local text = "- " .. entry.name .. " [" .. entry.variant .. "]"
  424.       row = drawLine(
  425.         monitor,
  426.         row,
  427.         text,
  428.         "",
  429.         colors.blue
  430.       )
  431.     end
  432.   end
  433.  
  434.  
  435. end
  436.  
  437.  
  438.  
  439. -------------------------------------------------------------------------------
  440. -- LOOP
  441. -------------------------------------------------------------------------------
  442.  
  443. local counter = time_between_runs
  444. scan(monitor, counter)
  445.  
  446. local timer = os.startTimer(1)
  447. while true do
  448.   local e = { os.pullEvent() }
  449.   if e[1] == "timer" and e[2] == timer then
  450.     counter = counter - 1
  451.     if counter <= 0 then
  452.       scan(monitor, time_between_runs)
  453.       counter = time_between_runs
  454.     else
  455.       drawHeader(monitor, counter)
  456.     end
  457.     timer = os.startTimer(1)
  458.   end
  459. end
  460.  
Advertisement