From 5aed86f7f71db85097f79d96a572d1155b83537c Mon Sep 17 00:00:00 2001 From: oilboi <47129783+oilboi@users.noreply.github.com> Date: Wed, 24 Jun 2020 23:46:36 -0400 Subject: [PATCH] Optimize player interactions --- mods/mob/api/interaction.lua | 5 +- mods/player_mechanics/player_interaction.lua | 204 +++++++++++-------- 2 files changed, 121 insertions(+), 88 deletions(-) diff --git a/mods/mob/api/interaction.lua b/mods/mob/api/interaction.lua index e5f2bff..fa3fe90 100644 --- a/mods/mob/api/interaction.lua +++ b/mods/mob/api/interaction.lua @@ -36,7 +36,6 @@ local data_item_amount --for look around local light_level local player_found -local meta local player_punch_timer local line_of_sight local obj @@ -123,9 +122,7 @@ mobs.create_interaction_functions = function(def,mob_register) --punch the player if self.attack_type == "punch" then if distance < 2.5 and self.punch_timer <= 0 and object:get_hp() > 0 then - meta = object:get_meta() - player_punch_timer = meta:get_float("player_punch_timer") - if player_punch_timer <= 0 then + if player_can_be_punched(object) then line_of_sight = minetest.line_of_sight(pos, pos2) if line_of_sight == true then self.punch_timer = 0.5 diff --git a/mods/player_mechanics/player_interaction.lua b/mods/player_mechanics/player_interaction.lua index 16bb8f8..e6901f3 100644 --- a/mods/player_mechanics/player_interaction.lua +++ b/mods/player_mechanics/player_interaction.lua @@ -3,6 +3,14 @@ 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) @@ -10,37 +18,40 @@ minetest.register_on_player_hpchange(function(player, hp_change, reason) --fall damage is handled on another globalstep calc return(0) elseif hp_change < 0 and reason.reason ~= "correction" then - minetest.sound_play("hurt", {object=player, gain = 1.0, max_hear_distance = 60,pitch = math.random(80,100)/100}) + 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 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 @@ -48,9 +59,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 @@ -58,9 +69,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 @@ -69,13 +80,14 @@ 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) recalculate_armor(player) end) @@ -83,53 +95,65 @@ 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, max_hear_distance = 32, - --pitch = math.random(60,100)/100 + --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") @@ -137,13 +161,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 @@ -154,13 +178,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, @@ -174,62 +198,72 @@ 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 + 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(calculate_armor_absorbtion(player)/3) + hp_modifier = ceil(calculate_armor_absorbtion(player)/3) --print("hp_modifier:",hp_modifier) - 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) @@ -237,13 +271,15 @@ minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch, end end) +local inv minetest.register_on_respawnplayer(function(player) - player:add_player_velocity(vector.multiply(player:get_player_velocity(),-1)) - player:get_inventory():set_list("main", {}) - player:get_inventory():set_list("craft", {}) - player:get_inventory():set_list("craftpreview", {}) - player:get_inventory():set_list("armor_head", {}) - player:get_inventory():set_list("armor_torso", {}) - player:get_inventory():set_list("armor_legs", {}) - player:get_inventory():set_list("armor_feet", {}) + 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 -- 2.44.0