Files
AcScripts/autocraft.lua
T
2026-09-05 03:59:29 +02:00

127 lines
4.1 KiB
Lua

function agc(name)
return assert(components:getFirst(name), "failed to get component "..name)
end
local computer = agc("computer")
local fs = require("filesystem")
local kernel = require("kernel")
local crafter = agc("digitalCrafter")
print("it works")
local function craft(...)
while true do
local cooldown = crafter.cooldownRemaining
if cooldown <= 0 then break end
sleep(cooldown)
end
return crafter:craft(...)
end
print("Which item would you like to craft?")
local buf = ""
local ctrlCReceived = false
local keyEvents = {}
kernel:registerEventCallback("charTyped", function(...) table.insert(keyEvents, {...}) end)
kernel:registerEventCallback("keyPressed", function(...) table.insert(keyEvents, {...}) end)
local matchingItems = {}
while true do
if #keyEvents > 0 then
local event = table.remove(keyEvents, 1)
if event[1] == "charTyped" then
if event[2] == "\n" then
if #matchingItems == 1 then
print()
print("Selected item: "..tostring(matchingItems[1]))
break
end
elseif event[2] == "\b" then
if #buf > 0 then
buf = buf:sub(1, #buf-1)
end
else
buf = buf .. event[2]
end
matchingItems = #buf > 0 and crafter:searchItemsByName(buf) or {}
printInline("\r["..(#matchingItems).." match"..(#matchingItems ~= 1 and "es" or "").."] "..buf.." ")
elseif event[1] == "keyPressed" then
local charRepr, code, _, mod = table.unpack(event, 2)
if code == 67 and (mod&2>0) then -- ctrl+c
ctrlCReceived = true
error("ctrl c pressed")
end
end
else
sleep(0.25)
end
end
assert(#matchingItems == 1, "not exactly 1 matching item")
local matchingItem = matchingItems[1]
local function readNumber(prompt)
printInline(prompt)
keyEvents = {}
local buf = ""
while true do
if #keyEvents > 0 then
local event = table.remove(keyEvents, 1)
if event[1] == "charTyped" then
if event[2] == "\n" then
if #matchingItems == 1 then
local num = tonumber(buf)
if num ~= nil then print() return num end
buf = ""
end
elseif event[2] == "\b" then
if #buf > 0 then
buf = buf:sub(1, #buf-1)
end
else
buf = buf .. event[2]
end
printInline("\r"..prompt.. " "..buf.." ")
elseif event[1] == "keyPressed" then
local charRepr, code, _, mod = table.unpack(event, 2)
if code == 67 and (mod&2>0) then -- ctrl+c
ctrlCReceived = true
error("ctrl c pressed")
end
end
else
sleep(0.25)
end
end
end
local quantity = readNumber("How many items do we want to craft?")
print("We want to craft "..quantity.."x "..matchingItem)
local craftingRecipesToExecute = {} -- this is a stack, use table.insert to add new recipes to craft, and remove from end when executing the recipes
local itemsLeftToCraft = {[matchingItem] = quantity} -- key=itemname, value=amountNeeded
local reservedItems = {} -- itemname:reservedQuantity; needed so we dont queue two recipes that need more ingredients in total than we have in our storage system
while next(itemsLeftToCraft) ~= nil do -- if there is anything left that needs to be crafted
local toCraft = assert(next(itemsLeftToCraft), "somehow got nil1")
itemsLeftToCraft[toCraft] = 0
-- check if cached recipe exists, if so use that
-- else
-- get possible recipes
-- compute how often we apply this recipe
-- add to craftingRecipesToExecute
-- reserve items we need for crafting, or add them to itemsLeftToCraft
-- TODO ac: add extraoutputs to 'recipe' datastructure
end