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