diff --git a/Logistics/startup.lua b/Logistics/startup.lua index 8be9b8e..b30654c 100644 --- a/Logistics/startup.lua +++ b/Logistics/startup.lua @@ -1,5 +1,5 @@ --- Turtle Logistics System v4.1 (Optimized) --- Supports direct container-to-container transfers +-- Turtle Logistics System v4.2 (Fluid Support) +-- Supports direct container-to-container transfers for items and fluids -- Config saved in config.cfg local configFile = "config.cfg" @@ -76,6 +76,37 @@ local function parseItemRequirements(input) return requirements end +-- Parse fluid requirements from string +local function parseFluidRequirements(input) + local requirements = {} + + -- Check if input is a JSON-like table + if input:sub(1,1) == "{" and input:sub(-1) == "}" then + -- Remove curly braces + local content = input:sub(2, -2) + + -- Split key-value pairs + for pair in content:gmatch("[^,]+") do + local key, value = pair:match("[\"']?(.-)[\"']?%s*:%s*(%d+)") + if key and value then + requirements[key] = tonumber(value) + end + end + else + -- Simple format: fluid:minAmount + for fluid in input:gmatch("%S+") do + local name, minAmount = fluid:match("([^:]+):(%d+)") + if name and minAmount then + requirements[name] = tonumber(minAmount) + else + requirements[fluid] = 0 -- No minimum requirement + end + end + end + + return requirements +end + -- Get container item list using container.list() local function getContainerItems(containerName) local container = peripheral.wrap(containerName) @@ -94,8 +125,97 @@ local function getContainerItems(containerName) return items end +-- Get fluid tank contents +local function getFluidTanks(containerName) + local container = peripheral.wrap(containerName) + if not container then return nil end + + if not container.tanks then + print("Error: Container does not support fluids: "..containerName) + return nil + end + + return container.tanks() +end + +-- Execute fluid transfer between containers +local function executeFluidTransfer(task) + -- Both source and destination must be containers for fluid transfers + if isDirection(task.source) or isDirection(task.destination) then + print("Error: Fluid transfers require container-to-container transfers") + return false + end + + local source = peripheral.wrap(task.source) + local destination = peripheral.wrap(task.destination) + + if not source or not destination then + if not source then print("Error: Source container not found: "..task.source) end + if not destination then print("Error: Destination container not found: "..task.destination) end + return false + end + + if not source.tanks or not destination.tanks then + print("Error: One or both containers do not support fluids") + return false + end + + -- Check min amount requirements + if task.fluids then + local sourceTanks = getFluidTanks(task.source) + if not sourceTanks then return false end + + local fluidAmounts = {} + for slot, tank in pairs(sourceTanks) do + if tank.name and task.fluids[tank.name] then + fluidAmounts[tank.name] = (fluidAmounts[tank.name] or 0) + tank.amount + end + end + + for fluidName, minAmount in pairs(task.fluids) do + if minAmount > 0 and (fluidAmounts[fluidName] or 0) < minAmount then + print("Not enough "..fluidName.." ("..(fluidAmounts[fluidName] or 0).." < "..minAmount..")") + return false + end + end + end + + -- Transfer fluids + local sourceTanks = getFluidTanks(task.source) + if not sourceTanks then return false end + + local totalTransferred = 0 + + for slot, tank in pairs(sourceTanks) do + local shouldTransfer = not task.fluids or (task.fluids[tank.name] ~= nil) + + if shouldTransfer and tank.name and tank.amount > 0 then + local amount = tank.amount + if task.fluids and task.fluids[tank.name] then + amount = math.min(amount, task.fluids[tank.name]) + end + + -- Push fluid from source to destination + local transferred = source.pushFluid(task.destination, task.concat, task.name) + totalTransferred = totalTransferred + transferred + + -- Update transferred amount in requirements + if task.fluids and task.fluids[tank.name] then + task.fluids[tank.name] = task.fluids[tank.name] - transferred + end + end + end + + return totalTransferred > 0 +end + -- Execute item transfer with min count requirements (Optimized) local function executeTransfer(task) + -- Handle fluid transfers separately + if task.type == "fluid" then + return executeFluidTransfer(task) + end + -- Case 1: Both source and destination are containers if not isDirection(task.source) and not isDirection(task.destination) then local source = peripheral.wrap(task.source) @@ -144,6 +264,11 @@ local function executeTransfer(task) local transferred = source.pushItems(destName, slot, count) totalTransferred = totalTransferred + transferred + + -- Update transferred count in requirements + if task.items and task.items[item.name] then + task.items[item.name] = task.items[item.name] - transferred + end end end @@ -313,6 +438,7 @@ local function processCommand(cmd) if command == "add" and #args >= 3 then local newTask = { + type = "item", source = args[2], destination = args[3], items = nil @@ -326,26 +452,60 @@ local function processCommand(cmd) table.insert(tasks, newTask) saveConfig() - print("Task added: "..newTask.source.." -> "..newTask.destination) + print("Item task added: "..newTask.source.." -> "..newTask.destination) + + elseif command == "addfluid" and #args >= 3 then + local newTask = { + type = "fluid", + source = args[2], + destination = args[3], + fluids = nil + } + + -- Parse fluid requirements + if #args > 3 then + local fluidsInput = table.concat(args, " ", 4) + newTask.fluids = parseFluidRequirements(fluidsInput) + end + + table.insert(tasks, newTask) + saveConfig() + print("Fluid task added: "..newTask.source.." -> "..newTask.destination) elseif command == "list" then if #tasks == 0 then print("No tasks configured") else for i, task in ipairs(tasks) do - local itemInfo = "" - if task.items then - local itemsList = {} - for name, minCount in pairs(task.items) do - if minCount > 0 then - table.insert(itemsList, name..":"..minCount) - else - table.insert(itemsList, name) + if task.type == "fluid" then + local fluidInfo = "" + if task.fluids then + local fluidsList = {} + for name, minAmount in pairs(task.fluids) do + if minAmount > 0 then + table.insert(fluidsList, name..":"..minAmount.."mB") + else + table.insert(fluidsList, name) + end end + fluidInfo = " ("..table.concat(fluidsList, ", ")..")" end - itemInfo = " ("..table.concat(itemsList, ", ")..")" + print("[FLUID "..i.."] "..task.source.." -> "..task.destination..fluidInfo) + else + local itemInfo = "" + if task.items then + local itemsList = {} + for name, minCount in pairs(task.items) do + if minCount > 0 then + table.insert(itemsList, name..":"..minCount) + else + table.insert(itemsList, name) + end + end + itemInfo = " ("..table.concat(itemsList, ", ")..")" + end + print("[ITEM "..i.."] "..task.source.." -> "..task.destination..itemInfo) end - print("["..i.."] "..task.source.." -> "..task.destination..itemInfo) end end @@ -366,10 +526,14 @@ local function processCommand(cmd) elseif command == "help" then print("Available commands:") - print("add [items] - Add transfer task") + print("add [items] - Add item transfer task") print(" Items format:") print(" Simple: item1[:minCount] item2[:minCount] ...") print(" JSON-like: {\"item1\":minCount, \"item2\":minCount}") + print("addfluid [fluids] - Add fluid transfer task") + print(" Fluids format:") + print(" Simple: fluid1[:minAmount] fluid2[:minAmount] ...") + print(" JSON-like: {\"fluid1\":minAmount, \"fluid2\":minAmount}") print("list - List all tasks") print("remove - Remove task") print("setname - Set turtle peripheral name") @@ -384,7 +548,7 @@ end -- Initialize loadConfig() -print("Turtle Logistics System started. Type 'help' for commands.") +print("Turtle Logistics System v4.2 started. Type 'help' for commands.") print("Current turtle name: "..turtleName) -- Main loop