Files
AcScripts/autocraft/recipeParseLib.lua
2026-09-11 08:50:09 +02:00

95 lines
3.4 KiB
Lua

local rv = {}
--[[
local function tailcall()
print("called")
if true then
print("calling")
return tailcall()
end
end
tailcall()
]]
local fs = require("filesystem")
local function trim(str) return string.gsub(str,"^[%s]*", ""):gsub("[%s]*$", "") end
function rv:getRecipes()
if not fs:fileExists("recipes.txt") then return {} end
local recipeText = fs:readAllText("recipes.txt")
local splits = string.split(recipeText, ";")
local allRecipes = {} -- outputInternalName : {resultCount:int, slots:{{possible options.....},nil,nil,....}}
for _, value in ipairs(splits) do
local trimmed = trim(value)
if #(trimmed) > 0 then
--print("trimmed:", ">>"..trimmed.."<<")
local resCnt, resItem, ingredients = trimmed:match("^(%d*) (%S+) = ([^;]*)$")
assert(ingredients, ("failed to match ingredients for line: >>%s<< from >>%s<<"):format(trimmed, value))
ingredients = trim(ingredients)
--print(("Can craft %sx %s using ingredients %s"):format(resCnt, resItem, ingredients))
assert(allRecipes[resItem] == nil, ("more than one recipe defined for %s"):format(resItem))
local slotTable = {}
for slotIdx, optionsString in ipairs(ingredients:gsub("%s",""):split(",")) do
if optionsString == "nil" then
slotTable[slotIdx] = nil
else
local slotOptions = {}
for _, option in ipairs(optionsString:split("|")) do
assert((option ~= nil) and (option ~= "nil"), "somehow option was nil or nilstring")
assert(option:find(":"), string.format("slotoptions '%s' does not contain :",option))
table.insert(slotOptions, option)
end
slotTable[slotIdx] = slotOptions
end
end
allRecipes[resItem] = {
resultCount = assert(tonumber(resCnt), ("couldnt parse number '%s'"):format(resCnt)),
slots = slotTable,
resultItem = resItem
}
end
end
return allRecipes
end
function rv:serializeSingleRecipe(recipe)
local slots = {}
for i = 1, 9 do
if recipe.slots[i] == nil or #(recipe.slots[i]) == 0 then
slots[i] = "nil"
else
slots[i] = table.concat(recipe.slots[i], "|")
end
end
return string.format("%d %s = %s", recipe.resultCount, recipe.resultItem, table.concat(slots,","))..";"
end
local function serializeRecipes(recipeTable)
local newText = ""
for k,v in pairs(recipeTable) do
assert(k == v.resultItem, "somehow resultItem doesnt match the key")
newText = newText .. rv:serializeSingleRecipe(v) .. "\n"
end
return newText
end
function rv:addNewRecipe(newRecipeTable)
local cnt = assert(newRecipeTable.resultCount, "resultCount not set")
local slots = assert(newRecipeTable.slots, "slots not set")
local resultItem = assert(newRecipeTable.resultItem, "resultItem not set")
local currRecipes = rv:getRecipes()
assert(currRecipes[resultItem] == nil, ("recipe for %s has already been defined"):format(resultItem))
currRecipes[resultItem] = {
resultCount = cnt,
slots = slots,
resultItem = resultItem
}
fs:writeAllText("recipes.txt", serializeRecipes(currRecipes))
end
return rv