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