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