diff --git a/core/src/main/java/tc/oc/pgm/api/event/PlayerSpleefEvent.java b/core/src/main/java/tc/oc/pgm/api/event/PlayerSpleefEvent.java index 02608d6b8f..11857b4651 100644 --- a/core/src/main/java/tc/oc/pgm/api/event/PlayerSpleefEvent.java +++ b/core/src/main/java/tc/oc/pgm/api/event/PlayerSpleefEvent.java @@ -2,9 +2,9 @@ import static tc.oc.pgm.util.Assert.assertNotNull; -import org.bukkit.block.Block; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; +import org.bukkit.util.Vector; import org.jetbrains.annotations.Nullable; import tc.oc.pgm.api.player.MatchPlayer; import tc.oc.pgm.api.player.ParticipantState; @@ -13,10 +13,10 @@ public class PlayerSpleefEvent extends Event { private final MatchPlayer victim; - private final Block block; + private final Vector block; private final SpleefInfo info; - public PlayerSpleefEvent(MatchPlayer victim, Block block, SpleefInfo info) { + public PlayerSpleefEvent(MatchPlayer victim, Vector block, SpleefInfo info) { this.victim = assertNotNull(victim); this.block = assertNotNull(block); this.info = assertNotNull(info); @@ -30,7 +30,7 @@ public SpleefInfo getSpleefInfo() { return info; } - public Block getBlock() { + public Vector getBlock() { return block; } diff --git a/core/src/main/java/tc/oc/pgm/tracker/trackers/SpleefTracker.java b/core/src/main/java/tc/oc/pgm/tracker/trackers/SpleefTracker.java index 33c3012c37..010126ebb2 100644 --- a/core/src/main/java/tc/oc/pgm/tracker/trackers/SpleefTracker.java +++ b/core/src/main/java/tc/oc/pgm/tracker/trackers/SpleefTracker.java @@ -9,6 +9,7 @@ import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityExplodeEvent; +import org.bukkit.util.Vector; import tc.oc.pgm.api.event.PlayerSpleefEvent; import tc.oc.pgm.api.match.Match; import tc.oc.pgm.api.match.MatchScope; @@ -31,14 +32,15 @@ public class SpleefTracker implements Listener { private static final float PLAYER_WIDTH = 0.6f; private static final float PLAYER_RADIUS = PLAYER_WIDTH / 2.0f; + private static final float BLOCK_OFFSET = PLAYER_RADIUS + 0.05f; // A player must leave the ground within this many ticks of a block being broken // under them for the fall to be caused by a spleef from that block - public static final long MAX_SPLEEF_TICKS = 20; + public static final long MAX_SPLEEF_TICKS = 30; private final TrackerMatchModule tracker; private final Match match; - private final Map brokenBlocks = new HashMap<>(); + private final Map brokenBlocks = new HashMap<>(); public SpleefTracker(TrackerMatchModule tracker) { this.tracker = tracker; @@ -68,64 +70,62 @@ public void onBlockBreak(final ParticipantBlockTransformEvent event) { } final SpleefInfo info = new SpleefInfo(breaker, match.getTick()); - brokenBlocks.put(block, info); + Vector pos = block.getLocation().toVector(); + brokenBlocks.put(pos, info); + // Only remove the BrokenBlock if it's the same one we added. It may have been replaced since + // then match .getExecutor(MatchScope.RUNNING) .schedule( - () -> { - // Only remove the BrokenBlock if it's the same one we added. It may have been - // replaced since then. - if (info == brokenBlocks.get(block)) { - brokenBlocks.remove(block); - } - }, + () -> brokenBlocks.remove(pos, info), (MAX_SPLEEF_TICKS + 1) * TimeUtils.TICK, TimeUnit.MILLISECONDS); } @EventHandler(priority = EventPriority.MONITOR) public void onPlayerOnGroundChanged(final PlayerOnGroundEvent event) { + if (event.getOnGround()) return; MatchPlayer player = match.getParticipant(event.getPlayer()); if (player == null) return; - Block block = this.lastBlockBrokenUnderPlayer(player); - if (block != null) { - SpleefInfo info = brokenBlocks.get(block); + Vector pos = this.lastBlockBrokenUnderPlayer(player); + if (pos != null) { + SpleefInfo info = brokenBlocks.get(pos); if (match.getTick().tick - info.getTime().tick <= MAX_SPLEEF_TICKS) { - match.callEvent(new PlayerSpleefEvent(player, block, info)); + match.callEvent(new PlayerSpleefEvent(player, pos, info)); } } } - public Block lastBlockBrokenUnderPlayer(MatchPlayer player) { + public Vector lastBlockBrokenUnderPlayer(MatchPlayer player) { Location playerLocation = player.getBukkit().getLocation(); int y = (int) Math.floor(playerLocation.getY() - 0.1); - int x1 = (int) Math.floor(playerLocation.getX() - PLAYER_RADIUS); - int z1 = (int) Math.floor(playerLocation.getZ() - PLAYER_RADIUS); + int x1 = (int) Math.floor(playerLocation.getX() - BLOCK_OFFSET); + int z1 = (int) Math.floor(playerLocation.getZ() - BLOCK_OFFSET); - int x2 = (int) Math.floor(playerLocation.getX() + PLAYER_RADIUS); - int z2 = (int) Math.floor(playerLocation.getZ() + PLAYER_RADIUS); + int x2 = (int) Math.floor(playerLocation.getX() + BLOCK_OFFSET); + int z2 = (int) Math.floor(playerLocation.getZ() + BLOCK_OFFSET); long latestTick = Long.MIN_VALUE; - Block latestBlock = null; + Vector latestPos = null; for (int x = x1; x <= x2; ++x) { for (int z = z1; z <= z2; ++z) { - Block block = playerLocation.getBlock(); - SpleefInfo info = this.brokenBlocks.get(block); + Vector pos = new Vector(x, y, z); + SpleefInfo info = this.brokenBlocks.get(pos); if (info != null) { long tick = info.getTime().tick; if (tick > latestTick) { latestTick = tick; - latestBlock = block; + latestPos = pos; } } } } - return latestBlock; + return latestPos; } } diff --git a/util/src/main/java/tc/oc/pgm/util/event/player/PlayerOnGroundEvent.java b/util/src/main/java/tc/oc/pgm/util/event/player/PlayerOnGroundEvent.java index 162987b1a7..a5b469f70c 100644 --- a/util/src/main/java/tc/oc/pgm/util/event/player/PlayerOnGroundEvent.java +++ b/util/src/main/java/tc/oc/pgm/util/event/player/PlayerOnGroundEvent.java @@ -8,7 +8,7 @@ @SportPaper public class PlayerOnGroundEvent extends PlayerEvent { private static final HandlerList handlers = new HandlerList(); - private boolean onGround; + private final boolean onGround; public PlayerOnGroundEvent(final Player player, boolean onGround) { super(player);