mirror of
https://github.com/minetest-mods/drawers.git
synced 2024-11-22 14:43:45 +01:00
Inital Commit
This commit is contained in:
commit
4c3dd28fcd
34
LICENSE.txt
Normal file
34
LICENSE.txt
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
Minetest Mod Storage Drawers
|
||||||
|
============================
|
||||||
|
Version 0.1-dev
|
||||||
|
|
||||||
|
License of source code (*.lua):
|
||||||
|
-------------------------------
|
||||||
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
License of media (sounds, textures, meshes):
|
||||||
|
--------------------------------------------
|
||||||
|
files: textures/*
|
||||||
|
copyright: (C) 2017 LNJ <git@lnj.li>
|
||||||
|
license: CC0 1.0 Universal (CC0-1.0)
|
15
README.md
Normal file
15
README.md
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# Minetest Mod Storage Drawers
|
||||||
|
Version 0.1-dev, Status: alpha, License: MIT
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
|
||||||
|
## Bug reports and suggestions
|
||||||
|
You can report bugs and suggest ideas on [GitHub](http://github.com/lnj2/drawers/issues/new),
|
||||||
|
alternatively you can also [email](mailto:git@lnj.li) me.
|
||||||
|
|
||||||
|
## Links
|
||||||
|
* [GitHub](http://github.com/lnj2/drawers/)
|
1
depends.txt
Normal file
1
depends.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
screwdriver?
|
341
init.lua
Normal file
341
init.lua
Normal file
@ -0,0 +1,341 @@
|
|||||||
|
--[[
|
||||||
|
Minetest Mod 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 = {}
|
||||||
|
|
||||||
|
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},
|
||||||
|
}
|
||||||
|
|
||||||
|
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_texture
|
||||||
|
local def = minetest.registered_items[name]
|
||||||
|
if name ~= "air" and def then
|
||||||
|
if def.inventory_image and #def.inventory_image > 0 then
|
||||||
|
texture = def.inventory_image
|
||||||
|
else
|
||||||
|
local c = #def.tiles
|
||||||
|
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_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
|
||||||
|
meta:set_string("name", name)
|
||||||
|
count = 0
|
||||||
|
|
||||||
|
-- get new stack max
|
||||||
|
base_stack_max = ItemStack(name):get_stack_max()
|
||||||
|
meta:set_int("base_stack_max", base_stack_max)
|
||||||
|
max_count = base_stack_max * stack_max_factor
|
||||||
|
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
|
||||||
|
})
|
||||||
|
|
||||||
|
-- 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("ntt_infotext", gen_info_text("Empty", 0,
|
||||||
|
stack_max_factor, base_stack_max))
|
||||||
|
|
||||||
|
|
||||||
|
-- data for the new visual
|
||||||
|
drawers.last_drawer_pos = pos
|
||||||
|
|
||||||
|
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
|
||||||
|
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)
|
||||||
|
core.node_dig(pos, node, player)
|
||||||
|
return
|
||||||
|
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.tiles = def.tiles or {"default_wood.png"}
|
||||||
|
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)
|
||||||
|
end
|
||||||
|
|
||||||
|
drawers.register_drawer("drawers:wood", {
|
||||||
|
description = "Wooden Drawer",
|
||||||
|
groups = {choppy = 3},
|
||||||
|
drawer_stack_max_factor = 3 * 8 -- normal chest size
|
||||||
|
})
|
BIN
textures/drawers_empty.png
Normal file
BIN
textures/drawers_empty.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 74 B |
Loading…
Reference in New Issue
Block a user