2 Commits

Author SHA1 Message Date
MayaTheShy
51b1009099 feat: add inventory-manager (stable) and inventory-manager-unstable package listings 2026-03-29 15:50:43 -04:00
MayaTheShy
6d66344feb feat: register cc-platform-core in packages.list
Add platform package entry pointing to Gitea repo for Opus
package manager installation.
2026-03-26 16:25:51 -04:00
26 changed files with 4613 additions and 6776 deletions

View File

@@ -33,19 +33,20 @@ end
function itemDB:makeKey(item) function itemDB:makeKey(item)
if not item then error('itemDB:makeKey: item is required', 2) end if not item then error('itemDB:makeKey: item is required', 2) end
return table.concat({ item.name, item.nbt }, ':') return table.concat({ item.name, item.damage or '*', item.nbtHash }, ':')
end end
function itemDB:splitKey(key, item) function itemDB:splitKey(key, item)
item = item or { } item = item or { }
local t = Util.split(key, '(.-):') local t = Util.split(key, '(.-):')
if #t[#t] > 8 then
if t[3] then item.nbtHash = table.remove(t)
item.nbt = t[3] end
t[3] = nil local damage = table.remove(t)
if damage ~= '*' then
item.damage = tonumber(damage)
end end
item.name = table.concat(t, ':') item.name = table.concat(t, ':')
return item return item
@@ -81,20 +82,36 @@ function itemDB:_get(key)
return item return item
end end
for k,item in pairs(self.data) do -- try finding an item that has damage values
if key.name == item.name and if type(key.damage) == 'number' then
key.nbt == item.nbt then item = TableDB.get(self, self:makeKey({ name = key.name, nbtHash = key.nbtHash }))
if item and item.maxDamage then
item = Util.shallowCopy(item) item = Util.shallowCopy(item)
item.damage = key.damage
if item.maxDamage > 0 and type(item.damage) == 'number' and item.damage > 0 then
item.displayName = string.format('%s (damage: %s)', item.displayName, item.damage)
end
return item return item
end end
else
for k,item in pairs(self.data) do
if key.name == item.name and
key.nbtHash == key.nbtHash and
item.maxDamage > 0 then
item = Util.shallowCopy(item)
item.nbtHash = key.nbtHash
return item
end
end
end end
if key.nbt then if key.nbtHash then
item = self:get({ name = key.name }) item = self:get({ name = key.name, damage = key.damage })
if item and item.ignoreNBT then if item and item.ignoreNBT then
item = Util.shallowCopy(item) item = Util.shallowCopy(item)
item.nbt = key.nbt item.nbtHash = key.nbtHash
item.damage = key.damage
return item return item
end end
end end
@@ -117,7 +134,8 @@ end
function itemDB:add(baseItem) function itemDB:add(baseItem)
local nItem = { local nItem = {
name = baseItem.name, name = baseItem.name,
nbt = baseItem.nbt, damage = baseItem.damage,
nbtHash = baseItem.nbtHash,
} }
-- if detail.maxDamage > 0 then -- if detail.maxDamage > 0 then
-- nItem.damage = '*' -- nItem.damage = '*'
@@ -125,6 +143,7 @@ function itemDB:add(baseItem)
nItem.displayName = safeString(baseItem.displayName) nItem.displayName = safeString(baseItem.displayName)
nItem.maxCount = baseItem.maxCount nItem.maxCount = baseItem.maxCount
nItem.maxDamage = baseItem.maxDamage
-- enchanted items -- enchanted items
if baseItem.enchantments then if baseItem.enchantments then
@@ -137,7 +156,7 @@ function itemDB:add(baseItem)
if k > 1 then if k > 1 then
nItem.displayName = nItem.displayName .. ', ' nItem.displayName = nItem.displayName .. ', '
end end
nItem.displayName = nItem.displayName .. v.displayName nItem.displayName = nItem.displayName .. v.fullName
end end
-- turtles / computers / etc -- turtles / computers / etc
@@ -173,8 +192,18 @@ function itemDB:add(baseItem)
if nItem.name == item.name and if nItem.name == item.name and
nItem.displayName == item.displayName then nItem.displayName == item.displayName then
if nItem.nbt ~= item.nbt then if nItem.nbtHash ~= item.nbtHash and nItem.damage ~= item.damage then
nItem.nbt = nil nItem.damage = '*'
nItem.nbtHash = nil
nItem.ignoreNBT = true
self.data[k] = nil
break
elseif nItem.damage ~= item.damage then
nItem.damage = '*'
self.data[k] = nil
break
elseif nItem.nbtHash ~= item.nbtHash then
nItem.nbtHash = nil
nItem.ignoreNBT = true nItem.ignoreNBT = true
self.data[k] = nil self.data[k] = nil
break break
@@ -185,7 +214,8 @@ function itemDB:add(baseItem)
TableDB.add(self, self:makeKey(nItem), nItem) TableDB.add(self, self:makeKey(nItem), nItem)
nItem = Util.shallowCopy(nItem) nItem = Util.shallowCopy(nItem)
nItem.nbt = baseItem.nbt nItem.damage = baseItem.damage
nItem.nbtHash = baseItem.nbtHash
return nItem return nItem
end end
@@ -204,8 +234,8 @@ function itemDB:getName(item)
-- fallback to nameDB -- fallback to nameDB
local strId = self:makeKey(item) local strId = self:makeKey(item)
local name = nameDB.data[strId] local name = nameDB.data[strId]
if not name then if not name and not item.damage then
name = nameDB.data[self:makeKey({ name = item.name, nbt = item.nbt })] name = nameDB.data[self:makeKey({ name = item.name, damage = 0, nbtHash = item.nbtHash })]
end end
return name or strId return name or strId
end end
@@ -220,17 +250,24 @@ function itemDB:load()
for key,item in pairs(self.data) do for key,item in pairs(self.data) do
self:splitKey(key, item) self:splitKey(key, item)
item.maxDamage = item.maxDamage or 0
item.maxCount = item.maxCount or 64 item.maxCount = item.maxCount or 64
end end
end end
function itemDB:flush() function itemDB:flush()
if self.dirty then if self.dirty then
local t = { } local t = { }
for k,v in pairs(self.data) do for k,v in pairs(self.data) do
v = Util.shallowCopy(v) v = Util.shallowCopy(v)
v.name = nil v.name = nil
v.nbt = nil v.damage = nil
v.nbtHash = nil
v.count = nil -- wipe out previously saved counts - temporary
if v.maxDamage == 0 then
v.maxDamage = nil
end
if v.maxCount == 64 then if v.maxCount == 64 then
v.maxCount = nil v.maxCount = nil
end end

