summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x[-rw-r--r--]init.lua398
-rwxr-xr-xlua/api.lua129
-rw-r--r--lua/helpers.lua84
-rwxr-xr-xlua/visual.lua233
4 files changed, 464 insertions, 380 deletions
diff --git a/init.lua b/init.lua
index 00cb05f..f27fbcc 100644..100755
--- a/init.lua
+++ b/init.lua
@@ -2,7 +2,6 @@
Minetest Mod Storage Drawers - A Mod adding storage drawers
Copyright (C) 2017 LNJ <git@lnj.li>
-Copyright (C) 2016 Mango Tango <mtango688@gmail.com>
MIT License
@@ -27,396 +26,35 @@ SOFTWARE.
drawers = {}
-local WOOD_SOUNDS
-local WOOD_ITEMSTRING
-local CHEST_ITEMSTRING
if default then
- WOOD_SOUNDS = default.node_sound_wood_defaults()
- WOOD_ITEMSTRING = "default:wood"
- CHEST_ITEMSTRING = "default:chest"
+ drawers.WOOD_SOUNDS = default.node_sound_wood_defaults()
+ drawers.WOOD_ITEMSTRING = "default:wood"
+ drawers.CHEST_ITEMSTRING = "default:chest"
elseif mcl_core then -- MineClone 2
- WOOD_ITEMSTRING = "mcl_core:wood"
- CHEST_ITEMSTRING = "mcl_chests:chest"
+ drawers.WOOD_ITEMSTRING = "mcl_core:wood"
+ drawers.CHEST_ITEMSTRING = "mcl_chests:chest"
if mcl_sounds then
- WOOD_SOUNDS = mcl_sounds.node_sound_wood_defaults()
+ drawers.WOOD_SOUNDS = mcl_sounds.node_sound_wood_defaults()
end
else
- WOOD_ITEMSTRING = "wood"
- CHEST_ITEMSTRING = "chest"
+ drawers.WOOD_ITEMSTRING = "wood"
+ drawers.CHEST_ITEMSTRING = "chest"
end
-local DEFAULT_VISUAL_TEXTURE = "drawers_empty.png"
-drawers.node_box_simple = {
- {-0.5, -0.5, -0.4375, 0.5, 0.5, 0.5},
- {-0.5, -0.5, -0.5, -0.4375, 0.5, -0.4375},
- {0.4375, -0.5, -0.5, 0.5, 0.5, -0.4375},
- {-0.4375, 0.4375, -0.5, 0.4375, 0.5, -0.4375},
- {-0.4375, -0.5, -0.5, 0.4375, -0.4375, -0.4375},
-}
+--
+-- Load files
+--
-local function gen_info_text(basename, count, factor, stack_max)
- -- in the end it should look like:
- -- Sand [4x99+43 / 24x99]
- -- bot NOT so:
- -- Dirt [2x99 + 0 / 24x99]
- local countstr = tostring(math.floor(count / stack_max)) .. "x" ..
- stack_max
- if count % stack_max ~= 0 then
- countstr = countstr .. " + " .. count % stack_max
- end
- return basename .. " [" .. countstr .. " / " .. factor .. "x" .. stack_max .. "]"
-end
-
-local function get_inv_image(name)
- local texture = DEFAULT_VISUAL_TEXTURE
- local def = core.registered_items[name]
- if name ~= "air" and def then
- if def.inventory_image and #def.inventory_image > 0 then
- texture = def.inventory_image
- else
- if not def.tiles then return texture end
-
- local c = #def.tiles or 0
- local x = {}
- for i, v in ipairs(def.tiles) do
- if type(v) == "table" then
- x[i] = v.name
- else
- x[i] = v
- end
- i = i + 1
- end
- if not x[3] then x[3] = x[1] end
- if not x[4] then x[4] = x[3] end
- texture = core.inventorycube(x[1], x[3], x[4])
- end
- end
- return texture
-end
-
-core.register_entity("drawers:visual", {
- initial_properties = {
- hp_max = 1,
- physical = false,
- collide_with_objects = false,
- collisionbox = {-0.4374, -0.4374, 0, 0.4374, 0.4374, 0}, -- for param2 0, 2
- visual = "upright_sprite", -- "wielditem" for items without inv img?
- visual_size = {x = 0.6, y = 0.6},
- textures = {"drawers_empty.png"},
- spritediv = {x = 1, y = 1},
- initial_sprite_basepos = {x = 0, y = 0},
- is_visible = true,
- },
-
- get_staticdata = function(self)
- return core.serialize({
- drawer_posx = self.drawer_pos.x,
- drawer_posy = self.drawer_pos.y,
- drawer_posz = self.drawer_pos.z,
- texture = self.texture
- })
- end,
-
- on_activate = function(self, staticdata, dtime_s)
- -- Restore data
- data = core.deserialize(staticdata)
- if data then
- self.drawer_pos = {
- x = data.drawer_posx,
- y = data.drawer_posy,
- z = data.drawer_posz,
- }
- self.texture = data.texture
- else
- self.drawer_pos = drawers.last_drawer_pos
- self.texture = drawers.last_texture or DEFAULT_VISUAL_TEXTURE
- end
-
-
- local node = core.get_node(self.drawer_pos)
-
- -- collisionbox
- local colbox = {-0.4374, -0.4374, 0, 0.4374, 0.4374, 0} -- for param2 = 0 or 2
- if node.param2 == 1 or node.param2 == 3 then
- colbox = {0, -0.4374, -0.4374, 0, 0.4374, 0.4374}
- end
-
-
- -- infotext
- local meta = core.get_meta(self.drawer_pos)
- local infotext = meta:get_string("entity_infotext") .. "\n\n\n\n\n"
-
- self.object:set_properties({
- collisionbox = colbox,
- infotext = infotext,
- textures = {self.texture}
- })
-
- -- make entity undestroyable
- self.object:set_armor_groups({immortal = 1})
- end,
-
- on_rightclick = function(self, clicker)
- local node = core.get_node(self.drawer_pos)
- local itemstack = clicker:get_wielded_item()
- local add_count = itemstack:get_count()
- local add_name = itemstack:get_name()
-
- local meta = core.get_meta(self.drawer_pos)
- local name = meta:get_string("name")
- local count = meta:get_int("count")
- local max_count = meta:get_int("max_count")
-
- local base_stack_max = meta:get_int("base_stack_max")
- local stack_max_factor = meta:get_int("stack_max_factor")
-
- -- if nothing to be added, return
- if add_count <= 0 then return end
- -- if no itemstring, return
- if item_name == "" then return end
-
- -- only add one, if player holding sneak key
- if clicker:get_player_control().sneak then
- add_count = 1
- end
-
- -- if current itemstring is not empty
- if name ~= "" then
- -- check if same item
- if add_name ~= name then return end
- else -- is empty
- name = add_name
- count = 0
-
- -- get new stack max
- base_stack_max = ItemStack(name):get_stack_max()
- max_count = base_stack_max * stack_max_factor
-
- -- Don't add items stackable only to 1
- if base_stack_max == 1 then
- return
- end
-
- meta:set_string("name", name)
- meta:set_int("base_stack_max", base_stack_max)
- meta:set_int("max_count", max_count)
- end
-
- -- set new counts:
- -- if new count is more than max_count
- if (count + add_count) > max_count then
- count = max_count
- itemstack:set_count((count + add_count) - max_count)
- else -- new count fits
- count = count + add_count
- itemstack:set_count(itemstack:get_count() - add_count)
- end
- -- set new drawer count
- meta:set_int("count", count)
-
- -- update infotext
- local infotext = gen_info_text(core.registered_items[name].description,
- count, stack_max_factor, base_stack_max)
- meta:set_string("entity_infotext", infotext)
-
- -- texture
- self.texture = get_inv_image(name)
-
- self.object:set_properties({
- infotext = infotext .. "\n\n\n\n\n",
- textures = {self.texture}
- })
-
- clicker:set_wielded_item(itemstack)
- end,
-
- on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir)
- local meta = minetest.get_meta(self.drawer_pos)
- local count = meta:get_int("count")
-
- if count <= 0 then
- return
- end
- local name = meta:get_string("name")
-
- local remove_count = 1
- if not puncher:get_player_control().sneak then
- remove_count = ItemStack(name):get_stack_max()
- end
- if remove_count > count then remove_count = count end
-
- local stack = ItemStack(name)
- stack:set_count(remove_count)
-
- local inv = puncher:get_inventory()
- if not inv:room_for_item("main", stack) then
- return
- end
-
- inv:add_item("main", stack)
- count = count - remove_count
- meta:set_int("count", count)
-
- -- update infotext
- local stack_max_factor = meta:get_int("stack_max_factor")
- local base_stack_max = meta:get_int("base_stack_max")
- local item_description = ""
- if core.registered_items[name] then
- item_description = core.registered_items[name].description
- end
+local modpath = core.get_modpath("drawers")
+dofile(modpath .. "/lua/helpers.lua")
+dofile(modpath .. "/lua/visual.lua")
+dofile(modpath .. "/lua/api.lua")
- if count <= 0 then
- meta:set_string("name", "")
- self.texture = "drawers_empty.png"
- item_description = "Empty"
- end
- local infotext = gen_info_text(item_description,
- count, stack_max_factor, base_stack_max)
- meta:set_string("entity_infotext", infotext)
-
- self.object:set_properties({
- infotext = infotext .. "\n\n\n\n\n",
- textures = {self.texture}
- })
- end
-})
-
-local function spawn_visual(pos)
- local node = core.get_node(pos)
-
- -- data for the new visual
- drawers.last_drawer_pos = pos
- drawers.last_texture = get_inv_image(core.get_meta(pos):get_string("name"))
-
- local bdir = core.facedir_to_dir(node.param2)
- local fdir = vector.new(-bdir.x, 0, -bdir.z)
- local pos2 = vector.add(pos, vector.multiply(fdir, 0.438))
-
- obj = core.add_entity(pos2, "drawers:visual")
-
- if bdir.x < 0 then obj:setyaw(0.5 * math.pi) end
- if bdir.z < 0 then obj:setyaw(math.pi) end
- if bdir.x > 0 then obj:setyaw(1.5 * math.pi) end
-
- drawers.last_texture = nil
-end
-
--- construct drawer
-local function drawer_on_construct(pos)
- local node = core.get_node(pos)
- local ndef = core.registered_nodes[node.name]
-
- local base_stack_max = core.nodedef_default.stack_max or 99
- local stack_max_factor = ndef.drawer_stack_max_factor or 24 -- 3x8
-
- -- meta
- local meta = core.get_meta(pos)
- meta:set_string("name", "")
- meta:set_int("count", 0)
- meta:set_int("max_count", base_stack_max * stack_max_factor)
- meta:set_int("stack_max_factor", stack_max_factor)
- meta:set_int("base_stack_max", base_stack_max)
- meta:set_string("entity_infotext", gen_info_text("Empty", 0,
- stack_max_factor, base_stack_max))
-
- spawn_visual(pos)
-end
-
--- destruct drawer
-local function drawer_on_destruct(pos)
- local objs = core.get_objects_inside_radius(pos, 0.5)
- if objs then
- for _, obj in pairs(objs) do
- if obj and obj:get_luaentity() and
- obj:get_luaentity().name == "drawers:visual" then
- obj:remove()
- return
- end
- end
- end
-end
-
--- drop all items
-local function drawer_on_dig(pos, node, player)
- local meta = core.get_meta(pos)
- local count = meta:get_int("count")
- local name = meta:get_string("name")
-
- -- remove node
- core.node_dig(pos, node, player)
-
- -- drop the items
- local stack_max = ItemStack(name):get_stack_max()
-
- local j = math.floor(count / stack_max) + 1
- local i = 1
- while i <= j do
- if not (i == j) then
- core.add_item(pos, name .. " " .. stack_max)
- else
- core.add_item(pos, name .. " " .. count % stack_max)
- end
- i = i + 1
- end
-end
-
-core.register_lbm({
- name = "drawers:restore_visual",
- nodenames = {"group:drawer"},
- run_at_every_load = true,
- action = function(pos, node)
- local objs = core.get_objects_inside_radius(pos, 0.5)
- if objs then
- for _, obj in pairs(objs) do
- if obj and obj:get_luaentity() and
- obj:get_luaentity().name == "drawers:visual" then
- return
- end
- end
- end
-
- -- no visual found, create a new one
- spawn_visual(pos)
- end
-})
-
-function drawers.register_drawer(name, def)
- def.description = def.description or "Drawer"
- def.drawtype = "nodebox"
- def.node_box = {type = "fixed", fixed = drawers.node_box_simple}
- def.collision_box = {type = "regular"}
- def.selection_box = {type = "regular"}
- def.paramtype = "light"
- def.paramtype2 = "facedir"
- def.legacy_facedir_simple = true
- def.groups = def.groups or {}
- def.groups.drawer = def.groups.drawer or 1
- def.drawer_stack_max_factor = def.drawer_stack_max_factor or 24
-
- -- events
- def.on_construct = drawer_on_construct
- def.on_destruct = drawer_on_destruct
- def.on_dig = drawer_on_dig
-
- if screwdriver then
- def.on_rotate = def.on_rotate or screwdriver.disallow
- end
-
- core.register_node(name, def)
-
- if (not def.no_craft) and def.material then
- core.register_craft({
- output = name,
- recipe = {
- {def.material, def.material, def.material},
- {"", CHEST_ITEMSTRING, ""},
- {def.material, def.material, def.material}
- }
- })
- end
-end
+--
+-- Register drawers
+--
drawers.register_drawer("drawers:wood", {
description = "Wooden Drawer",
diff --git a/lua/api.lua b/lua/api.lua
new file mode 100755
index 0000000..ecda9f2
--- /dev/null
+++ b/lua/api.lua
@@ -0,0 +1,129 @@
+--[[
+Minetest Mod Storage Drawers - A Mod adding storage drawers
+
+Copyright (C) 2017 LNJ <git@lnj.li>
+Copyright (C) 2016 Mango Tango <mtango688@gmail.com>
+
+MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+]]
+
+drawers.node_box_simple = {
+ {-0.5, -0.5, -0.4375, 0.5, 0.5, 0.5},
+ {-0.5, -0.5, -0.5, -0.4375, 0.5, -0.4375},
+ {0.4375, -0.5, -0.5, 0.5, 0.5, -0.4375},
+ {-0.4375, 0.4375, -0.5, 0.4375, 0.5, -0.4375},
+ {-0.4375, -0.5, -0.5, 0.4375, -0.4375, -0.4375},
+}
+
+-- construct drawer
+function drawers.drawer_on_construct(pos)
+ local node = core.get_node(pos)
+ local ndef = core.registered_nodes[node.name]
+
+ local base_stack_max = core.nodedef_default.stack_max or 99
+ local stack_max_factor = ndef.drawer_stack_max_factor or 24 -- 3x8
+
+ -- meta
+ local meta = core.get_meta(pos)
+ meta:set_string("name", "")
+ meta:set_int("count", 0)
+ meta:set_int("max_count", base_stack_max * stack_max_factor)
+ meta:set_int("stack_max_factor", stack_max_factor)
+ meta:set_int("base_stack_max", base_stack_max)
+ meta:set_string("entity_infotext", drawers.gen_info_text("Empty", 0,
+ stack_max_factor, base_stack_max))
+
+ drawers.spawn_visual(pos)
+end
+
+-- destruct drawer
+function drawers.drawer_on_destruct(pos)
+ local objs = core.get_objects_inside_radius(pos, 0.5)
+ if objs then
+ for _, obj in pairs(objs) do
+ if obj and obj:get_luaentity() and
+ obj:get_luaentity().name == "drawers:visual" then
+ obj:remove()
+ return
+ end
+ end
+ end
+end
+
+-- drop all items
+function drawers.drawer_on_dig(pos, node, player)
+ local meta = core.get_meta(pos)
+ local count = meta:get_int("count")
+ local name = meta:get_string("name")
+
+ -- remove node
+ core.node_dig(pos, node, player)
+
+ -- drop the items
+ local stack_max = ItemStack(name):get_stack_max()
+
+ local j = math.floor(count / stack_max) + 1
+ local i = 1
+ while i <= j do
+ if not (i == j) then
+ core.add_item(pos, name .. " " .. stack_max)
+ else
+ core.add_item(pos, name .. " " .. count % stack_max)
+ end
+ i = i + 1
+ end
+end
+
+function drawers.register_drawer(name, def)
+ def.description = def.description or "Drawer"
+ def.drawtype = "nodebox"
+ def.node_box = {type = "fixed", fixed = drawers.node_box_simple}
+ def.collision_box = {type = "regular"}
+ def.selection_box = {type = "regular"}
+ def.paramtype = "light"
+ def.paramtype2 = "facedir"
+ def.legacy_facedir_simple = true
+ def.groups = def.groups or {}
+ def.groups.drawer = def.groups.drawer or 1
+ def.drawer_stack_max_factor = def.drawer_stack_max_factor or 24
+
+ -- events
+ def.on_construct = drawers.drawer_on_construct
+ def.on_destruct = drawers.drawer_on_destruct
+ def.on_dig = drawers.drawer_on_dig
+
+ if screwdriver then
+ def.on_rotate = def.on_rotate or screwdriver.disallow
+ end
+
+ core.register_node(name, def)
+
+ if (not def.no_craft) and def.material then
+ core.register_craft({
+ output = name,
+ recipe = {
+ {def.material, def.material, def.material},
+ {"", drawers.CHEST_ITEMSTRING, ""},
+ {def.material, def.material, def.material}
+ }
+ })
+ end
+end
diff --git a/lua/helpers.lua b/lua/helpers.lua
new file mode 100644
index 0000000..11263f4
--- /dev/null
+++ b/lua/helpers.lua
@@ -0,0 +1,84 @@
+--[[
+Minetest Mod Storage Drawers - A Mod adding storage drawers
+
+Copyright (C) 2017 LNJ <git@lnj.li>
+Copyright (C) 2016 Mango Tango <mtango688@gmail.com>
+
+MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+]]
+
+function drawers.gen_info_text(basename, count, factor, stack_max)
+ -- in the end it should look like:
+ -- Sand [4x99+43 / 24x99]
+ local countstr = tostring(math.floor(count / stack_max)) .. "x" ..
+ stack_max
+ if count % stack_max ~= 0 then
+ countstr = countstr .. " + " .. count % stack_max
+ end
+ return basename .. " [" .. countstr .. " / " .. factor .. "x" .. stack_max .. "]"
+end
+
+function drawers.get_inv_image(name)
+ local texture = "drawers_empty.png"
+ local def = core.registered_items[name]
+ if name ~= "air" and def then
+ if def.inventory_image and #def.inventory_image > 0 then
+ texture = def.inventory_image
+ else
+ if not def.tiles then return texture end
+
+ local c = #def.tiles or 0
+ local x = {}
+ for i, v in ipairs(def.tiles) do
+ if type(v) == "table" then
+ x[i] = v.name
+ else
+ x[i] = v
+ end
+ i = i + 1
+ end
+ if not x[3] then x[3] = x[1] end
+ if not x[4] then x[4] = x[3] end
+ texture = core.inventorycube(x[1], x[3], x[4])
+ end
+ end
+ return texture
+end
+
+function drawers.spawn_visual(pos)
+ local node = core.get_node(pos)
+
+ -- data for the new visual
+ drawers.last_drawer_pos = pos
+ drawers.last_texture = drawers.get_inv_image(core.get_meta(pos):get_string("name"))
+
+ local bdir = core.facedir_to_dir(node.param2)
+ local fdir = vector.new(-bdir.x, 0, -bdir.z)
+ local pos2 = vector.add(pos, vector.multiply(fdir, 0.438))
+
+ obj = core.add_entity(pos2, "drawers:visual")
+
+ if bdir.x < 0 then obj:setyaw(0.5 * math.pi) end
+ if bdir.z < 0 then obj:setyaw(math.pi) end
+ if bdir.x > 0 then obj:setyaw(1.5 * math.pi) end
+
+ drawers.last_texture = nil
+end
diff --git a/lua/visual.lua b/lua/visual.lua
new file mode 100755
index 0000000..448ecc5
--- /dev/null
+++ b/lua/visual.lua
@@ -0,0 +1,233 @@
+--[[
+Minetest Mod Storage Drawers - A Mod adding storage drawers
+
+Copyright (C) 2017 LNJ <git@lnj.li>
+
+MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+]]
+
+core.register_entity("drawers:visual", {
+ initial_properties = {
+ hp_max = 1,
+ physical = false,
+ collide_with_objects = false,
+ collisionbox = {-0.4374, -0.4374, 0, 0.4374, 0.4374, 0}, -- for param2 0, 2
+ visual = "upright_sprite", -- "wielditem" for items without inv img?
+ visual_size = {x = 0.6, y = 0.6},
+ textures = {"drawers_empty.png"},
+ spritediv = {x = 1, y = 1},
+ initial_sprite_basepos = {x = 0, y = 0},
+ is_visible = true,
+ },
+
+ get_staticdata = function(self)
+ return core.serialize({
+ drawer_posx = self.drawer_pos.x,
+ drawer_posy = self.drawer_pos.y,
+ drawer_posz = self.drawer_pos.z,
+ texture = self.texture
+ })
+ end,
+
+ on_activate = function(self, staticdata, dtime_s)
+ -- Restore data
+ data = core.deserialize(staticdata)
+ if data then
+ self.drawer_pos = {
+ x = data.drawer_posx,
+ y = data.drawer_posy,
+ z = data.drawer_posz,
+ }
+ self.texture = data.texture
+ else
+ self.drawer_pos = drawers.last_drawer_pos
+ self.texture = drawers.last_texture or "drawers_empty.png"
+ end
+
+
+ local node = core.get_node(self.drawer_pos)
+
+ -- collisionbox
+ local colbox = {-0.4374, -0.4374, 0, 0.4374, 0.4374, 0} -- for param2 = 0 or 2
+ if node.param2 == 1 or node.param2 == 3 then
+ colbox = {0, -0.4374, -0.4374, 0, 0.4374, 0.4374}
+ end
+
+
+ -- infotext
+ local meta = core.get_meta(self.drawer_pos)
+ local infotext = meta:get_string("entity_infotext") .. "\n\n\n\n\n"
+
+ self.object:set_properties({
+ collisionbox = colbox,
+ infotext = infotext,
+ textures = {self.texture}
+ })
+
+ -- make entity undestroyable
+ self.object:set_armor_groups({immortal = 1})
+ end,
+
+ on_rightclick = function(self, clicker)
+ local node = core.get_node(self.drawer_pos)
+ local itemstack = clicker:get_wielded_item()
+ local add_count = itemstack:get_count()
+ local add_name = itemstack:get_name()
+
+ local meta = core.get_meta(self.drawer_pos)
+ local name = meta:get_string("name")
+ local count = meta:get_int("count")
+ local max_count = meta:get_int("max_count")
+
+ local base_stack_max = meta:get_int("base_stack_max")
+ local stack_max_factor = meta:get_int("stack_max_factor")
+
+ -- if nothing to be added, return
+ if add_count <= 0 then return end
+ -- if no itemstring, return
+ if item_name == "" then return end
+
+ -- only add one, if player holding sneak key
+ if clicker:get_player_control().sneak then
+ add_count = 1
+ end
+
+ -- if current itemstring is not empty
+ if name ~= "" then
+ -- check if same item
+ if add_name ~= name then return end
+ else -- is empty
+ name = add_name
+ count = 0
+
+ -- get new stack max
+ base_stack_max = ItemStack(name):get_stack_max()
+ max_count = base_stack_max * stack_max_factor
+
+ -- Don't add items stackable only to 1
+ if base_stack_max == 1 then
+ return
+ end
+
+ meta:set_string("name", name)
+ meta:set_int("base_stack_max", base_stack_max)
+ meta:set_int("max_count", max_count)
+ end
+
+ -- set new counts:
+ -- if new count is more than max_count
+ if (count + add_count) > max_count then
+ count = max_count
+ itemstack:set_count((count + add_count) - max_count)
+ else -- new count fits
+ count = count + add_count
+ itemstack:set_count(itemstack:get_count() - add_count)
+ end
+ -- set new drawer count
+ meta:set_int("count", count)
+
+ -- update infotext
+ local infotext = drawers.gen_info_text(core.registered_items[name].description,
+ count, stack_max_factor, base_stack_max)
+ meta:set_string("entity_infotext", infotext)
+
+ -- texture
+ self.texture = drawers.get_inv_image(name)
+
+ self.object:set_properties({
+ infotext = infotext .. "\n\n\n\n\n",
+ textures = {self.texture}
+ })
+
+ clicker:set_wielded_item(itemstack)
+ end,
+
+ on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir)
+ local meta = core.get_meta(self.drawer_pos)
+ local count = meta:get_int("count")
+
+ if count <= 0 then
+ return
+ end
+ local name = meta:get_string("name")
+
+ local remove_count = 1
+ if not puncher:get_player_control().sneak then
+ remove_count = ItemStack(name):get_stack_max()
+ end
+ if remove_count > count then remove_count = count end
+
+ local stack = ItemStack(name)
+ stack:set_count(remove_count)
+
+ local inv = puncher:get_inventory()
+ if not inv:room_for_item("main", stack) then
+ return
+ end
+
+ inv:add_item("main", stack)
+ count = count - remove_count
+ meta:set_int("count", count)
+
+ -- update infotext
+ local stack_max_factor = meta:get_int("stack_max_factor")
+ local base_stack_max = meta:get_int("base_stack_max")
+ local item_description = ""
+ if core.registered_items[name] then
+ item_description = core.registered_items[name].description
+ end
+
+ if count <= 0 then
+ meta:set_string("name", "")
+ self.texture = "drawers_empty.png"
+ item_description = "Empty"
+ end
+
+ local infotext = drawers.gen_info_text(item_description,
+ count, stack_max_factor, base_stack_max)
+ meta:set_string("entity_infotext", infotext)
+
+ self.object:set_properties({
+ infotext = infotext .. "\n\n\n\n\n",
+ textures = {self.texture}
+ })
+ end
+})
+
+core.register_lbm({
+ name = "drawers:restore_visual",
+ nodenames = {"group:drawer"},
+ run_at_every_load = true,
+ action = function(pos, node)
+ local objs = core.get_objects_inside_radius(pos, 0.5)
+ if objs then
+ for _, obj in pairs(objs) do
+ if obj and obj:get_luaentity() and
+ obj:get_luaentity().name == "drawers:visual" then
+ return
+ end
+ end
+ end
+
+ -- no visual found, create a new one
+ drawers.spawn_visual(pos)
+ end
+})