]> git.lizzy.rs Git - Crafter.git/blob - mods/player/player_interaction.lua
Remove debug info
[Crafter.git] / mods / player / player_interaction.lua
1 --hurt sound and disable fall damage group handling
2 minetest.register_on_player_hpchange(function(player, hp_change, reason)
3         if reason.type == "fall" then
4                 if minetest.get_item_group(minetest.get_node(player:get_pos()).name, "disable_fall_damage") > 0 then
5                         return(0)
6                 else
7                         --boots absorb fall damage
8                         local fall_damage = math.floor(player:get_player_velocity().y+0.5)+13
9                         --print("fall damage:",fall_damage)
10                         local inv = player:get_inventory()
11                         local stack = inv:get_stack("armor_feet", 1)
12                         local name = stack:get_name()
13                         if name ~= "" then
14                                 local absorption = 0
15
16                                 absorption = minetest.get_item_group(name,"armor_level")*2
17                                 --print("absorbtion:",absorption)
18                                 local wear_level = ((9-minetest.get_item_group(name,"armor_level"))*8)*(5-minetest.get_item_group(name,"armor_type"))*math.abs(fall_damage)
19                                 
20                                 stack:add_wear(wear_level)
21                                 
22                                 inv:set_stack("armor_feet", 1, stack)
23                                 
24                                 local new_stack = inv:get_stack("armor_feet",1):get_name()
25
26                         if new_stack == "" then                                 
27                                         minetest.sound_play("armor_break",{to_player=player:get_player_name(),gain=1,pitch=math.random(80,100)/100})
28                                         recalculate_armor(player)
29                                         set_armor_gui(player)
30                                         --do particles too
31                                 else
32                                         minetest.sound_play("armor_fall_damage", {object=player, gain = 1.0, max_hear_distance = 60,pitch = math.random(80,100)/100})   
33                                 end
34                                 local pos = player:get_pos()
35                                 minetest.add_particlespawner({
36                                         amount = 30,
37                                         time = 0.00001,
38                                         minpos = {x=pos.x-0.5, y=pos.y+0.1, z=pos.z-0.5},
39                                         maxpos = {x=pos.x+0.5, y=pos.y+0.1, z=pos.z+0.5},
40                                         minvel = vector.new(-0.5,1,-0.5),
41                                         maxvel = vector.new(0.5 ,2 ,0.5),
42                                         minacc = {x=0, y=-9.81, z=1},
43                                         maxacc = {x=0, y=-9.81, z=1},
44                                         minexptime = 0.5,
45                                         maxexptime = 1.5,
46                                         minsize = 0,
47                                         maxsize = 0,
48                                         --attached = player,
49                                         collisiondetection = true,
50                                         collision_removal = true,
51                                         vertical = false,
52                                         node = {name= name.."particletexture"},
53                                         --texture = "eat_particles_1.png"
54                                 })
55
56                                 fall_damage = fall_damage + absorption
57
58                                 if fall_damage >= 0 then
59                                         fall_damage = 0
60                                 else
61                                         minetest.sound_play("hurt", {object=player, gain = 1.0, max_hear_distance = 60,pitch = math.random(80,100)/100})
62                                 end
63                         else
64                                 minetest.sound_play("hurt", {object=player, gain = 1.0, max_hear_distance = 60,pitch = math.random(80,100)/100})
65                         end
66                         --print("returned fall damage",fall_damage)
67                         return(fall_damage)
68                 end
69         elseif hp_change < 0 then
70                 minetest.sound_play("hurt", {object=player, gain = 1.0, max_hear_distance = 60,pitch = math.random(80,100)/100})
71         end
72         return(hp_change)
73 end, true)
74
75 --throw all items on death
76 minetest.register_on_dieplayer(function(player, reason)
77         local pos = player:get_pos()
78         local inv = player:get_inventory()
79         
80         for i = 1,inv:get_size("main") do
81                 local stack = inv:get_stack("main", i)
82                 local name = stack:get_name()
83                 local count = stack:get_count()
84                 if name ~= "" then
85                         local obj = minetest.add_item(pos, stack)
86                         if obj then
87                                 obj:set_velocity(vector.new(math.random(-3,3),math.random(4,8),math.random(-3,3)))
88                         end
89                         inv:set_stack("main", i, ItemStack(""))
90                 else
91                         inv:set_stack("main", i, ItemStack(""))
92                 end
93         end
94
95         local stack = inv:get_stack("armor_head", 1)
96         local name = stack:get_name()
97         if name ~= "" then
98                 local obj = minetest.add_item(pos, stack)
99                 if obj then
100                         obj:set_velocity(vector.new(math.random(-3,3),math.random(4,8),math.random(-3,3)))
101                 end
102                 inv:set_stack("armor_head", 1, ItemStack(""))
103         end
104
105         stack = inv:get_stack("armor_torso", 1)
106         name = stack:get_name()
107         if name ~= "" then
108                 local obj = minetest.add_item(pos, stack)
109                 if obj then
110                         obj:set_velocity(vector.new(math.random(-3,3),math.random(4,8),math.random(-3,3)))
111                 end
112                 inv:set_stack("armor_torso", 1, ItemStack(""))
113         end
114
115         stack = inv:get_stack("armor_legs", 1)
116         name = stack:get_name()
117         if name ~= "" then
118                 local obj = minetest.add_item(pos, stack)
119                 if obj then
120                         obj:set_velocity(vector.new(math.random(-3,3),math.random(4,8),math.random(-3,3)))
121                 end
122                 inv:set_stack("armor_legs", 1, ItemStack(""))
123         end
124
125
126         stack = inv:get_stack("armor_feet", 1)
127         name = stack:get_name()
128         if name ~= "" then
129                 local obj = minetest.add_item(pos, stack)
130                 if obj then
131                         obj:set_velocity(vector.new(math.random(-3,3),math.random(4,8),math.random(-3,3)))
132                 end
133                 inv:set_stack("armor_feet", 1, ItemStack(""))
134         end
135
136
137         recalculate_armor(player)
138 end)
139
140
141 --this dumps the players crafting table on closing the inventory
142 dump_craft = function(player)
143         local inv = player:get_inventory()
144         local pos = player:get_pos()
145         pos.y = pos.y + player:get_properties().eye_height
146         for i = 1,inv:get_size("craft") do
147                 local item = inv:get_stack("craft", i)
148                 local obj = minetest.add_item(pos, item)
149                 if obj then
150                         local x=math.random(-2,2)*math.random()
151                         local y=math.random(2,5)
152                         local z=math.random(-2,2)*math.random()
153                         obj:set_velocity({x=x, y=y, z=z})
154                 end
155                 inv:set_stack("craft", i, nil)
156         end
157 end
158
159
160 --play sound to keep up with player's placing vs inconsistent client placing sound 
161 minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack, pointed_thing)
162         local node = minetest.registered_nodes[newnode.name]
163         local sound = node.sounds
164         local placing = ""
165         if sound then
166                 placing = sound.placing
167         end
168         --only play the sound when is defined
169         if type(placing) == "table" then
170                 minetest.sound_play(placing.name, {
171                           pos = pos,
172                           gain = placing.gain,
173                           --pitch = math.random(60,100)/100
174                 })
175         end
176 end)
177
178 --replace stack when empty (building)
179 minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack, pointed_thing)
180         local old = itemstack:get_name()
181         --pass through to check
182         minetest.after(0,function(pos, newnode, placer, oldnode, itemstack, pointed_thing,old)
183                 if not placer then
184                         return
185                 end
186                 local new = placer:get_wielded_item():get_name()
187                 if old ~= new and new == "" then
188                         local inv = placer:get_inventory()
189                         --check if another stack
190                         if inv:contains_item("main", old) then
191                                 --print("moving stack")
192                                 --run through inventory
193                                 for i = 1,inv:get_size("main") do
194                                         --if found set wielded item and remove old stack
195                                         if inv:get_stack("main", i):get_name() == old then
196                                                 local count = inv:get_stack("main", i):get_count()
197                                                 placer:set_wielded_item(old.." "..count)
198                                                 inv:set_stack("main",i,ItemStack(""))   
199                                                 minetest.sound_play("pickup", {
200                                                           to_player = player,
201                                                           gain = 0.7,
202                                                           pitch = math.random(60,100)/100
203                                                 })
204                                                 return                          
205                                         end
206                                 end
207                         end
208                 end
209         end,pos, newnode, placer, oldnode, itemstack, pointed_thing,old)
210 end)
211
212 local do_critical_particles = function(pos)
213         minetest.add_particlespawner({
214                 amount = 40,
215                 time = 0.001,
216                 minpos = pos,
217                 maxpos = pos,
218                 minvel = vector.new(-2,-2,-2),
219                 maxvel = vector.new(2,8,2),
220                 minacc = {x=0, y=4, z=0},
221                 maxacc = {x=0, y=12, z=0},
222                 minexptime = 1.1,
223                 maxexptime = 1.5,
224                 minsize = 1,
225                 maxsize = 2,
226                 collisiondetection = false,
227                 vertical = false,
228                 texture = "critical.png",
229         })
230 end
231
232 --we need to do this to override the default damage mechanics
233 minetest.register_on_joinplayer(function(player)
234         local meta = player:get_meta()
235         meta:set_float("player_punch_timer",0)
236 end)
237
238 minetest.register_globalstep(function(dtime)
239         for _,player in ipairs(minetest.get_connected_players()) do
240                 local meta = player:get_meta()
241                 local punch_timer = meta:get_float("player_punch_timer")
242
243                 --limit this so the game engine isn't calculating huge floats
244                 if punch_timer > 0 then
245                         punch_timer = punch_timer - dtime
246                         if punch_timer < 0 then punch_timer = 0 end
247                         meta:set_float("player_punch_timer",punch_timer)
248                 end
249         end
250 end)
251
252 --this throws the player when they're punched and activates the custom damage mechanics
253 minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch, tool_capabilities, dir, damage)
254         local meta = player:get_meta()
255         local punch_timer = meta:get_float("player_punch_timer")
256         local hurt = tool_capabilities.damage_groups.damage
257         local hp = player:get_hp()
258         if punch_timer <= 0 and hp > 0 then
259                 meta:set_float("player_punch_timer",0.25)
260                 if hitter:is_player() and hitter ~= player then
261                         local puncher_vel = hitter:get_player_velocity().y
262                         if puncher_vel < 0 then
263                                 hurt = hurt * 1.5
264                                 critical = true
265                                 do_critical_particles(player:get_pos())
266                                 minetest.sound_play("critical", {pos=player:get_pos(), gain = 0.1, max_hear_distance = 16,pitch = math.random(80,100)/100})
267                         end
268                 end
269
270                 dir = vector.multiply(dir,10)
271                 local vel = player:get_player_velocity()
272                 dir.y = 0
273                 if vel.y <= 0 then
274                         dir.y = 7
275                 end
276
277                 local hp_modifier = math.ceil(calculate_armor_absorbtion(player)/3)
278                 --print("hp_modifier:",hp_modifier)
279                 damage_armor(player,math.abs(hurt))
280
281                 --print("hurt:",hurt,"|","hp_modifier:",hp_modifier)
282                 local modify_output = (hurt == 0)
283                 
284                 hurt = hurt - hp_modifier
285
286                 if modify_output == false and hurt <= 0 then
287                         hurt = 1
288                 elseif modify_output == true then
289                         hurt = 0
290                 end
291                 player:add_player_velocity(dir)
292                 player:set_hp(hp-hurt)
293         end
294 end)
295
296