View File

@@ -23,10 +23,14 @@ function nameDB:loadDirectory(directory)
error('Unable to read ' .. fs.combine(directory, file)) error('Unable to read ' .. fs.combine(directory, file))
end end
for strId, blockName in pairs(blocks) do for strId, block in pairs(blocks) do
strId = string.format('%s:%s', mod, strId) strId = string.format('%s:%s', mod, strId)
if type(blockName) == 'string' then if type(block.name) == 'string' then
self.data[strId] = blockName self.data[strId .. ':0'] = block.name
else
for nid,name in pairs(block.name) do
self.data[strId .. ':' .. (nid-1)] = name
end
end end
end end

File diff suppressed because one or more lines are too long

View File

@@ -2,7 +2,6 @@ local Event = require('opus.event')
local Milo = require('milo') local Milo = require('milo')
local Sound = require('opus.sound') local Sound = require('opus.sound')
local Storage = require('milo.storage') local Storage = require('milo.storage')
local TurtleInv = require('milo.turtleInv')
local UI = require('opus.ui') local UI = require('opus.ui')
local Util = require('opus.util') local Util = require('opus.util')
@@ -19,6 +18,7 @@ multishell.setTitle(multishell.getCurrent(), 'Milo')
local function Syntax(msg) local function Syntax(msg)
print([[ print([[
Turtle must be provided with: Turtle must be provided with:
* Introspection module (never bound)
* Workbench * Workbench
Turtle must be connected to: Turtle must be connected to:
@@ -46,6 +46,10 @@ if not modem.getNameLocal() then
Syntax('Wired modem is not active') Syntax('Wired modem is not active')
end 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 if not device.workbench then
turtle.equip('right', 'minecraft:crafting_table:0') turtle.equip('right', 'minecraft:crafting_table:0')
if not device.workbench then if not device.workbench then
@@ -54,7 +58,6 @@ if not device.workbench then
end end
local localName = modem.getNameLocal() local localName = modem.getNameLocal()
TurtleInv.setLocalName(localName)
local context = { local context = {
resources = Util.readTable(Milo.RESOURCE_FILE) or { }, resources = Util.readTable(Milo.RESOURCE_FILE) or { },
@@ -73,7 +76,7 @@ local context = {
turtleInventory = { turtleInventory = {
name = localName, name = localName,
mtype = 'hidden', mtype = 'hidden',
adapter = TurtleInv, adapter = introspection.getInventory(),
} }
} }

View File

@@ -281,12 +281,11 @@ end
local function splitKey(key) local function splitKey(key)
local t = Util.split(key, '(.-):') local t = Util.split(key, '(.-):')
local item = { } local item = { }
if t[3] then if #t[#t] > 8 then
item.nbt = t[3] item.nbtHash = table.remove(t)
end end
t[3] = nil item.damage = tonumber(table.remove(t))
item.name = table.concat(t, ':') item.name = table.concat(t, ':')
return item return item
end end

View File

@@ -20,12 +20,10 @@ local Craft = {
local function splitKey(key) local function splitKey(key)
local t = Util.split(key, '(.-):') local t = Util.split(key, '(.-):')
local item = { } local item = { }
if #t[#t] > 8 then
if t[3] then item.nbtHash = table.remove(t)
item.nbt = t[3]
t[3] = nil
end end
item.damage = tonumber(table.remove(t))
item.name = table.concat(t, ':') item.name = table.concat(t, ':')
return item return item
end end
@@ -34,7 +32,7 @@ local function makeRecipeKey(item)
if type(item) == 'string' then if type(item) == 'string' then
item = splitKey(item) item = splitKey(item)
end end
return table.concat({ item.name, item.nbt }, ':') return table.concat({ item.name, item.damage or 0, item.nbtHash }, ':')
end end
local function convert(ingredient) local function convert(ingredient)
@@ -49,7 +47,8 @@ local function getCraftingTool(storage, item)
for _,v in pairs(items) do for _,v in pairs(items) do
if item.name == v.name and if item.name == v.name and
(not item.nbt or item.nbt == v.nbt) then (not item.damage or item.damage == v.damage) and
(not item.nbtHash or item.nbtHash == v.nbtHash) then
return v return v
end end
end end
@@ -94,7 +93,11 @@ function Craft.getItemCount(items, item)
local count = 0 local count = 0
for _,v in pairs(items) do for _,v in pairs(items) do
if v.name == item.name and if v.name == item.name and
v.nbt == item.nbt then (not item.damage or v.damage == item.damage) and
v.nbtHash == item.nbtHash then
if item.damage then
return v.count
end
count = count + v.count count = count + v.count
end end
end end
@@ -384,7 +387,18 @@ function Craft.findRecipe(key)
end end
local item = itemDB:splitKey(key) local item = itemDB:splitKey(key)
return Craft.recipes[makeRecipeKey(item)] 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
end end
-- determine the full list of ingredients needed to craft -- determine the full list of ingredients needed to craft

View File

@@ -93,7 +93,7 @@ function Milo:getMatches(item, flags)
local count = 0 local count = 0
local items = self:listItems() local items = self:listItems()
if not flags.ignoreNbt then if not flags.ignoreDamage and not flags.ignoreNbtHash then
local key = item.key or itemDB:makeKey(item) local key = item.key or itemDB:makeKey(item)
local v = items[key] local v = items[key]
if v then if v then
@@ -104,7 +104,8 @@ function Milo:getMatches(item, flags)
else else
for key,v in pairs(items) do for key,v in pairs(items) do
if item.name == v.name and if item.name == v.name and
(flags.ignoreNbt or item.nbt == v.nbt) then (flags.ignoreDamage or item.damage == v.damage) and
(flags.ignoreNbtHash or item.nbtHash == v.nbtHash) then
t[key] = Util.shallowCopy(v) t[key] = Util.shallowCopy(v)
count = count + v.count count = count + v.count
@@ -124,7 +125,7 @@ function Milo:getTurtleInventory()
for i, v in pairs(self.context.turtleInventory.adapter.list()) do for i, v in pairs(self.context.turtleInventory.adapter.list()) do
list[i] = itemDB:get(v, function() list[i] = itemDB:get(v, function()
return self.context.turtleInventory.adapter.getItemDetail(i) return self.context.turtleInventory.adapter.getItemMeta(i)
end) end)
end end
@@ -276,15 +277,22 @@ function Milo:learnRecipe()
for _,v1 in pairs(results) do for _,v1 in pairs(results) do
for _,v2 in pairs(ingredients) do for _,v2 in pairs(ingredients) do
if v1.name == v2.name and if v1.name == v2.name and
v1.nbt == v2.nbt then v1.nbtHash == v2.nbtHash and
(v1.damage == v2.damage or
(v1.maxDamage > 0 and v2.maxDamage > 0 and
v1.damage ~= v2.damage)) then
if not newRecipe.crafingTools then if not newRecipe.crafingTools then
newRecipe.craftingTools = { } newRecipe.craftingTools = { }
end end
local tool = Util.shallowCopy(v2) 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 :( Turtles can only craft one item at a time using a tool :(
]] -- Todo: check if this still applies ]]--
maxCount = 1 maxCount = 1
newRecipe.craftingTools[itemDB:makeKey(tool)] = true newRecipe.craftingTools[itemDB:makeKey(tool)] = true

View File

@@ -19,17 +19,15 @@ function Adapter:listItems(throttle)
local cache = { } local cache = { }
throttle = throttle or Util.throttle() throttle = throttle or Util.throttle()
local list = self.list() for k,v in pairs(self.list()) do
for k,v in pairs(list) do
if v.count > 0 then if v.count > 0 then
local key = table.concat({ v.name, v.nbt }, ':') local key = table.concat({ v.name, v.damage, v.nbtHash }, ':')
local entry = cache[key] local entry = cache[key]
if entry then if entry then
entry.count = entry.count + v.count entry.count = entry.count + v.count
else else
cache[key] = itemDB:get(v, function() return self.getItemDetail(k) end) cache[key] = itemDB:get(v, function() return self.getItemMeta(k) end)
end end
throttle() throttle()
end end
@@ -39,10 +37,6 @@ function Adapter:listItems(throttle)
-- useful for when inserting into chests -- useful for when inserting into chests
-- ie. insert only if chest does not have item and has free slots -- ie. insert only if chest does not have item and has free slots
-- bodge to make statsView not delay
-- todo: handle this better properly
self.__used = Util.size(list)
self.cache = cache self.cache = cache
end end

View File

@@ -321,7 +321,7 @@ function Storage:listItemsRaw(throttle)
local items = chest.list() local items = chest.list()
for slot, item in pairs(items) do for slot, item in pairs(items) do
items[slot] = itemDB:get(item, function() return chest.getItemDetail(slot) end) items[slot] = itemDB:get(item, function() return chest.getItemMeta(slot) end)
end end
res[v.name] = items res[v.name] = items
@@ -340,7 +340,7 @@ function Storage:listProviders(throttle)
for chest, items in pairs(rawItems) do for chest, items in pairs(rawItems) do
for slot, item in pairs(items) do for slot, item in pairs(items) do
local key = table.concat({item.name, item.nbt}, ":") local key = table.concat({item.name, item.damage, item.nbtHash}, ":")
if not res[key] then if not res[key] then
res[key] = {} res[key] = {}
end end
@@ -443,7 +443,7 @@ function Storage:updateCache(adapter, item, count)
return return
end end
local key = item.key or table.concat({ item.name, item.nbt }, ':') local key = item.key or table.concat({ item.name, item.damage, item.nbtHash }, ':')
local entry = adapter.cache[key] local entry = adapter.cache[key]
if not entry then if not entry then
@@ -489,18 +489,15 @@ function Storage:_sn(name)
end end
local function isValidTransfer(adapter, target) local function isValidTransfer(adapter, target)
if string.find(target,":inventory") or string.find(target,":equipment") then
return false
end
-- lazily cache transfer locations -- lazily cache transfer locations
--[[if not adapter.transferLocations then if not adapter.transferLocations then
adapter.transferLocations = adapter.getTransferLocations() adapter.transferLocations = adapter.getTransferLocations()
end end
for _,v in pairs(adapter.transferLocations) do]] for _,v in pairs(adapter.transferLocations) do
-- if v == target then if v == target then
return true return true
-- end end
--end end
end end
local function rawExport(source, target, item, qty, slot) local function rawExport(source, target, item, qty, slot)
@@ -532,7 +529,8 @@ local function rawExport(source, target, item, qty, slot)
local stacks = source.list() local stacks = source.list()
for key,stack in Util.rpairs(stacks) do for key,stack in Util.rpairs(stacks) do
if stack.name == item.name and if stack.name == item.name and
stack.nbt == item.nbt then stack.damage == item.damage and
stack.nbtHash == item.nbtHash then
local amount = math.min(qty, stack.count) local amount = math.min(qty, stack.count)
if amount > 0 then if amount > 0 then
amount = transfer(key, amount, slot) amount = transfer(key, amount, slot)
@@ -562,7 +560,7 @@ end
function Storage:export(target, slot, count, item) function Storage:export(target, slot, count, item)
local timer = Util.timer() local timer = Util.timer()
local total = 0 local total = 0
local key = item.key or table.concat({ item.name, item.nbt }, ':') local key = item.key or table.concat({ item.name, item.damage, item.nbtHash }, ':')
local function provide(adapter, pcount) local function provide(adapter, pcount)
-- update cache before export to allow for simultaneous calls -- update cache before export to allow for simultaneous calls
@@ -653,7 +651,7 @@ function Storage:import(source, slot, count, item)
local timer = Util.timer() local timer = Util.timer()
local total = 0 local total = 0
local key = item.key or table.concat({ item.name, item.nbt }, ':') local key = item.key or table.concat({ item.name, item.damage, item.nbtHash }, ':')
if not self.cache then if not self.cache then
self:listItems() self:listItems()
@@ -666,15 +664,13 @@ function Storage:import(source, slot, count, item)
entry = itemDB:add(item) entry = itemDB:add(item)
else else
-- get the metadata from the device and add to db -- get the metadata from the device and add to db
entry = itemDB:add(source.adapter.getItemDetail(slot)) entry = itemDB:add(source.adapter.getItemMeta(slot))
end end
itemDB:flush() itemDB:flush()
end end
item = entry item = entry
local function insert(adapter) local function insert(adapter)
if adapter.__used and adapter.__size and adapter.__used == adapter.__size then return 0 end
local amount = rawInsert(adapter, source.adapter, slot, count) local amount = rawInsert(adapter, source.adapter, slot, count)
if amount > 0 then if amount > 0 then

View File

@@ -1,41 +0,0 @@
--[[ 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

View File

@@ -312,10 +312,14 @@ The settings will take effect immediately!]],
margin = 1, margin = 1,
manualControls = true, manualControls = true,
[1] = UI.Checkbox { [1] = UI.Checkbox {
formLabel = 'Ignore NBT', formKey = 'ignoreNbt', formLabel = 'Ignore Dmg', formKey = 'ignoreDamage',
help = 'Ignore damage of item',
},
[2] = UI.Checkbox {
formLabel = 'Ignore NBT', formKey = 'ignoreNbtHash',
help = 'Ignore NBT of item', help = 'Ignore NBT of item',
}, },
[2] = UI.Chooser { [3] = UI.Chooser {
width = 13, width = 13,
formLabel = 'Mode', formKey = 'blacklist', formLabel = 'Mode', formKey = 'blacklist',
nochoice = 'whitelist', nochoice = 'whitelist',
@@ -323,7 +327,7 @@ The settings will take effect immediately!]],
{ name = 'whitelist', value = false }, { name = 'whitelist', value = false },
{ name = 'blacklist', value = true }, { name = 'blacklist', value = true },
}, },
help = 'Accept item by default or deny by default' help = 'Ignore damage of item'
}, },
scan = UI.Button { scan = UI.Button {
x = -11, y = 1, x = -11, y = 1,
@@ -345,7 +349,7 @@ The settings will take effect immediately!]],
self.form:setValues(entry) self.form:setValues(entry)
self:resetGrid() self:resetGrid()
self.form[2].inactive = whitelistOnly self.form[3].inactive = whitelistOnly
UI.SlideOut.show(self) UI.SlideOut.show(self)
self:setFocus(self.form.scan) self:setFocus(self.form.scan)

View File

@@ -30,7 +30,7 @@ function ExportTask:cycle(context)
end end
local function exportSingleSlot() local function exportSingleSlot()
local slot = node.adapter.getItemDetail(entry.slot) local slot = node.adapter.getItemMeta(entry.slot)
if slot and slot.count == slot.maxCount then if slot and slot.count == slot.maxCount then
return return
@@ -41,7 +41,8 @@ function ExportTask:cycle(context)
for key in pairs(entry.filter) do for key in pairs(entry.filter) do
local filterItem = itemDB:splitKey(key) local filterItem = itemDB:splitKey(key)
if (slot.name == filterItem.name and if (slot.name == filterItem.name and
(entry.ignoreNbt or slot.nbt == filterItem.nbt)) then (entry.ignoreDamage or slot.damage == filterItem.damage) and
(entry.ignoreNbtHash or slot.nbtHash == filterItem.nbtHash)) then
local items = Milo:getMatches(filterItem, entry) local items = Milo:getMatches(filterItem, entry)
local _, item = next(items) local _, item = next(items)
@@ -80,7 +81,8 @@ function ExportTask:cycle(context)
for i = 1, node.adapter.__size do for i = 1, node.adapter.__size do
local slot = slots[i] local slot = slots[i]
if (not slot or slot.name == item.name and if (not slot or slot.name == item.name and
(entry.ignoreNbt or slot.nbt == item.nbt) and (entry.ignoreDamage or slot.damage == item.damage) and
(entry.ignoreNbtHash or slot.nbtHash == item.nbtHash) and
slot.count < item.maxCount) then slot.count < item.maxCount) then
return true return true

View File

@@ -21,7 +21,7 @@ function ImportTask:cycle(context)
for _, entry in pairs(node.imports) do for _, entry in pairs(node.imports) do
local function itemMatchesFilter(item) local function itemMatchesFilter(item)
if not entry.ignoreNbt then if not entry.ignoreDamage and not entry.ignoreNbtHash then
local key = itemDB:makeKey(item) local key = itemDB:makeKey(item)
return entry.filter[key] return entry.filter[key]
end end
@@ -29,7 +29,8 @@ function ImportTask:cycle(context)
for key in pairs(entry.filter) do for key in pairs(entry.filter) do
local v = itemDB:splitKey(key) local v = itemDB:splitKey(key)
if item.name == v.name and if item.name == v.name and
(entry.ignoreNbt or item.nbt == v.nbt) then (entry.ignoreDamage or item.damage == v.damage) and
(entry.ignoreNbtHash or item.nbtHash == v.nbtHash) then
return true return true
end end
end end
@@ -51,7 +52,7 @@ function ImportTask:cycle(context)
local function importSlot(slotNo) local function importSlot(slotNo)
local item = itemDB:get(list[slotNo], function() local item = itemDB:get(list[slotNo], function()
return node.adapter.getItemDetail(slotNo) return node.adapter.getItemMeta(slotNo)
end) end)
if item and matchesFilter(item) then if item and matchesFilter(item) then
if context.storage:import(node, slotNo, item.count, item) ~= item.count then if context.storage:import(node, slotNo, item.count, item) ~= item.count then

View File

@@ -20,18 +20,16 @@ function infoTab:draw()
Ansi.orange, item.displayName, Ansi.reset, Ansi.orange, item.displayName, Ansi.reset,
item.name) item.name)
if item.nbt then if item.nbtHash then
value = value .. item.nbt .. '\n' value = value .. item.nbtHash .. '\n'
end end
value = value .. string.format('\n%sCount:%s %s', value = value .. string.format('\n%sCount:%s %s',
Ansi.yellow, Ansi.reset, item.count) Ansi.yellow, Ansi.reset, item.count)
if item.durability then value = value .. string.format('\n%sDamage:%s %s',
value = value .. string.format('\n%Durability:%s %s', Ansi.yellow, Ansi.reset, item.damage)
Ansi.yellow, Ansi.reset, item.durability)
end
if item.maxDamage and item.maxDamage > 0 then if item.maxDamage and item.maxDamage > 0 then
value = value .. string.format(' (max: %s)', item.maxDamage) value = value .. string.format(' (max: %s)', item.maxDamage)
end end

