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