lora wip
This commit is contained in:
370
inventoryManager/apis/lora.lua
Normal file
370
inventoryManager/apis/lora.lua
Normal file
@@ -0,0 +1,370 @@
|
||||
local Craft = require('turtle.craft')
|
||||
local itemDB = require('itemDB')
|
||||
local Util = require('util')
|
||||
|
||||
local os = _G.os
|
||||
local term = _G.term
|
||||
local turtle = _G.turtle
|
||||
|
||||
local Lora = {
|
||||
RECIPES_FILE = 'usr/config/recipes.db',
|
||||
RESOURCE_FILE = 'usr/config/resources.db',
|
||||
|
||||
STATUS_INFO = 'info',
|
||||
STATUS_WARNING = 'warning',
|
||||
STATUS_ERROR = 'error',
|
||||
|
||||
tasks = { },
|
||||
craftingStatus = { },
|
||||
}
|
||||
|
||||
function Lora:init(context)
|
||||
self.context = context
|
||||
end
|
||||
|
||||
function Lora:getContext()
|
||||
return self.context
|
||||
end
|
||||
|
||||
function Lora:pauseCrafting()
|
||||
self.craftingPaused = true
|
||||
end
|
||||
|
||||
function Lora:resumeCrafting()
|
||||
self.craftingPaused = false
|
||||
end
|
||||
|
||||
function Lora:isCraftingPaused()
|
||||
return self.craftingPaused
|
||||
end
|
||||
|
||||
function Lora:uniqueKey(item)
|
||||
return table.concat({ item.name, item.damage, item.nbtHash }, ':')
|
||||
end
|
||||
|
||||
function Lora:getCraftingStatus()
|
||||
return self.craftingStatus
|
||||
end
|
||||
|
||||
function Lora:resetCraftingStatus()
|
||||
self.craftingStatus = { }
|
||||
self.context.inventoryAdapter.activity = { }
|
||||
end
|
||||
|
||||
function Lora:updateCraftingStatus(list)
|
||||
for k,v in pairs(list) do
|
||||
self.craftingStatus[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
function Lora:registerTask(task)
|
||||
table.insert(self.tasks, task)
|
||||
end
|
||||
|
||||
function Lora:showError(msg)
|
||||
term.clear()
|
||||
self.context.jobList:showError()
|
||||
print(msg)
|
||||
print('rebooting in 5 secs')
|
||||
os.sleep(5)
|
||||
os.reboot()
|
||||
end
|
||||
|
||||
function Lora:getItem(items, inItem, ignoreDamage, ignoreNbtHash)
|
||||
for _,item in pairs(items) do
|
||||
if item.name == inItem.name and
|
||||
(ignoreDamage or item.damage == inItem.damage) and
|
||||
(ignoreNbtHash or item.nbtHash == inItem.nbtHash) then
|
||||
return item
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Lora:getItemWithQty(res, ignoreDamage, ignoreNbtHash)
|
||||
local items = self:listItems()
|
||||
local item = self:getItem(items, res, ignoreDamage, ignoreNbtHash)
|
||||
|
||||
if item and (ignoreDamage or ignoreNbtHash) then
|
||||
local count = 0
|
||||
|
||||
for _,v in pairs(items) do
|
||||
if item.name == v.name and
|
||||
(ignoreDamage or item.damage == v.damage) and
|
||||
(ignoreNbtHash or item.nbtHash == v.nbtHash) then
|
||||
count = count + v.count
|
||||
end
|
||||
end
|
||||
item.count = count
|
||||
end
|
||||
|
||||
return item
|
||||
end
|
||||
|
||||
function Lora:clearGrid()
|
||||
local function clear()
|
||||
turtle.eachFilledSlot(function(slot)
|
||||
self.context.inventoryAdapter:insert(slot.index, slot.count, nil, slot)
|
||||
end)
|
||||
|
||||
for i = 1, 16 do
|
||||
if turtle.getItemCount(i) ~= 0 then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
return clear() or clear()
|
||||
end
|
||||
|
||||
function Lora:eject(item, qty)
|
||||
local s, m = pcall(function()
|
||||
self.context.inventoryAdapter:provide(item, qty)
|
||||
turtle.emptyInventory()
|
||||
end)
|
||||
if not s and m then
|
||||
debug(m)
|
||||
end
|
||||
end
|
||||
|
||||
function Lora:mergeResources(t)
|
||||
for _,v in pairs(self.context.resources) do
|
||||
local item = Lora:getItem(t, v)
|
||||
if item then
|
||||
Util.merge(item, v)
|
||||
else
|
||||
item = Util.shallowCopy(v)
|
||||
item.count = 0
|
||||
table.insert(t, item)
|
||||
end
|
||||
end
|
||||
|
||||
for k in pairs(Craft.recipes) do
|
||||
local v = itemDB:splitKey(k)
|
||||
local item = Lora:getItem(t, v)
|
||||
if not item then
|
||||
item = Util.shallowCopy(v)
|
||||
item.count = 0
|
||||
table.insert(t, item)
|
||||
end
|
||||
item.has_recipe = true
|
||||
end
|
||||
|
||||
for _,v in pairs(t) do
|
||||
if not v.displayName then
|
||||
v.displayName = itemDB:getName(v)
|
||||
end
|
||||
v.lname = v.displayName:lower()
|
||||
end
|
||||
end
|
||||
|
||||
function Lora:saveResources()
|
||||
local t = { }
|
||||
|
||||
for k,v in pairs(self.context.resources) do
|
||||
v = Util.shallowCopy(v)
|
||||
local keys = Util.transpose({ 'auto', 'low', 'limit',
|
||||
'ignoreDamage', 'ignoreNbtHash',
|
||||
'rsControl', 'rsDevice', 'rsSide' })
|
||||
|
||||
for _,key in pairs(Util.keys(v)) do
|
||||
if not keys[key] then
|
||||
v[key] = nil
|
||||
end
|
||||
end
|
||||
if not Util.empty(v) then
|
||||
t[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
Util.writeTable(Lora.RESOURCE_FILE, t)
|
||||
end
|
||||
|
||||
-- Return a list of everything in the system
|
||||
function Lora:listItems()
|
||||
for _ = 1, 5 do
|
||||
self.items = self.context.inventoryAdapter:listItems()
|
||||
if self.items then
|
||||
break
|
||||
end
|
||||
-- jobList:showError('Error - retrying in 3 seconds')
|
||||
os.sleep(3)
|
||||
end
|
||||
if not self.items then
|
||||
self:showError('Error - rebooting in 5 seconds')
|
||||
end
|
||||
|
||||
return self.items
|
||||
end
|
||||
|
||||
function Lora:addCraftingRequest(item, craftList, count)
|
||||
local key = self:uniqueKey(item)
|
||||
local request = craftList[key]
|
||||
if not craftList[key] then
|
||||
request = { name = item.name, damage = item.damage, nbtHash = item.nbtHash, count = 0 }
|
||||
request.displayName = itemDB:getName(request)
|
||||
craftList[key] = request
|
||||
end
|
||||
request.count = request.count + count
|
||||
return request
|
||||
end
|
||||
|
||||
-- Craft
|
||||
function Lora:craftItem(recipe, items, originalItem, craftList, count)
|
||||
local missing = { }
|
||||
local toCraft = Craft.getCraftableAmount(recipe, count, items, missing)
|
||||
if missing.name then
|
||||
originalItem.status = string.format('%s missing', itemDB:getName(missing.name))
|
||||
originalItem.statusCode = self.STATUS_WARNING
|
||||
end
|
||||
|
||||
local crafted = 0
|
||||
|
||||
if toCraft > 0 then
|
||||
crafted = Craft.craftRecipe(recipe, toCraft, self.context.inventoryAdapter)
|
||||
self:clearGrid()
|
||||
items = self:listItems()
|
||||
count = count - crafted
|
||||
end
|
||||
|
||||
if count > 0 and items then
|
||||
local ingredients = Craft.getResourceList4(recipe, items, count)
|
||||
for _,ingredient in pairs(ingredients) do
|
||||
if ingredient.need > 0 then
|
||||
local item = self:addCraftingRequest(ingredient, craftList, ingredient.need)
|
||||
if Craft.findRecipe(item) then
|
||||
item.status = string.format('%s missing', itemDB:getName(ingredient))
|
||||
item.statusCode = self.STATUS_WARNING
|
||||
else
|
||||
item.status = 'no recipe'
|
||||
item.statusCode = self.STATUS_ERROR
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return crafted
|
||||
end
|
||||
|
||||
-- Craft as much as possible regardless if all ingredients are available
|
||||
function Lora:forceCraftItem(inRecipe, items, originalItem, craftList, inCount)
|
||||
local summed = { }
|
||||
local throttle = Util.throttle()
|
||||
|
||||
local function sumItems(recipe, count)
|
||||
count = math.ceil(count / recipe.count)
|
||||
local craftable = count
|
||||
|
||||
for key,iqty in pairs(Craft.sumIngredients(recipe)) do
|
||||
throttle()
|
||||
local item = itemDB:splitKey(key)
|
||||
local summedItem = summed[key]
|
||||
if not summedItem then
|
||||
summedItem = Util.shallowCopy(item)
|
||||
summedItem.recipe = Craft.findRecipe(item)
|
||||
summedItem.count = Craft.getItemCount(items, key)
|
||||
summedItem.need = 0
|
||||
summedItem.used = 0
|
||||
summedItem.craftable = 0
|
||||
summed[key] = summedItem
|
||||
end
|
||||
|
||||
local total = count * iqty -- 4 * 2
|
||||
local used = math.min(summedItem.count, total) -- 5
|
||||
local need = total - used -- 3
|
||||
|
||||
if recipe.craftingTools and recipe.craftingTools[key] then
|
||||
if summedItem.count > 0 then
|
||||
summedItem.used = 1
|
||||
summedItem.need = 0
|
||||
need = 0
|
||||
elseif not summedItem.recipe then
|
||||
summedItem.need = 1
|
||||
need = 1
|
||||
else
|
||||
need = 1
|
||||
end
|
||||
else
|
||||
summedItem.count = summedItem.count - used
|
||||
summedItem.used = summedItem.used + used
|
||||
end
|
||||
|
||||
if need > 0 then
|
||||
if not summedItem.recipe then
|
||||
craftable = math.min(craftable, math.floor(used / iqty))
|
||||
summedItem.need = summedItem.need + need
|
||||
else
|
||||
local c = sumItems(summedItem.recipe, need) -- 4
|
||||
craftable = math.min(craftable, math.floor((used + c) / iqty))
|
||||
summedItem.craftable = summedItem.craftable + c
|
||||
end
|
||||
end
|
||||
end
|
||||
if craftable > 0 then
|
||||
craftable = Craft.craftRecipe(recipe, craftable * recipe.count,
|
||||
self.context.inventoryAdapter) / recipe.count
|
||||
self:clearGrid()
|
||||
end
|
||||
|
||||
return craftable * recipe.count
|
||||
end
|
||||
|
||||
local count = sumItems(inRecipe, inCount)
|
||||
|
||||
if count < inCount then
|
||||
for _,ingredient in pairs(summed) do
|
||||
if ingredient.need > 0 then
|
||||
local item = self:addCraftingRequest(ingredient, craftList, ingredient.need)
|
||||
if Craft.findRecipe(item) then
|
||||
item.status = string.format('%s missing', itemDB:getName(ingredient))
|
||||
item.statusCode = self.STATUS_WARNING
|
||||
else
|
||||
item.status = '(no recipe)'
|
||||
item.statusCode = self.STATUS_ERROR
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return count
|
||||
end
|
||||
|
||||
function Lora:craft(recipe, items, item, craftList)
|
||||
item.status = nil
|
||||
item.statusCode = nil
|
||||
item.crafted = 0
|
||||
|
||||
if self:isCraftingPaused() then
|
||||
return
|
||||
end
|
||||
|
||||
if not self:clearGrid() then
|
||||
item.status = 'Grid obstructed'
|
||||
item.statusCode = self.STATUS_ERROR
|
||||
return
|
||||
end
|
||||
|
||||
if item.forceCrafting then
|
||||
item.crafted = self:forceCraftItem(recipe, items, item, craftList, item.count)
|
||||
else
|
||||
item.crafted = self:craftItem(recipe, items, item, craftList, item.count)
|
||||
end
|
||||
end
|
||||
|
||||
function Lora:craftItems(craftList)
|
||||
for _,key in pairs(Util.keys(craftList)) do
|
||||
local item = craftList[key]
|
||||
if item.count > 0 then
|
||||
local recipe = Craft.recipes[key]
|
||||
if recipe then
|
||||
self:craft(recipe, self:listItems(), item, craftList)
|
||||
elseif not self.context.controllerAdapter then
|
||||
item.status = '(no recipe)'
|
||||
item.statusCode = self.STATUS_ERROR
|
||||
end
|
||||
end
|
||||
end
|
||||
self:updateCraftingStatus(craftList)
|
||||
for _,v in pairs(craftList) do
|
||||
debug(v)
|
||||
end
|
||||
end
|
||||
|
||||
return Lora
|
||||
@@ -1,334 +0,0 @@
|
||||
local Craft = require('turtle.craft')
|
||||
local itemDB = require('itemDB')
|
||||
local Util = require('util')
|
||||
|
||||
local os = _G.os
|
||||
local term = _G.term
|
||||
local turtle = _G.turtle
|
||||
|
||||
local Lora = {
|
||||
RECIPES_FILE = 'usr/config/recipes.db',
|
||||
RESOURCE_FILE = 'usr/config/resources.db',
|
||||
|
||||
STATUS_INFO = 'info',
|
||||
STATUS_WARNING = 'warning',
|
||||
STATUS_ERROR = 'error',
|
||||
|
||||
tasks = { },
|
||||
craftingStatus = { },
|
||||
}
|
||||
|
||||
function Lora:init(context)
|
||||
self.context = context
|
||||
end
|
||||
|
||||
function Lora:getContext()
|
||||
return self.context
|
||||
end
|
||||
|
||||
function Lora:pauseCrafting()
|
||||
self.craftingPaused = true
|
||||
end
|
||||
|
||||
function Lora:resumeCrafting()
|
||||
self.craftingPaused = false
|
||||
end
|
||||
|
||||
function Lora:isCraftingPaused()
|
||||
return self.craftingPaused
|
||||
end
|
||||
|
||||
function Lora:uniqueKey(item)
|
||||
return table.concat({ item.name, item.damage, item.nbtHash }, ':')
|
||||
end
|
||||
|
||||
function Lora:getCraftingStatus()
|
||||
return self.craftingStatus
|
||||
end
|
||||
|
||||
function Lora:resetCraftingStatus()
|
||||
self.craftingStatus = { }
|
||||
end
|
||||
|
||||
function Lora:updateCraftingStatus(list)
|
||||
for k,v in pairs(list) do
|
||||
self.craftingStatus[k] = v
|
||||
end
|
||||
|
||||
self.context.jobList:updateList(self.craftingStatus)
|
||||
end
|
||||
|
||||
function Lora:registerTask(task)
|
||||
table.insert(self.tasks, task)
|
||||
end
|
||||
|
||||
function Lora:showError(msg)
|
||||
term.clear()
|
||||
self.context.jobList:showError()
|
||||
print(msg)
|
||||
print('rebooting in 5 secs')
|
||||
os.sleep(5)
|
||||
os.reboot()
|
||||
end
|
||||
|
||||
function Lora:getItem(items, inItem, ignoreDamage, ignoreNbtHash)
|
||||
for _,item in pairs(items) do
|
||||
if item.name == inItem.name and
|
||||
(ignoreDamage or item.damage == inItem.damage) and
|
||||
(ignoreNbtHash or item.nbtHash == inItem.nbtHash) then
|
||||
return item
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Lora:getItemWithQty(res, ignoreDamage, ignoreNbtHash)
|
||||
local items = self:listItems()
|
||||
local item = self:getItem(items, res, ignoreDamage, ignoreNbtHash)
|
||||
|
||||
if item and (ignoreDamage or ignoreNbtHash) then
|
||||
local count = 0
|
||||
|
||||
for _,v in pairs(items) do
|
||||
if item.name == v.name and
|
||||
(ignoreDamage or item.damage == v.damage) and
|
||||
(ignoreNbtHash or item.nbtHash == v.nbtHash) then
|
||||
count = count + v.count
|
||||
end
|
||||
end
|
||||
item.count = count
|
||||
end
|
||||
|
||||
return item
|
||||
end
|
||||
|
||||
function Lora:clearGrid()
|
||||
local function clear()
|
||||
turtle.eachFilledSlot(function(slot)
|
||||
self.context.inventoryAdapter:insert(slot.index, slot.count, nil, slot)
|
||||
end)
|
||||
|
||||
for i = 1, 16 do
|
||||
if turtle.getItemCount(i) ~= 0 then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
return clear() or clear()
|
||||
end
|
||||
|
||||
function Lora:eject(item, qty)
|
||||
local s, m = pcall(function()
|
||||
self.context.inventoryAdapter:provide(item, qty)
|
||||
turtle.emptyInventory()
|
||||
end)
|
||||
if not s and m then
|
||||
debug(m)
|
||||
end
|
||||
end
|
||||
|
||||
function Lora:saveResources()
|
||||
local t = { }
|
||||
|
||||
for k,v in pairs(self.context.resources) do
|
||||
v = Util.shallowCopy(v)
|
||||
local keys = Util.transpose({ 'auto', 'low', 'limit',
|
||||
'ignoreDamage', 'ignoreNbtHash',
|
||||
'rsControl', 'rsDevice', 'rsSide' })
|
||||
|
||||
for _,key in pairs(Util.keys(v)) do
|
||||
if not keys[key] then
|
||||
v[key] = nil
|
||||
end
|
||||
end
|
||||
if not Util.empty(v) then
|
||||
t[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
Util.writeTable(Lora.RESOURCE_FILE, t)
|
||||
end
|
||||
|
||||
-- Return a list of everything in the system
|
||||
function Lora:listItems()
|
||||
for _ = 1, 5 do
|
||||
self.items = self.context.inventoryAdapter:listItems()
|
||||
if self.items then
|
||||
break
|
||||
end
|
||||
-- jobList:showError('Error - retrying in 3 seconds')
|
||||
os.sleep(3)
|
||||
end
|
||||
if not self.items then
|
||||
self:showError('Error - rebooting in 5 seconds')
|
||||
end
|
||||
|
||||
return self.items
|
||||
end
|
||||
|
||||
function Lora:addCraftingRequest(item, craftList, count)
|
||||
local key = self:uniqueKey(item)
|
||||
local request = craftList[key]
|
||||
if not craftList[key] then
|
||||
request = { name = item.name, damage = item.damage, nbtHash = item.nbtHash, count = 0 }
|
||||
request.displayName = itemDB:getName(request)
|
||||
craftList[key] = request
|
||||
end
|
||||
request.count = request.count + count
|
||||
return request
|
||||
end
|
||||
|
||||
-- Craft
|
||||
function Lora:craftItem(recipe, items, originalItem, craftList, count)
|
||||
local missing = { }
|
||||
local toCraft = Craft.getCraftableAmount(recipe, count, items, missing)
|
||||
if missing.name then
|
||||
originalItem.status = string.format('%s missing', itemDB:getName(missing.name))
|
||||
originalItem.statusCode = self.STATUS_WARNING
|
||||
end
|
||||
|
||||
local crafted = 0
|
||||
|
||||
if toCraft > 0 then
|
||||
crafted = Craft.craftRecipe(recipe, toCraft, self.context.inventoryAdapter)
|
||||
self:clearGrid()
|
||||
items = self:listItems()
|
||||
count = count - crafted
|
||||
end
|
||||
|
||||
if count > 0 and items then
|
||||
local ingredients = Craft.getResourceList4(recipe, items, count)
|
||||
for _,ingredient in pairs(ingredients) do
|
||||
if ingredient.need > 0 then
|
||||
local item = self:addCraftingRequest(ingredient, craftList, ingredient.need)
|
||||
if Craft.findRecipe(item) then
|
||||
item.status = string.format('%s missing', itemDB:getName(ingredient))
|
||||
item.statusCode = self.STATUS_WARNING
|
||||
else
|
||||
item.status = 'no recipe'
|
||||
item.statusCode = self.STATUS_ERROR
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return crafted
|
||||
end
|
||||
|
||||
-- Craft as much as possible regardless if all ingredients are available
|
||||
function Lora:forceCraftItem(inRecipe, items, originalItem, craftList, inCount)
|
||||
local summed = { }
|
||||
local throttle = Util.throttle()
|
||||
|
||||
local function sumItems(recipe, count)
|
||||
count = math.ceil(count / recipe.count)
|
||||
local craftable = count
|
||||
|
||||
for key,iqty in pairs(Craft.sumIngredients(recipe)) do
|
||||
throttle()
|
||||
local item = itemDB:splitKey(key)
|
||||
local summedItem = summed[key]
|
||||
if not summedItem then
|
||||
summedItem = Util.shallowCopy(item)
|
||||
summedItem.recipe = Craft.findRecipe(item)
|
||||
summedItem.count = Craft.getItemCount(items, key)
|
||||
summedItem.need = 0
|
||||
summedItem.used = 0
|
||||
summedItem.craftable = 0
|
||||
summed[key] = summedItem
|
||||
end
|
||||
|
||||
local total = count * iqty -- 4 * 2
|
||||
local used = math.min(summedItem.count, total) -- 5
|
||||
local need = total - used -- 3
|
||||
|
||||
if recipe.craftingTools and recipe.craftingTools[key] then
|
||||
if summedItem.count > 0 then
|
||||
summedItem.used = 1
|
||||
summedItem.need = 0
|
||||
need = 0
|
||||
elseif not summedItem.recipe then
|
||||
summedItem.need = 1
|
||||
need = 1
|
||||
else
|
||||
need = 1
|
||||
end
|
||||
else
|
||||
summedItem.count = summedItem.count - used
|
||||
summedItem.used = summedItem.used + used
|
||||
end
|
||||
|
||||
if need > 0 then
|
||||
if not summedItem.recipe then
|
||||
craftable = math.min(craftable, math.floor(used / iqty))
|
||||
summedItem.need = summedItem.need + need
|
||||
else
|
||||
local c = sumItems(summedItem.recipe, need) -- 4
|
||||
craftable = math.min(craftable, math.floor((used + c) / iqty))
|
||||
summedItem.craftable = summedItem.craftable + c
|
||||
end
|
||||
end
|
||||
end
|
||||
if craftable > 0 then
|
||||
craftable = Craft.craftRecipe(recipe, craftable * recipe.count,
|
||||
self.context.inventoryAdapter) / recipe.count
|
||||
self:clearGrid()
|
||||
end
|
||||
|
||||
return craftable * recipe.count
|
||||
end
|
||||
|
||||
local count = sumItems(inRecipe, inCount)
|
||||
|
||||
if count < inCount then
|
||||
for _,ingredient in pairs(summed) do
|
||||
if ingredient.need > 0 then
|
||||
local item = self:addCraftingRequest(ingredient, craftList, ingredient.need)
|
||||
if Craft.findRecipe(item) then
|
||||
item.status = string.format('%s missing', itemDB:getName(ingredient))
|
||||
item.statusCode = self.STATUS_WARNING
|
||||
else
|
||||
item.status = '(no recipe)'
|
||||
item.statusCode = self.STATUS_ERROR
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return count
|
||||
end
|
||||
|
||||
function Lora:craft(recipe, items, item, craftList)
|
||||
item.status = nil
|
||||
item.statusCode = nil
|
||||
item.crafted = 0
|
||||
|
||||
if self:isCraftingPaused() then
|
||||
return
|
||||
end
|
||||
|
||||
if not self:clearGrid() then
|
||||
item.status = 'Grid obstructed'
|
||||
item.statusCode = self.STATUS_ERROR
|
||||
return
|
||||
end
|
||||
|
||||
if item.forceCrafting then
|
||||
item.crafted = self:forceCraftItem(recipe, items, item, craftList, item.count)
|
||||
else
|
||||
item.crafted = self:craftItem(recipe, items, item, craftList, item.count)
|
||||
end
|
||||
end
|
||||
|
||||
function Lora:craftItems(craftList)
|
||||
for _,key in pairs(Util.keys(craftList)) do
|
||||
local item = craftList[key]
|
||||
local recipe = Craft.recipes[key]
|
||||
if recipe then
|
||||
self:craft(recipe, self:listItems(), item, craftList)
|
||||
elseif not self.context.controllerAdapter then
|
||||
item.status = '(no recipe)'
|
||||
item.statusCode = self.STATUS_ERROR
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return Lora
|
||||
@@ -1,12 +0,0 @@
|
||||
local Util = require('util')
|
||||
|
||||
local fs = _G.fs
|
||||
local shell = _ENV.shell
|
||||
|
||||
local Tasks = {
|
||||
list = { }
|
||||
}
|
||||
|
||||
|
||||
|
||||
return Tasks
|
||||
@@ -12,6 +12,7 @@ function NetworkedAdapter:init(args)
|
||||
remoteDefaults = { },
|
||||
dirty = true,
|
||||
listCount = 0,
|
||||
activity = { },
|
||||
}
|
||||
Util.merge(self, defaults)
|
||||
Util.merge(self, args)
|
||||
@@ -43,11 +44,9 @@ listCount = 0,
|
||||
elseif not b.priority then
|
||||
return true
|
||||
end
|
||||
return a.priority < b.priority
|
||||
return a.priority > b.priority
|
||||
end)
|
||||
end
|
||||
|
||||
_G._p = self --------------------------------------------- DEBUG
|
||||
end
|
||||
|
||||
function NetworkedAdapter:isValid()
|
||||
@@ -66,6 +65,10 @@ function NetworkedAdapter:listItems(throttle)
|
||||
end
|
||||
self.listCount = self.listCount + 1
|
||||
debug(self.listCount)
|
||||
|
||||
-- todo: only listItems from dirty remotes
|
||||
-- todo: better handling of empty inventories
|
||||
|
||||
local cache = { }
|
||||
local items = { }
|
||||
throttle = throttle or Util.throttle()
|
||||
@@ -111,6 +114,7 @@ function NetworkedAdapter:getItemInfo(item)
|
||||
end
|
||||
|
||||
function NetworkedAdapter:provide(item, qty, slot, direction)
|
||||
local key = table.concat({ item.name, item.damage, item.nbtHash }, ':')
|
||||
local total = 0
|
||||
|
||||
for _, remote in ipairs(self.remotes) do
|
||||
@@ -119,6 +123,8 @@ debug('%s -> slot %d: %d %s', remote.side, slot or -1, qty, item.name)
|
||||
if amount > 0 then
|
||||
self.dirty = true
|
||||
remote.dirty = true
|
||||
local entry = self.activity[key] or 0
|
||||
self.activity[key] = entry + amount
|
||||
end
|
||||
qty = qty - amount
|
||||
total = total + amount
|
||||
@@ -164,9 +170,11 @@ function NetworkedAdapter:insert(slot, qty, toSlot, item, source)
|
||||
local function insert(remote)
|
||||
local amount = remote:insert(slot, qty, toSlot, source or self.direction)
|
||||
if amount > 0 then
|
||||
debug('%s(%d) -> %s: %d', source or self.direction, slot, remote.side, amount)
|
||||
debug('%s(%d) -> %s: %d', source or self.localName, slot, remote.side, amount)
|
||||
self.dirty = true
|
||||
remote.dirty = true
|
||||
local entry = self.activity[key] or 0
|
||||
self.activity[key] = entry + amount
|
||||
end
|
||||
qty = qty - amount
|
||||
total = total + amount
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
local itemDB = require('itemDB')
|
||||
local Util = require('util')
|
||||
|
||||
local device = _G.device
|
||||
local fs = _G.fs
|
||||
local turtle = _G.turtle
|
||||
|
||||
local RECIPES_DIR = 'usr/etc/recipes'
|
||||
local USER_RECIPES = 'usr/config/recipes.db'
|
||||
local RECIPES_DIR = 'usr/etc/recipes'
|
||||
local USER_RECIPES = 'usr/config/recipes.db'
|
||||
local MACHINE_LOOKUP = 'usr/config/machine_crafting.db'
|
||||
|
||||
local Craft = { }
|
||||
|
||||
@@ -53,6 +55,26 @@ function Craft.getItemCount(items, item)
|
||||
return count
|
||||
end
|
||||
|
||||
local function machineCraft(recipe, qty, inventoryAdapter, machineName)
|
||||
local machine = device[machineName]
|
||||
if not machine then
|
||||
debug('machine not found')
|
||||
else
|
||||
for k in pairs(recipe.ingredients) do
|
||||
if machine.getItemMeta(k) then
|
||||
debug('machine in use: ' .. k)
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
for k,v in pairs(recipe.ingredients) do
|
||||
inventoryAdapter:provide(splitKey(v), qty, k, machineName)
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
local function turtleCraft(recipe, qty, inventoryAdapter)
|
||||
if not clearGrid(inventoryAdapter) then
|
||||
return false
|
||||
@@ -92,6 +114,12 @@ function Craft.loadRecipes()
|
||||
|
||||
local recipes = Util.readTable(USER_RECIPES) or { }
|
||||
Util.merge(Craft.recipes, recipes)
|
||||
|
||||
for k,v in pairs(Craft.recipes) do
|
||||
v.result = k
|
||||
end
|
||||
|
||||
Craft.machineLookup = Util.readTable(MACHINE_LOOKUP) or { }
|
||||
end
|
||||
|
||||
function Craft.sumIngredients(recipe)
|
||||
@@ -104,6 +132,13 @@ function Craft.sumIngredients(recipe)
|
||||
return t
|
||||
end
|
||||
|
||||
local function makeRecipeKey(item)
|
||||
if type(item) == 'string' then
|
||||
item = splitKey(item)
|
||||
end
|
||||
return table.concat({ item.name, item.damage or 0, item.nbtHash }, ':')
|
||||
end
|
||||
|
||||
function Craft.craftRecipe(recipe, count, inventoryAdapter)
|
||||
if type(recipe) == 'string' then
|
||||
recipe = Craft.recipes[recipe]
|
||||
@@ -142,7 +177,11 @@ function Craft.craftRecipe(recipe, count, inventoryAdapter)
|
||||
|
||||
local crafted = 0
|
||||
repeat
|
||||
if not turtleCraft(recipe, math.min(count, maxCount), inventoryAdapter) then
|
||||
-- fix
|
||||
if Craft.machineLookup[recipe.result] then
|
||||
machineCraft(recipe, math.min(count, maxCount), inventoryAdapter, Craft.machineLookup[recipe.result])
|
||||
break
|
||||
elseif not turtleCraft(recipe, math.min(count, maxCount), inventoryAdapter) then
|
||||
turtle.select(1)
|
||||
break
|
||||
end
|
||||
@@ -154,13 +193,6 @@ function Craft.craftRecipe(recipe, count, inventoryAdapter)
|
||||
return crafted * recipe.count
|
||||
end
|
||||
|
||||
local function makeRecipeKey(item)
|
||||
if type(item) == 'string' then
|
||||
item = splitKey(item)
|
||||
end
|
||||
return table.concat({ item.name, item.damage or 0, item.nbtHash }, ':')
|
||||
end
|
||||
|
||||
function Craft.findRecipe(key)
|
||||
if type(key) ~= 'string' then
|
||||
key = itemDB:makeKey(key)
|
||||
|
||||
Reference in New Issue
Block a user