mirror of
https://github.com/minetest-mods/drawers.git
synced 2024-11-21 22:23:44 +01:00
Large drawer controller refactoring
This commit is contained in:
parent
7cf8cb33aa
commit
62b5fa51ae
57
lua/api.lua
57
lua/api.lua
@ -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,12 +316,29 @@ 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
|
||||||
|
|
||||||
|
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
|
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)
|
||||||
@ -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
|
|
Loading…
Reference in New Issue
Block a user