View File

@@ -29,7 +29,11 @@ local manageTab = UI.Tab {
transform = 'number', transform = 'number',
}, },
[4] = UI.Checkbox { [4] = UI.Checkbox {
formLabel = 'Ignore NBT', formKey = 'ignoreNbt', formLabel = 'Ignore Dmg', formKey = 'ignoreDamage',
help = 'Ignore damage of item',
},
[5] = UI.Checkbox {
formLabel = 'Ignore NBT', formKey = 'ignoreNbtHash',
help = 'Ignore NBT of item', help = 'Ignore NBT of item',
}, },
}, },
@@ -40,6 +44,8 @@ function manageTab:setItem(item)
self.res = Util.shallowCopy(context.resources[item.key] or { }) self.res = Util.shallowCopy(context.resources[item.key] or { })
self.res.displayName = self.item.displayName self.res.displayName = self.item.displayName
self.form:setValues(self.res) self.form:setValues(self.res)
-- TODO: ignore damage should not be active if there is not a maxDamage value
end end
function manageTab:eventHandler(event) function manageTab:eventHandler(event)
@@ -70,7 +76,8 @@ function manageTab:eventHandler(event)
local newKey = { local newKey = {
name = self.item.name, name = self.item.name,
nbt = not self.res.ignoreNbt and self.item.nbt or nil, damage = self.res.ignoreDamage and 0 or self.item.damage,
nbtHash = not self.res.ignoreNbtHash and self.item.nbtHash or nil,
} }
context.resources[self.item.key] = nil context.resources[self.item.key] = nil

