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