diff --git a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaSession.java b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaSession.java index f20457f..a9c92b9 100644 --- a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaSession.java +++ b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaSession.java @@ -20,6 +20,7 @@ public class DropperArenaSession extends AbstractArenaSession { private final @NotNull DropperArena arena; private final @NotNull Player player; private final @NotNull DropperArenaGameMode gameMode; + private boolean startedMoving = false; /** * Instantiates a new dropper arena session @@ -39,6 +40,22 @@ public class DropperArenaSession extends AbstractArenaSession { this.entryState.setArenaState(); } + /** + * Marks that this arena's player has started moving + */ + public void setStartedMoving() { + this.startedMoving = true; + } + + /** + * Gets whether the player of this session has started moving in the arena + * + * @return
True if the player has started moving
+ */ + public boolean getStartedMoving() { + return this.startedMoving; + } + /** * Gets the player playing in this session * @@ -103,6 +120,12 @@ public class DropperArenaSession extends AbstractArenaSession { return new DropperGUI(player); } + @Override + public void reset() { + this.startedMoving = false; + super.reset(); + } + @Override protected void removeSession() { // Remove this session for game sessions to stop listeners from fiddling more with the player diff --git a/src/main/java/net/knarcraft/minigames/listener/MoveListener.java b/src/main/java/net/knarcraft/minigames/listener/MoveListener.java index 18a1bb7..f11ee9f 100644 --- a/src/main/java/net/knarcraft/minigames/listener/MoveListener.java +++ b/src/main/java/net/knarcraft/minigames/listener/MoveListener.java @@ -12,6 +12,7 @@ import net.knarcraft.minigames.config.DropperConfiguration; import net.knarcraft.minigames.config.Message; import net.knarcraft.minigames.config.ParkourConfiguration; import net.knarcraft.minigames.config.SharedConfiguration; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.block.Block; import org.bukkit.entity.Player; @@ -132,14 +133,26 @@ public class MoveListener implements Listener { * @param arenaSessionThe dropper session of the player triggering the event
*/ private void doDropperArenaChecks(@NotNull PlayerMoveEvent event, @NotNull DropperArenaSession arenaSession) { - if (event.getTo() == null) { + // If the player has yet to move in the arena, allow them to look around + boolean startedMoving = arenaSession.getStartedMoving(); + if (event.getTo() == null || + (!startedMoving && isSameLocation(event.getFrom(), event.getTo()))) { return; } + + // Marks the player as started moving if necessary, so they can no longer hang in the air + if (!startedMoving) { + arenaSession.setStartedMoving(); + } + // Prevent the player from flying upwards while in flight mode if (event.getFrom().getY() < event.getTo().getY() || (dropperConfiguration.blockSneaking() && event.getPlayer().isSneaking()) || (dropperConfiguration.blockSprinting() && event.getPlayer().isSprinting())) { event.setCancelled(true); + // Force movement downwards once the player lets go + Bukkit.getScheduler().scheduleSyncDelayedTask(MiniGames.getInstance(), + () -> updatePlayerVelocity(arenaSession), 1); return; } @@ -154,6 +167,18 @@ public class MoveListener implements Listener { updatePlayerVelocity(arenaSession); } + /** + * Checks if two locations are the same, excluding rotation + * + * @param location1The first location to check
+ * @param location2The second location to check
+ * @returnTrue if the locations are the same, excluding rotation
+ */ + private boolean isSameLocation(Location location1, Location location2) { + return location1.getX() == location2.getX() && location1.getY() == location2.getY() && + location1.getZ() == location2.getZ(); + } + /** * Check if the player in the session is triggering a block with a special significance *