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
7 minetest.sound_play("hurt", {object=player, gain = 1.0, max_hear_distance = 60,pitch = math.random(80,100)/100})
9 elseif hp_change < 0 then
10 local hp_modifier = math.ceil(calculate_armor_absorbtion(player)/2)
11 damage_armor(player,math.abs(hp_change))
12 hp_change = hp_change + hp_modifier
13 minetest.sound_play("hurt", {object=player, gain = 1.0, max_hear_distance = 60,pitch = math.random(80,100)/100})
15 if hp_change >= 0 then
22 --throw all items on death
23 minetest.register_on_dieplayer(function(player, reason)
24 local pos = player:get_pos()
25 local inv = player:get_inventory()
27 for i = 1,inv:get_size("main") do
28 local stack = inv:get_stack("main", i)
29 local name = stack:get_name()
30 local count = stack:get_count()
32 local obj = minetest.add_item(pos, name.." "..count)
34 obj:set_velocity(vector.new(math.random(-3,3),math.random(4,8),math.random(-3,3)))
36 inv:set_stack("main", i, ItemStack(""))
38 inv:set_stack("main", i, ItemStack(""))
42 local stack = inv:get_stack("armor_head", 1)
43 local name = stack:get_name()
45 local obj = minetest.add_item(pos, name)
47 obj:set_velocity(vector.new(math.random(-3,3),math.random(4,8),math.random(-3,3)))
49 inv:set_stack("armor_head", 1, ItemStack(""))
52 stack = inv:get_stack("armor_torso", 1)
53 name = stack:get_name()
55 local obj = minetest.add_item(pos, name)
57 obj:set_velocity(vector.new(math.random(-3,3),math.random(4,8),math.random(-3,3)))
59 inv:set_stack("armor_torso", 1, ItemStack(""))
62 stack = inv:get_stack("armor_legs", 1)
63 name = stack:get_name()
65 local obj = minetest.add_item(pos, name)
67 obj:set_velocity(vector.new(math.random(-3,3),math.random(4,8),math.random(-3,3)))
69 inv:set_stack("armor_legs", 1, ItemStack(""))
73 stack = inv:get_stack("armor_feet", 1)
74 name = stack:get_name()
76 local obj = minetest.add_item(pos, name)
78 obj:set_velocity(vector.new(math.random(-3,3),math.random(4,8),math.random(-3,3)))
80 inv:set_stack("armor_feet", 1, ItemStack(""))
84 recalculate_armor(player)
88 --this dumps the players crafting table on closing the inventory
89 dump_craft = function(player)
90 local inv = player:get_inventory()
91 local pos = player:get_pos()
92 pos.y = pos.y + player:get_properties().eye_height
93 for i = 1,inv:get_size("craft") do
94 local item = inv:get_stack("craft", i)
95 local obj = minetest.add_item(pos, item)
97 local x=math.random(-2,2)*math.random()
98 local y=math.random(2,5)
99 local z=math.random(-2,2)*math.random()
100 obj:set_velocity({x=x, y=y, z=z})
102 inv:set_stack("craft", i, nil)
107 --play sound to keep up with player's placing vs inconsistent client placing sound
108 minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack, pointed_thing)
109 local node = minetest.registered_nodes[newnode.name]
110 local sound = node.sounds
113 placing = sound.placing
115 --only play the sound when is defined
116 if type(placing) == "table" then
117 minetest.sound_play(placing.name, {
120 --pitch = math.random(60,100)/100
125 --replace stack when empty (building)
126 minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack, pointed_thing)
127 local old = itemstack:get_name()
128 --pass through to check
129 minetest.after(0,function(pos, newnode, placer, oldnode, itemstack, pointed_thing,old)
133 local new = placer:get_wielded_item():get_name()
134 if old ~= new and new == "" then
135 local inv = placer:get_inventory()
136 --check if another stack
137 if inv:contains_item("main", old) then
138 --print("moving stack")
139 --run through inventory
140 for i = 1,inv:get_size("main") do
141 --if found set wielded item and remove old stack
142 if inv:get_stack("main", i):get_name() == old then
143 local count = inv:get_stack("main", i):get_count()
144 placer:set_wielded_item(old.." "..count)
145 inv:set_stack("main",i,ItemStack(""))
146 minetest.sound_play("pickup", {
149 pitch = math.random(60,100)/100
156 end,pos, newnode, placer, oldnode, itemstack, pointed_thing,old)
159 local do_critical_particles = function(pos)
160 minetest.add_particlespawner({
165 minvel = vector.new(-2,-2,-2),
166 maxvel = vector.new(2,8,2),
167 minacc = {x=0, y=4, z=0},
168 maxacc = {x=0, y=12, z=0},
173 collisiondetection = false,
175 texture = "critical.png",
179 --we need to do this to override the default damage mechanics
180 local punch_timers = {}
181 minetest.register_on_joinplayer(function(player)
182 local name = player:get_player_name()
183 punch_timers[name] = 0
186 minetest.register_globalstep(function(dtime)
187 for _,player in ipairs(minetest.get_connected_players()) do
188 local name = player:get_player_name()
189 --limit this so the game engine isn't calculating huge floats
190 if punch_timers[name] and punch_timers[name] <= 10 then
191 punch_timers[name] = punch_timers[name] + dtime
196 --this throws the player when they're punched and activates the custom damage mechanics
197 minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch, tool_capabilities, dir, damage)
198 local name = player:get_player_name()
199 local hurt = tool_capabilities.damage_groups.damage
200 local hp = player:get_hp()
201 if punch_timers[name] > 0.8 and hp > 0 then
202 if hitter:is_player() then
203 local puncher_vel = hitter:get_player_velocity().y
204 if puncher_vel < 0 then
207 do_critical_particles(player:get_pos())
208 minetest.sound_play("critical", {pos=player:get_pos(), gain = 0.1, max_hear_distance = 16,pitch = math.random(80,100)/100})
212 dir = vector.multiply(dir,10)
213 local vel = player:get_player_velocity()
218 punch_timers[name] = 0
219 player:add_player_velocity(dir)
220 player:set_hp(hp-hurt)