]> git.lizzy.rs Git - Crafter.git/blob - mods/armor/init.lua
57df99d7358a7742a420422b4afb7e2653e5dc2e
[Crafter.git] / mods / armor / init.lua
1 function recalculate_armor(player)
2     if not player or (player and not player:is_player()) then return end
3     local inv = player:get_inventory()
4
5     local player_skin = get_skin(player)
6     local armor_skin = "blank_skin.png"
7
8     local stack = inv:get_stack("armor_head",1):get_name()
9     if stack ~= "" and minetest.get_item_group(stack,"helmet") > 0 then
10         local skin_element = minetest.get_itemdef(stack, "wearing_texture")
11         player_skin = player_skin.."^"..skin_element
12     end
13
14     stack = inv:get_stack("armor_torso",1):get_name()
15     if stack ~= "" and minetest.get_item_group(stack,"chestplate") > 0 then
16         local skin_element = minetest.get_itemdef(stack, "wearing_texture")
17         armor_skin = armor_skin.."^"..skin_element
18     end
19
20     stack = inv:get_stack("armor_legs",1):get_name()
21     if stack ~= "" and minetest.get_item_group(stack,"leggings") > 0 then
22         local skin_element = minetest.get_itemdef(stack, "wearing_texture")
23         armor_skin = armor_skin.."^"..skin_element
24     end
25
26     stack = inv:get_stack("armor_feet",1):get_name()
27     if stack ~= "" and minetest.get_item_group(stack,"boots") > 0 then
28         local skin_element = minetest.get_itemdef(stack, "wearing_texture")
29         armor_skin = armor_skin.."^"..skin_element
30     end
31     player:set_properties({textures = {player_skin,armor_skin}})
32 end
33
34 function calculate_armor_absorbtion(player)
35     if not player or (player and not player:is_player()) then return end
36
37     local inv = player:get_inventory()
38     local armor_absorbtion = 0
39
40     local stack = inv:get_stack("armor_head",1):get_name()
41     if stack ~= "" then
42         local level = minetest.get_item_group(stack,"armor_level")
43         local defense = minetest.get_item_group(stack,"armor_defense")
44         armor_absorbtion = armor_absorbtion + (level*defense)
45     end
46
47     stack = inv:get_stack("armor_torso",1):get_name()
48     if stack ~= "" then
49         local level = minetest.get_item_group(stack,"armor_level")
50         local defense = minetest.get_item_group(stack,"armor_defense")
51         armor_absorbtion = armor_absorbtion + (level*defense)
52     end
53
54     stack = inv:get_stack("armor_legs",1):get_name()
55     if stack ~= "" then
56         local level = minetest.get_item_group(stack,"armor_level")
57         local defense = minetest.get_item_group(stack,"armor_defense")
58         armor_absorbtion = armor_absorbtion + (level*defense)
59     end
60
61     stack = inv:get_stack("armor_feet",1):get_name()
62     if stack ~= "" then
63         local level = minetest.get_item_group(stack,"armor_level")
64         local defense = minetest.get_item_group(stack,"armor_defense")
65         armor_absorbtion = armor_absorbtion + (level*defense)
66     end
67     if armor_absorbtion > 0 then
68         armor_absorbtion = math.ceil(armor_absorbtion/4)
69     end
70     return(armor_absorbtion)
71 end
72
73 function set_armor_gui(player)
74     if not player or (player and not player:is_player()) then return end
75     local meta  = player:get_meta()
76     local level = calculate_armor_absorbtion(player)
77     local hud = meta:get_int("armor_bar")
78     player:hud_change(hud, "number", level)
79 end
80
81
82
83 function damage_armor(player,damage)
84     if not player or (player and not player:is_player()) then return end
85
86     local inv = player:get_inventory()
87     
88     local recalc = false
89
90     local stack = inv:get_stack("armor_head",1)
91     local name = stack:get_name()
92     if name ~= "" then
93         local wear_level = ((9-minetest.get_item_group(name,"armor_level"))*8)*(5-minetest.get_item_group(name,"armor_type"))*damage
94         stack:add_wear(wear_level)
95         inv:set_stack("armor_head", 1, stack)
96         local new_stack = inv:get_stack("armor_head",1):get_name()
97         if new_stack == "" then
98             recalc = true
99         end
100     end
101
102     stack = inv:get_stack("armor_torso",1)
103     name = stack:get_name()
104     if name ~= "" then
105         local wear_level = ((9-minetest.get_item_group(name,"armor_level"))*4)*(5-minetest.get_item_group(name,"armor_type"))*damage
106         stack:add_wear(wear_level)
107         inv:set_stack("armor_torso", 1, stack)
108         local new_stack = inv:get_stack("armor_torso",1):get_name()
109         if new_stack == "" then
110             recalc = true
111         end
112     end
113
114     stack = inv:get_stack("armor_legs",1)
115     name = stack:get_name()
116     if name ~= "" then
117         local wear_level = ((9-minetest.get_item_group(name,"armor_level"))*6)*(5-minetest.get_item_group(name,"armor_type"))*damage
118         stack:add_wear(wear_level)
119         inv:set_stack("armor_legs", 1, stack)
120         local new_stack = inv:get_stack("armor_legs",1):get_name()
121         if new_stack == "" then
122             recalc = true
123         end
124     end
125
126     stack = inv:get_stack("armor_feet",1)
127     name = stack:get_name()
128     if name ~= "" then
129         local wear_level = ((9-minetest.get_item_group(name,"armor_level"))*10)*(5-minetest.get_item_group(name,"armor_type"))*damage
130         stack:add_wear(wear_level)
131         inv:set_stack("armor_feet", 1, stack)
132         local new_stack = inv:get_stack("armor_feet",1):get_name()
133         if new_stack == "" then
134             recalc = true
135         end
136     end
137
138     if recalc == true then
139         minetest.sound_play("armor_break",{to_player=player:get_player_name(),gain=1,pitch=math.random(80,100)/100})
140         recalculate_armor(player)
141         set_armor_gui(player)
142         --do particles too
143     end
144 end
145
146
147 minetest.register_on_joinplayer(function(player)
148     local meta = player:get_meta()
149         player:hud_add({
150                 hud_elem_type = "statbar",
151                 position = {x = 0.5, y = 1},
152                 text = "armor_icon_bg.png",
153                 number = 20,
154                 --direction = 1,
155                 size = {x = 24, y = 24},
156                 offset = {x = (-10 * 24) - 25, y = -(48 + 50 + 39)},
157         })
158         local armor_bar = player:hud_add({
159                 hud_elem_type = "statbar",
160                 position = {x = 0.5, y = 1},
161                 text = "armor_icon.png",
162                 number = calculate_armor_absorbtion(player),--meta:get_int("hunger"),
163                 --direction = 1,
164                 size = {x = 24, y = 24},
165                 offset = {x = (-10 * 24) - 25, y = -(48 + 50 + 39)},
166         })
167     meta:set_int("armor_bar", armor_bar)
168     
169     local inv = player:get_inventory()
170     inv:set_size("armor_head" ,1)
171     inv:set_size("armor_torso",1)
172     inv:set_size("armor_legs" ,1)
173     inv:set_size("armor_feet" ,1)
174
175     minetest.after(0.1,function()
176         recalculate_armor(player)
177     end)
178 end)
179
180 minetest.register_on_dieplayer(function(player)
181     set_armor_gui(player)
182 end)
183
184 minetest.register_on_player_inventory_action(function(player, action, inventory, inventory_info)
185     if inventory_info.from_list == "armor_head" or inventory_info.from_list == "armor_torso" or inventory_info.from_list == "armor_legs" or inventory_info.from_list == "armor_feet" or
186        inventory_info.to_list   == "armor_head" or inventory_info.to_list   == "armor_torso" or inventory_info.to_list   == "armor_legs" or inventory_info.to_list   == "armor_feet" then
187         minetest.after(0,function()
188             recalculate_armor(player)
189             set_armor_gui(player)
190         end)
191     end
192 end)
193
194 --only allow players to put armor in the right slots to stop exploiting chestplates
195 minetest.register_allow_player_inventory_action(function(player, action, inventory, inventory_info)
196     if inventory_info.to_list == "armor_head" then
197         local stack = inventory:get_stack(inventory_info.from_list,inventory_info.from_index)
198         local item = stack:get_name()
199         if minetest.get_item_group(item, "helmet") == 0 then
200             return(0)
201         end
202     elseif inventory_info.to_list == "armor_torso" then
203         local stack = inventory:get_stack(inventory_info.from_list,inventory_info.from_index)
204         local item = stack:get_name()
205         if minetest.get_item_group(item, "chestplate") == 0 then
206             return(0)
207         end
208     elseif inventory_info.to_list == "armor_legs" then
209         local stack = inventory:get_stack(inventory_info.from_list,inventory_info.from_index)
210         local item = stack:get_name()
211         if minetest.get_item_group(item, "leggings") == 0 then
212             return(0)
213         end
214     elseif inventory_info.to_list == "armor_feet" then
215         local stack = inventory:get_stack(inventory_info.from_list,inventory_info.from_index)
216         local item = stack:get_name()
217         if minetest.get_item_group(item, "boots") == 0 then
218             return(0)
219         end
220     end
221 end)
222
223 local materials = {["iron"]=4,["chain"]=6,["gold"]=2,["diamond"]=8} --max 8
224 local armor_type = {["helmet"]=2,["chestplate"]=4,["leggings"]=3,["boots"]=1} --max 4
225
226 local function bool_int(state)
227     if state == true then return(1) end
228     if state == false or not state then return(0) end
229 end
230
231 for material_id,material in pairs(materials) do
232     for armor_id,armor in pairs(armor_type) do
233         --print(material_id,material,"|",armor_id,armor)
234         minetest.register_tool("armor:"..material_id.."_"..armor_id,{
235             description = material_id:gsub("^%l", string.upper).." "..armor_id:gsub("^%l", string.upper),
236     
237             groups = {
238                 armor         = 1,
239                 armor_level   = material,
240                 armor_defense = armor,
241                 helmet        = bool_int(armor_id == "helmet"),
242                 chestplate    = bool_int(armor_id == "chestplate"),
243                 leggings      = bool_int(armor_id == "leggings"),
244                 boots         = bool_int(armor_id == "boots"),
245             },
246             inventory_image = material_id.."_"..armor_id.."_item.png",
247             stack_max = 1,
248             wearing_texture = material_id.."_"..armor_id..".png",
249             tool_capabilities = {
250                 full_punch_interval = 0,
251                 max_drop_level = 0,
252                 groupcaps = {
253                 },
254                 damage_groups = {
255
256                 },
257                 punch_attack_uses = 0,
258             }
259         })
260
261         if armor_id == "helmet" then
262             minetest.register_craft({
263                 output = "armor:"..material_id.."_"..armor_id,
264                 recipe = {
265                     {"main:"..material_id, "main:"..material_id, "main:"..material_id},
266                     {"main:"..material_id, ""                  , "main:"..material_id},
267                     {""                  , ""                  , ""                  }
268                 }
269             })
270         elseif armor_id == "chestplate" then
271             minetest.register_craft({
272                 output = "armor:"..material_id.."_"..armor_id,
273                 recipe = {
274                     {"main:"..material_id, ""                  , "main:"..material_id},
275                     {"main:"..material_id, "main:"..material_id, "main:"..material_id},
276                     {"main:"..material_id, "main:"..material_id, "main:"..material_id}
277                 }
278             })
279         elseif armor_id == "leggings" then
280             minetest.register_craft({
281                 output = "armor:"..material_id.."_"..armor_id,
282                 recipe = {
283                     {"main:"..material_id, "main:"..material_id, "main:"..material_id},
284                     {"main:"..material_id, ""                  , "main:"..material_id},
285                     {"main:"..material_id, ""                  , "main:"..material_id}
286                 }
287             })
288         elseif armor_id == "boots" then
289             minetest.register_craft({
290                 output = "armor:"..material_id.."_"..armor_id,
291                 recipe = {
292                     {""                  , "", ""                  },
293                     {"main:"..material_id, "", "main:"..material_id},
294                     {"main:"..material_id, "", "main:"..material_id}
295                 }
296             })
297             minetest.register_node("armor:"..material_id.."_"..armor_id.."particletexture", {
298                 description = "NIL",
299                 tiles = {material_id.."_"..armor_id.."_item.png"},
300                 groups = {},
301                 drop = "",
302                 drawtype = "allfaces",
303                 on_construct = function(pos)
304                     minetest.remove_node(pos)
305                 end,
306             })
307         end
308         
309     end
310 end