Large drawer controller refactoring

This commit is contained in:
Linus Jahn 2020-06-09 20:01:17 +02:00
parent 7cf8cb33aa
commit 62b5fa51ae
No known key found for this signature in database
GPG Key ID: 4663231A91A1E27B
5 changed files with 199 additions and 236 deletions

@ -177,9 +177,26 @@ function drawers.remove_drawer_upgrade(pos, listname, index, stack, player)
drawers.update_drawer_upgrades(pos) drawers.update_drawer_upgrades(pos)
end end
function drawers.drawer_insert_object(pos, node, stack, direction) --[[
Inserts an incoming stack into a specific slot of a drawer.
]]
function drawers.drawer_insert_object(pos, stack, visualid)
local visual = drawers.get_visual(pos, visualid)
if not visual then
return stack
end
return visual:try_insert_stack(stack, true)
end
--[[
Inserts an incoming stack into a drawer and uses all slots.
]]
function drawers.drawer_insert_object_from_tube(pos, node, stack, direction)
local drawer_visuals = drawers.drawer_visuals[core.serialize(pos)] local drawer_visuals = drawers.drawer_visuals[core.serialize(pos)]
if not drawer_visuals then return stack end if not drawer_visuals then
return stack
end
-- first try to insert in the correct slot (if there are already items) -- first try to insert in the correct slot (if there are already items)
local leftover = stack local leftover = stack
@ -198,14 +215,29 @@ function drawers.drawer_insert_object(pos, node, stack, direction)
return leftover return leftover
end end
function drawers.drawer_can_insert_object(pos, node, stack, direction) --[[
Returns how much (count) of a stack can be inserted to a drawer slot.
]]
function drawers.drawer_can_insert_stack(pos, stack, visualid)
local visual = drawers.get_visual(pos, visualid)
if not visual then
return 0
end
return visual:can_insert_stack(stack)
end
--[[
Returns whether a stack can be (partially) inserted to any slot of a drawer.
]]
function drawers.drawer_can_insert_stack_from_tube(pos, node, stack, direction)
local drawer_visuals = drawers.drawer_visuals[core.serialize(pos)] local drawer_visuals = drawers.drawer_visuals[core.serialize(pos)]
if not drawer_visuals then if not drawer_visuals then
return false return false
end end
for _, visual in pairs(drawer_visuals) do for _, visual in pairs(drawer_visuals) do
if visual.itemName == "" or (visual.itemName == stack:get_name() and visual.count ~= visual.maxCount) then if visual:can_insert_stack(stack) > 0 then
return true return true
end end
end end
@ -233,6 +265,19 @@ function drawers.drawer_take_item(pos, itemstack)
return ItemStack() return ItemStack()
end end
--[[
Returns the content of a drawer slot.
]]
function drawers.drawer_get_content(pos, visualid)
local drawer_meta = core.get_meta(pos)
return {
name = drawer_meta:get_string("name" .. visualid),
count = drawer_meta:get_int("count" .. visualid),
maxCount = drawer_meta:get_int("max_count" .. visualid)
}
end
function drawers.register_drawer(name, def) function drawers.register_drawer(name, def)
def.description = def.description or S("Wooden") def.description = def.description or S("Wooden")
def.drawtype = "nodebox" def.drawtype = "nodebox"
@ -263,9 +308,9 @@ function drawers.register_drawer(name, def)
def.groups.tubedevice_receiver = 1 def.groups.tubedevice_receiver = 1
def.tube = def.tube or {} def.tube = def.tube or {}
def.tube.insert_object = def.tube.insert_object or def.tube.insert_object = def.tube.insert_object or
drawers.drawer_insert_object drawers.drawer_insert_object_from_tube
def.tube.can_insert = def.tube.can_insert or def.tube.can_insert = def.tube.can_insert or
drawers.drawer_can_insert_object drawers.drawer_can_insert_stack_from_tube
def.tube.connect_sides = {left = 1, right = 1, back = 1, top = 1, def.tube.connect_sides = {left = 1, right = 1, back = 1, top = 1,
bottom = 1} bottom = 1}

