Mineclonia/mods/ITEMS/minetest-3d_armor/3d_armor_stand/init.lua

234 lines
6.3 KiB
Lua
Raw Normal View History

2017-01-06 03:23:11 +00:00
local elements = {"head", "torso", "legs", "feet"}
local function get_stand_object(pos)
local object = nil
local objects = minetest.get_objects_inside_radius(pos, 0.5) or {}
for _, obj in pairs(objects) do
local ent = obj:get_luaentity()
if ent then
if ent.name == "3d_armor_stand:armor_entity" then
-- Remove duplicates
if object then
obj:remove()
else
object = obj
end
end
end
end
return object
end
local function update_entity(pos)
local node = minetest.get_node(pos)
local object = get_stand_object(pos)
if object then
if not string.find(node.name, "3d_armor_stand:") then
object:remove()
return
end
else
object = minetest.add_entity(pos, "3d_armor_stand:armor_entity")
end
if object then
local texture = "3d_armor_trans.png"
local textures = {}
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local yaw = 0
if inv then
for _, element in pairs(elements) do
local stack = inv:get_stack("armor_"..element, 1)
if stack:get_count() == 1 then
local item = stack:get_name() or ""
local def = stack:get_definition() or {}
local groups = def.groups or {}
if groups["armor_"..element] then
local texture = def.texture or item:gsub("%:", "_")
table.insert(textures, texture..".png")
end
end
end
end
if #textures > 0 then
texture = table.concat(textures, "^")
end
if node.param2 then
local rot = node.param2 % 4
if rot == 1 then
yaw = 3 * math.pi / 2
elseif rot == 2 then
yaw = math.pi
elseif rot == 3 then
yaw = math.pi / 2
end
end
object:setyaw(yaw)
object:set_properties({textures={texture}})
end
end
2017-02-27 17:32:35 +00:00
-- FIXME: The armor stand should be an entity
2017-01-06 03:23:11 +00:00
minetest.register_node("3d_armor_stand:armor_stand", {
2017-01-06 03:29:38 +00:00
description = "Armor Stand",
2017-03-11 15:42:23 +00:00
_doc_items_longdesc = "An armor stand is a decorative object which displays different pieces of armor.",
_doc_items_usagehelp = "Hold an armor item in your hand and rightclick the armor stand to put it on the armor stand. To take a piece of armor from the armor stand, select your hand and rightclick the armor stand. You'll retrieve the first armor item from above.",
2017-01-06 03:23:11 +00:00
drawtype = "mesh",
mesh = "3d_armor_stand.obj",
2017-01-06 03:41:48 +00:00
inventory_image = "3d_armor_stand_item.png",
wield_image = "3d_armor_stand_item.png",
2017-01-06 03:23:11 +00:00
tiles = {"default_wood.png", "default_steel_block.png"},
paramtype = "light",
paramtype2 = "facedir",
walkable = false,
is_ground_content = false,
2017-01-16 22:34:40 +00:00
stack_max = 16,
2017-01-06 03:23:11 +00:00
selection_box = {
type = "fixed",
fixed = {-0.5,-0.5,-0.5, 0.5,1.4,0.5}
},
2017-02-27 17:32:35 +00:00
-- FIXME: This should be breakable by 2 quick punches
groups = {handy=1, deco_block=1},
_mcl_hardness = 2,
sounds = mcl_sounds.node_sound_wood_defaults(),
2017-01-06 03:23:11 +00:00
on_construct = function(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
for _, element in pairs(elements) do
inv:set_size("armor_"..element, 1)
end
end,
can_dig = function(pos, player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
for _, element in pairs(elements) do
if not inv:is_empty("armor_"..element) then
return false
end
end
return true
end,
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
-- Check if player wields armor
local name = itemstack:get_name()
local list
for e=1, #elements do
local g = minetest.get_item_group(name, "armor_" .. elements[e])
if g ~= nil and g ~= 0 then
list = "armor_" .. elements[e]
break
end
end
-- If player wields armor, put it on armor stand
local inv = minetest.get_inventory({type = "node", pos = pos})
local wielditem = clicker:get_wielded_item()
if not inv then return end
if list then
if inv:room_for_item(list, itemstack) then
inv:add_item(list, itemstack)
update_entity(pos)
itemstack:take_item()
end
return itemstack
elseif wielditem:get_name() == "" then
-- If player does not wield anything, take the first available armor from the armor stand
-- and give it to the player
for e=1, #elements do
local stand_armor = inv:get_stack("armor_" .. elements[e], 1)
if not stand_armor:is_empty() then
local pinv = clicker:get_inventory()
pinv:set_stack("main", clicker:get_wield_index(), stand_armor)
stand_armor:take_item()
inv:set_stack("armor_" .. elements[e], 1, stand_armor)
update_entity(pos)
return clicker:get_wielded_item()
end
end
end
return itemstack
end,
2017-01-06 03:23:11 +00:00
after_place_node = function(pos)
minetest.add_entity(pos, "3d_armor_stand:armor_entity")
end,
allow_metadata_inventory_put = function(pos, listname, index, stack)
local def = stack:get_definition() or {}
local groups = def.groups or {}
if groups[listname] then
return 1
end
return 0
end,
allow_metadata_inventory_move = function(pos)
return 0
end,
on_metadata_inventory_put = function(pos)
update_entity(pos)
end,
on_metadata_inventory_take = function(pos)
update_entity(pos)
end,
after_destruct = function(pos)
update_entity(pos)
end,
on_blast = function(pos)
local object = get_stand_object(pos)
if object then
object:remove()
end
minetest.after(1, function(pos)
update_entity(pos)
end, pos)
end,
})
minetest.register_entity("3d_armor_stand:armor_entity", {
physical = true,
visual = "mesh",
mesh = "3d_armor_entity.obj",
visual_size = {x=1, y=1},
collisionbox = {-0.1,-0.4,-0.1, 0.1,1.3,0.1},
2017-01-06 03:23:11 +00:00
textures = {"3d_armor_trans.png"},
pos = nil,
timer = 0,
on_activate = function(self)
local pos = self.object:getpos()
2017-02-14 19:22:34 +00:00
self.object:set_armor_groups({immortal=1})
2017-01-06 03:23:11 +00:00
if pos then
self.pos = vector.round(pos)
update_entity(pos)
end
end,
on_step = function(self, dtime)
if not self.pos then
return
end
self.timer = self.timer + dtime
if self.timer > 1 then
self.timer = 0
local pos = self.object:getpos()
if pos then
if vector.equals(vector.round(pos), self.pos) then
return
end
end
update_entity(self.pos)
self.object:remove()
end
end,
})
2017-03-21 03:03:33 +00:00
if minetest.get_modpath("doc_identifier") ~= nil then
doc.sub.identifier.register_object("3d_armor_stand:armor_entity", "nodes", "3d_armor_stand:armor_stand")
end
2017-01-06 03:23:11 +00:00
minetest.register_craft({
output = "3d_armor_stand:armor_stand",
recipe = {
2017-01-31 22:32:56 +00:00
{"mcl_core:stick", "mcl_core:stick", "mcl_core:stick"},
{"", "mcl_core:stick", ""},
2017-06-05 16:40:56 +00:00
{"mcl_core:stick", "mcl_stairs:slab_stone", "mcl_core:stick"},
2017-01-06 03:23:11 +00:00
}
})