movescript/src/itemscript.lua

166 lines
4.6 KiB
Lua
Raw Normal View History

2022-12-17 15:15:34 +00:00
--[[
Itemscript - A simplified set of methods for item manipulation.
Author: Andrew Lalis <andrewlalisofficial@gmail.com>
]]--
2022-12-17 15:35:11 +00:00
VERSION = "0.0.1"
2022-12-17 15:15:34 +00:00
local t = turtle
-- The itemscript module. Functions defined within this table are exported.
local itemscript = {}
-- Determines if an item stack matches the given name.
-- If fuzzy, then the item name will be matched against the given name.
local function stackMatches(itemStack, name, fuzzy)
2022-12-17 15:15:34 +00:00
return itemStack ~= nil and
(
(not fuzzy and itemStack.name == name) or
string.find(itemStack.name, name)
)
end
2022-12-21 13:30:44 +00:00
local function notFilter(filter)
return function(item)
return not filter(item)
end
end
2022-12-21 13:30:44 +00:00
local function andFilter(filters)
return function(item)
for _, filter in pairs(filters) do
if not filter(item) then
return false
end
end
2022-12-21 13:30:44 +00:00
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
2022-12-21 13:30:44 +00:00
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)
2022-12-21 13:39:55 +00:00
local prefixIdx, prefixIdxEnd = string.find(expr, "^[!#]+")
2022-12-21 13:30:44 +00:00
local fuzzy = false
local negated = false
if prefixIdx ~= nil then
2022-12-21 13:47:02 +00:00
for i = prefixIdx, prefixIdxEnd do
2022-12-21 13:30:44 +00:00
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
2022-12-21 13:52:19 +00:00
return function(item)
local matches = stackMatches(item, expr, fuzzy)
if negated then
matches = not matches
end
return matches
end
end
2022-12-21 13:30:44 +00:00
-- Converts an arbitrary variable into a filter; useful for any function that's public, so users can supply any 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
2022-12-21 13:32:28 +00:00
table.insert(filters, parseItemFilterExpression(expr))
2022-12-21 13:30:44 +00:00
end
return orFilter(filters)
elseif type(var) == "string" then
2022-12-21 13:32:28 +00:00
return parseItemFilterExpression(var)
2022-12-21 13:30:44 +00:00
elseif type(var) == "function" then
return var
else
error("Unsupported filter type: " .. type(var))
end
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)
2022-12-17 15:15:34 +00:00
local count = 0
for i = 1, 16 do
local item = t.getItemDetail(i)
2022-12-21 13:30:44 +00:00
if filter(item) then
2022-12-17 15:15:34 +00:00
count = count + item.count
end
end
return count
end
-- Selects a slot containing at least one of the given item type.
-- Returns a boolean indicating whether we could find and select the item.
2022-12-21 13:30:44 +00:00
function itemscript.select(filterExpr)
local filter = convertToFilter(filterExpr)
2022-12-17 15:15:34 +00:00
for i = 1, 16 do
local item = t.getItemDetail(i)
2022-12-21 13:30:44 +00:00
if filter(item) then
2022-12-17 15:15:34 +00:00
t.select(i)
return true
end
end
return false
end
-- Helper function to drop items in a flexible way, using a drop function and filtering function.
local function dropFiltered(dropFunction, filter)
2022-12-17 15:15:34 +00:00
for i = 1, 16 do
local item = t.getItemDetail(i)
2022-12-21 13:30:44 +00:00
if filter(item) then
2022-12-17 15:15:34 +00:00
t.select(i)
dropFunction()
end
end
end
2022-12-21 13:30:44 +00:00
function itemscript.dropAll(filterExpr)
dropFiltered(t.drop, convertToFilter(filterExpr))
2022-12-17 15:15:34 +00:00
end
2022-12-21 13:30:44 +00:00
function itemscript.dropAllDown(filterExpr)
dropFiltered(t.dropDown, convertToFilter(filterExpr))
2022-12-17 20:46:14 +00:00
end
2022-12-21 13:30:44 +00:00
function itemscript.dropAllUp(filterExpr)
dropFiltered(t.dropUp, convertToFilter(filterExpr))
2022-12-17 15:15:34 +00:00
end
-- Cleans up the turtle's inventory by compacting all stacks of items.
function itemscript.organize()
error("Not yet implemented.")
end
return itemscript