diff --git a/src/main/java/com/alttd/ctf/events/SnowballEvent.java b/src/main/java/com/alttd/ctf/events/SnowballEvent.java index 7bb51de..2941496 100644 --- a/src/main/java/com/alttd/ctf/events/SnowballEvent.java +++ b/src/main/java/com/alttd/ctf/events/SnowballEvent.java @@ -5,6 +5,7 @@ import com.alttd.ctf.game.GamePhase; import com.alttd.ctf.game_class.GameClass; import com.alttd.ctf.team.TeamPlayer; import lombok.extern.slf4j.Slf4j; +import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.entity.Snowball; import org.bukkit.event.EventHandler; @@ -12,6 +13,8 @@ import org.bukkit.event.Listener; import org.bukkit.entity.Player; import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.entity.ProjectileLaunchEvent; +import org.bukkit.util.Vector; +import org.jetbrains.annotations.NotNull; import java.util.Optional; @@ -26,7 +29,7 @@ public class SnowballEvent implements Listener { @FunctionalInterface private interface SnowballHitConsumer { - void apply(Player hitPlayer, Player shooter, TeamPlayer shooterTeamPlayer); + void apply(Player hitPlayer, Player shooter, TeamPlayer shooterTeamPlayer, Snowball snowball); } @FunctionalInterface @@ -36,7 +39,10 @@ public class SnowballEvent implements Listener { @EventHandler public void onSnowballHit(EntityDamageByEntityEvent event) { - handleSnowballHit(event, (hitPlayer, shooter, shooterTeamPlayer) -> { + handleSnowballHit(event, (hitPlayer, shooter, shooterTeamPlayer, snowball) -> { + if (blockedAttack(hitPlayer, snowball)) { //Disable damage when it is blocked + return; + } GameClass shooterClass = shooterTeamPlayer.getGameClass(); shooter.setCooldown(Material.SNOWBALL, shooterClass.getThrowTickSpeed()); @@ -55,6 +61,20 @@ public class SnowballEvent implements Listener { }); } + private boolean blockedAttack(@NotNull Player hitPlayer, @NotNull Snowball snowball) { + if (!hitPlayer.isBlocking()) { + return false; + } + Location playerLocation = hitPlayer.getLocation(); + Vector playerFacing = playerLocation.getDirection().normalize(); + Location snowballLocation = snowball.getLocation(); + Vector impactDirection = snowballLocation.toVector().subtract(playerLocation.toVector()).normalize(); + + double angle = playerFacing.angle(impactDirection); + + return !(Math.toDegrees(angle) > 80); //Blocked if the angle was <= 80 + } + private void handleSnowballThrown(ProjectileLaunchEvent event, SnowballThrownConsumer consumer) { Optional optionalGamePhase = gameManager.getGamePhase(); if (optionalGamePhase.isEmpty()) { @@ -121,6 +141,6 @@ public class SnowballEvent implements Listener { log.debug("The shooter hit a member of their own team"); return; } - consumer.apply(hitPlayer, shooter, teamPlayerHit.get()); + consumer.apply(hitPlayer, shooter, teamPlayerHit.get(), snowball); } }