1 local elements
= {"head", "torso", "legs", "feet"}
3 local function get_stand_object(pos
)
5 local objects
= minetest
.get_objects_inside_radius(pos
, 0.5) or {}
6 for _
, obj
in pairs(objects
) do
7 local ent
= obj
:get_luaentity()
9 if ent
.name
== "3d_armor_stand:armor_entity" then
22 local function update_entity(pos
)
23 local node
= minetest
.get_node(pos
)
24 local object
= get_stand_object(pos
)
26 if not string.find(node
.name
, "3d_armor_stand:") then
31 object
= minetest
.add_entity(pos
, "3d_armor_stand:armor_entity")
34 local texture
= "3d_armor_trans.png"
36 local meta
= minetest
.get_meta(pos
)
37 local inv
= meta
:get_inventory()
40 for _
, element
in pairs(elements
) do
41 local stack
= inv
:get_stack("armor_"..element
, 1)
42 if stack
:get_count() == 1 then
43 local item
= stack
:get_name() or ""
44 local def
= stack
:get_definition() or {}
45 local groups
= def
.groups
or {}
46 if groups
["armor_"..element
] then
47 local texture
= def
.texture
or item
:gsub("%:", "_")
48 table.insert(textures
, texture
..".png")
54 texture
= table.concat(textures
, "^")
57 local rot
= node
.param2
% 4
67 object
:set_properties({textures
={texture
}})
71 -- Drop all armor of the armor stand on the ground
72 local drop_armor
= function(pos
)
73 local meta
= minetest
.get_meta(pos
)
74 local inv
= meta
:get_inventory()
75 for _
, element
in pairs(elements
) do
76 local stack
= inv
:get_stack("armor_"..element
, 1)
77 if not stack
:is_empty() then
78 local p
= {x
=pos
.x
+math
.random(0, 10)/10-0.5, y
=pos
.y
, z
=pos
.z
+math
.random(0, 10)/10-0.5}
79 minetest
.add_item(p
, stack
)
84 -- FIXME: The armor stand should be an entity
85 minetest
.register_node("3d_armor_stand:armor_stand", {
86 description
= "Armor Stand",
87 _doc_items_longdesc
= "An armor stand is a decorative object which can display different pieces of armor. Anything which players can wear as armor can also be put on an armor stand.",
88 _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.",
90 mesh
= "3d_armor_stand.obj",
91 inventory_image
= "3d_armor_stand_item.png",
92 wield_image
= "3d_armor_stand_item.png",
93 tiles
= {"default_wood.png", "mcl_stairs_stone_slab_top.png"},
95 paramtype2
= "facedir",
97 is_ground_content
= false,
101 fixed
= {-0.5,-0.5,-0.5, 0.5,1.4,0.5}
103 -- FIXME: This should be breakable by 2 quick punches
104 groups
= {handy
=1, deco_block
=1},
106 sounds
= mcl_sounds
.node_sound_wood_defaults(),
107 on_construct
= function(pos
)
108 local meta
= minetest
.get_meta(pos
)
109 local inv
= meta
:get_inventory()
110 for _
, element
in pairs(elements
) do
111 inv
:set_size("armor_"..element
, 1)
114 -- Drop all armor on the ground when it got destroyed
115 on_destruct
= drop_armor
,
116 -- Put piece of armor on armor stand, or take one away
117 on_rightclick
= function(pos
, node
, clicker
, itemstack
, pointed_thing
)
118 -- Check if player wields armor
119 local name
= itemstack
:get_name()
121 for e
=1, #elements
do
122 local g
= minetest
.get_item_group(name
, "armor_" .. elements
[e
])
123 if g
~= nil and g
~= 0 then
124 list
= "armor_" .. elements
[e
]
129 -- If player wields armor, put it on armor stand
130 local inv
= minetest
.get_inventory({type = "node", pos
= pos
})
131 local wielditem
= clicker
:get_wielded_item()
132 if not inv
then return end
134 -- ... but only if the slot is free
135 local single_item
= ItemStack(itemstack
)
136 single_item
:set_count(1)
137 if inv
:is_empty(list
) then
138 inv
:add_item(list
, single_item
)
140 itemstack
:take_item()
145 -- Take armor from stand if player has a free hand or wields the same armor type (if stackable)
146 for e
=1, #elements
do
147 local stand_armor
= inv
:get_stack("armor_" .. elements
[e
], 1)
148 if not stand_armor
:is_empty() then
149 local pinv
= clicker
:get_inventory()
152 if wielditem
:get_name() == "" then
153 pinv
:set_stack("main", clicker
:get_wield_index(), stand_armor
)
155 -- Stackable armor type (if not already full). This is the case for e.g. mob heads.
156 -- This is done purely for convenience.
157 elseif (wielditem
:get_name() == stand_armor
:get_name() and wielditem
:get_count() < wielditem
:get_stack_max()) then
158 wielditem
:set_count(wielditem
:get_count()+1)
159 pinv
:set_stack("main", clicker
:get_wield_index(), wielditem
)
163 stand_armor
:take_item()
164 inv
:set_stack("armor_" .. elements
[e
], 1, stand_armor
)
167 return clicker
:get_wielded_item()
172 after_place_node
= function(pos
)
173 minetest
.add_entity(pos
, "3d_armor_stand:armor_entity")
175 allow_metadata_inventory_put
= function(pos
, listname
, index
, stack
)
176 local def
= stack
:get_definition() or {}
177 local groups
= def
.groups
or {}
178 if groups
[listname
] then
183 allow_metadata_inventory_move
= function(pos
)
186 on_metadata_inventory_put
= function(pos
)
189 on_metadata_inventory_take
= function(pos
)
192 after_destruct
= function(pos
)
195 on_blast
= function(pos
)
196 local object
= get_stand_object(pos
)
200 minetest
.after(1, function(pos
)
206 minetest
.register_entity("3d_armor_stand:armor_entity", {
209 mesh
= "3d_armor_entity.obj",
210 visual_size
= {x
=1, y
=1},
211 collisionbox
= {-0.1,-0.4,-0.1, 0.1,1.3,0.1},
212 textures
= {"3d_armor_trans.png"},
215 on_activate
= function(self
)
216 local pos
= self
.object
:getpos()
217 self
.object
:set_armor_groups({immortal
=1})
219 self
.pos
= vector
.round(pos
)
223 on_step
= function(self
, dtime
)
227 self
.timer
= self
.timer
+ dtime
228 if self
.timer
> 1 then
230 local pos
= self
.object
:getpos()
232 if vector
.equals(vector
.round(pos
), self
.pos
) then
236 update_entity(self
.pos
)
242 if minetest
.get_modpath("doc_identifier") ~= nil then
243 doc
.sub
.identifier
.register_object("3d_armor_stand:armor_entity", "nodes", "3d_armor_stand:armor_stand")
246 minetest
.register_craft({
247 output
= "3d_armor_stand:armor_stand",
249 {"mcl_core:stick", "mcl_core:stick", "mcl_core:stick"},
250 {"", "mcl_core:stick", ""},
251 {"mcl_core:stick", "mcl_stairs:slab_stone", "mcl_core:stick"},