# SmoothKnockback
# Needs of the following script to work:
# https://code.skript.pl/JbopZdnW/
# Uses the following addons:
# skript-mirror
# MundoSK (with ProtocolLib)
options:
# Multipliers - this is how much the player is pushed to make that 'smooth' effect,
# the air multipliers are the ones when the player is in the air, i.e. falling.
horizontalMultiplier: 0.8
airHorizontalMultiplier: 0.95
verticalMultiplier: 0.875
airVerticalMultiplier: 0.95
function applyKnockbackFormula(entity: player, damager: player, x-diff: number, z-diff: number):
set {_horizontal-distance} to sqrt(({_x-diff}^2) * ({_z-diff}^2))
set {_vertical-distance} to 0.4
set {_velocity} to velocity of {_entity} // vector(2, 2, 2)
remove ({_x-diff} / {_horizontal-distance}) * {_vertical-distance} from x of {_velocity}
set y of {_velocity} to {_vertical-distance}
remove ({_z-diff} / {_horizontal-distance}) * {_vertical-distance} from z of {_velocity}
if y of {_velocity} is greater than 0.4000000059604645:
set y of {_velocity} to 0.4000000059604645
set {_i} to 0 + knockback level in {_damager}'s tool
if {_damager} is sprinting:
add 1 to {_i}
if {_i} > 0:
add (sin((yaw of {_damager} * 3.1415927) / 180) * i * 0.5) * -1 to x of {_velocity}
add 0.1 to y of {_velocity}
add (cos((yaw of {_damager} * 3.1415927) / 180) * i * 0.5) * -1 to z of {_velocity}
set velocity of {_entity} to {_velocity}
function sendKnockbackPacket(entity: player, x: number, y: number, z: number):
set {_packet} to new play_server_entity_velocity packet
set {_entity}'s world pentity 0 of {_packet to {_entity}
set int pnum 1 of {_packet} to {_x} * 8000
set int pnum 2 of {_packet} to {_y} * 8000
set int pnum 3 of {_packet} to {_z} * 8000
send packet {_packet} to all players
on damage of player:
victim is a player
if victim's no damage ticks is less than (victim's max no damage ticks / 2):
if mod(victim's y-pos, 1) is 0:
set {_horizontal-multiplier} to {@horizontalMultiplier}
set {_vertical-multiplier} to {@verticalMultiplier}
else:
set {_horizontal-multiplier} to {@airHorizontalMultiplier}
set {_vertical-multiplier} to {@airVerticalMultiplier}
set {_x-diff} to attacker's x-pos - victim's x-pos
set {_z-diff} to attacker-'s z-pos - victim's z-pos
applyKnockbackFormula(victim, attacker, {_x-diff}, {_z-diff})
set {_velocity} to velocity of victim
sendKnockbackPacket(victim, x of {_velocity} * {_horizontal-multiplier}, y of {_velocity} * {_vertical-multiplier}, z of {_velocity} * {_horizontal-multiplier})
on "org.bukkit.event.player.PlayerVelocityEvent":
set {_player} to event.getPlayer()
if last damage cause of {_player} is attack:
cancel event