410 lines
9.7 KiB
Lua
410 lines
9.7 KiB
Lua
local txt = smart_inventory.txt
|
|
|
|
--------------------------------------------------------------
|
|
-- Filter class
|
|
--------------------------------------------------------------
|
|
local filter_class = {}
|
|
local filter_class_mt = {__index = filter_class}
|
|
|
|
function filter_class:check_item_by_name(itemname)
|
|
if minetest.registered_items[itemname] then
|
|
return self:check_item_by_def(minetest.registered_items[itemname])
|
|
end
|
|
end
|
|
|
|
function filter_class:check_item_by_def(def)
|
|
error("check_item_by_def needs redefinition:"..debug.traceback())
|
|
end
|
|
|
|
function filter_class:_get_description(group)
|
|
if txt then
|
|
if txt[group.name] then
|
|
return txt[group.name].." ("..group.name..")"
|
|
elseif group.parent and group.parent.childs[group.name] and txt[group.parent.name] then
|
|
return txt[group.parent.name].." "..group.parent.childs[group.name].." ("..group.name..")"
|
|
else
|
|
return group.name
|
|
end
|
|
else
|
|
return group.name
|
|
end
|
|
end
|
|
filter_class.get_description = filter_class._get_description
|
|
|
|
function filter_class:_get_keyword(group)
|
|
return group.group_desc
|
|
end
|
|
|
|
filter_class.get_keyword = filter_class._get_keyword
|
|
|
|
function filter_class:is_valid(group)
|
|
return true
|
|
end
|
|
|
|
local filter = {}
|
|
filter.registered_filter = {}
|
|
|
|
function filter.get(name)
|
|
return filter.registered_filter[name]
|
|
end
|
|
|
|
function filter.register_filter(def)
|
|
assert(def.name, "filter needs a name")
|
|
assert(def.check_item_by_def, "filter function check_item_by_def required")
|
|
assert(not filter.registered_filter[def.name], "filter already exists")
|
|
setmetatable(def, filter_class_mt)
|
|
filter.registered_filter[def.name] = def
|
|
end
|
|
|
|
|
|
-- rename groups for beter consistency
|
|
filter.group_rename = {
|
|
customnode_default = "customnode",
|
|
}
|
|
|
|
-- group configurations per basename
|
|
-- true means is dimension
|
|
-- 1 means replace the base only ("food_choco_powder" => food:choco_powder")
|
|
filter.base_group_config = {
|
|
armor = true,
|
|
physics = true,
|
|
basecolor = true,
|
|
excolor = true,
|
|
color = true,
|
|
unicolor = true,
|
|
food = 1,
|
|
customnode = true,
|
|
}
|
|
|
|
-- hide this groups
|
|
filter.group_hide_config = {
|
|
armor_count = true,
|
|
not_in_creative_inventory = false,
|
|
}
|
|
|
|
-- value of this group will be recalculated to %
|
|
filter.group_wear_config = {
|
|
armor_use = true,
|
|
}
|
|
|
|
-- Ususally 1 means true for group values. This is an exceptions table for this rule
|
|
filter.group_with_value_1_config = {
|
|
oddly_breakable_by_hand = true,
|
|
}
|
|
|
|
--------------------------------------------------------------
|
|
-- Filter group
|
|
--------------------------------------------------------------
|
|
filter.register_filter({
|
|
name = "group",
|
|
check_item_by_def = function(self, def)
|
|
local ret = {}
|
|
for k_orig, v in pairs(def.groups) do
|
|
local k = filter.group_rename[k_orig] or k_orig
|
|
local mk, mv
|
|
|
|
-- Check group base
|
|
local basename
|
|
for z in k:gmatch("[^_]+") do
|
|
basename = z
|
|
break
|
|
end
|
|
local basegroup_config = filter.base_group_config[basename]
|
|
if basegroup_config == true then
|
|
mk = string.gsub(k, "_", ":")
|
|
elseif basegroup_config == 1 then
|
|
mk = string.gsub(k, "^"..basename.."_", basename..":")
|
|
else
|
|
mk = k
|
|
end
|
|
|
|
-- stack wear related value
|
|
if filter.group_wear_config[k] then
|
|
mv = tostring(math.floor(v / 65535 * 10000 + 0.5)/100).." %"
|
|
-- value-expandable groups
|
|
elseif v ~= 1 or k == filter.group_with_value_1_config[k] then
|
|
mv = v
|
|
else
|
|
mv = true
|
|
end
|
|
|
|
if v ~= 0 and mk and not filter.group_hide_config[k] then
|
|
ret[mk] = mv
|
|
end
|
|
end
|
|
return ret
|
|
end,
|
|
})
|
|
|
|
filter.register_filter({
|
|
name = "type",
|
|
check_item_by_def = function(self, def)
|
|
return self.name..":"..def.type
|
|
end,
|
|
get_keyword = function(self, group)
|
|
if group.name ~= self.name then
|
|
return group.parent.childs[group.name]
|
|
end
|
|
end
|
|
})
|
|
|
|
filter.register_filter({
|
|
name = "mod",
|
|
check_item_by_def = function(self, def)
|
|
if def.mod_origin then
|
|
return self.name..":"..def.mod_origin
|
|
end
|
|
end,
|
|
get_keyword = function(self, group)
|
|
if group.name ~= self.name then
|
|
return group.parent.childs[group.name]
|
|
end
|
|
end
|
|
})
|
|
|
|
filter.register_filter({
|
|
name = "translucent",
|
|
check_item_by_def = function(self, def)
|
|
if def.sunlight_propagates ~= 0 then
|
|
return def.sunlight_propagates
|
|
end
|
|
end,
|
|
})
|
|
|
|
filter.register_filter({
|
|
name = "light",
|
|
check_item_by_def = function(self, def)
|
|
if def.light_source ~= 0 then
|
|
return def.light_source
|
|
end
|
|
end,
|
|
})
|
|
|
|
filter.register_filter({
|
|
name = "metainv",
|
|
check_item_by_def = function(self, def)
|
|
if def.allow_metadata_inventory_move or
|
|
def.allow_metadata_inventory_take or
|
|
def.allow_metadata_inventory_put or
|
|
def.on_metadata_inventory_move or
|
|
def.on_metadata_inventory_take or
|
|
def.on_metadata_inventory_put then
|
|
return true
|
|
end
|
|
end,
|
|
})
|
|
|
|
--[[ does it sense to filter them? I cannot define the human readable groups for them
|
|
filter.register_filter({
|
|
name = "drawtype",
|
|
check_item_by_def = function(self, def)
|
|
if def.drawtype ~= "normal" then
|
|
return def.drawtype
|
|
end
|
|
end,
|
|
})
|
|
]]
|
|
|
|
local shaped_groups = {}
|
|
local shaped_list = minetest.setting_get("smart_inventory_shaped_groups") or "carpet,door,fence,stair,slab,wall,micro,panel,slope"
|
|
if shaped_list then
|
|
for z in shaped_list:gmatch("[^,]+") do
|
|
shaped_groups[z] = true
|
|
end
|
|
end
|
|
|
|
filter.register_filter({
|
|
name = "shape",
|
|
check_item_by_def = function(self, def)
|
|
local door_groups
|
|
if shaped_groups["door"] then
|
|
local door_filter = filter.get("door")
|
|
door_groups = door_filter:check_item_by_def(def)
|
|
if door_groups and door_groups.door then
|
|
return true
|
|
end
|
|
end
|
|
|
|
for k, v in pairs(def.groups) do
|
|
if k ~= "door" and shaped_groups[k] then
|
|
return true
|
|
end
|
|
end
|
|
end,
|
|
})
|
|
|
|
--[[ disabled since debug.getupvalue is not usable to secure environment
|
|
filter.register_filter({
|
|
name = "food",
|
|
check_item_by_def = function(self, def)
|
|
if def.on_use then
|
|
local name,change=debug.getupvalue(def.on_use, 1)
|
|
if name~=nil and name=="hp_change" and change > 0 then
|
|
return tostring(change)
|
|
end
|
|
end
|
|
end,
|
|
})
|
|
|
|
filter.register_filter({
|
|
name = "toxic",
|
|
check_item_by_def = function(self, def)
|
|
if def.on_use then
|
|
local name,change=debug.getupvalue(def.on_use, 1)
|
|
if name~=nil and name=="hp_change" and change < 0 then
|
|
return tostring(change)
|
|
end
|
|
end
|
|
end,
|
|
})
|
|
]]
|
|
|
|
filter.register_filter({
|
|
name = "tool",
|
|
check_item_by_def = function(self, def)
|
|
if not def.tool_capabilities then
|
|
return
|
|
end
|
|
local rettab = {}
|
|
for k, v in pairs(def.tool_capabilities) do
|
|
if type(v) ~= "table" and v ~= 0 then
|
|
rettab["tool:"..k] = v
|
|
end
|
|
end
|
|
if def.tool_capabilities.damage_groups then
|
|
for k, v in pairs(def.tool_capabilities.damage_groups) do
|
|
if v ~= 0 then
|
|
rettab["damage:"..k] = v
|
|
end
|
|
end
|
|
end
|
|
--[[ disabled, I cannot find right human readable interpretation for this
|
|
if def.tool_capabilities.groupcaps then
|
|
for groupcap, gdef in pairs(def.tool_capabilities.groupcaps) do
|
|
for k, v in pairs(gdef) do
|
|
if type(v) ~= "table" then
|
|
rettab["groupcaps:"..groupcap..":"..k] = v
|
|
end
|
|
end
|
|
end
|
|
end
|
|
]]
|
|
return rettab
|
|
end,
|
|
get_keyword = function(self, group)
|
|
if group.name == "tool" or group.name == "damage" then
|
|
return nil
|
|
else
|
|
return self:_get_keyword(group)
|
|
end
|
|
end
|
|
})
|
|
|
|
filter.register_filter({
|
|
name = "armor",
|
|
check_item_by_def = function(self, def)
|
|
return def.armor_groups
|
|
end,
|
|
})
|
|
|
|
filter.register_filter({
|
|
name = 'clothing_cape',
|
|
check_item_by_def = function(self, def)
|
|
if def.groups.cape then
|
|
return 'clothing'
|
|
end
|
|
end
|
|
})
|
|
|
|
|
|
-- Burn times
|
|
filter.register_filter({
|
|
name = "fuel",
|
|
check_item_by_def = function(self, def)
|
|
local burntime = minetest.get_craft_result({method="fuel",width=1,items={def.name}}).time
|
|
if burntime > 0 then
|
|
return "fuel:"..burntime
|
|
end
|
|
end
|
|
})
|
|
|
|
|
|
-- Group assignment done in cache framework internally
|
|
filter.register_filter({
|
|
name = "recipetype",
|
|
check_item_by_def = function(self, def) end,
|
|
get_keyword = function(self, group)
|
|
if group.name ~= self.name then
|
|
return group.parent.childs[group.name]
|
|
end
|
|
end
|
|
})
|
|
|
|
-- Group assignment done in cache framework internally
|
|
filter.register_filter({
|
|
name = "ingredient",
|
|
check_item_by_def = function(self, def) end,
|
|
get_description = function(self, group)
|
|
local itemname = group.name:sub(12)
|
|
if txt and txt["ingredient"] and
|
|
minetest.registered_items[itemname] and minetest.registered_items[itemname].description then
|
|
return txt["ingredient"] .." "..minetest.registered_items[itemname].description.." ("..group.name..")"
|
|
else
|
|
return group.name
|
|
end
|
|
end,
|
|
get_keyword = function(self, group)
|
|
-- not searchable by ingedient
|
|
return nil
|
|
end,
|
|
is_valid = function(self, groupname)
|
|
local itemname = groupname:sub(12)
|
|
if itemname ~= "" and minetest.registered_items[itemname] then
|
|
return true
|
|
end
|
|
end
|
|
})
|
|
|
|
|
|
local door_groups
|
|
local function fill_door_groups()
|
|
door_groups = {}
|
|
for _, extend_def in pairs(minetest.registered_items) do
|
|
local base_def
|
|
if extend_def.groups and extend_def.groups.door then
|
|
if extend_def.door then
|
|
base_def = minetest.registered_items[extend_def.door.name]
|
|
elseif extend_def.drop and type(extend_def.drop) == "string" then
|
|
base_def = minetest.registered_items[extend_def.drop]
|
|
end
|
|
end
|
|
if base_def then
|
|
door_groups[base_def.name] = extend_def
|
|
door_groups[extend_def.name] = false
|
|
end
|
|
end
|
|
end
|
|
|
|
filter.register_filter({
|
|
name = "door",
|
|
check_item_by_def = function(self, def)
|
|
if not door_groups then
|
|
fill_door_groups()
|
|
end
|
|
if not door_groups[def.name] then
|
|
return
|
|
end
|
|
|
|
local group_filter = filter.get("group")
|
|
local ret = group_filter:check_item_by_def(door_groups[def.name])
|
|
if ret then
|
|
ret["not_in_creative_inventory"] = nil
|
|
return ret
|
|
end
|
|
end
|
|
})
|
|
|
|
----------------
|
|
return filter
|
|
|