添加货运程序

This commit is contained in:
HKXluo
2025-10-22 11:45:33 +08:00
parent 6d456c121b
commit e908c0bf4d

400
Logistics/startup.lua Normal file
View File

@@ -0,0 +1,400 @@
-- Turtle Logistics System v4.1 (Optimized)
-- Supports direct container-to-container transfers
-- 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
-- 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
-- Execute item transfer with min count requirements (Optimized)
local function executeTransfer(task)
-- 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
print("Not enough "..itemName.." ("..(itemCounts[itemName] or 0).." < "..minCount..")")
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
print("Not enough "..itemName.." ("..(itemCounts[itemName] or 0).." < "..minCount..")")
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 = {
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("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)
end
end
itemInfo = " ("..table.concat(itemsList, ", ")..")"
end
print("["..i.."] "..task.source.." -> "..task.destination..itemInfo)
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 <source> <destination> [items] - Add transfer task")
print(" Items format:")
print(" Simple: item1[:minCount] item2[:minCount] ...")
print(" JSON-like: {\"item1\":minCount, \"item2\":minCount}")
print("list - List all tasks")
print("remove <index> - Remove task")
print("setname <name> - 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 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
)