Add blocking mechanics for snowball hits
Introduced a check to disable snowball damage if the target is blocking and the impact angle is within 80 degrees. Extended `SnowballHitConsumer` to include the `Snowball` object for more accurate handling of hits. This improves gameplay by allowing players to block snowball attacks with proper positioning.
This commit is contained in:
parent
4af509eb5f
commit
91ee3cf8f9
|
|
@ -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<GamePhase> 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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user