123 lines
3.2 KiB
Lua
123 lines
3.2 KiB
Lua
|
|
local get_settings = ...
|
|
local chest_nodenames, cooldowns = {}, {}
|
|
|
|
local function can_quickstack(settings, index, stack)
|
|
if stack:is_empty() or settings["qs_locked_"..index] or
|
|
settings.qs_lock_tools and minetest.registered_tools[stack:get_name()] then
|
|
return false
|
|
end
|
|
return true
|
|
end
|
|
|
|
local function find_nearby_chests(player)
|
|
local pos = vector.round(player:get_pos())
|
|
local pos1 = vector.subtract(pos, vector.new(4, 3, 4))
|
|
local pos2 = vector.add(pos, vector.new(4, 3, 4))
|
|
return minetest.find_nodes_in_area(pos1, pos2, chest_nodenames, true)
|
|
end
|
|
|
|
local function stack_to_chest(settings, pos, player, items, allow_put)
|
|
local inv = minetest.get_meta(pos):get_inventory()
|
|
if inv:get_size("main") == 0 or inv:is_empty("main") then
|
|
return
|
|
end
|
|
local items_added = false
|
|
for _,stack in pairs(items) do
|
|
if inv:contains_item("main", stack:peek_item(1), settings.qs_exact_match) then
|
|
local count = stack:get_count()
|
|
if allow_put then
|
|
count = allow_put(pos, "main", nil, stack, player)
|
|
end
|
|
if count and count > 0 then
|
|
local to_add = stack:take_item(count)
|
|
local leftover = inv:add_item("main", to_add)
|
|
if leftover:get_count() < count then
|
|
items_added = true
|
|
end
|
|
stack:add_item(leftover)
|
|
end
|
|
end
|
|
end
|
|
return items_added
|
|
end
|
|
|
|
local function quickstack(player)
|
|
if not player then
|
|
return
|
|
end
|
|
local inv = player:get_inventory()
|
|
if inv:is_empty("main") then
|
|
return
|
|
end
|
|
local player_name = player:get_player_name()
|
|
local now = os.time()
|
|
if cooldowns[player_name] and now < cooldowns[player_name] then
|
|
return
|
|
end
|
|
cooldowns[player_name] = now + 3
|
|
local settings = get_settings(player)
|
|
local items = {}
|
|
for i, stack in pairs(inv:get_list("main")) do
|
|
if can_quickstack(settings, i, stack) then
|
|
items[i] = stack
|
|
end
|
|
end
|
|
if next(items) == nil then
|
|
return
|
|
end
|
|
local chests = find_nearby_chests(player)
|
|
if next(chests) == nil then
|
|
return
|
|
end
|
|
local items_added = false
|
|
for name, positions in pairs(chests) do
|
|
local def = minetest.registered_nodes[name]
|
|
if def then
|
|
local allow_put = def.allow_metadata_inventory_put
|
|
for _,pos in pairs(positions) do
|
|
if stack_to_chest(settings, pos, player, items, allow_put) then
|
|
items_added = true
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if items_added then
|
|
for i, stack in pairs(items) do
|
|
inv:set_stack("main", i, stack)
|
|
end
|
|
minetest.sound_play("quickstack_pop", {to_player = player_name, gain = 0.1})
|
|
end
|
|
end
|
|
|
|
local function setting_to_table(setting)
|
|
local t = {}
|
|
local str = minetest.settings:get(setting)
|
|
if not str then
|
|
return t
|
|
end
|
|
for _,name in pairs(str:split(",")) do
|
|
name = name:trim()
|
|
if minetest.registered_nodes[name] then
|
|
t[name] = true
|
|
end
|
|
end
|
|
return t
|
|
end
|
|
|
|
minetest.register_on_mods_loaded(function()
|
|
local exclude_nodes = setting_to_table("quickstack_exclude_nodes")
|
|
local include_nodes = setting_to_table("quickstack_include_nodes")
|
|
for name, def in pairs(minetest.registered_nodes) do
|
|
if not exclude_nodes[name] then
|
|
if name:find("chest") or def.description and def.description:find("[Cc]hest") then
|
|
include_nodes[name] = true
|
|
end
|
|
end
|
|
end
|
|
for name in pairs(include_nodes) do
|
|
table.insert(chest_nodenames, name)
|
|
end
|
|
end)
|
|
|
|
return quickstack
|