mirror of
https://github.com/minetest-mods/drawers.git
synced 2024-11-08 16:03:43 +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