Add digiline support

This commit is contained in:
Linus Jahn 2020-01-09 14:20:43 +01:00
parent eedbbfcdff
commit 439eb81ccd
No known key found for this signature in database
GPG Key ID: 4663231A91A1E27B
4 changed files with 130 additions and 38 deletions

@ -200,8 +200,9 @@ end
function drawers.drawer_can_insert_object(pos, node, stack, direction) function drawers.drawer_can_insert_object(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 false end if not drawer_visuals then
return false
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.itemName == "" or (visual.itemName == stack:get_name() and visual.count ~= visual.maxCount) then
@ -211,6 +212,27 @@ function drawers.drawer_can_insert_object(pos, node, stack, direction)
return false return false
end end
function drawers.drawer_take_item(pos, itemstack)
local drawer_visuals = drawers.drawer_visuals[core.serialize(pos)]
if not drawer_visuals then
return ItemStack("")
end
-- check for max count
if itemstack:get_count() > itemstack:get_stack_max() then
itemstack:set_count(itemstack:get_stack_max())
end
for _, visual in pairs(drawer_visuals) do
if visual.itemName == itemstack:get_name() and visual.count ~= visual.maxCount then
return visual:take_items(itemstack:get_count())
end
end
return ItemStack()
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"

@ -1,7 +1,7 @@
--[[ --[[
Minetest Mod Storage Drawers - A Mod adding storage drawers Minetest Mod Storage Drawers - A Mod adding storage drawers
Copyright (C) 2017-2019 Linus Jahn <lnj@kaidan.im> Copyright (C) 2017-2020 Linus Jahn <lnj@kaidan.im>
Copyright (C) 2018 isaiah658 Copyright (C) 2018 isaiah658
MIT License MIT License
@ -216,6 +216,52 @@ local function index_drawers(pos)
return controllerInventory return controllerInventory
end end
--[[
Returns a table of all stored itemstrings in the drawer network with their
drawer position and visualid.
It uses the cached data, if possible, but if the itemstring is not contained
the network is reindexed.
]]
local function controller_get_drawer_index(pos, itemstring)
local meta = core.get_meta(pos)
-- 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
-- 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"))
-- If the index has not been created
if not drawers_table_index then
drawers_table_index = index_drawers(pos)
meta:set_string("drawers_table_index", core.serialize(drawers_table_index))
-- If the item isn't in the index
elseif not drawers_table_index[itemstring] then
drawers_table_index = index_drawers(pos)
meta:set_string("drawers_table_index", core.serialize(drawers_table_index))
-- 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
elseif drawers_table_index[itemstring] then
local visualid = drawers_table_index[itemstring]["visualid"]
local indexed_drawer_meta = core.get_meta({
x = drawers_table_index[itemstring]["drawer_pos_x"],
y = drawers_table_index[itemstring]["drawer_pos_y"],
z = drawers_table_index[itemstring]["drawer_pos_z"]
})
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 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
return drawers_table_index
end
local function controller_node_timer(pos, elapsed) local function controller_node_timer(pos, elapsed)
-- Inizialize metadata -- Inizialize metadata
local meta = core.get_meta(pos) local meta = core.get_meta(pos)
@ -287,34 +333,7 @@ local function controller_node_timer(pos, elapsed)
return true return true
end end
-- If the index has not been created, the item isn't in the index, the drawers_table_index = controller_get_drawer_index(pos, src_name)
-- 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.
local drawers_table_index = core.deserialize(meta:get_string("drawers_table_index"))
-- If the index has not been created
if not drawers_table_index then
drawers_table_index = index_drawers(pos)
meta:set_string("drawers_table_index", core.serialize(drawers_table_index))
-- If the item isn't in the index
elseif not drawers_table_index[src_name] then
drawers_table_index = index_drawers(pos)
meta:set_string("drawers_table_index", core.serialize(drawers_table_index))
-- 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
elseif drawers_table_index[src_name] then
local visualid = drawers_table_index[src_name]["visualid"]
local indexed_drawer_meta = core.get_meta({x = drawers_table_index[src_name]["drawer_pos_x"], y = drawers_table_index[src_name]["drawer_pos_y"], z = drawers_table_index[src_name]["drawer_pos_z"]})
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 indexed_drawer_meta_name ~= src_name 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
-- This might not be needed, but my concern is if the above indexing takes -- 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 -- enough time, there could be a "race condition" where the item in the src
@ -433,6 +452,42 @@ 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_digiline_receive(pos, _, channel, msg)
local meta = core.get_meta(pos)
local own_channel = meta:get_string("digiline_channel")
if own_channel == "" then
own_channel = "drawer_controller"
end
if channel ~= own_channel then
return
end
local item = ItemStack(msg)
local itemstring = item:get_name()
local drawers_index = controller_get_drawer_index(pos, itemstring)
if not drawers_index[itemstring] then
-- we can't do anything: the requested item doesn't exist
return
end
local drawer_data = drawers_index[itemstring]
local drawer_pos = {
x = drawer_data["drawer_pos_x"],
y = drawer_data["drawer_pos_y"],
z = drawer_data["drawer_pos_z"]
}
local taken_stack = drawers.drawer_take_item(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())
end
-- Registers the drawer controller -- Registers the drawer controller
local function register_controller() local function register_controller()
-- Set the controller definition using a table to allow for pipeworks and -- Set the controller definition using a table to allow for pipeworks and
@ -517,6 +572,15 @@ local function register_controller()
def.after_dig_node = pipeworks.after_dig def.after_dig_node = pipeworks.after_dig
end end
if digilines then
def.digiline = {
receptor = {},
effector = {
action = controller_on_digiline_receive
},
}
end
core.register_node("drawers:controller", def) core.register_node("drawers:controller", def)
end end

@ -231,7 +231,13 @@ core.register_entity("drawers:visual", {
return return
end end
local stack = self:take_items(add_stack) local stack
if add_stack then
stack = self:take_stack()
else
stack = self:take_items(1)
end
if stack ~= nil then if stack ~= nil then
-- add removed stack to player's inventory -- add removed stack to player's inventory
inv:add_item("main", stack) inv:add_item("main", stack)
@ -241,17 +247,13 @@ core.register_entity("drawers:visual", {
end end
end, end,
take_items = function(self, take_stack) take_items = function(self, removeCount)
local meta = core.get_meta(self.drawer_pos) local meta = core.get_meta(self.drawer_pos)
if self.count <= 0 then if self.count <= 0 then
return return
end end
local removeCount = 1
if take_stack then
removeCount = ItemStack(self.itemName):get_stack_max()
end
if removeCount > self.count then if removeCount > self.count then
removeCount = self.count removeCount = self.count
end end
@ -270,6 +272,10 @@ core.register_entity("drawers:visual", {
return stack return stack
end, end,
take_stack = function(self)
return self:take_items(ItemStack(self.itemName):get_stack_max())
end,
try_insert_stack = function(self, itemstack, insert_stack) try_insert_stack = function(self, itemstack, insert_stack)
local stackCount = itemstack:get_count() local stackCount = itemstack:get_count()
local stackName = itemstack:get_name() local stackName = itemstack:get_name()

@ -1,2 +1,2 @@
name = drawers name = drawers
optional_depends = default, mcl_core, screwdriver, pipeworks, intllib, moreores optional_depends = default, mcl_core, screwdriver, pipeworks, intllib, moreores, digilines