]> git.lizzy.rs Git - Crafter.git/blobdiff - mods/player_mechanics/player_interaction.lua
Update player_interaction.lua
[Crafter.git] / mods / player_mechanics / player_interaction.lua
index a26546567b3f7dcb034bf75e2b85a27507106eee..9d051c336e9d61f66c650131b683f8bdc9618d9c 100644 (file)
-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
@@ -153,9 +60,9 @@ minetest.register_on_dieplayer(function(player, reason)
        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
@@ -163,9 +70,9 @@ minetest.register_on_dieplayer(function(player, reason)
        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
@@ -174,66 +81,80 @@ minetest.register_on_dieplayer(function(player, reason)
        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")
@@ -241,13 +162,13 @@ minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack
                                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
@@ -258,13 +179,13 @@ minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack
 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,
@@ -278,67 +199,93 @@ local do_critical_particles = function(pos)
 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