-local minetest,armor_class,math,pairs,ipairs = minetest,armor_class,math,pairs,ipairs
-
-local pos
-local name
-local damage_nodes
-local real_nodes
-local a_min
-local a_max
-local _
-local cancel_fall_damage = function(player)
- name = player:get_player_name()
- if player:get_hp() <= 0 then
- return
- end
- -- used for finding a damage node from the center of the player
- -- rudementary collision detection
- pos = player:get_pos()
- pos.y = pos.y + (player:get_properties().collisionbox[5]/2)
- a_min = vector.new(
- pos.x-0.25,
- pos.y-0.85,
- pos.z-0.25
- )
- a_max = vector.new(
- pos.x+0.25,
- pos.y+0.85,
- pos.z+0.25
- )
- _,saving_nodes = minetest.find_nodes_in_area( a_min, a_max, {"group:disable_fall_damage"})
- real_nodes = {}
- for node_data,_ in pairs(saving_nodes) do
- if saving_nodes[node_data] > 0 then
- table.insert(real_nodes,node_data)
- end
- end
- -- find the highest damage node
- if table.getn(real_nodes) > 0 then
- return(true)
- end
- return(false)
-end
-
-
-
-
-
-
+local
+minetest,math,pairs,ipairs,type
+=
+minetest,math,pairs,ipairs,type
+
+local add_item = minetest.add_item
+local random = math.random
+local play_sound = minetest.sound_play
+local add_ps = minetest.add_particlespawner
+local abs = math.abs
+local ceil = math.ceil
+local new_vec = vector.new
+local multiply_vec = vector.multiply
--hurt sound and disable fall damage group handling
minetest.register_on_player_hpchange(function(player, hp_change, reason)
if reason.type == "fall" then
- if cancel_fall_damage(player) then
- return(0)
- else
- --boots absorb fall damage
- local fall_damage = math.floor(player:get_player_velocity().y+0.5)+13
- --print("fall damage:",fall_damage)
- local inv = player:get_inventory()
- local stack = inv:get_stack("armor_feet", 1)
- local name = stack:get_name()
- if name ~= "" then
- local absorption = 0
-
- absorption = minetest.get_item_group(name,"armor_level")*2
- --print("absorbtion:",absorption)
- local wear_level = ((9-minetest.get_item_group(name,"armor_level"))*8)*(5-minetest.get_item_group(name,"armor_type"))*math.abs(fall_damage)
-
- stack:add_wear(wear_level)
-
- inv:set_stack("armor_feet", 1, stack)
-
- local new_stack = inv:get_stack("armor_feet",1):get_name()
-
- if new_stack == "" then
- minetest.sound_play("armor_break",{to_player=player:get_player_name(),gain=1,pitch=math.random(80,100)/100})
- armor_class.recalculate_armor(player)
- armor_class.set_armor_gui(player)
- --do particles too
- elseif minetest.get_item_group(new_stack,"boots") > 0 then
- local pos = player:get_pos()
- minetest.add_particlespawner({
- amount = 30,
- time = 0.00001,
- minpos = {x=pos.x-0.5, y=pos.y+0.1, z=pos.z-0.5},
- maxpos = {x=pos.x+0.5, y=pos.y+0.1, z=pos.z+0.5},
- minvel = vector.new(-0.5,1,-0.5),
- maxvel = vector.new(0.5 ,2 ,0.5),
- minacc = {x=0, y=-9.81, z=1},
- maxacc = {x=0, y=-9.81, z=1},
- minexptime = 0.5,
- maxexptime = 1.5,
- minsize = 0,
- maxsize = 0,
- --attached = player,
- collisiondetection = true,
- collision_removal = true,
- vertical = false,
- node = {name= name.."particletexture"},
- --texture = "eat_particles_1.png"
- })
- minetest.sound_play("armor_fall_damage", {object=player, gain = 1.0, max_hear_distance = 60,pitch = math.random(80,100)/100})
- end
-
- fall_damage = fall_damage + absorption
-
- if fall_damage >= 0 then
- fall_damage = 0
- else
- minetest.sound_play("hurt", {object=player, gain = 1.0, max_hear_distance = 60,pitch = math.random(80,100)/100})
- end
- else
- minetest.sound_play("hurt", {object=player, gain = 1.0, max_hear_distance = 60,pitch = math.random(80,100)/100})
- end
- --print("returned fall damage",fall_damage)
- return(fall_damage)
- end
- elseif hp_change < 0 then
- minetest.sound_play("hurt", {object=player, gain = 1.0, max_hear_distance = 60,pitch = math.random(80,100)/100})
+ --fall damage is handled on another globalstep calc
+ return(0)
+ elseif hp_change < 0 and reason.reason ~= "correction" then
+ play_sound("hurt", {object=player, gain = 1.0, max_hear_distance = 60,pitch = random(80,100)/100})
end
return(hp_change)
end, true)
--throw all items on death
+local pos
+local inv
+local stack
+local count
+local obj
+local name
minetest.register_on_dieplayer(function(player, reason)
- local pos = player:get_pos()
- local inv = player:get_inventory()
+ pos = player:get_pos()
+ inv = player:get_inventory()
for i = 1,inv:get_size("main") do
- local stack = inv:get_stack("main", i)
- local name = stack:get_name()
- local count = stack:get_count()
+ stack = inv:get_stack("main", i)
+ name = stack:get_name()
+ count = stack:get_count()
if name ~= "" then
- local obj = minetest.add_item(pos, stack)
+ obj = add_item(pos, stack)
if obj then
- obj:set_velocity(vector.new(math.random(-3,3),math.random(4,8),math.random(-3,3)))
+ obj:set_velocity(new_vec(random(-3,3),random(4,8),random(-3,3)))
end
inv:set_stack("main", i, ItemStack(""))
- else
- inv:set_stack("main", i, ItemStack(""))
end
end
- local stack = inv:get_stack("armor_head", 1)
- local name = stack:get_name()
+ stack = inv:get_stack("armor_head", 1)
+ name = stack:get_name()
if name ~= "" then
- local obj = minetest.add_item(pos, stack)
+ obj = add_item(pos, stack)
if obj then
- obj:set_velocity(vector.new(math.random(-3,3),math.random(4,8),math.random(-3,3)))
+ obj:set_velocity(new_vec(random(-3,3),random(4,8),random(-3,3)))
end
inv:set_stack("armor_head", 1, ItemStack(""))
end
stack = inv:get_stack("armor_torso", 1)
name = stack:get_name()
if name ~= "" then
- local obj = minetest.add_item(pos, stack)
+ obj = add_item(pos, stack)
if obj then
- obj:set_velocity(vector.new(math.random(-3,3),math.random(4,8),math.random(-3,3)))
+ obj:set_velocity(new_vec(random(-3,3),random(4,8),random(-3,3)))
end
inv:set_stack("armor_torso", 1, ItemStack(""))
end
stack = inv:get_stack("armor_legs", 1)
name = stack:get_name()
if name ~= "" then
- local obj = minetest.add_item(pos, stack)
+ obj = add_item(pos, stack)
if obj then
- obj:set_velocity(vector.new(math.random(-3,3),math.random(4,8),math.random(-3,3)))
+ obj:set_velocity(new_vec(random(-3,3),random(4,8),random(-3,3)))
end
inv:set_stack("armor_legs", 1, ItemStack(""))
end
stack = inv:get_stack("armor_feet", 1)
name = stack:get_name()
if name ~= "" then
- local obj = minetest.add_item(pos, stack)
+ obj = add_item(pos, stack)
if obj then
- obj:set_velocity(vector.new(math.random(-3,3),math.random(4,8),math.random(-3,3)))
+ obj:set_velocity(new_vec(random(-3,3),random(4,8),random(-3,3)))
end
inv:set_stack("armor_feet", 1, ItemStack(""))
end
+ dump_craft(player)
- armor_class.recalculate_armor(player)
+ recalculate_armor(player)
end)
--this dumps the players crafting table on closing the inventory
dump_craft = function(player)
- local inv = player:get_inventory()
- local pos = player:get_pos()
- pos.y = pos.y + player:get_properties().eye_height
+ pos = player:get_pos()
+ inv = player:get_inventory()
for i = 1,inv:get_size("craft") do
- local item = inv:get_stack("craft", i)
- local obj = minetest.add_item(pos, item)
- if obj then
- local x=math.random(-2,2)*math.random()
- local y=math.random(2,5)
- local z=math.random(-2,2)*math.random()
- obj:set_velocity({x=x, y=y, z=z})
+ stack = inv:get_stack("craft", i)
+ name = stack:get_name()
+ count = stack:get_count()
+ if name ~= "" then
+ obj = add_item(pos, stack)
+ if obj then
+ obj:set_velocity(new_vec(random(-3,3),random(4,8),random(-3,3)))
+ end
+ inv:set_stack("craft", i, ItemStack(""))
end
- inv:set_stack("craft", i, nil)
end
end
+local registered_nodes
+minetest.register_on_mods_loaded(function()
+ registered_nodes = minetest.registered_nodes
+end)
+
--play sound to keep up with player's placing vs inconsistent client placing sound
+local node
+local sound
+local placing
minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack, pointed_thing)
- local node = minetest.registered_nodes[newnode.name]
- local sound = node.sounds
- local placing = ""
+ node = registered_nodes[newnode.name]
+ sound = node.sounds
+ placing = ""
if sound then
placing = sound.placing
end
--only play the sound when is defined
if type(placing) == "table" then
- minetest.sound_play(placing.name, {
+ play_sound(placing.name, {
pos = pos,
gain = placing.gain,
- --pitch = math.random(60,100)/100
+ max_hear_distance = 32,
+ --pitch = random(60,100)/100
})
end
end)
--replace stack when empty (building)
+local new
+local inv
+local old
+local count
minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack, pointed_thing)
- local old = itemstack:get_name()
+ old = itemstack:get_name()
--pass through to check
minetest.after(0,function(pos, newnode, placer, oldnode, itemstack, pointed_thing,old)
if not placer then
return
end
- local new = placer:get_wielded_item():get_name()
+ new = placer:get_wielded_item():get_name()
if old ~= new and new == "" then
- local inv = placer:get_inventory()
+ inv = placer:get_inventory()
--check if another stack
if inv:contains_item("main", old) then
--print("moving stack")
for i = 1,inv:get_size("main") do
--if found set wielded item and remove old stack
if inv:get_stack("main", i):get_name() == old then
- local count = inv:get_stack("main", i):get_count()
+ count = inv:get_stack("main", i):get_count()
placer:set_wielded_item(old.." "..count)
inv:set_stack("main",i,ItemStack(""))
- minetest.sound_play("pickup", {
+ play_sound("pickup", {
to_player = player,
gain = 0.7,
- pitch = math.random(60,100)/100
+ pitch = random(60,100)/100
})
return
end
end)
local do_critical_particles = function(pos)
- minetest.add_particlespawner({
+ add_ps({
amount = 40,
time = 0.001,
minpos = pos,
maxpos = pos,
- minvel = vector.new(-2,-2,-2),
- maxvel = vector.new(2,8,2),
+ minvel = new_vec(-2,-2,-2),
+ maxvel = new_vec(2,8,2),
minacc = {x=0, y=4, z=0},
maxacc = {x=0, y=12, z=0},
minexptime = 1.1,
end
--we need to do this to override the default damage mechanics
+local pool = {}
+
+local name
minetest.register_on_joinplayer(function(player)
- local meta = player:get_meta()
- meta:set_float("player_punch_timer",0)
+ name = player:get_player_name()
+ pool[name] = minetest.get_us_time()/1000000
end)
-minetest.register_globalstep(function(dtime)
- for _,player in ipairs(minetest.get_connected_players()) do
- local meta = player:get_meta()
- local punch_timer = meta:get_float("player_punch_timer")
-
- --limit this so the game engine isn't calculating huge floats
- if punch_timer > 0 then
- punch_timer = punch_timer - dtime
- if punch_timer < 0 then punch_timer = 0 end
- meta:set_float("player_punch_timer",punch_timer)
- end
- end
-end)
+local name
+function player_can_be_punched(player)
+ name = player:get_player_name()
+ return((minetest.get_us_time()/1000000)-pool[name] >= 0.5)
+end
--this throws the player when they're punched and activates the custom damage mechanics
+local name
+local temp_pool
+local hurt
+local punch_diff
+local hurt
+local hp
+local puncher_vel
+local vel
+local hp_modifier
+local modify_output
minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch, tool_capabilities, dir, damage)
- local meta = player:get_meta()
- local punch_timer = meta:get_float("player_punch_timer")
- local hurt = tool_capabilities.damage_groups.damage
- local hp = player:get_hp()
- if punch_timer <= 0 and hp > 0 then
- meta:set_float("player_punch_timer",0.25)
+ name = player:get_player_name()
+ temp_pool = pool[name]
+
+ punch_diff = (minetest.get_us_time()/1000000)-temp_pool
+
+ hurt = tool_capabilities.damage_groups.damage
+ if not hurt then
+ hurt = 0
+ end
+ hp = player:get_hp()
+
+ if punch_diff >= 0.5 and hp > 0 then
+
+ temp_pool = minetest.get_us_time()/1000000
+
if hitter:is_player() and hitter ~= player then
- local puncher_vel = hitter:get_player_velocity().y
+ puncher_vel = hitter:get_player_velocity().y
if puncher_vel < 0 then
hurt = hurt * 1.5
- critical = true
do_critical_particles(player:get_pos())
- minetest.sound_play("critical", {pos=player:get_pos(), gain = 0.1, max_hear_distance = 16,pitch = math.random(80,100)/100})
+ play_sound("critical", {pos=player:get_pos(), gain = 0.1, max_hear_distance = 16,pitch = random(80,100)/100})
end
end
- dir = vector.multiply(dir,10)
- local vel = player:get_player_velocity()
+ dir = multiply_vec(dir,10)
+ vel = player:get_player_velocity()
dir.y = 0
if vel.y <= 0 then
dir.y = 7
end
- local hp_modifier = math.ceil(armor_class.calculate_armor_absorbtion(player)/3)
+ hp_modifier = ceil(calculate_armor_absorbtion(player)/3)
--print("hp_modifier:",hp_modifier)
- armor_class.damage_armor(player,math.abs(hurt))
+ damage_armor(player,abs(hurt))
--print("hurt:",hurt,"|","hp_modifier:",hp_modifier)
- local modify_output = (hurt == 0)
+ modify_output = (hurt == 0)
hurt = hurt - hp_modifier
- if modify_output == false and hurt <= 0 then
+ if not modify_output and hurt <= 0 then
hurt = 1
- elseif modify_output == true then
+ elseif modify_output then
hurt = 0
end
+
player:add_player_velocity(dir)
+
player:set_hp(hp-hurt)
end
end)
-
+local inv
+minetest.register_on_respawnplayer(function(player)
+ player:add_player_velocity(multiply_vec(player:get_player_velocity(),-1))
+ inv = player:get_inventory()
+ inv:set_list("main", {})
+ inv:set_list("craft", {})
+ inv:set_list("craftpreview", {})
+ inv:set_list("armor_head", {})
+ inv:set_list("armor_torso", {})
+ inv:set_list("armor_legs", {})
+ inv:set_list("armor_feet", {})
+end)
\ No newline at end of file