mirror of
https://github.com/minetest-mods/drawers.git
synced 2024-12-22 20:42:22 +01:00
Split up source code into multiple files
This commit is contained in:
parent
89287fd82c
commit
65e1ef85f3
398
init.lua
Normal file → Executable file
398
init.lua
Normal file → Executable file
@ -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 modpath = core.get_modpath("drawers")
|
||||
dofile(modpath .. "/lua/helpers.lua")
|
||||
dofile(modpath .. "/lua/visual.lua")
|
||||
dofile(modpath .. "/lua/api.lua")
|
||||
|
||||
|
||||
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
|
||||
|
||||
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",
|
||||
|
129
lua/api.lua
Executable file
129
lua/api.lua
Executable file
@ -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
|
84
lua/helpers.lua
Normal file
84
lua/helpers.lua
Normal file
@ -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
|
233
lua/visual.lua
Executable file
233
lua/visual.lua
Executable file
@ -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
|
||||
})
|
Loading…
Reference in New Issue
Block a user