@ -46,16 +46,15 @@ local S, NS = dofile(MP.."/intllib.lua")
local default_loaded = core.get_modpath("default") and default local default_loaded = core.get_modpath("default") and default
local mcl_loaded = core.get_modpath("mcl_core") and mcl_core local mcl_loaded = core.get_modpath("mcl_core") and mcl_core
local pipeworks_loaded = core.get_modpath("pipeworks") and pipeworks local pipeworks_loaded = core.get_modpath("pipeworks") and pipeworks
local digilines_loaded = core.get_modpath("digilines") and digilines
local controller_interval = tonumber(core.settings:get("drawers_controller_interval")) or 1.0 local function controller_formspec(pos)
local function controller_formspec(pos, meta_current_state)
local formspec = local formspec =
"size[8,8.5]".. "size[8,8.5]"..
drawers.gui_bg.. drawers.gui_bg..
drawers.gui_bg_img.. drawers.gui_bg_img..
drawers.gui_slots.. drawers.gui_slots..
"label[0,0;" .. S("Current State: ") .. meta_current_state .. "]" .. "label[0,0;" .. S("Drawer Controller") .. "]" ..
"list[current_name;src;3.5,1.75;1,1;]".. "list[current_name;src;3.5,1.75;1,1;]"..
"list[current_player;main;0,4.25;8,1;]".. "list[current_player;main;0,4.25;8,1;]"..
"list[current_player;main;0,5.5;8,3;8]".. "list[current_player;main;0,5.5;8,3;8]"..
@ -63,7 +62,7 @@ local function controller_formspec(pos, meta_current_state)
"listring[current_name;src]".. "listring[current_name;src]"..
"listring[current_player;main]" "listring[current_player;main]"
if digilines and pipeworks then if digilines_loaded and pipeworks_loaded then
formspec = formspec .. "field[1,3.5;4,1;digilineChannel;" .. S("Digiline Channel") .. ";${digilineChannel}]" formspec = formspec .. "field[1,3.5;4,1;digilineChannel;" .. S("Digiline Channel") .. ";${digilineChannel}]"
formspec = formspec .. "button_exit[5,3.2;2,1;saveChannel;" .. S("Save") .. "]" formspec = formspec .. "button_exit[5,3.2;2,1;saveChannel;" .. S("Save") .. "]"
end end
@ -149,20 +148,12 @@ local function add_drawer_to_inventory(controllerInventory, pos)
-- If we already indexed this item previously, check which drawer -- If we already indexed this item previously, check which drawer
-- has the most space and have that one be the one indexed -- has the most space and have that one be the one indexed
if controllerInventory[item_id] then if controllerInventory[item_id] then
local indexed_drawer_meta = core.get_meta({ local content = drawers.drawer_get_content(controllerInventory[item_id].drawer_pos, controllerInventory[item_id].visualid)
controllerInventory[item_id]["drawer_pos"], local new_content = drawers.drawer_get_content(pos, slot_id)
})
local indexed_drawer_meta_count = indexed_drawer_meta:get_int(
"count" .. controllerInventory[item_id]["visualid"])
local indexed_drawer_meta_max_count = indexed_drawer_meta:get_int(
"max_count" .. controllerInventory[item_id]["visualid"])
local drawer_meta_count = meta:get_int("count" .. slot_id) -- If the already indexed drawer has less space, we override the
local drawer_meta_max_count = meta:get_int("max_count" .. slot_id) -- table index for that item with the new drawer
if (new_content.maxCount - new_content.count) > (content.maxCount - content.count) then
-- If the already indexed drawer has less space, we override the table index for that item with the new drawer
if (indexed_drawer_meta_max_count - indexed_drawer_meta_count)
< (drawer_meta_max_count - drawer_meta_count) then
controllerInventory[item_id] = controller_index_slot(pos, slot_id) controllerInventory[item_id] = controller_index_slot(pos, slot_id)
end end
else else
@ -231,183 +222,75 @@ local function controller_get_drawer_index(pos, itemstring)
-- If the index has not been created, the item isn't in the index, the -- If the index has not been created, the item isn't in the index, the
-- item in the drawer is no longer the same item in the index, or the item -- item in the drawer is no longer the same item in the index, or the item
-- is in the index but it's full, run the index_drawers function. -- is in the index but it's full, run the index_drawers function.
local drawers_table_index = core.deserialize(meta:get_string("drawers_table_index")) local drawer_net_index = core.deserialize(meta:get_string("drawers_table_index"))
-- If the index has not been created -- If the index has not been created
if not drawers_table_index then if not drawer_net_index then
drawers_table_index = index_drawers(pos) drawer_net_index = index_drawers(pos)
meta:set_string("drawers_table_index", core.serialize(drawers_table_index)) meta:set_string("drawers_table_index", core.serialize(drawer_net_index))
-- If the item isn't in the index -- If the item isn't in the index
elseif not drawers_table_index[itemstring] then elseif not drawer_net_index[itemstring] then
drawers_table_index = index_drawers(pos) drawer_net_index = index_drawers(pos)
meta:set_string("drawers_table_index", core.serialize(drawers_table_index)) meta:set_string("drawers_table_index", core.serialize(drawer_net_index))
-- If the item is in the index but either the name that was indexed is not -- If the item is in the index but either the name that was indexed is not
-- the same as what is currently in the drawer or the drawer is full -- the same as what is currently in the drawer or the drawer is full
elseif drawers_table_index[itemstring] then elseif drawer_net_index[itemstring] then
local visualid = drawers_table_index[itemstring]["visualid"] local content = drawers.drawer_get_content(drawer_net_index[itemstring].drawer_pos, drawer_net_index[itemstring].visualid)
local indexed_drawer_meta = core.get_meta({
drawers_table_index[itemstring]["drawer_pos"] if content.name ~= itemstring or content.count >= content.maxCount then
}) drawer_net_index = index_drawers(pos)
local indexed_drawer_meta_name = indexed_drawer_meta:get_string("name" .. visualid) meta:set_string("drawers_table_index", core.serialize(drawer_net_index))
local indexed_drawer_meta_count = indexed_drawer_meta:get_int("count" .. visualid)
local indexed_drawer_meta_max_count = indexed_drawer_meta:get_int("max_count" .. visualid)
if indexed_drawer_meta_name ~= itemstring or indexed_drawer_meta_count >= indexed_drawer_meta_max_count then
drawers_table_index = index_drawers(pos)
meta:set_string("drawers_table_index", core.serialize(drawers_table_index))
end end
end end
return drawers_table_index return drawer_net_index
end end
local function controller_node_timer(pos, elapsed) local function controller_insert_to_drawers(pos, stack)
-- Inizialize metadata -- Inizialize metadata
local meta = core.get_meta(pos) local meta = core.get_meta(pos)
local meta_current_state = meta:get_string("current_state")
local meta_times_ran_while_jammed = meta:get_float("times_ran_while_jammed")
local meta_jammed_item_name = meta:get_string("jammed_item_name")
local inv = meta:get_inventory() local inv = meta:get_inventory()
local src = inv:get_stack("src", 1)
local src_name = src:get_name()
--[[ local drawer_net_index = controller_get_drawer_index(pos, stack:get_name())
There are four scenarios for the item slot in the controller.
1: No item is in the controller.
2: Item is not stackable.
3. Item is allowed and there is either an existing drawer for that item with room or an empty drawer.
4: Item is allowed, but there is no room.
There are three different possibilities for "current_state". -- We check if there is a drawer with the item and it isn't full. We will
1: "running" which means means it's operating normally. -- put the items we can into it.
2: "stopped" meaning the controller makes no attempt to put in the item possibly due to being unallowed for various reasons. if drawer_net_index[stack:get_name()] then
3: "jammed" meaning the item is allowed in to drawers, but there was no space to deposit it last time it ran. local drawer_pos = drawer_net_index[stack:get_name()]["drawer_pos"]
]] local visualid = drawer_net_index[stack:get_name()]["visualid"]
local content = drawers.drawer_get_content(drawer_pos, visualid)
--[[
If current state is jammed, the item that jammed it is the same item in the
src inv slot, and the amount of times ran while jammed is 8 or higher, we
set the current state to stopped. Will possibly want to make an option in the
formspec to ignore this an continue running if the user plans on using the
system in a way that may cause frequent jams making it a hassle to manually
clear it each time
]]
if meta_current_state == "jammed" and meta_jammed_item_name == src_name and meta_times_ran_while_jammed >= 2 then
meta:set_string("current_state", "stopped")
meta:set_string("formspec", controller_formspec(pos, S("Stopped")))
return true
end
-- If current state is stopped, and the item that jammed it is the same
-- item in the src inv slot, we don't do anything
if meta_current_state == "stopped" and meta_jammed_item_name == src_name then
return true
end
-- If current state is stopped, and the item that jammed it is not the
-- same item in the src inv slot, we set the current state to running and
-- clear the jam counter.
if meta_current_state == "stopped" and meta_jammed_item_name ~= src_name then
meta:set_string("current_state", "running")
meta:set_string("formspec", controller_formspec(pos, S("Running")))
meta:set_float("times_ran_while_jammed", 0)
end
-- If no item is in the controller, nothing is searched and current_state
-- is set to running and no jams.
if inv:is_empty("src") then
meta:set_string("current_state", "running")
meta:set_string("formspec", controller_formspec(pos, S("Running")))
meta:set_float("times_ran_while_jammed", 0)
return true
end
-- If a non stackable item is in the controller, such as a written book,
-- set the current_state to stopped because they are not allowed in drawers
if src:get_stack_max() == 1 then
meta:set_string("current_state", "stopped")
meta:set_string("formspec", controller_formspec(pos, S("Stopped")))
meta:set_string("jammed_item_name", src_name)
meta:set_float("times_ran_while_jammed", 1)
return true
end
local drawers_table_index = controller_get_drawer_index(pos, src_name)
-- This might not be needed, but my concern is if the above indexing takes
-- enough time, there could be a "race condition" where the item in the src
-- inventory is no longer the same item when we checked before or the
-- quantity of the items changed so I'm having it grab the item stack again
-- just in case.
-- If a race condition does occur, items could be lost or duplicated
src = inv:get_stack("src", 1)
src_name = src:get_name()
local src_count = src:get_count()
local src_stack_max = src:get_stack_max()
-- At this point, the item either was in the index or everything was reindexed so we check again
-- If there is a drawer with the item and it isn't full, we will put the items we can in to it
if drawers_table_index[src_name] then
local indexed_drawer_pos = drawers_table_index[src_name]["drawer_pos"]
local visualid = drawers_table_index[src_name]["visualid"]
local indexed_drawer_meta = core.get_meta(indexed_drawer_pos)
local indexed_drawer_meta_name = indexed_drawer_meta:get_string("name" .. visualid)
local indexed_drawer_meta_count = indexed_drawer_meta:get_int("count" .. visualid)
local indexed_drawer_meta_max_count = indexed_drawer_meta:get_int("max_count" .. visualid)
-- If the the item in the drawer is the same as the one we are trying to -- If the the item in the drawer is the same as the one we are trying to
-- store, the drawer is not full, and the drawer entity is loaded, we -- store, the drawer is not full, and the drawer entity is loaded, we
-- will put the items in the drawer -- will put the items in the drawer
if indexed_drawer_meta_name == src_name and indexed_drawer_meta_count < indexed_drawer_meta_max_count and drawers.drawer_visuals[core.serialize(indexed_drawer_pos)] then if content.name == stack:get_name() and
local leftover = drawers.drawer_insert_object(indexed_drawer_pos, nil, src, nil) content.count < content.maxCount and
inv:set_stack("src", 1, leftover) drawers.drawer_visuals[core.serialize(drawer_pos)] then
-- Set the controller metadata return drawers.drawer_insert_object(drawer_pos, stack, visualid)
meta:set_string("current_state", "running")
meta:set_string("formspec", controller_formspec(pos, S("Running")))
meta:set_float("times_ran_while_jammed", 0)
else
meta:set_string("current_state", "jammed")
meta:set_string("formspec", controller_formspec(pos, S("Jammed")))
meta:set_string("jammed_item_name", src_name)
meta:set_float("times_ran_while_jammed", meta_times_ran_while_jammed + 1)
end end
elseif drawers_table_index["empty"] then elseif drawer_net_index["empty"] then
local indexed_drawer_pos = drawers_table_index["empty"]["drawer_pos"] local drawer_pos = drawer_net_index["empty"]["drawer_pos"]
local visualid = drawers_table_index["empty"]["visualid"] local visualid = drawer_net_index["empty"]["visualid"]
local content = drawers.drawer_get_content(drawer_pos, visualid)
local indexed_drawer_meta = core.get_meta(indexed_drawer_pos)
local indexed_drawer_meta_name = indexed_drawer_meta:get_string("name" .. visualid)
-- If the drawer is still empty and the drawer entity is loaded, we will put the items in the drawer -- If the drawer is still empty and the drawer entity is loaded, we will put the items in the drawer
if indexed_drawer_meta_name == "" and drawers.drawer_visuals[core.serialize(indexed_drawer_pos)] then if content.name == "" and drawers.drawer_visuals[core.serialize(drawer_pos)] then
local leftover = drawers.drawer_insert_object(indexed_drawer_pos, nil, src, nil) local leftover = drawers.drawer_insert_object(drawer_pos, stack, visualid)
inv:set_stack("src", 1, leftover)
-- Add the item to the drawers table index and set the empty one to nil -- Add the item to the drawers table index and set the empty one to nil
drawers_table_index["empty"] = nil drawer_net_index["empty"] = nil
drawers_table_index[src_name] = indexed_drawer_pos drawer_net_index[stack:get_name()] = controller_index_slot(drawer_pos, visualid)
-- Set the controller metadata -- Set the controller metadata
meta:set_string("current_state", "running") meta:set_string("drawers_table_index", core.serialize(drawer_net_index))
meta:set_string("formspec", controller_formspec(pos, S("Running")))
meta:set_float("times_ran_while_jammed", 0) return leftover
meta:set_string("drawers_table_index", core.serialize(drawers_table_index))
else
meta:set_string("current_state", "jammed")
meta:set_string("formspec", controller_formspec(pos, S("Jammed")))
meta:set_string("jammed_item_name", src_name)
meta:set_float("times_ran_while_jammed", meta_times_ran_while_jammed + 1)
end end
else
meta:set_string("current_state", "jammed")
meta:set_string("formspec", controller_formspec(pos, S("Jammed")))
meta:set_string("jammed_item_name", src_name)
meta:set_float("times_ran_while_jammed", meta_times_ran_while_jammed + 1)
end end
return true return stack
end end
local function controller_can_dig(pos, player) local function controller_can_dig(pos, player)
@ -418,15 +301,10 @@ end
local function controller_on_construct(pos) local function controller_on_construct(pos)
local meta = core.get_meta(pos) local meta = core.get_meta(pos)
meta:set_string("current_state", "running")
meta:set_float("times_ran_while_jammed", 0)
meta:set_string("jammed_item_name", "")
meta:set_string("drawers_table_index", "") meta:set_string("drawers_table_index", "")
meta:set_string("formspec", controller_formspec(pos, S("Running"))) meta:set_string("formspec", controller_formspec(pos))
meta:get_inventory():set_size("src", 1) meta:get_inventory():set_size("src", 1)
core.get_node_timer(pos):start(controller_interval)
end end
local function controller_on_blast(pos) local function controller_on_blast(pos)
@ -438,14 +316,31 @@ local function controller_on_blast(pos)
end end
local function controller_allow_metadata_inventory_put(pos, listname, index, stack, player) local function controller_allow_metadata_inventory_put(pos, listname, index, stack, player)
if core.is_protected(pos, player:get_player_name()) then if (player and core.is_protected(pos, player:get_player_name())) or listname ~= "src" then
return 0 return 0
end end
if listname == "src" then
return stack:get_count() local drawer_net_index = controller_get_drawer_index(pos, stack:get_name())
if drawer_net_index[stack:get_name()] then
local drawer = drawer_net_index[stack:get_name()]
if drawers.drawer_get_content(drawer.drawer_pos, drawer.visualid).name == stack:get_name() then
return drawers.drawer_can_insert_stack(drawer.drawer_pos, stack, drawer["visualid"])
end end
end end
if drawer_net_index["empty"] then
local drawer = drawer_net_index["empty"]
if drawers.drawer_get_content(drawer.drawer_pos, drawer.visualid).name == "" then
return drawers.drawer_can_insert_stack(drawer.drawer_pos, stack, drawer.visualid)
end
end
return 0
end
local function controller_allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player) local function controller_allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
local meta = core.get_meta(pos) local meta = core.get_meta(pos)
local inv = meta:get_inventory() local inv = meta:get_inventory()
@ -460,6 +355,18 @@ local function controller_allow_metadata_inventory_take(pos, listname, index, st
return stack:get_count() return stack:get_count()
end end
local function controller_on_metadata_inventory_put(pos, listname, index, stack, player)
if listname ~= "src" then
return
end
local inv = core.get_meta(pos):get_inventory()
local complete_stack = inv:get_stack("src", 1)
local leftover = controller_insert_to_drawers(pos, complete_stack)
inv:set_stack("src", 1, leftover)
end
local function controller_on_digiline_receive(pos, _, channel, msg) local function controller_on_digiline_receive(pos, _, channel, msg)
local meta = core.get_meta(pos) local meta = core.get_meta(pos)
@ -468,21 +375,16 @@ local function controller_on_digiline_receive(pos, _, channel, msg)
end end
local item = ItemStack(msg) local item = ItemStack(msg)
local itemstring = item:get_name() local drawers_index = controller_get_drawer_index(pos, item:get_name())
local drawers_index = controller_get_drawer_index(pos, itemstring) if not drawers_index[item:get_name()] then
if not drawers_index[itemstring] then
-- we can't do anything: the requested item doesn't exist -- we can't do anything: the requested item doesn't exist
return return
end end
local drawer_data = drawers_index[itemstring] local taken_stack = drawers.drawer_take_item(drawers_index[item:get_name()]["drawer_pos"], item)
local dir = core.facedir_to_dir(core.get_node(pos).param2)
local taken_stack = drawers.drawer_take_item(drawer_data["drawer_pos"], item)
local node = core.get_node(pos)
local dir = core.facedir_to_dir(node.param2)
pipeworks.tube_inject_item(pos, pos, dir, taken_stack:to_string()) pipeworks.tube_inject_item(pos, pos, dir, taken_stack:to_string())
end end
@ -545,8 +447,8 @@ local function register_controller()
def.can_dig = controller_can_dig def.can_dig = controller_can_dig
def.on_construct = controller_on_construct def.on_construct = controller_on_construct
def.on_blast = controller_on_blast def.on_blast = controller_on_blast
def.on_timer = controller_node_timer
def.on_receive_fields = controller_on_receive_fields def.on_receive_fields = controller_on_receive_fields
def.on_metadata_inventory_put = controller_on_metadata_inventory_put
def.allow_metadata_inventory_put = controller_allow_metadata_inventory_put def.allow_metadata_inventory_put = controller_allow_metadata_inventory_put
def.allow_metadata_inventory_move = controller_allow_metadata_inventory_move def.allow_metadata_inventory_move = controller_allow_metadata_inventory_move
@ -558,16 +460,11 @@ local function register_controller()
def.tube = {} def.tube = {}
def.tube.insert_object = function(pos, node, stack, tubedir) def.tube.insert_object = function(pos, node, stack, tubedir)
-- add stack to inventory return controller_insert_to_drawers(pos, stack)
local remaining_stack = core.get_meta(pos):get_inventory():add_item("src", stack)
-- kick off controller work
controller_node_timer(pos)
return remaining_stack
end end
def.tube.can_insert = function(pos, node, stack, tubedir) def.tube.can_insert = function(pos, node, stack, tubedir)
return core.get_meta(pos):get_inventory():room_for_item("src", stack) return controller_allow_metadata_inventory_put(pos, "src", nil, stack, nil)
end end
def.tube.connect_sides = { def.tube.connect_sides = {
@ -578,7 +475,7 @@ local function register_controller()
def.after_dig_node = pipeworks.after_dig def.after_dig_node = pipeworks.after_dig
end end
if digilines and pipeworks then if digilines_loaded and pipeworks_loaded then
def.digiline = { def.digiline = {
receptor = {}, receptor = {},
effector = { effector = {

@ -208,6 +208,26 @@ function drawers.remove_visuals(pos)
end end
end end
--[[
Returns the visual object for the visualid of the drawer at pos.
visualid can be: "", "1", "2", ... or 1, 2, ...
]]
function drawers.get_visual(pos, visualid)
local drawer_visuals = drawers.drawer_visuals[core.serialize(pos)]
if not drawer_visuals then
return nil
end
-- not a real index (starts with 1)
local index = tonumber(visualid)
if visualid == "" then
index = 1
end
return drawer_visuals[index]
end
function drawers.update_drawer_upgrades(pos) function drawers.update_drawer_upgrades(pos)
local node = core.get_node(pos) local node = core.get_node(pos)
local ndef = core.registered_nodes[node.name] local ndef = core.registered_nodes[node.name]

@ -276,57 +276,59 @@ core.register_entity("drawers:visual", {
return self:take_items(ItemStack(self.itemName):get_stack_max()) return self:take_items(ItemStack(self.itemName):get_stack_max())
end, end,
try_insert_stack = function(self, itemstack, insert_stack) can_insert_stack = function(self, stack)
if stack:get_name() == "" or stack:get_count() <= 0 then
return 0
end
-- don't allow unstackable stacks
if self.itemName == "" and stack:get_stack_max() ~= 1 then
return stack:get_count()
end
if self.itemName ~= stack:get_name() then
return 0
end
if (self.count + stack:get_count()) <= self.maxCount then
return stack:get_count()
end
return self.maxCount - self.count
end,
try_insert_stack = function(self, itemstack, insert_all)
local stackCount = itemstack:get_count() local stackCount = itemstack:get_count()
local stackName = itemstack:get_name() local stackName = itemstack:get_name()
-- if nothing to be added, return local insertCount = self:can_insert_stack(itemstack)
if stackCount <= 0 then return itemstack end
-- if no itemstring, return
if stackName == "" then return itemstack end
-- only add one, if player holding sneak key if insertCount == 0 then
if not insert_stack then
stackCount = 1
end
-- if current itemstring is not empty
if self.itemName ~= "" then
-- check if same item
if stackName ~= self.itemName then return itemstack end
else -- is empty
self.itemName = stackName
self.count = 0
-- get new stack max
self.itemStackMax = ItemStack(self.itemName):get_stack_max()
self.maxCount = self.itemStackMax * self.stackMaxFactor
end
-- Don't add items stackable only to 1
if self.itemStackMax == 1 then
self.itemName = ""
return itemstack return itemstack
end end
-- set new counts: -- only add one, if player holding sneak key
-- if new count is more than max_count if not insert_all then
if (self.count + stackCount) > self.maxCount then insertCount = 1
itemstack:set_count(self.count + stackCount - self.maxCount)
self.count = self.maxCount
else -- new count fits
self.count = self.count + stackCount
-- this is for only removing one
itemstack:set_count(itemstack:get_count() - stackCount)
end end
-- update infotext, texture -- in case the drawer was empty, initialize count, itemName, maxCount
if self.itemName == "" then
self.count = 0
self.itemName = itemstack:get_name()
self.maxCount = itemstack:get_stack_max() * self.stackMaxFactor
end
-- update everything
self.count = self.count + insertCount
self:updateInfotext() self:updateInfotext()
self:updateTexture() self:updateTexture()
self:saveMetaData() self:saveMetaData()
if itemstack:get_count() == 0 then itemstack = ItemStack("") end -- return leftover
itemstack:take_item(insertCount)
if itemstack:get_count() == 0 then
return ItemStack("")
end
return itemstack return itemstack
end, end,

@ -1 +0,0 @@
drawers_controller_interval (Drawer Controller update interval in seconds) float 1.0 0.1 10.0