View File

@@ -42,7 +42,7 @@ function recipeTab:setItem(item)
}) })
end end
local key = itemDB:splitKey(self.recipe.result) local key = itemDB:splitKey(self.recipe.result)
self.ignoreResultNBT.inactive = not key.nbt self.ignoreResultNBT.inactive = not key.nbtHash
end end
self.grid:setValues(t) self.grid:setValues(t)
end end
@@ -53,7 +53,7 @@ function recipeTab:eventHandler(event)
Milo:updateRecipe(self.recipe.result) Milo:updateRecipe(self.recipe.result)
local item = itemDB:splitKey(self.recipe.result) local item = itemDB:splitKey(self.recipe.result)
item.nbt = nil item.nbtHash = nil
self.recipe.result = itemDB:makeKey(item) self.recipe.result = itemDB:makeKey(item)
-- add updated entry -- add updated entry
@@ -64,13 +64,13 @@ function recipeTab:eventHandler(event)
elseif event.type == 'grid_focus_row' then elseif event.type == 'grid_focus_row' then
local key = itemDB:splitKey(event.selected.key) local key = itemDB:splitKey(event.selected.key)
self.ignoreNBT.inactive = not key.nbt self.ignoreNBT.inactive = not key.nbtHash
self.ignoreNBT:draw() self.ignoreNBT:draw()
elseif event.type == 'ignore_nbt' then elseif event.type == 'ignore_nbt' then
local selected = self.grid:getSelected() local selected = self.grid:getSelected()
local item = itemDB:splitKey(selected.key) local item = itemDB:splitKey(selected.key)
item.nbt = nil item.nbtHash = nil
selected.key = itemDB:makeKey(item) selected.key = itemDB:makeKey(item)
self.grid:draw() self.grid:draw()

