mirror of
https://git.minetest.land/VoxeLibre/VoxeLibre.git
synced 2024-12-26 01:49:32 +01:00
Merge pull request 'Finish PVP Combat Parity with the rest + PVP Tweaks' (#4078) from Eliy21/MineClone2:combat_fixes into master
Reviewed-on: https://git.minetest.land/MineClone2/MineClone2/pulls/4078 Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
This commit is contained in:
commit
d11526f8e8
6 changed files with 107 additions and 20 deletions
|
@ -522,7 +522,7 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
|
|||
|
||||
if is_player then
|
||||
-- is mob out of reach?
|
||||
if vector.distance(mob_pos, player_pos) > 3 then
|
||||
if vector.distance(mob_pos, player_pos) > 3 then
|
||||
return
|
||||
end
|
||||
-- is mob protected?
|
||||
|
|
|
@ -57,7 +57,9 @@ function mcl_bows.shoot_arrow(arrow_item, pos, dir, yaw, shooter, power, damage,
|
|||
damage = damage + (enchantments.power + 1) / 4
|
||||
end
|
||||
if enchantments.punch then
|
||||
knockback = enchantments.punch * 21
|
||||
knockback = enchantments.punch * 24
|
||||
else
|
||||
knockback = 4.875
|
||||
end
|
||||
if enchantments.flame then
|
||||
mcl_burning.set_on_fire(obj, math.huge)
|
||||
|
|
|
@ -48,7 +48,7 @@ function mcl_bows_s.shoot_arrow_crossbow(arrow_item, pos, dir, yaw, shooter, pow
|
|||
if damage == nil then
|
||||
damage = 3
|
||||
end
|
||||
local knockback
|
||||
local knockback = 4.875
|
||||
if crossbow_stack then
|
||||
local enchantments = mcl_enchanting.get_enchantments(crossbow_stack)
|
||||
if enchantments.piercing then
|
||||
|
|
|
@ -133,7 +133,11 @@ minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch,
|
|||
if wielditem then
|
||||
local fire_aspect_level = mcl_enchanting.get_enchantment(wielditem, "fire_aspect")
|
||||
if fire_aspect_level > 0 then
|
||||
mcl_burning.set_on_fire(player, fire_aspect_level * 4)
|
||||
local player_pos = player:get_pos()
|
||||
local hitter_pos = hitter:get_pos()
|
||||
if vector.distance(hitter_pos, player_pos) <= 3 then
|
||||
mcl_burning.set_on_fire(player, fire_aspect_level * 4)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -276,15 +280,65 @@ function minetest.calculate_knockback(player, hitter, time_from_last_punch, tool
|
|||
if hitter then
|
||||
luaentity = hitter:get_luaentity()
|
||||
end
|
||||
if hitter and hitter:is_player() then
|
||||
if hitter and hitter:is_player() and distance <= 3 then
|
||||
local wielditem = hitter:get_wielded_item()
|
||||
knockback = knockback + 5 * mcl_enchanting.get_enchantment(wielditem, "knockback")
|
||||
--knockback = knockback + 3 * mcl_enchanting.get_enchantment(wielditem, "knockback")
|
||||
local enchant = mcl_enchanting.get_enchantment(wielditem, "knockback")
|
||||
knockback = knockback + 3.22 * enchant
|
||||
-- add vertical lift to knockback
|
||||
local v = player:get_velocity()
|
||||
local added_v = 0
|
||||
local invul = player:get_meta():get_int("mcl_damage:invulnerable")
|
||||
if v and v.y <= 0.01 and v.y >= -0.01 and invul == 0 then
|
||||
local regular_v = 6.4
|
||||
local enchant_v = 7
|
||||
regular_v = regular_v * math.abs(dir.y - 1)
|
||||
enchant_v = enchant_v * math.abs(dir.y - 1)
|
||||
if enchant == 0 then
|
||||
player:add_velocity({x = 0, y = regular_v, z = 0})
|
||||
added_v = regular_v
|
||||
else
|
||||
player:add_velocity({x = 0, y = enchant_v, z = 0})
|
||||
added_v = enchant_v
|
||||
end
|
||||
-- add minimum knockback
|
||||
if knockback <= 1.5 then
|
||||
knockback = knockback + 4.875
|
||||
elseif knockback <= 6.19 then
|
||||
knockback = knockback + 0.609375
|
||||
end
|
||||
end
|
||||
-- counteract forward velocity when hit
|
||||
local self_dir_dot = (v.x * dir.x) + (v.z * dir.z)
|
||||
if self_dir_dot < 0 then
|
||||
player:add_velocity({x = v.x * -1, y = 0, z = v.z * -1})
|
||||
end
|
||||
-- add player velocity to knockback
|
||||
local h_name = hitter:get_player_name()
|
||||
local hv = hitter:get_velocity()
|
||||
local dir_dot = (hv.x * dir.x) + (hv.z * dir.z)
|
||||
if dir_dot > 0 then
|
||||
knockback = knockback + dir_dot * 2
|
||||
local hitter_mag = math.sqrt((hv.x * hv.x) + (hv.z * hv.z))
|
||||
if dir_dot > 0 and mcl_sprint.is_sprinting(h_name) then
|
||||
knockback = knockback + hitter_mag * 0.6875
|
||||
elseif dir_dot > 0 then
|
||||
knockback = knockback + hitter_mag * 0.515625
|
||||
end
|
||||
-- reduce floatiness
|
||||
minetest.after(0.25, function()
|
||||
player:add_velocity({x = 0, y = (v.y + added_v) * -0.375, z = 0})
|
||||
end)
|
||||
-- reduce knockback when moving towards hitter while attacking
|
||||
local self_dir_dot = (v.x * dir.x) + (v.z * dir.z)
|
||||
local control = player:get_player_control()
|
||||
if self_dir_dot < -4.3 and control.up and control.LMB then
|
||||
knockback = knockback * 0.6
|
||||
end
|
||||
-- remove knockback if invulnerable
|
||||
if invul > 0 then
|
||||
knockback = 0
|
||||
end
|
||||
elseif hitter and hitter:is_player() and distance > 3 then
|
||||
knockback = 0
|
||||
elseif luaentity and luaentity._knockback then
|
||||
local kb = knockback + luaentity._knockback / 4
|
||||
local punch_dir = dir
|
||||
|
|
|
@ -228,6 +228,11 @@ minetest.register_globalstep(function(dtime)
|
|||
-- Apply animations based on what the player is doing
|
||||
if player:get_hp() == 0 then
|
||||
player_set_animation(player, "die")
|
||||
elseif player:get_meta():get_int("mcl_damage:damage_animation") > 0 then
|
||||
player_set_animation(player, "walk", animation_speed_mod)
|
||||
minetest.after(0.5, function()
|
||||
player:get_meta():set_int("mcl_damage:damage_animation", 0)
|
||||
end)
|
||||
elseif mcl_playerplus.elytra[player] and mcl_playerplus.elytra[player].active then
|
||||
player_set_animation(player, "stand")
|
||||
elseif walking and velocity.x > 0.35
|
||||
|
|
|
@ -663,6 +663,8 @@ minetest.register_on_joinplayer(function(player)
|
|||
lastPos = nil,
|
||||
swimDistance = 0,
|
||||
jump_cooldown = -1, -- Cooldown timer for jumping, we need this to prevent the jump exhaustion to increase rapidly
|
||||
last_damage = 0,
|
||||
invul_timestamp = 0,
|
||||
}
|
||||
mcl_playerplus.elytra[player] = {active = false, rocketing = 0, speed = 0}
|
||||
|
||||
|
@ -727,19 +729,43 @@ mcl_damage.register_modifier(function(obj, damage, reason)
|
|||
end
|
||||
end, -200)
|
||||
|
||||
-- damage invulnerability
|
||||
mcl_damage.register_modifier(function(obj, damage, reason)
|
||||
local invul = obj:get_meta():get_int("mcl_damage:invulnerable")
|
||||
if invul > 0 then
|
||||
return 0
|
||||
else
|
||||
obj:get_meta():set_int("mcl_damage:invulnerable", 1)
|
||||
minetest.after(0.5, function()
|
||||
obj:get_meta():set_int("mcl_damage:invulnerable", 0)
|
||||
end)
|
||||
return damage
|
||||
minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch, tool_capabilities, dir, damage)
|
||||
-- attack reach limit
|
||||
if hitter and hitter:is_player() then
|
||||
local player_pos = player:get_pos()
|
||||
local hitter_pos = hitter:get_pos()
|
||||
if vector.distance(player_pos, hitter_pos) > 3 then
|
||||
damage = 0
|
||||
return damage
|
||||
end
|
||||
end
|
||||
end, -1000)
|
||||
-- damage invulnerability
|
||||
if hitter then
|
||||
local name = player:get_player_name()
|
||||
local time_now = minetest.get_us_time()
|
||||
local invul_timestamp = mcl_playerplus_internal[name].invul_timestamp
|
||||
local time_diff = time_now - invul_timestamp
|
||||
-- check for invulnerability time in microseconds (0.5 second)
|
||||
if time_diff <= 500000 and time_diff >= 0 then
|
||||
player:get_meta():set_int("mcl_damage:invulnerable", 1)
|
||||
minetest.after(0.5, function()
|
||||
player:get_meta():set_int("mcl_damage:invulnerable", 0)
|
||||
end)
|
||||
damage = damage - mcl_playerplus_internal[name].last_damage
|
||||
if damage < 0 then
|
||||
damage = 0
|
||||
end
|
||||
return damage
|
||||
else
|
||||
mcl_playerplus_internal[name].last_damage = damage
|
||||
mcl_playerplus_internal[name].invul_timestamp = time_now
|
||||
player:get_meta():set_int("mcl_damage:damage_animation", 1)
|
||||
minetest.after(0.5, function()
|
||||
player:get_meta():set_int("mcl_damage:damage_animation", 0)
|
||||
end)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_on_respawnplayer(function(player)
|
||||
local pos = player:get_pos()
|
||||
|
|
Loading…
Reference in a new issue