milo storage filter + crafting fixes
This commit is contained in:
@@ -7,9 +7,9 @@ local Util = require('util')
|
|||||||
local device = _G.device
|
local device = _G.device
|
||||||
local os = _G.os
|
local os = _G.os
|
||||||
|
|
||||||
local NetworkedAdapter = class()
|
local Storage = class()
|
||||||
|
|
||||||
function NetworkedAdapter:init(args)
|
function Storage:init(args)
|
||||||
local defaults = {
|
local defaults = {
|
||||||
remoteDefaults = { },
|
remoteDefaults = { },
|
||||||
dirty = true,
|
dirty = true,
|
||||||
@@ -32,7 +32,7 @@ debug('%s: %s', e, tostring(dev))
|
|||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
function NetworkedAdapter:showStorage()
|
function Storage:showStorage()
|
||||||
local t = { }
|
local t = { }
|
||||||
for k,v in pairs(self.remoteDefaults) do
|
for k,v in pairs(self.remoteDefaults) do
|
||||||
local online = v.adapter and v.adapter.online
|
local online = v.adapter and v.adapter.online
|
||||||
@@ -49,7 +49,7 @@ function NetworkedAdapter:showStorage()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function NetworkedAdapter:setOnline(online)
|
function Storage:setOnline(online)
|
||||||
if online ~= self.storageOnline then
|
if online ~= self.storageOnline then
|
||||||
self.storageOnline = online
|
self.storageOnline = online
|
||||||
os.queueEvent(self.storageOnline and 'storage_online' or 'storage_offline', online)
|
os.queueEvent(self.storageOnline and 'storage_online' or 'storage_offline', online)
|
||||||
@@ -57,11 +57,11 @@ function NetworkedAdapter:setOnline(online)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function NetworkedAdapter:isOnline()
|
function Storage:isOnline()
|
||||||
return self.storageOnline
|
return self.storageOnline
|
||||||
end
|
end
|
||||||
|
|
||||||
function NetworkedAdapter:initStorage()
|
function Storage:initStorage()
|
||||||
local online = true
|
local online = true
|
||||||
|
|
||||||
debug('Initializing storage')
|
debug('Initializing storage')
|
||||||
@@ -80,7 +80,24 @@ function NetworkedAdapter:initStorage()
|
|||||||
self:setOnline(online)
|
self:setOnline(online)
|
||||||
end
|
end
|
||||||
|
|
||||||
function NetworkedAdapter:onlineAdapters(reversed)
|
function Storage:filterActive(mtype, filter)
|
||||||
|
local iter = { }
|
||||||
|
for _, v in pairs(self.remoteDefaults) do
|
||||||
|
if v.adapter and v.adapter.online and v.mtype == mtype then
|
||||||
|
if not filter or filter(v) then
|
||||||
|
table.insert(iter, v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local i = 0
|
||||||
|
return function()
|
||||||
|
i = i + 1
|
||||||
|
return iter[i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Storage:onlineAdapters(reversed)
|
||||||
local iter = { }
|
local iter = { }
|
||||||
for _, v in pairs(self.remoteDefaults) do
|
for _, v in pairs(self.remoteDefaults) do
|
||||||
if v.adapter and v.adapter.online and v.mtype == 'storage' then
|
if v.adapter and v.adapter.online and v.mtype == 'storage' then
|
||||||
@@ -113,13 +130,13 @@ function NetworkedAdapter:onlineAdapters(reversed)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function NetworkedAdapter:refresh(throttle)
|
function Storage:refresh(throttle)
|
||||||
self.dirty = true
|
self.dirty = true
|
||||||
return self:listItems(throttle)
|
return self:listItems(throttle)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- provide a consolidated list of items
|
-- provide a consolidated list of items
|
||||||
function NetworkedAdapter:listItems(throttle)
|
function Storage:listItems(throttle)
|
||||||
if not self.dirty then
|
if not self.dirty then
|
||||||
return self.items
|
return self.items
|
||||||
end
|
end
|
||||||
@@ -160,11 +177,11 @@ self.listCount = self.listCount + 1
|
|||||||
return items
|
return items
|
||||||
end
|
end
|
||||||
|
|
||||||
function NetworkedAdapter:export(target, slot, count, item)
|
function Storage:export(target, slot, count, item)
|
||||||
return self:provide(item, count, slot, target)
|
return self:provide(item, count, slot, target)
|
||||||
end
|
end
|
||||||
|
|
||||||
function NetworkedAdapter:provide(item, qty, slot, direction)
|
function Storage:provide(item, qty, slot, direction)
|
||||||
local total = 0
|
local total = 0
|
||||||
|
|
||||||
for _, adapter in self:onlineAdapters() do
|
for _, adapter in self:onlineAdapters() do
|
||||||
@@ -186,7 +203,7 @@ debug('EXT: %s(%d): %s -> %s%s',
|
|||||||
return total
|
return total
|
||||||
end
|
end
|
||||||
|
|
||||||
function NetworkedAdapter:trash(source, slot, count)
|
function Storage:trash(source, slot, count)
|
||||||
local trashcan = Util.find(self.remoteDefaults, 'mtype', 'trashcan')
|
local trashcan = Util.find(self.remoteDefaults, 'mtype', 'trashcan')
|
||||||
if trashcan and trashcan.adapter and trashcan.adapter.online then
|
if trashcan and trashcan.adapter and trashcan.adapter.online then
|
||||||
debug('TRA: %s[%d] (%d)', source or self.localName, slot, count or 64)
|
debug('TRA: %s[%d] (%d)', source or self.localName, slot, count or 64)
|
||||||
@@ -195,16 +212,16 @@ debug('TRA: %s[%d] (%d)', source or self.localName, slot, count or 64)
|
|||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
function NetworkedAdapter:import(source, slot, count, item)
|
function Storage:import(source, slot, count, item)
|
||||||
return self:insert(slot, count, nil, item, source)
|
return self:insert(slot, count, nil, item, source)
|
||||||
end
|
end
|
||||||
|
|
||||||
function NetworkedAdapter:insert(slot, qty, toSlot, item, source)
|
function Storage:insert(slot, qty, toSlot, item, source)
|
||||||
local total = 0
|
local total = 0
|
||||||
|
|
||||||
-- toSlot is not really valid with this adapter
|
-- toSlot is not really valid with this adapter
|
||||||
if toSlot then
|
if toSlot then
|
||||||
error('NetworkedAdapter: toSlot is not valid')
|
error('Storage: toSlot is not valid')
|
||||||
end
|
end
|
||||||
|
|
||||||
local key = table.concat({ item.name, item.damage, item.nbtHash }, ':')
|
local key = table.concat({ item.name, item.damage, item.nbtHash }, ':')
|
||||||
@@ -265,4 +282,4 @@ debug('INS: %s(%d): %s[%d] -> %s',
|
|||||||
return total
|
return total
|
||||||
end
|
end
|
||||||
|
|
||||||
return NetworkedAdapter
|
return Storage
|
||||||
|
|||||||
@@ -137,8 +137,6 @@ local function turtleCraft(recipe, inventoryAdapter, request, count)
|
|||||||
|
|
||||||
turtle.select(1)
|
turtle.select(1)
|
||||||
if turtle.craft() then
|
if turtle.craft() then
|
||||||
request.status = nil
|
|
||||||
request.statusCode = Craft.STATUS_SUCCESS
|
|
||||||
request.crafted = request.crafted + count * recipe.count
|
request.crafted = request.crafted + count * recipe.count
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@@ -154,13 +152,36 @@ function Craft.craftRecipe(recipe, count, inventoryAdapter, origItem)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for _,key in pairs(Util.keys(origItem.ingredients)) do
|
-- wait til all requests have been completed
|
||||||
local e = origItem.ingredients[key]
|
local isPending = false
|
||||||
if e and e.transient then
|
for key, request in pairs(origItem.ingredients) do
|
||||||
origItem.ingredients[key] = nil
|
if request.pending then
|
||||||
|
local irecipe = Craft.findRecipe(key)
|
||||||
|
machineCraft(irecipe, inventoryAdapter,
|
||||||
|
Craft.machineLookup[irecipe.result], request)
|
||||||
|
isPending = request.pending or isPending
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return Craft.craftRecipeInternal(recipe, count, inventoryAdapter, origItem)
|
|
||||||
|
local crafted = 0
|
||||||
|
--if not isPending then
|
||||||
|
for _,key in pairs(Util.keys(origItem.ingredients)) do
|
||||||
|
local e = origItem.ingredients[key]
|
||||||
|
if e and e.transient then
|
||||||
|
origItem.ingredients[key] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
crafted = Craft.craftRecipeInternal(recipe, count, inventoryAdapter, origItem)
|
||||||
|
--end
|
||||||
|
|
||||||
|
for _, request in pairs(origItem.ingredients) do
|
||||||
|
if request.crafted >= request.count then
|
||||||
|
request.status = nil
|
||||||
|
request.statusCode = Craft.STATUS_SUCCESS
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return crafted
|
||||||
end
|
end
|
||||||
|
|
||||||
function Craft.craftRecipeInternal(recipe, count, inventoryAdapter, origItem)
|
function Craft.craftRecipeInternal(recipe, count, inventoryAdapter, origItem)
|
||||||
@@ -179,8 +200,8 @@ function Craft.craftRecipeInternal(recipe, count, inventoryAdapter, origItem)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if request.pending then
|
if request.pending then
|
||||||
machineCraft(recipe, inventoryAdapter,
|
--machineCraft(recipe, inventoryAdapter,
|
||||||
Craft.machineLookup[recipe.result], request)
|
-- Craft.machineLookup[recipe.result], request)
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,49 +1,44 @@
|
|||||||
local itemDB = require('itemDB')
|
local itemDB = require('itemDB')
|
||||||
local Milo = require('milo')
|
local Milo = require('milo')
|
||||||
|
|
||||||
local device = _G.device
|
|
||||||
|
|
||||||
local ExportTask = {
|
local ExportTask = {
|
||||||
name = 'exporter',
|
name = 'exporter',
|
||||||
priority = 40,
|
priority = 40,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local function filter(a)
|
||||||
|
return a.exports
|
||||||
|
end
|
||||||
|
|
||||||
function ExportTask:cycle(context)
|
function ExportTask:cycle(context)
|
||||||
for target, v in pairs(context.config.remoteDefaults) do
|
for machine in context.storage:filterActive('machine', filter) do
|
||||||
if v.exports then
|
for _, entry in pairs(machine.exports) do
|
||||||
local machine = device[target]
|
local slotNo = type(entry.slot) == 'number' and entry.slot or nil -- '*' indicates any slot
|
||||||
if machine and machine.getItemMeta then
|
|
||||||
for _, entry in pairs(v.exports) do
|
|
||||||
local slotNo = type(entry.slot) == 'number' and entry.slot or nil -- '*' indicates any slot
|
|
||||||
|
|
||||||
local slot = (slotNo and machine.getItemMeta(slotNo)) or { count = 0 }
|
local slot = (slotNo and machine.adapter.getItemMeta(slotNo)) or { count = 0 }
|
||||||
for key in pairs(entry.filter) do
|
for key in pairs(entry.filter or { }) do
|
||||||
local item = itemDB:splitKey(key)
|
local item = itemDB:splitKey(key)
|
||||||
|
|
||||||
-- is something else is in this slot
|
-- is something else is in this slot
|
||||||
if not slot.name or slot.name == item.name then
|
if not slot.name or slot.name == item.name then
|
||||||
local maxCount = slot.maxCount or itemDB:getMaxCount(item)
|
local maxCount = slot.maxCount or itemDB:getMaxCount(item)
|
||||||
local count = maxCount - slot.count
|
local count = maxCount - slot.count
|
||||||
if not slotNo then
|
if not slotNo then
|
||||||
-- TODO: should we just execute export -
|
-- TODO: should we just execute export -
|
||||||
-- or scan all slots for space ??
|
-- or scan all slots for space ??
|
||||||
count = machine.size() * maxCount - slot.count
|
count = machine.adapter.size() * maxCount - slot.count
|
||||||
end
|
end
|
||||||
if count > 0 then
|
if count > 0 then
|
||||||
item = Milo:getItemWithQty(item)
|
item = Milo:getItemWithQty(item)
|
||||||
if item and count > 0 then
|
if item and count > 0 then
|
||||||
context.storage:export(
|
context.storage:export(
|
||||||
target,
|
machine.name,
|
||||||
slotNo,
|
slotNo,
|
||||||
math.min(count, item.count),
|
math.min(count, item.count),
|
||||||
item)
|
item)
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
|
||||||
debug('Invalid export target: ' .. target)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,48 +1,43 @@
|
|||||||
local Milo = require('milo')
|
local Milo = require('milo')
|
||||||
|
|
||||||
local device = _G.device
|
|
||||||
|
|
||||||
local ImportTask = {
|
local ImportTask = {
|
||||||
name = 'importer',
|
name = 'importer',
|
||||||
priority = 20,
|
priority = 20,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local function filter(a)
|
||||||
|
return a.imports
|
||||||
|
end
|
||||||
|
|
||||||
function ImportTask:cycle(context)
|
function ImportTask:cycle(context)
|
||||||
for source, v in pairs(context.config.remoteDefaults) do
|
for inventory in context.storage:filterActive('machine', filter) do
|
||||||
if v.imports then
|
for _, entry in pairs(inventory.imports) do
|
||||||
local inventory = device[source]
|
|
||||||
if inventory then
|
|
||||||
for _, entry in pairs(v.imports) do
|
|
||||||
|
|
||||||
local function matchesFilter(item)
|
local function matchesFilter(item)
|
||||||
if not entry.filter then
|
if not entry.filter then
|
||||||
return true
|
return true
|
||||||
end
|
|
||||||
|
|
||||||
local key = Milo:uniqueKey(item)
|
|
||||||
if entry.blacklist then
|
|
||||||
return not entry.filter[key]
|
|
||||||
end
|
|
||||||
return entry.filter[key]
|
|
||||||
end
|
|
||||||
|
|
||||||
local function importSlot(slotNo)
|
|
||||||
local item = inventory.getItemMeta(slotNo)
|
|
||||||
if item and matchesFilter(item) then
|
|
||||||
context.storage:import(source, slotNo, item.count, item)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if type(entry.slot) == 'number' then
|
|
||||||
importSlot(entry.slot)
|
|
||||||
else
|
|
||||||
for i = 1, inventory.size() do
|
|
||||||
importSlot(i)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local key = Milo:uniqueKey(item)
|
||||||
|
if entry.blacklist then
|
||||||
|
return not entry.filter[key]
|
||||||
|
end
|
||||||
|
return entry.filter[key]
|
||||||
|
end
|
||||||
|
|
||||||
|
local function importSlot(slotNo)
|
||||||
|
local item = inventory.adapter.getItemMeta(slotNo)
|
||||||
|
if item and matchesFilter(item) then
|
||||||
|
context.storage:import(inventory.name, slotNo, item.count, item)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if type(entry.slot) == 'number' then
|
||||||
|
importSlot(entry.slot)
|
||||||
else
|
else
|
||||||
debug('Invalid import source: ' .. source)
|
for i = 1, inventory.adapter.size() do
|
||||||
|
importSlot(i)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,23 +1,14 @@
|
|||||||
local Milo = require('milo')
|
local Milo = require('milo')
|
||||||
|
|
||||||
local device = _G.device
|
|
||||||
|
|
||||||
local InputChest = {
|
local InputChest = {
|
||||||
name = 'input',
|
name = 'input',
|
||||||
priority = 10,
|
priority = 10,
|
||||||
}
|
}
|
||||||
|
|
||||||
function InputChest:cycle(context)
|
function InputChest:cycle(context)
|
||||||
for source,v in pairs(context.config.remoteDefaults) do
|
for inventory in context.storage:filterActive('input') do
|
||||||
if v.mtype == 'input' then
|
for slot, item in pairs(inventory.adapter.list()) do
|
||||||
local inventory = device[source]
|
context.storage:import(inventory.name, slot, item.count, item)
|
||||||
|
|
||||||
local list = inventory and inventory.list and inventory.list()
|
|
||||||
if list then
|
|
||||||
for slot, item in pairs(list) do
|
|
||||||
context.storage:import(source, slot, item.count, item)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -6,28 +6,19 @@ local LimitTask = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function LimitTask:cycle(context)
|
function LimitTask:cycle(context)
|
||||||
local trashcan
|
local trashcan = context.storage:filterActive('trashcan')()
|
||||||
|
|
||||||
for k,v in pairs(context.config.remoteDefaults) do
|
if trashcan then
|
||||||
if v.mtype == 'trashcan' then
|
for _,res in pairs(context.resources) do
|
||||||
trashcan = k
|
if res.limit then
|
||||||
break
|
local item = Milo:getItemWithQty(res, res.ignoreDamage, res.ignoreNbtHash)
|
||||||
end
|
if item and item.count > res.limit then
|
||||||
end
|
context.storage:export(
|
||||||
|
trashcan.name,
|
||||||
if not trashcan then
|
nil,
|
||||||
return
|
item.count - res.limit,
|
||||||
end
|
item)
|
||||||
|
end
|
||||||
for _,res in pairs(context.resources) do
|
|
||||||
if res.limit then
|
|
||||||
local item = Milo:getItemWithQty(res, res.ignoreDamage, res.ignoreNbtHash)
|
|
||||||
if item and item.count > res.limit then
|
|
||||||
context.storage:export(
|
|
||||||
trashcan,
|
|
||||||
nil,
|
|
||||||
item.count - res.limit,
|
|
||||||
item)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,62 +1,61 @@
|
|||||||
local Craft = require('turtle.craft')
|
local Craft = require('turtle.craft')
|
||||||
local Milo = require('milo')
|
local Milo = require('milo')
|
||||||
|
|
||||||
local device = _G.device
|
|
||||||
|
|
||||||
local PotionImportTask = {
|
local PotionImportTask = {
|
||||||
name = 'potions',
|
name = 'potions',
|
||||||
priority = 30,
|
priority = 30,
|
||||||
brewQueue = { },
|
brewQueue = { },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local function filter(a)
|
||||||
|
return a.adapter.type == 'minecraft:brewing_stand'
|
||||||
|
end
|
||||||
|
|
||||||
function PotionImportTask:cycle(context)
|
function PotionImportTask:cycle(context)
|
||||||
for _, v in pairs(device) do
|
for bs in context.storage:filterActive('machine', filter) do
|
||||||
if v.type == 'minecraft:brewing_stand' then
|
if bs.adapter.getBrewTime() == 0 then
|
||||||
if v.getBrewTime() == 0 then
|
local list = bs.adapter.list()
|
||||||
local list = v.list()
|
|
||||||
|
|
||||||
if list[1] and not list[4] then
|
if list[1] and not list[4] then
|
||||||
-- brewing has completd
|
-- brewing has completd
|
||||||
|
|
||||||
if self.brewQueue[v.name] and list[1] then
|
if self.brewQueue[bs.name] and list[1] then
|
||||||
local key = Milo:uniqueKey(list[1])
|
local key = Milo:uniqueKey(list[1])
|
||||||
if not Craft.findRecipe(key) then
|
if not Craft.findRecipe(key) then
|
||||||
debug('saving new recipe')
|
Milo:saveMachineRecipe(self.brewQueue[bs.name], list[1], bs.name)
|
||||||
Milo:saveMachineRecipe(self.brewQueue[v.name], list[1], v.name)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
for slot = 1, 3 do
|
|
||||||
if list[slot] then
|
|
||||||
context.storage:import(v.name, slot, 1, list[slot])
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
self.brewQueue[v.name] = nil
|
for slot = 1, 3 do
|
||||||
|
if list[slot] then
|
||||||
elseif not self.brewQueue[v.name] then
|
context.storage:import(bs.name, slot, 1, list[slot])
|
||||||
local recipe = {
|
|
||||||
count = 3,
|
|
||||||
ingredients = { },
|
|
||||||
maxCount = 3,
|
|
||||||
}
|
|
||||||
local list = v.list()
|
|
||||||
|
|
||||||
local function valid()
|
|
||||||
for i = 1, 4 do
|
|
||||||
if not list[i] then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
return true
|
end
|
||||||
|
end
|
||||||
|
self.brewQueue[bs.name] = nil
|
||||||
|
|
||||||
|
elseif not self.brewQueue[bs.name] then
|
||||||
|
local recipe = {
|
||||||
|
count = 3,
|
||||||
|
ingredients = { },
|
||||||
|
maxCount = 3,
|
||||||
|
}
|
||||||
|
local list = bs.adapter.list()
|
||||||
|
|
||||||
|
local function valid()
|
||||||
|
for i = 1, 4 do
|
||||||
|
if not list[i] then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
if valid() then
|
||||||
|
for i = 1, 4 do
|
||||||
|
recipe.ingredients[i] = Milo:uniqueKey(list[i])
|
||||||
end
|
end
|
||||||
|
|
||||||
if valid() then
|
self.brewQueue[bs.name] = recipe
|
||||||
for i = 1, 4 do
|
|
||||||
recipe.ingredients[i] = Milo:uniqueKey(list[i])
|
|
||||||
end
|
|
||||||
|
|
||||||
self.brewQueue[v.name] = recipe
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -9,10 +9,10 @@ local RedstoneTask = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function RedstoneTask:cycle(context)
|
function RedstoneTask:cycle(context)
|
||||||
for _,v in pairs(context.config.remoteDefaults) do
|
for v in context.storage:filterActive({ 'mtype', 'machine' }) do
|
||||||
if v.redstone then
|
if v.redstone then
|
||||||
local ri = device[v.redstone.integrator]
|
local ri = device[v.redstone.integrator]
|
||||||
if not ri or not v.adapter or not v.adapter.online then
|
if not ri or not v.adapter then
|
||||||
debug(v.redstone)
|
debug(v.redstone)
|
||||||
else
|
else
|
||||||
local function conditionsSatisfied()
|
local function conditionsSatisfied()
|
||||||
|
|||||||
Reference in New Issue
Block a user