forked from VoxeLibre/VoxeLibre
Merge pull request 'Finish PVP Combat Parity with the rest + PVP Tweaks' (#4078) from Eliy21/MineClone2:combat_fixes into master
Reviewed-on: MineClone2/MineClone2#4078 Reviewed-by: the-real-herowl <the-real-herowl@noreply.git.minetest.land>
This commit is contained in:
commit
d11526f8e8
|
@ -522,7 +522,7 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
|
||||||
|
|
||||||
if is_player then
|
if is_player then
|
||||||
-- is mob out of reach?
|
-- is mob out of reach?
|
||||||
if vector.distance(mob_pos, player_pos) > 3 then
|
if vector.distance(mob_pos, player_pos) > 3 then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
-- is mob protected?
|
-- 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
|
damage = damage + (enchantments.power + 1) / 4
|
||||||
end
|
end
|
||||||
if enchantments.punch then
|
if enchantments.punch then
|
||||||
knockback = enchantments.punch * 21
|
knockback = enchantments.punch * 24
|
||||||
|
else
|
||||||
|
knockback = 4.875
|
||||||
end
|
end
|
||||||
if enchantments.flame then
|
if enchantments.flame then
|
||||||
mcl_burning.set_on_fire(obj, math.huge)
|
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
|
if damage == nil then
|
||||||
damage = 3
|
damage = 3
|
||||||
end
|
end
|
||||||
local knockback
|
local knockback = 4.875
|
||||||
if crossbow_stack then
|
if crossbow_stack then
|
||||||
local enchantments = mcl_enchanting.get_enchantments(crossbow_stack)
|
local enchantments = mcl_enchanting.get_enchantments(crossbow_stack)
|
||||||
if enchantments.piercing then
|
if enchantments.piercing then
|
||||||
|
|
|
@ -133,7 +133,11 @@ minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch,
|
||||||
if wielditem then
|
if wielditem then
|
||||||
local fire_aspect_level = mcl_enchanting.get_enchantment(wielditem, "fire_aspect")
|
local fire_aspect_level = mcl_enchanting.get_enchantment(wielditem, "fire_aspect")
|
||||||
if fire_aspect_level > 0 then
|
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
|
end
|
||||||
end
|
end
|
||||||
|
@ -276,15 +280,65 @@ function minetest.calculate_knockback(player, hitter, time_from_last_punch, tool
|
||||||
if hitter then
|
if hitter then
|
||||||
luaentity = hitter:get_luaentity()
|
luaentity = hitter:get_luaentity()
|
||||||
end
|
end
|
||||||
if hitter and hitter:is_player() then
|
if hitter and hitter:is_player() and distance <= 3 then
|
||||||
local wielditem = hitter:get_wielded_item()
|
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
|
-- add player velocity to knockback
|
||||||
|
local h_name = hitter:get_player_name()
|
||||||
local hv = hitter:get_velocity()
|
local hv = hitter:get_velocity()
|
||||||
local dir_dot = (hv.x * dir.x) + (hv.z * dir.z)
|
local dir_dot = (hv.x * dir.x) + (hv.z * dir.z)
|
||||||
if dir_dot > 0 then
|
local hitter_mag = math.sqrt((hv.x * hv.x) + (hv.z * hv.z))
|
||||||
knockback = knockback + dir_dot * 2
|
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
|
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
|
elseif luaentity and luaentity._knockback then
|
||||||
local kb = knockback + luaentity._knockback / 4
|
local kb = knockback + luaentity._knockback / 4
|
||||||
local punch_dir = dir
|
local punch_dir = dir
|
||||||
|
|
|
@ -228,6 +228,11 @@ minetest.register_globalstep(function(dtime)
|
||||||
-- Apply animations based on what the player is doing
|
-- Apply animations based on what the player is doing
|
||||||
if player:get_hp() == 0 then
|
if player:get_hp() == 0 then
|
||||||
player_set_animation(player, "die")
|
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
|
elseif mcl_playerplus.elytra[player] and mcl_playerplus.elytra[player].active then
|
||||||
player_set_animation(player, "stand")
|
player_set_animation(player, "stand")
|
||||||
elseif walking and velocity.x > 0.35
|
elseif walking and velocity.x > 0.35
|
||||||
|
|
|
@ -663,6 +663,8 @@ minetest.register_on_joinplayer(function(player)
|
||||||
lastPos = nil,
|
lastPos = nil,
|
||||||
swimDistance = 0,
|
swimDistance = 0,
|
||||||
jump_cooldown = -1, -- Cooldown timer for jumping, we need this to prevent the jump exhaustion to increase rapidly
|
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}
|
mcl_playerplus.elytra[player] = {active = false, rocketing = 0, speed = 0}
|
||||||
|
|
||||||
|
@ -727,19 +729,43 @@ mcl_damage.register_modifier(function(obj, damage, reason)
|
||||||
end
|
end
|
||||||
end, -200)
|
end, -200)
|
||||||
|
|
||||||
-- damage invulnerability
|
minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch, tool_capabilities, dir, damage)
|
||||||
mcl_damage.register_modifier(function(obj, damage, reason)
|
-- attack reach limit
|
||||||
local invul = obj:get_meta():get_int("mcl_damage:invulnerable")
|
if hitter and hitter:is_player() then
|
||||||
if invul > 0 then
|
local player_pos = player:get_pos()
|
||||||
return 0
|
local hitter_pos = hitter:get_pos()
|
||||||
else
|
if vector.distance(player_pos, hitter_pos) > 3 then
|
||||||
obj:get_meta():set_int("mcl_damage:invulnerable", 1)
|
damage = 0
|
||||||
minetest.after(0.5, function()
|
return damage
|
||||||
obj:get_meta():set_int("mcl_damage:invulnerable", 0)
|
end
|
||||||
end)
|
|
||||||
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)
|
minetest.register_on_respawnplayer(function(player)
|
||||||
local pos = player:get_pos()
|
local pos = player:get_pos()
|
||||||
|
|
Loading…
Reference in New Issue