View File

@@ -2,7 +2,7 @@ local Craft = require('milo.craft2')
local itemDB = require('core.itemDB') local itemDB = require('core.itemDB')
local Milo = require('milo') local Milo = require('milo')
local BLAZE_POWDER = "minecraft:blaze_powder" local BLAZE_POWDER = "minecraft:blaze_powder:0"
local PotionImportTask = { local PotionImportTask = {
name = 'potions', name = 'potions',

View File

@@ -94,7 +94,7 @@ local function client(socket)
local function deposit() local function deposit()
local node = makeNode(data.source or 'inventory') local node = makeNode(data.source or 'inventory')
if node then if node then
local slot = node.adapter.getItemDetail(data.slot) local slot = node.adapter.getItemMeta(data.slot)
if slot then if slot then
if context.storage:import(node, data.slot, slot.count, slot) > 0 then if context.storage:import(node, data.slot, slot.count, slot) > 0 then
local item = Milo:getItem(slot) local item = Milo:getItem(slot)

View File

@@ -58,7 +58,7 @@ function page.tabs.inventory:enable()
local list = { } local list = { }
for k, item in pairs(inv) do for k, item in pairs(inv) do
item = itemDB:get(item, function() return ni.getInventory().getItemDetail(k) end) item = itemDB:get(item, function() return ni.getInventory().getItemMeta(k) end)
local key = makeKey(item) local key = makeKey(item)
if not list[key] then if not list[key] then
item.key = key item.key = key
@@ -129,7 +129,7 @@ Event.onInterval(5, function()
pcall(function() -- prevent errors from some mod items pcall(function() -- prevent errors from some mod items
for slot,v in pairs(ni.getInventory().list()) do for slot,v in pairs(ni.getInventory().list()) do
local item = itemDB:get(v, function() ni.getInventory().getItemDetail(slot) end) local item = itemDB:get(v, function() ni.getInventory().getItemMeta(slot) end)
if item then if item then
if context.state.autostore[makeKey(item)] then if context.state.autostore[makeKey(item)] then
context:sendRequest({ context:sendRequest({

View File

@@ -53,7 +53,7 @@ function page:updateInventoryList()
for slot, item in pairs(inv) do for slot, item in pairs(inv) do
if (context.state.depositAll.includeHotbar or slot > 9) and item.name ~= 'plethora:neuralconnector' then if (context.state.depositAll.includeHotbar or slot > 9) and item.name ~= 'plethora:neuralconnector' then
item = itemDB:get(item, function() return ni.getInventory().getItemDetail(slot) end) item = itemDB:get(item, function() return ni.getInventory().getItemMeta(slot) end)
local key = makeKey(item) local key = makeKey(item)
if not list[key] then if not list[key] then
item.displayName = item.displayName:match('(.+) %(damage:.+%)') or item.displayName item.displayName = item.displayName:match('(.+) %(damage:.+%)') or item.displayName
@@ -89,7 +89,7 @@ function page:depositAll()
local inv = ni.getInventory().list() local inv = ni.getInventory().list()
for slot, item in pairs(inv) do for slot, item in pairs(inv) do
item = itemDB:get(item, function() return ni.getInventory().getItemDetail(slot) end) item = itemDB:get(item, function() return ni.getInventory().getItemMeta(slot) end)
local key = makeKey(item) local key = makeKey(item)
if not context.state.depositAll.retain[key] then if not context.state.depositAll.retain[key] then
if (context.state.depositAll.includeHotbar or slot > 9) and item.name ~= 'plethora:neuralconnector' then if (context.state.depositAll.includeHotbar or slot > 9) and item.name ~= 'plethora:neuralconnector' then

View File

@@ -33,7 +33,7 @@ function page:enable()
local list = { } local list = { }
for k, item in pairs(inv) do for k, item in pairs(inv) do
item = itemDB:get(item, function() return ni.getInventory().getItemDetail(k) end) item = itemDB:get(item, function() return ni.getInventory().getItemMeta(k) end)
local key = itemDB:makeKey(item) local key = itemDB:makeKey(item)
if not list[key] then if not list[key] then
item.key = key item.key = key
@@ -58,9 +58,9 @@ local function getFood(food)
for slot,v in pairs(ni.getInventory().list()) do for slot,v in pairs(ni.getInventory().list()) do
local key = itemDB:makeKey(v) local key = itemDB:makeKey(v)
if key == food then if key == food then
local item = ni.getInventory().getItemDetail(slot) local item = ni.getInventory().getItem(slot)
if item and item.saturation then if item and item.consume then
return slot return item
end end
break break
end end
@@ -87,7 +87,7 @@ Event.onInterval(5, function()
if context.state.food and ni.getMetaOwner().food.hungry then if context.state.food and ni.getMetaOwner().food.hungry then
local item = getFood(context.state.food) local item = getFood(context.state.food)
if item then if item then
ni.getInventory().consume(item) item.consume()
end end
end end
end) end)
@@ -101,4 +101,4 @@ return {
callback = function() callback = function()
UI:setPage(page) UI:setPage(page)
end, end,
} }

View File

@@ -15,13 +15,14 @@ function ReplenishTask:cycle(context)
local _, count = Milo:getMatches(item, res) local _, count = Milo:getMatches(item, res)
if count < res.low then if count < res.low then
local nbt local nbtHash
if not res.ignoreNbt then if not res.ignoreNbtHash then
nbt = item.nbt nbtHash = item.nbtHash
end end
Milo:requestCrafting({ Milo:requestCrafting({
name = item.name, name = item.name,
nbt = nbt, damage = res.ignoreDamage and 0 or item.damage,
nbtHash = nbtHash,
requested = res.low - count, requested = res.low - count,
count = count, count = count,
replenish = true, replenish = true,

View File

@@ -23,6 +23,9 @@
[ 'moonscript' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/moonscript/.package', [ 'moonscript' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/moonscript/.package',
[ 'neural' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/neural/.package', [ 'neural' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/neural/.package',
[ 'pl' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/pl/.package', [ 'pl' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/pl/.package',
[ 'platform' ] = 'https://git.spatulaa.com/MayaTheShy/cc-platform-core/raw/branch/main/.package',
[ 'inventory-manager' ] = 'https://git.spatulaa.com/MayaTheShy/Inventory-Manager-CC/raw/branch/stable/.package',
[ 'inventory-manager-unstable' ] = 'https://git.spatulaa.com/MayaTheShy/Inventory-Manager-CC/raw/branch/main/.package',
-- [ 'pickup' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/pickup/.package', -- [ 'pickup' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/pickup/.package',
[ 'recipeBook' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/recipeBook/.package', [ 'recipeBook' ] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/recipeBook/.package',
[ 'screenSaver'] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/screenSaver/.package', [ 'screenSaver'] = 'https://raw.githubusercontent.com/kepler155c/opus-apps/develop-1.8/screenSaver/.package',

View File

@@ -1,8 +1,8 @@
{ {
{ {
url = "https://raw.githubusercontent.com/iuzx0/opus-recipes/main/sc-goodies", url = "https://raw.githubusercontent.com/kepler155c/opus-recipes/master/switchcraft",
version = "MC 1.19.4", version = "MC 1.12",
localName = "sc-goodies", localName = "switchcraft",
name = "SwitchCraft Goodies mod", name = "Switchcraft Server",
}, },
} }

File diff suppressed because it is too large Load Diff

View File

@@ -12,7 +12,7 @@ local jua = require("swshop.jua")
local await = jua.await local await = jua.await
local device = _G.device local device = _G.device
local json = { encode=textutils.serializeJSON, decode = textutils.unserialiseJSON } local json = _G.json
local rs = _G.rs local rs = _G.rs
local textutils = _G.textutils local textutils = _G.textutils