From e79f135b12f03e892b56fb1facb1b72d28738613 Mon Sep 17 00:00:00 2001 From: HKXluo Date: Wed, 22 Oct 2025 12:49:18 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E7=89=A9=E5=93=81=E6=95=B0?= =?UTF-8?q?=E9=87=8Fbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .history/Logistics/startup_20251022124027.lua | 560 +++++++++++++++++ .history/Logistics/startup_20251022124918.lua | 571 ++++++++++++++++++ Logistics/startup.lua | 51 +- 3 files changed, 1160 insertions(+), 22 deletions(-) create mode 100644 .history/Logistics/startup_20251022124027.lua create mode 100644 .history/Logistics/startup_20251022124918.lua diff --git a/.history/Logistics/startup_20251022124027.lua b/.history/Logistics/startup_20251022124027.lua new file mode 100644 index 0000000..2712387 --- /dev/null +++ b/.history/Logistics/startup_20251022124027.lua @@ -0,0 +1,560 @@ +-- 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" +local tasks = {} +local turtleName = "turtle_" .. os.getComputerID() -- Default name +local directions = { + up = "up", down = "down", forward = "forward" +} + +-- Load configuration +local function loadConfig() + if fs.exists(configFile) then + local file = fs.open(configFile, "r") + local data = file.readAll() + file.close() + tasks = textutils.unserialize(data) or {} + end + + -- Load turtle name if set + if fs.exists("turtle_name.cfg") then + local nameFile = fs.open("turtle_name.cfg", "r") + turtleName = nameFile.readAll() + nameFile.close() + end +end + +-- Save configuration +local function saveConfig() + local file = fs.open(configFile, "w") + file.write(textutils.serialize(tasks)) + file.close() +end + +-- Save turtle name +local function saveTurtleName() + local nameFile = fs.open("turtle_name.cfg", "w") + nameFile.write(turtleName) + nameFile.close() +end + +-- Check if value is a direction +local function isDirection(value) + return directions[value] ~= nil +end + +-- Parse item requirements from string +local function parseItemRequirements(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: item:minCount + for item in input:gmatch("%S+") do + local name, minCount = item:match("([^:]+):(%d+)") + if name and minCount then + requirements[name] = tonumber(minCount) + else + requirements[item] = 0 -- No minimum requirement + end + end + end + + 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) + if not container then return nil end + + local items = {} + local containerList = container.list() + + for slot, item in pairs(containerList) do + items[slot] = { + count = item.count, + name = item.name + } + end + + 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 + 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, amount, tank.name) + totalTransferred = totalTransferred + transferred + + -- 移除更新任务配置的代码 + -- 不要更新任务配置中的要求数量 + 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) + 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 + + -- Get destination name for pushItems + local destName = peripheral.getName(destination) + + -- Check min count requirements + if task.items then + local sourceItems = getContainerItems(task.source) + local itemCounts = {} + + for slot, item in pairs(sourceItems) do + if task.items[item.name] then + itemCounts[item.name] = (itemCounts[item.name] or 0) + item.count + end + end + + for itemName, minCount in pairs(task.items) do + if minCount > 0 and (itemCounts[itemName] or 0) < minCount then + return false + end + end + end + + -- Transfer items directly + local sourceItems = getContainerItems(task.source) + local totalTransferred = 0 + + for slot, item in pairs(sourceItems) do + local shouldTransfer = not task.items or (task.items[item.name] ~= nil) + + if shouldTransfer then + local count = item.count + if task.items and task.items[item.name] then + count = math.min(count, task.items[item.name]) + end + + local transferred = source.pushItems(destName, slot, count) + totalTransferred = totalTransferred + transferred + + -- 移除更新任务配置的代码 + -- 不要更新任务配置中的要求数量 + end + end + + return totalTransferred > 0 + + -- Case 2: Source is direction, destination is container + elseif isDirection(task.source) and not isDirection(task.destination) then + local destination = peripheral.wrap(task.destination) + if not destination then + print("Error: Destination container not found: "..task.destination) + return false + end + + -- Suck items from direction (limited to 16 slots) + local sucked = false + local suckFunc = turtle.suck + if task.source == "up" then suckFunc = turtle.suckUp + elseif task.source == "down" then suckFunc = turtle.suckDown end + + for i = 1, 16 do + if suckFunc() then + sucked = true + else + break + end + end + + if not sucked then return false end + + -- Push items to destination container + local pushed = false + for slot = 1, 16 do + if turtle.getItemCount(slot) > 0 then + if destination.pullItems(turtleName, slot) > 0 then + pushed = true + end + end + end + + return pushed + + -- Case 3: Source is container, destination is direction + elseif not isDirection(task.source) and isDirection(task.destination) then + local source = peripheral.wrap(task.source) + if not source then + print("Error: Source container not found: "..task.source) + return false + end + + -- Check min count requirements + if task.items then + local sourceItems = getContainerItems(task.source) + local itemCounts = {} + + for slot, item in pairs(sourceItems) do + if task.items[item.name] then + itemCounts[item.name] = (itemCounts[item.name] or 0) + item.count + end + end + + for itemName, minCount in pairs(task.items) do + if minCount > 0 and (itemCounts[itemName] or 0) < minCount then + return false + end + end + end + + -- Pull items to turtle + local sourceItems = getContainerItems(task.source) + local pulled = false + + for slot, item in pairs(sourceItems) do + local shouldTransfer = not task.items or (task.items[item.name] ~= nil) + + if shouldTransfer then + local count = item.count + if task.items and task.items[item.name] then + count = math.min(count, task.items[item.name]) + end + + if source.pushItems(turtleName, slot, count) > 0 then + pulled = true + end + + -- 移除更新任务配置的代码 + -- 不要更新任务配置中的要求数量 + end + end + + if not pulled then return false end + + -- Drop items to direction + local dropFunc = turtle.drop + if task.destination == "up" then dropFunc = turtle.dropUp + elseif task.destination == "down" then dropFunc = turtle.dropDown end + + local dropped = false + for slot = 1, 16 do + if turtle.getItemCount(slot) > 0 then + turtle.select(slot) + if dropFunc() then + dropped = true + end + end + end + + return dropped + + -- Case 4: Both source and destination are directions + else + -- Suck items from source direction (limited to 16 slots) + local suckFunc = turtle.suck + if task.source == "up" then suckFunc = turtle.suckUp + elseif task.source == "down" then suckFunc = turtle.suckDown end + + local sucked = false + for i = 1, 16 do + if suckFunc() then + sucked = true + else + break + end + end + + if not sucked then return false end + + -- Drop items to destination direction + local dropFunc = turtle.drop + if task.destination == "up" then dropFunc = turtle.dropUp + elseif task.destination == "down" then dropFunc = turtle.dropDown end + + local dropped = false + for slot = 1, 16 do + if turtle.getItemCount(slot) > 0 then + turtle.select(slot) + if dropFunc() then + dropped = true + end + end + end + + return dropped + end +end + +-- Main task loop (optimized) +local function taskLoop() + while true do + for i, task in ipairs(tasks) do + local success, err = pcall(executeTransfer, task) + if not success then + print("Task "..i.." error: "..err) + end + end + os.sleep(0.5) -- Slightly longer sleep to reduce CPU usage + end +end + +-- Command processing +local function processCommand(cmd) + local args = {} + for word in cmd:gmatch("%S+") do + table.insert(args, word) + end + + if #args == 0 then return end + + local command = args[1]:lower() + + if command == "add" and #args >= 3 then + local newTask = { + type = "item", + source = args[2], + destination = args[3], + items = nil + } + + -- Parse item requirements + if #args > 3 then + local itemsInput = table.concat(args, " ", 4) + newTask.items = parseItemRequirements(itemsInput) + end + + table.insert(tasks, newTask) + saveConfig() + 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 + 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 + 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 + end + end + + elseif command == "remove" and #args >= 2 then + local index = tonumber(args[2]) + if index and tasks[index] then + table.remove(tasks, index) + saveConfig() + print("Task "..index.." removed") + else + print("Invalid task index") + end + + elseif command == "setname" and #args >= 2 then + turtleName = args[2] + saveTurtleName() + print("Turtle name set to: "..turtleName) + + elseif command == "help" then + print("Available commands:") + 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") + print("exit - Exit program") + + elseif command == "exit" then + print("Exiting program") + os.sleep(0.5) + error("Program terminated", 0) + end +end + +-- Initialize +loadConfig() +print("Turtle Logistics System v4.2 started. Type 'help' for commands.") +print("Current turtle name: "..turtleName) + +-- Main loop +parallel.waitForAll( + function() + while true do + write("> ") + local command = read() + processCommand(command) + end + end, + taskLoop +) \ No newline at end of file diff --git a/.history/Logistics/startup_20251022124918.lua b/.history/Logistics/startup_20251022124918.lua new file mode 100644 index 0000000..937e68e --- /dev/null +++ b/.history/Logistics/startup_20251022124918.lua @@ -0,0 +1,571 @@ +-- Turtle Logistics System v4.3 (Silent Mode & Full Transfer) +-- Supports direct container-to-container transfers for items and fluids +-- Config saved in config.cfg + +local configFile = "config.cfg" +local tasks = {} +local turtleName = "turtle_" .. os.getComputerID() -- Default name +local directions = { + up = "up", down = "down", forward = "forward" +} + +-- Load configuration +local function loadConfig() + if fs.exists(configFile) then + local file = fs.open(configFile, "r") + local data = file.readAll() + file.close() + tasks = textutils.unserialize(data) or {} + end + + -- Load turtle name if set + if fs.exists("turtle_name.cfg") then + local nameFile = fs.open("turtle_name.cfg", "r") + turtleName = nameFile.readAll() + nameFile.close() + end +end + +-- Save configuration +local function saveConfig() + local file = fs.open(configFile, "w") + file.write(textutils.serialize(tasks)) + file.close() +end + +-- Save turtle name +local function saveTurtleName() + local nameFile = fs.open("turtle_name.cfg", "w") + nameFile.write(turtleName) + nameFile.close() +end + +-- Check if value is a direction +local function isDirection(value) + return directions[value] ~= nil +end + +-- Parse item requirements from string +local function parseItemRequirements(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: item:minCount + for item in input:gmatch("%S+") do + local name, minCount = item:match("([^:]+):(%d+)") + if name and minCount then + requirements[name] = tonumber(minCount) + else + requirements[item] = 0 -- No minimum requirement + end + end + end + + 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) + if not container then return nil end + + local items = {} + local containerList = container.list() + + for slot, item in pairs(containerList) do + items[slot] = { + count = item.count, + name = item.name + } + end + + 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 (only if minAmount > 0) + 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 + -- Only check if minAmount > 0 + if minAmount > 0 and (fluidAmounts[fluidName] or 0) < minAmount then + 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 + -- If minAmount is 0, transfer all available + if task.fluids[tank.name] == 0 then + amount = tank.amount + else + amount = math.min(amount, task.fluids[tank.name]) + end + end + + -- Push fluid from source to destination + local transferred = source.pushFluid(task.destination, amount, tank.name) + totalTransferred = totalTransferred + transferred + 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) + 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 + + -- Get destination name for pushItems + local destName = peripheral.getName(destination) + + -- Check min count requirements (only if minCount > 0) + if task.items then + local sourceItems = getContainerItems(task.source) + local itemCounts = {} + + for slot, item in pairs(sourceItems) do + if task.items[item.name] then + itemCounts[item.name] = (itemCounts[item.name] or 0) + item.count + end + end + + for itemName, minCount in pairs(task.items) do + -- Only check if minCount > 0 + if minCount > 0 and (itemCounts[itemName] or 0) < minCount then + return false + end + end + end + + -- Transfer items directly + local sourceItems = getContainerItems(task.source) + local totalTransferred = 0 + + for slot, item in pairs(sourceItems) do + local shouldTransfer = not task.items or (task.items[item.name] ~= nil) + + if shouldTransfer then + local count = item.count + if task.items and task.items[item.name] then + -- If minCount is 0, transfer all available + if task.items[item.name] == 0 then + count = item.count + else + count = math.min(count, task.items[item.name]) + end + end + + local transferred = source.pushItems(destName, slot, count) + totalTransferred = totalTransferred + transferred + end + end + + return totalTransferred > 0 + + -- Case 2: Source is direction, destination is container + elseif isDirection(task.source) and not isDirection(task.destination) then + local destination = peripheral.wrap(task.destination) + if not destination then + print("Error: Destination container not found: "..task.destination) + return false + end + + -- Suck items from direction (limited to 16 slots) + local sucked = false + local suckFunc = turtle.suck + if task.source == "up" then suckFunc = turtle.suckUp + elseif task.source == "down" then suckFunc = turtle.suckDown end + + for i = 1, 16 do + if suckFunc() then + sucked = true + else + break + end + end + + if not sucked then return false end + + -- Push items to destination container + local pushed = false + for slot = 1, 16 do + if turtle.getItemCount(slot) > 0 then + if destination.pullItems(turtleName, slot) > 0 then + pushed = true + end + end + end + + return pushed + + -- Case 3: Source is container, destination is direction + elseif not isDirection(task.source) and isDirection(task.destination) then + local source = peripheral.wrap(task.source) + if not source then + print("Error: Source container not found: "..task.source) + return false + end + + -- Check min count requirements (only if minCount > 0) + if task.items then + local sourceItems = getContainerItems(task.source) + local itemCounts = {} + + for slot, item in pairs(sourceItems) do + if task.items[item.name] then + itemCounts[item.name] = (itemCounts[item.name] or 0) + item.count + end + end + + for itemName, minCount in pairs(task.items) do + -- Only check if minCount > 0 + if minCount > 0 and (itemCounts[itemName] or 0) < minCount then + return false + end + end + end + + -- Pull items to turtle + local sourceItems = getContainerItems(task.source) + local pulled = false + + for slot, item in pairs(sourceItems) do + local shouldTransfer = not task.items or (task.items[item.name] ~= nil) + + if shouldTransfer then + local count = item.count + if task.items and task.items[item.name] then + -- If minCount is 0, transfer all available + if task.items[item.name] == 0 then + count = item.count + else + count = math.min(count, task.items[item.name]) + end + end + + if source.pushItems(turtleName, slot, count) > 0 then + pulled = true + end + end + end + + if not pulled then return false end + + -- Drop items to direction + local dropFunc = turtle.drop + if task.destination == "up" then dropFunc = turtle.dropUp + elseif task.destination == "down" then dropFunc = turtle.dropDown end + + local dropped = false + for slot = 1, 16 do + if turtle.getItemCount(slot) > 0 then + turtle.select(slot) + if dropFunc() then + dropped = true + end + end + end + + return dropped + + -- Case 4: Both source and destination are directions + else + -- Suck items from source direction (limited to 16 slots) + local suckFunc = turtle.suck + if task.source == "up" then suckFunc = turtle.suckUp + elseif task.source == "down" then suckFunc = turtle.suckDown end + + local sucked = false + for i = 1, 16 do + if suckFunc() then + sucked = true + else + break + end + end + + if not sucked then return false end + + -- Drop items to destination direction + local dropFunc = turtle.drop + if task.destination == "up" then dropFunc = turtle.dropUp + elseif task.destination == "down" then dropFunc = turtle.dropDown end + + local dropped = false + for slot = 1, 16 do + if turtle.getItemCount(slot) > 0 then + turtle.select(slot) + if dropFunc() then + dropped = true + end + end + end + + return dropped + end +end + +-- Main task loop (optimized) +local function taskLoop() + while true do + for i, task in ipairs(tasks) do + local success, err = pcall(executeTransfer, task) + if not success then + print("Task "..i.." error: "..err) + end + end + os.sleep(0.5) -- Slightly longer sleep to reduce CPU usage + end +end + +-- Command processing +local function processCommand(cmd) + local args = {} + for word in cmd:gmatch("%S+") do + table.insert(args, word) + end + + if #args == 0 then return end + + local command = args[1]:lower() + + if command == "add" and #args >= 3 then + local newTask = { + type = "item", + source = args[2], + destination = args[3], + items = nil + } + + -- Parse item requirements + if #args > 3 then + local itemsInput = table.concat(args, " ", 4) + newTask.items = parseItemRequirements(itemsInput) + end + + table.insert(tasks, newTask) + saveConfig() + 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 + 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 + 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 + end + end + + elseif command == "remove" and #args >= 2 then + local index = tonumber(args[2]) + if index and tasks[index] then + table.remove(tasks, index) + saveConfig() + print("Task "..index.." removed") + else + print("Invalid task index") + end + + elseif command == "setname" and #args >= 2 then + turtleName = args[2] + saveTurtleName() + print("Turtle name set to: "..turtleName) + + elseif command == "help" then + print("Available commands:") + print("add [items] - Add item transfer task") + print(" Items format:") + print(" Simple: item1[:minCount] item2[:minCount] ...") + print(" JSON-like: {\"item1\":minCount, \"item2\":minCount}") + print(" Set minCount to 0 to transfer all available items") + print("addfluid [fluids] - Add fluid transfer task") + print(" Fluids format:") + print(" Simple: fluid1[:minAmount] fluid2[:minAmount] ...") + print(" JSON-like: {\"fluid1\":minAmount, \"fluid2\":minAmount}") + print(" Set minAmount to 0 to transfer all available fluid") + print("list - List all tasks") + print("remove - Remove task") + print("setname - Set turtle peripheral name") + print("exit - Exit program") + + elseif command == "exit" then + print("Exiting program") + os.sleep(0.5) + error("Program terminated", 0) + end +end + +-- Initialize +loadConfig() +print("Turtle Logistics System v4.3 started. Type 'help' for commands.") +print("Current turtle name: "..turtleName) + +-- Main loop +parallel.waitForAll( + function() + while true do + write("> ") + local command = read() + processCommand(command) + end + end, + taskLoop +) \ No newline at end of file diff --git a/Logistics/startup.lua b/Logistics/startup.lua index b30654c..937e68e 100644 --- a/Logistics/startup.lua +++ b/Logistics/startup.lua @@ -1,4 +1,4 @@ --- Turtle Logistics System v4.2 (Fluid Support) +-- Turtle Logistics System v4.3 (Silent Mode & Full Transfer) -- Supports direct container-to-container transfers for items and fluids -- Config saved in config.cfg @@ -160,7 +160,7 @@ local function executeFluidTransfer(task) return false end - -- Check min amount requirements + -- Check min amount requirements (only if minAmount > 0) if task.fluids then local sourceTanks = getFluidTanks(task.source) if not sourceTanks then return false end @@ -173,8 +173,8 @@ local function executeFluidTransfer(task) end for fluidName, minAmount in pairs(task.fluids) do + -- Only check if minAmount > 0 if minAmount > 0 and (fluidAmounts[fluidName] or 0) < minAmount then - print("Not enough "..fluidName.." ("..(fluidAmounts[fluidName] or 0).." < "..minAmount..")") return false end end @@ -192,17 +192,17 @@ local function executeFluidTransfer(task) 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]) + -- If minAmount is 0, transfer all available + if task.fluids[tank.name] == 0 then + amount = tank.amount + else + amount = math.min(amount, task.fluids[tank.name]) + end end -- Push fluid from source to destination - local transferred = source.pushFluid(task.destination, task.concat, task.name) + local transferred = source.pushFluid(task.destination, amount, tank.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 @@ -230,7 +230,7 @@ local function executeTransfer(task) -- Get destination name for pushItems local destName = peripheral.getName(destination) - -- Check min count requirements + -- Check min count requirements (only if minCount > 0) if task.items then local sourceItems = getContainerItems(task.source) local itemCounts = {} @@ -242,8 +242,8 @@ local function executeTransfer(task) end for itemName, minCount in pairs(task.items) do + -- Only check if minCount > 0 if minCount > 0 and (itemCounts[itemName] or 0) < minCount then - print("Not enough "..itemName.." ("..(itemCounts[itemName] or 0).." < "..minCount..")") return false end end @@ -259,16 +259,16 @@ local function executeTransfer(task) if shouldTransfer then local count = item.count if task.items and task.items[item.name] then - count = math.min(count, task.items[item.name]) + -- If minCount is 0, transfer all available + if task.items[item.name] == 0 then + count = item.count + else + count = math.min(count, task.items[item.name]) + end end 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 @@ -318,7 +318,7 @@ local function executeTransfer(task) return false end - -- Check min count requirements + -- Check min count requirements (only if minCount > 0) if task.items then local sourceItems = getContainerItems(task.source) local itemCounts = {} @@ -330,8 +330,8 @@ local function executeTransfer(task) end for itemName, minCount in pairs(task.items) do + -- Only check if minCount > 0 if minCount > 0 and (itemCounts[itemName] or 0) < minCount then - print("Not enough "..itemName.." ("..(itemCounts[itemName] or 0).." < "..minCount..")") return false end end @@ -347,7 +347,12 @@ local function executeTransfer(task) if shouldTransfer then local count = item.count if task.items and task.items[item.name] then - count = math.min(count, task.items[item.name]) + -- If minCount is 0, transfer all available + if task.items[item.name] == 0 then + count = item.count + else + count = math.min(count, task.items[item.name]) + end end if source.pushItems(turtleName, slot, count) > 0 then @@ -530,10 +535,12 @@ local function processCommand(cmd) print(" Items format:") print(" Simple: item1[:minCount] item2[:minCount] ...") print(" JSON-like: {\"item1\":minCount, \"item2\":minCount}") + print(" Set minCount to 0 to transfer all available items") print("addfluid [fluids] - Add fluid transfer task") print(" Fluids format:") print(" Simple: fluid1[:minAmount] fluid2[:minAmount] ...") print(" JSON-like: {\"fluid1\":minAmount, \"fluid2\":minAmount}") + print(" Set minAmount to 0 to transfer all available fluid") print("list - List all tasks") print("remove - Remove task") print("setname - Set turtle peripheral name") @@ -548,7 +555,7 @@ end -- Initialize loadConfig() -print("Turtle Logistics System v4.2 started. Type 'help' for commands.") +print("Turtle Logistics System v4.3 started. Type 'help' for commands.") print("Current turtle name: "..turtleName) -- Main loop