Added advanced filter stuff.
This commit is contained in:
parent
702c315428
commit
dd97d16e05
|
@ -22,66 +22,114 @@ local function stackMatches(itemStack, name, fuzzy)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
--[[
|
-- Creates a filter function that filters on items whose names match the given list of names.
|
||||||
The following describes an item filter:
|
local function makeItemNamesFilter(names, fuzzy)
|
||||||
A table containing a filter mechanism.
|
return function(item)
|
||||||
{
|
for _, itemName in pairs(names) do
|
||||||
filterFunction = stackMatches,
|
if stackMatches(item, itemName, fuzzy) then
|
||||||
fuzzy = false,
|
|
||||||
whitelist = true
|
|
||||||
}
|
|
||||||
The filterFunction is defined like so:
|
|
||||||
function filterFunction(item, filter)
|
|
||||||
return true | false
|
|
||||||
end
|
|
||||||
]]--
|
|
||||||
|
|
||||||
function itemscript.makeFilter(var, fuzzy, whitelist)
|
|
||||||
local filter = {
|
|
||||||
filterFunction = nil,
|
|
||||||
fuzzy = fuzzy or false,
|
|
||||||
whitelist = whitelist
|
|
||||||
}
|
|
||||||
if type(var) == "string" then
|
|
||||||
-- If the filter is a single item name, define a single-item filter that matches against the name.
|
|
||||||
filter.filterFunction = function (item, filter)
|
|
||||||
local matches = stackMatches(item, var, filter.fuzzy)
|
|
||||||
if filter.whitelist then
|
|
||||||
return matches
|
|
||||||
else
|
|
||||||
return not matches
|
|
||||||
end
|
|
||||||
end
|
|
||||||
elseif type(var) == "table" then
|
|
||||||
-- If the filter is a list of item names, define a multi-item filter.
|
|
||||||
filter.filterFunction = function (item, filter)
|
|
||||||
for _, itemName in pairs(var) do
|
|
||||||
if filter.whitelist and stackMatches(item, itemName, filter.fuzzy) then
|
|
||||||
return true
|
return true
|
||||||
elseif not filter.whitelist and not stackMatches(item, itemName, filter.fuzzy) then
|
end
|
||||||
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- If whitelist and we couldn't find a match, return false.
|
|
||||||
-- If blacklist and we couldn't find a non-match, return true.
|
local function notFilter(filter)
|
||||||
return not filter.whitelist
|
return function(item)
|
||||||
|
return not filter(item)
|
||||||
end
|
end
|
||||||
elseif type(var) == "function" then
|
|
||||||
-- Otherwise, just use the provided filter.
|
|
||||||
filter.filterFunction = var
|
|
||||||
end
|
end
|
||||||
filter.apply = function(item)
|
|
||||||
return filter.filterFunction(item, filter)
|
local function andFilter(filters)
|
||||||
|
return function(item)
|
||||||
|
for _, filter in pairs(filters) do
|
||||||
|
if not filter(item) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function orFilter(filters)
|
||||||
|
return function(item)
|
||||||
|
for _, filter in pairs(filters) do
|
||||||
|
if filter(item) then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Parses a filter expression string and returns a filter that implements it.
|
||||||
|
--[[
|
||||||
|
Item Filter Expressions:
|
||||||
|
|
||||||
|
A filter expression is a way to define a complex method of matching item
|
||||||
|
stacks.
|
||||||
|
|
||||||
|
Prepending ! will match any item stack whose name does not match.
|
||||||
|
Prepending # will do a fuzzy match using string.find.
|
||||||
|
]]--
|
||||||
|
local function parseItemFilterExpression(expr)
|
||||||
|
local prefixIdx, prefixIdxEnd = string.find(expr, "^[!#]*")
|
||||||
|
local fuzzy = false
|
||||||
|
local negated = false
|
||||||
|
if prefixIdx ~= nil then
|
||||||
|
for i = prefixIdx, i <= prefixIdxEnd do
|
||||||
|
if expr[i] == "!" then
|
||||||
|
negated = true
|
||||||
|
elseif expr[i] == "#" then
|
||||||
|
fuzzy = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
expr = string.sub(expr, prefixIdxEnd + 1, string.len(expr))
|
||||||
|
end
|
||||||
|
local namespaceSeparatorIdx = string.find(expr, ":")
|
||||||
|
if namespaceSeparatorIdx == nil and not fuzzy then
|
||||||
|
expr = "minecraft:" .. expr
|
||||||
|
end
|
||||||
|
local filter = makeItemNamesFilter({expr}, fuzzy)
|
||||||
|
if negated then
|
||||||
|
filter = notFilter(filter)
|
||||||
end
|
end
|
||||||
return filter
|
return filter
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Gets the total number of items of a certain type in the turtle's inventory.
|
-- Converts an arbitrary variable into a filter; useful for any function that's public, so users can supply any filter.
|
||||||
function itemscript.totalCount(filter)
|
-- It converts the following:
|
||||||
|
-- filter function tables directly.
|
||||||
|
-- strings and lists of strings are translated into an item names filter.
|
||||||
|
-- Functions are added with default fuzzy and whitelist parameters.
|
||||||
|
local function convertToFilter(var)
|
||||||
|
if type(var) == "table" and #var > 0 and type(var[1]) == "string" then
|
||||||
|
local filters = {}
|
||||||
|
for _, expr in pairs(var) do
|
||||||
|
table.insert(filters, parseFilterExpression(expr))
|
||||||
|
end
|
||||||
|
return orFilter(filters)
|
||||||
|
elseif type(var) == "string" then
|
||||||
|
return parseFilterExpression(var)
|
||||||
|
elseif type(var) == "function" then
|
||||||
|
return var
|
||||||
|
else
|
||||||
|
error("Unsupported filter type: " .. type(var))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Convenience function for creating a filter function that allows specifying fuzziness.
|
||||||
|
function itemscript.nameFilter(name, fuzzy)
|
||||||
|
return makeItemNamesFilter({name}, fuzzy)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Gets the total number of items in the turtle's inventory that match the given expression.
|
||||||
|
function itemscript.totalCount(filterExpr)
|
||||||
|
local filter = convertToFilter(filterExpr)
|
||||||
local count = 0
|
local count = 0
|
||||||
for i = 1, 16 do
|
for i = 1, 16 do
|
||||||
local item = t.getItemDetail(i)
|
local item = t.getItemDetail(i)
|
||||||
if filter.apply(item) then
|
if filter(item) then
|
||||||
count = count + item.count
|
count = count + item.count
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -90,10 +138,11 @@ end
|
||||||
|
|
||||||
-- Selects a slot containing at least one of the given item type.
|
-- Selects a slot containing at least one of the given item type.
|
||||||
-- Returns a boolean indicating whether we could find and select the item.
|
-- Returns a boolean indicating whether we could find and select the item.
|
||||||
function itemscript.select(filter)
|
function itemscript.select(filterExpr)
|
||||||
|
local filter = convertToFilter(filterExpr)
|
||||||
for i = 1, 16 do
|
for i = 1, 16 do
|
||||||
local item = t.getItemDetail(i)
|
local item = t.getItemDetail(i)
|
||||||
if filter.apply(item) then
|
if filter(item) then
|
||||||
t.select(i)
|
t.select(i)
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
@ -105,23 +154,23 @@ end
|
||||||
local function dropFiltered(dropFunction, filter)
|
local function dropFiltered(dropFunction, filter)
|
||||||
for i = 1, 16 do
|
for i = 1, 16 do
|
||||||
local item = t.getItemDetail(i)
|
local item = t.getItemDetail(i)
|
||||||
if filter.apply(item) then
|
if filter(item) then
|
||||||
t.select(i)
|
t.select(i)
|
||||||
dropFunction()
|
dropFunction()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function itemscript.dropAll(filter)
|
function itemscript.dropAll(filterExpr)
|
||||||
dropFiltered(t.drop, filter)
|
dropFiltered(t.drop, convertToFilter(filterExpr))
|
||||||
end
|
end
|
||||||
|
|
||||||
function itemscript.dropAllDown(filter)
|
function itemscript.dropAllDown(filterExpr)
|
||||||
dropFiltered(t.dropDown, filter)
|
dropFiltered(t.dropDown, convertToFilter(filterExpr))
|
||||||
end
|
end
|
||||||
|
|
||||||
function itemscript.dropAllUp(filter)
|
function itemscript.dropAllUp(filterExpr)
|
||||||
dropFiltered(t.dropUp, filter)
|
dropFiltered(t.dropUp, convertToFilter(filterExpr))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Cleans up the turtle's inventory by compacting all stacks of items.
|
-- Cleans up the turtle's inventory by compacting all stacks of items.
|
||||||
|
|
Loading…
Reference in New Issue