diff --git a/milo/MiloLocal.lua b/milo/MiloLocal.lua index ed1c282..b65d05d 100644 --- a/milo/MiloLocal.lua +++ b/milo/MiloLocal.lua @@ -2,6 +2,7 @@ local Event = require('opus.event') local Milo = require('milo') local Sound = require('opus.sound') local Storage = require('milo.storage') +local TurtleInv = require('milo.turtleInv') local UI = require('opus.ui') local Util = require('opus.util') @@ -18,7 +19,6 @@ multishell.setTitle(multishell.getCurrent(), 'Milo') local function Syntax(msg) print([[ Turtle must be provided with: - * Introspection module (never bound) * Workbench Turtle must be connected to: @@ -46,10 +46,6 @@ if not modem.getNameLocal() then Syntax('Wired modem is not active') end -local introspection = device['plethora:introspection'] or - turtle.equip('left', 'plethora:module:0') and device['plethora:introspection'] or - Syntax('Introspection module missing') - if not device.workbench then turtle.equip('right', 'minecraft:crafting_table:0') if not device.workbench then @@ -58,6 +54,7 @@ if not device.workbench then end local localName = modem.getNameLocal() +TurtleInv.setLocalName(localName) local context = { resources = Util.readTable(Milo.RESOURCE_FILE) or { }, @@ -76,7 +73,7 @@ local context = { turtleInventory = { name = localName, mtype = 'hidden', - adapter = introspection.getInventory(), + adapter = TurtleInv, } } diff --git a/milo/MiloRemote.lua b/milo/MiloRemote.lua index 0e702db..9a18708 100644 --- a/milo/MiloRemote.lua +++ b/milo/MiloRemote.lua @@ -283,7 +283,7 @@ local function splitKey(key) local t = Util.split(key, '(.-):') local item = { } if #t[#t] > 8 then - item.nbtHash = table.remove(t) + item.nbt = table.remove(t) end item.damage = tonumber(table.remove(t)) item.name = table.concat(t, ':') diff --git a/milo/apis/craft2.lua b/milo/apis/craft2.lua index 57b7004..4b5bfe2 100644 --- a/milo/apis/craft2.lua +++ b/milo/apis/craft2.lua @@ -20,10 +20,11 @@ local Craft = { local function splitKey(key) local t = Util.split(key, '(.-):') local item = { } - if #t[#t] > 8 then - item.nbtHash = table.remove(t) + + if t[3] then + item.nbt = t[3] end - item.damage = tonumber(table.remove(t)) + item.name = table.concat(t, ':') return item end @@ -32,7 +33,7 @@ local function makeRecipeKey(item) if type(item) == 'string' then item = splitKey(item) end - return table.concat({ item.name, item.damage or 0, item.nbtHash }, ':') + return table.concat({ item.name, item.nbt }, ':') end local function convert(ingredient) @@ -47,8 +48,7 @@ local function getCraftingTool(storage, item) for _,v in pairs(items) do if item.name == v.name and - (not item.damage or item.damage == v.damage) and - (not item.nbtHash or item.nbtHash == v.nbtHash) then + (not item.nbt or item.nbt == v.nbt) then return v end end @@ -93,11 +93,7 @@ function Craft.getItemCount(items, item) local count = 0 for _,v in pairs(items) do if v.name == item.name and - (not item.damage or v.damage == item.damage) and - v.nbtHash == item.nbtHash then - if item.damage then - return v.count - end + v.nbt == item.nbt then count = count + v.count end end @@ -387,18 +383,7 @@ function Craft.findRecipe(key) end local item = itemDB:splitKey(key) - if item.damage then - return Craft.recipes[makeRecipeKey(item)] - end - - -- handle cases where the request is like : IC2:reactorVent:* - for rkey,recipe in pairs(Craft.recipes) do - local r = itemDB:splitKey(rkey) - if item.name == r.name and - (not item.nbtHash or r.nbtHash == item.nbtHash) then - return recipe - end - end + return Craft.recipes[makeRecipeKey(item)] end -- determine the full list of ingredients needed to craft diff --git a/milo/apis/init.lua b/milo/apis/init.lua index 41b42b2..dbc1fa9 100644 --- a/milo/apis/init.lua +++ b/milo/apis/init.lua @@ -93,7 +93,7 @@ function Milo:getMatches(item, flags) local count = 0 local items = self:listItems() - if not flags.ignoreDamage and not flags.ignoreNbtHash then + if not flags.ignoreNbt then local key = item.key or itemDB:makeKey(item) local v = items[key] if v then @@ -104,8 +104,7 @@ function Milo:getMatches(item, flags) else for key,v in pairs(items) do if item.name == v.name and - (flags.ignoreDamage or item.damage == v.damage) and - (flags.ignoreNbtHash or item.nbtHash == v.nbtHash) then + (flags.ignoreNbt or item.nbt == v.nbt) then t[key] = Util.shallowCopy(v) count = count + v.count @@ -125,7 +124,7 @@ function Milo:getTurtleInventory() for i, v in pairs(self.context.turtleInventory.adapter.list()) do list[i] = itemDB:get(v, function() - return self.context.turtleInventory.adapter.getItemMeta(i) + return self.context.turtleInventory.adapter.getItemDetail(i) end) end @@ -277,22 +276,15 @@ function Milo:learnRecipe() for _,v1 in pairs(results) do for _,v2 in pairs(ingredients) do if v1.name == v2.name and - v1.nbtHash == v2.nbtHash and - (v1.damage == v2.damage or - (v1.maxDamage > 0 and v2.maxDamage > 0 and - v1.damage ~= v2.damage)) then + v1.nbt == v2.nbt then if not newRecipe.crafingTools then newRecipe.craftingTools = { } end local tool = Util.shallowCopy(v2) - if tool.maxDamage > 0 then - tool.damage = '*' - v2.damage = '*' - end --[[ Turtles can only craft one item at a time using a tool :( - ]]-- + ]] -- Todo: check if this still applies maxCount = 1 newRecipe.craftingTools[itemDB:makeKey(tool)] = true diff --git a/milo/apis/miniAdapter.lua b/milo/apis/miniAdapter.lua index aaf14f3..cb348b4 100644 --- a/milo/apis/miniAdapter.lua +++ b/milo/apis/miniAdapter.lua @@ -21,13 +21,13 @@ function Adapter:listItems(throttle) for k,v in pairs(self.list()) do if v.count > 0 then - local key = table.concat({ v.name, v.damage, v.nbtHash }, ':') + local key = table.concat({ v.name, v.nbt }, ':') local entry = cache[key] if entry then entry.count = entry.count + v.count else - cache[key] = itemDB:get(v, function() return self.getItemMeta(k) end) + cache[key] = itemDB:get(v, function() return self.getItemDetail(k) end) end throttle() end diff --git a/milo/apis/storage.lua b/milo/apis/storage.lua index 2cdbc3d..20b4acd 100644 --- a/milo/apis/storage.lua +++ b/milo/apis/storage.lua @@ -321,7 +321,7 @@ function Storage:listItemsRaw(throttle) local items = chest.list() for slot, item in pairs(items) do - items[slot] = itemDB:get(item, function() return chest.getItemMeta(slot) end) + items[slot] = itemDB:get(item, function() return chest.getItemDetail(slot) end) end res[v.name] = items @@ -340,7 +340,7 @@ function Storage:listProviders(throttle) for chest, items in pairs(rawItems) do for slot, item in pairs(items) do - local key = table.concat({item.name, item.damage, item.nbtHash}, ":") + local key = table.concat({item.name, item.nbt}, ":") if not res[key] then res[key] = {} end @@ -443,7 +443,7 @@ function Storage:updateCache(adapter, item, count) return end - local key = item.key or table.concat({ item.name, item.damage, item.nbtHash }, ':') + local key = item.key or table.concat({ item.name, item.nbt }, ':') local entry = adapter.cache[key] if not entry then @@ -490,14 +490,14 @@ end local function isValidTransfer(adapter, target) -- lazily cache transfer locations - if not adapter.transferLocations then + --[[if not adapter.transferLocations then adapter.transferLocations = adapter.getTransferLocations() end - for _,v in pairs(adapter.transferLocations) do - if v == target then + for _,v in pairs(adapter.transferLocations) do]] + -- if v == target then return true - end - end + -- end + --end end local function rawExport(source, target, item, qty, slot) @@ -529,8 +529,7 @@ local function rawExport(source, target, item, qty, slot) local stacks = source.list() for key,stack in Util.rpairs(stacks) do if stack.name == item.name and - stack.damage == item.damage and - stack.nbtHash == item.nbtHash then + stack.nbt == item.nbt then local amount = math.min(qty, stack.count) if amount > 0 then amount = transfer(key, amount, slot) @@ -560,7 +559,7 @@ end function Storage:export(target, slot, count, item) local timer = Util.timer() local total = 0 - local key = item.key or table.concat({ item.name, item.damage, item.nbtHash }, ':') + local key = item.key or table.concat({ item.name, item.nbt }, ':') local function provide(adapter, pcount) -- update cache before export to allow for simultaneous calls @@ -651,7 +650,7 @@ function Storage:import(source, slot, count, item) local timer = Util.timer() local total = 0 - local key = item.key or table.concat({ item.name, item.damage, item.nbtHash }, ':') + local key = item.key or table.concat({ item.name, item.nbt }, ':') if not self.cache then self:listItems() @@ -664,7 +663,7 @@ function Storage:import(source, slot, count, item) entry = itemDB:add(item) else -- get the metadata from the device and add to db - entry = itemDB:add(source.adapter.getItemMeta(slot)) + entry = itemDB:add(source.adapter.getItemDetail(slot)) end itemDB:flush() end diff --git a/milo/apis/turtleInv.lua b/milo/apis/turtleInv.lua new file mode 100644 index 0000000..42488a9 --- /dev/null +++ b/milo/apis/turtleInv.lua @@ -0,0 +1,41 @@ +--[[ Emulate a CC:T inventory on the turtle +]] + +local TurtleInv = {} + +local turtle = _G.turtle + +local inventorySize = 16 + +local localName = "milo_local_name_unset" + +function TurtleInv.setLocalName(name) + localName = name +end + +function TurtleInv.size() + return inventorySize +end + +function TurtleInv.list() + local list = {} + for slot = 1, inventorySize do + list[slot] = turtle.getItemDetail(slot) + end + return list +end + +function TurtleInv.getItemDetail(slot) + return turtle.getItemDetail(slot, true) +end + +function TurtleInv.pullItems(fromName, fromSlot, limit, toSlot) + return peripheral.call(fromName, "pushItems", localName, fromSlot, limit, toSlot) +end + +function TurtleInv.pushItems(toName, fromSlot, limit, toSlot) + return peripheral.call(toName, "pullItems", localName, fromSlot, limit, toSlot) +end + + +return TurtleInv diff --git a/milo/core/machines.lua b/milo/core/machines.lua index cdc5ce1..ef5c620 100644 --- a/milo/core/machines.lua +++ b/milo/core/machines.lua @@ -312,14 +312,10 @@ The settings will take effect immediately!]], margin = 1, manualControls = true, [1] = UI.Checkbox { - formLabel = 'Ignore Dmg', formKey = 'ignoreDamage', - help = 'Ignore damage of item', - }, - [2] = UI.Checkbox { - formLabel = 'Ignore NBT', formKey = 'ignoreNbtHash', + formLabel = 'Ignore NBT', formKey = 'ignoreNbt', help = 'Ignore NBT of item', }, - [3] = UI.Chooser { + [2] = UI.Chooser { width = 13, formLabel = 'Mode', formKey = 'blacklist', nochoice = 'whitelist', @@ -327,7 +323,7 @@ The settings will take effect immediately!]], { name = 'whitelist', value = false }, { name = 'blacklist', value = true }, }, - help = 'Ignore damage of item' + help = 'Accept item by default or deny by default' }, scan = UI.Button { x = -11, y = 1, @@ -349,7 +345,7 @@ The settings will take effect immediately!]], self.form:setValues(entry) self:resetGrid() - self.form[3].inactive = whitelistOnly + self.form[2].inactive = whitelistOnly UI.SlideOut.show(self) self:setFocus(self.form.scan) diff --git a/milo/plugins/exportTask.lua b/milo/plugins/exportTask.lua index 3fc6a9f..bf0990b 100644 --- a/milo/plugins/exportTask.lua +++ b/milo/plugins/exportTask.lua @@ -30,7 +30,7 @@ function ExportTask:cycle(context) end local function exportSingleSlot() - local slot = node.adapter.getItemMeta(entry.slot) + local slot = node.adapter.getItemDetail(entry.slot) if slot and slot.count == slot.maxCount then return @@ -41,8 +41,7 @@ function ExportTask:cycle(context) for key in pairs(entry.filter) do local filterItem = itemDB:splitKey(key) if (slot.name == filterItem.name and - (entry.ignoreDamage or slot.damage == filterItem.damage) and - (entry.ignoreNbtHash or slot.nbtHash == filterItem.nbtHash)) then + (entry.ignoreNbt or slot.nbt == filterItem.nbt)) then local items = Milo:getMatches(filterItem, entry) local _, item = next(items) @@ -81,8 +80,7 @@ function ExportTask:cycle(context) for i = 1, node.adapter.__size do local slot = slots[i] if (not slot or slot.name == item.name and - (entry.ignoreDamage or slot.damage == item.damage) and - (entry.ignoreNbtHash or slot.nbtHash == item.nbtHash) and + (entry.ignoreNbt or slot.nbt == item.nbt) and slot.count < item.maxCount) then return true diff --git a/milo/plugins/importTask.lua b/milo/plugins/importTask.lua index f7ac84c..3a1c0a6 100644 --- a/milo/plugins/importTask.lua +++ b/milo/plugins/importTask.lua @@ -21,7 +21,7 @@ function ImportTask:cycle(context) for _, entry in pairs(node.imports) do local function itemMatchesFilter(item) - if not entry.ignoreDamage and not entry.ignoreNbtHash then + if not entry.ignoreNbt then local key = itemDB:makeKey(item) return entry.filter[key] end @@ -29,8 +29,7 @@ function ImportTask:cycle(context) for key in pairs(entry.filter) do local v = itemDB:splitKey(key) if item.name == v.name and - (entry.ignoreDamage or item.damage == v.damage) and - (entry.ignoreNbtHash or item.nbtHash == v.nbtHash) then + (entry.ignoreNbt or item.nbt == v.nbt) then return true end end @@ -52,7 +51,7 @@ function ImportTask:cycle(context) local function importSlot(slotNo) local item = itemDB:get(list[slotNo], function() - return node.adapter.getItemMeta(slotNo) + return node.adapter.getItemDetail(slotNo) end) if item and matchesFilter(item) then if context.storage:import(node, slotNo, item.count, item) ~= item.count then diff --git a/milo/plugins/item/infoTab.lua b/milo/plugins/item/infoTab.lua index 6634948..1e3009b 100644 --- a/milo/plugins/item/infoTab.lua +++ b/milo/plugins/item/infoTab.lua @@ -20,16 +20,18 @@ function infoTab:draw() Ansi.orange, item.displayName, Ansi.reset, item.name) - if item.nbtHash then - value = value .. item.nbtHash .. '\n' + if item.nbt then + value = value .. item.nbt .. '\n' end value = value .. string.format('\n%sCount:%s %s', Ansi.yellow, Ansi.reset, item.count) - value = value .. string.format('\n%sDamage:%s %s', - Ansi.yellow, Ansi.reset, item.damage) - + if item.durability then + value = value .. string.format('\n%Durability:%s %s', + Ansi.yellow, Ansi.reset, item.durability) + end + if item.maxDamage and item.maxDamage > 0 then value = value .. string.format(' (max: %s)', item.maxDamage) end diff --git a/milo/plugins/item/manageTab.lua b/milo/plugins/item/manageTab.lua index e1f49fe..776829e 100644 --- a/milo/plugins/item/manageTab.lua +++ b/milo/plugins/item/manageTab.lua @@ -29,11 +29,7 @@ local manageTab = UI.Tab { transform = 'number', }, [4] = UI.Checkbox { - formLabel = 'Ignore Dmg', formKey = 'ignoreDamage', - help = 'Ignore damage of item', - }, - [5] = UI.Checkbox { - formLabel = 'Ignore NBT', formKey = 'ignoreNbtHash', + formLabel = 'Ignore NBT', formKey = 'ignoreNbt', help = 'Ignore NBT of item', }, }, @@ -44,8 +40,6 @@ function manageTab:setItem(item) self.res = Util.shallowCopy(context.resources[item.key] or { }) self.res.displayName = self.item.displayName self.form:setValues(self.res) - - -- TODO: ignore damage should not be active if there is not a maxDamage value end function manageTab:eventHandler(event) @@ -76,8 +70,7 @@ function manageTab:eventHandler(event) local newKey = { name = self.item.name, - damage = self.res.ignoreDamage and 0 or self.item.damage, - nbtHash = not self.res.ignoreNbtHash and self.item.nbtHash or nil, + nbt = not self.res.ignoreNbt and self.item.nbt or nil, } context.resources[self.item.key] = nil diff --git a/milo/plugins/item/recipeTab.lua b/milo/plugins/item/recipeTab.lua index 591715f..9759e98 100644 --- a/milo/plugins/item/recipeTab.lua +++ b/milo/plugins/item/recipeTab.lua @@ -42,7 +42,7 @@ function recipeTab:setItem(item) }) end local key = itemDB:splitKey(self.recipe.result) - self.ignoreResultNBT.inactive = not key.nbtHash + self.ignoreResultNBT.inactive = not key.nbt end self.grid:setValues(t) end @@ -53,7 +53,7 @@ function recipeTab:eventHandler(event) Milo:updateRecipe(self.recipe.result) local item = itemDB:splitKey(self.recipe.result) - item.nbtHash = nil + item.nbt = nil self.recipe.result = itemDB:makeKey(item) -- add updated entry @@ -64,13 +64,13 @@ function recipeTab:eventHandler(event) elseif event.type == 'grid_focus_row' then local key = itemDB:splitKey(event.selected.key) - self.ignoreNBT.inactive = not key.nbtHash + self.ignoreNBT.inactive = not key.nbt self.ignoreNBT:draw() elseif event.type == 'ignore_nbt' then local selected = self.grid:getSelected() local item = itemDB:splitKey(selected.key) - item.nbtHash = nil + item.nbt = nil selected.key = itemDB:makeKey(item) self.grid:draw() diff --git a/milo/plugins/remote.lua b/milo/plugins/remote.lua index ff1b929..c74dd45 100644 --- a/milo/plugins/remote.lua +++ b/milo/plugins/remote.lua @@ -94,7 +94,7 @@ local function client(socket) local function deposit() local node = makeNode(data.source or 'inventory') if node then - local slot = node.adapter.getItemMeta(data.slot) + local slot = node.adapter.getItemDetail(data.slot) if slot then if context.storage:import(node, data.slot, slot.count, slot) > 0 then local item = Milo:getItem(slot) diff --git a/milo/plugins/replenishTask.lua b/milo/plugins/replenishTask.lua index 3423197..d0b2d07 100644 --- a/milo/plugins/replenishTask.lua +++ b/milo/plugins/replenishTask.lua @@ -15,14 +15,13 @@ function ReplenishTask:cycle(context) local _, count = Milo:getMatches(item, res) if count < res.low then - local nbtHash - if not res.ignoreNbtHash then - nbtHash = item.nbtHash + local nbt + if not res.ignoreNbt then + nbt = item.nbt end Milo:requestCrafting({ name = item.name, - damage = res.ignoreDamage and 0 or item.damage, - nbtHash = nbtHash, + nbt = nbt, requested = res.low - count, count = count, replenish = true, diff --git a/swshop/swshop.lua b/swshop/swshop.lua index 8529f5a..5a8a065 100644 --- a/swshop/swshop.lua +++ b/swshop/swshop.lua @@ -12,7 +12,7 @@ local jua = require("swshop.jua") local await = jua.await local device = _G.device -local json = _G.json +local json = { encode=textutils.serializeJSON, decode = textutils.unserialiseJSON } local rs = _G.rs local textutils = _G.textutils