From a84e164edfde863b10b62c379b00d3f58c3b399c Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 17 Apr 2023 12:49:59 +0200 Subject: [PATCH] Adds an option to enforce ordered checkpoint triggering --- README.md | 13 +++---- .../net/knarcraft/minigames/MiniGames.java | 2 +- .../minigames/arena/parkour/ParkourArena.java | 4 +++ .../config/ParkourConfiguration.java | 11 ++++++ .../minigames/listener/CommandListener.java | 2 ++ .../minigames/listener/MoveListener.java | 36 +++++++++++++------ src/main/resources/config.yml | 5 +++ 7 files changed, 56 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 226abf6..ea7a708 100644 --- a/README.md +++ b/README.md @@ -149,12 +149,13 @@ You could use `/droppergroupswap Sea Savanna` to change the order to: ### Parkour -| Name | Type | Default | Description | -|-----------------------------------|------------|--------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| mustDoGroupedInSequence | true/false | true | Whether grouped dropper arenas must be played in the correct sequence | -| ignoreRecordsUntilGroupBeatenOnce | true/false | false | Whether records won't be registered unless the player has already beaten all arenas in a group. That means players are required to do a second play-through to register a record for a grouped arena. | -| makePlayersInvisible | true/false | false | Whether players should be made invisible while playing in a dropper arena | -| killPlaneBlocks | list | [see this](#killplaneblocks-default) | The types of blocks compromising parkour arenas' kill planes. Add any materials you want to use for the "bottom" of your parkour arenas. +WOOL and other block tags are supported. | +| Name | Type | Default | Description | +|-----------------------------------|------------|--------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| enforceCheckpointOrder | true/false | false | Whether to enforce the order in which a player must reach checkpoints. Enabling this ensures that a player cannot trigger a previous checkpoint by accident. It also ensures players cannot skip a checkpoint, even if the arena layout makes it possible. | +| mustDoGroupedInSequence | true/false | true | Whether grouped dropper arenas must be played in the correct sequence | +| ignoreRecordsUntilGroupBeatenOnce | true/false | false | Whether records won't be registered unless the player has already beaten all arenas in a group. That means players are required to do a second play-through to register a record for a grouped arena. | +| makePlayersInvisible | true/false | false | Whether players should be made invisible while playing in a dropper arena | +| killPlaneBlocks | list | [see this](#killplaneblocks-default) | The types of blocks compromising parkour arenas' kill planes. Add any materials you want to use for the "bottom" of your parkour arenas. +WOOL and other block tags are supported. | #### blockWhitelist default: diff --git a/src/main/java/net/knarcraft/minigames/MiniGames.java b/src/main/java/net/knarcraft/minigames/MiniGames.java index 00eaaa7..f26726a 100644 --- a/src/main/java/net/knarcraft/minigames/MiniGames.java +++ b/src/main/java/net/knarcraft/minigames/MiniGames.java @@ -238,7 +238,7 @@ public final class MiniGames extends JavaPlugin { PluginManager pluginManager = getServer().getPluginManager(); pluginManager.registerEvents(new DamageListener(), this); - pluginManager.registerEvents(new MoveListener(this.dropperConfiguration), this); + pluginManager.registerEvents(new MoveListener(this.dropperConfiguration, this.parkourConfiguration), this); pluginManager.registerEvents(new PlayerLeaveListener(), this); pluginManager.registerEvents(new CommandListener(), this); diff --git a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArena.java b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArena.java index 212ebff..2494e02 100644 --- a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArena.java +++ b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArena.java @@ -393,6 +393,10 @@ public class ParkourArena implements Arena { * @return

True if successfully cleared

*/ public boolean clearCheckpoints() { + if (checkpoints.isEmpty()) { + return false; + } + this.checkpoints.clear(); this.parkourArenaHandler.saveArenas(); return true; diff --git a/src/main/java/net/knarcraft/minigames/config/ParkourConfiguration.java b/src/main/java/net/knarcraft/minigames/config/ParkourConfiguration.java index 16497ee..eb8703d 100644 --- a/src/main/java/net/knarcraft/minigames/config/ParkourConfiguration.java +++ b/src/main/java/net/knarcraft/minigames/config/ParkourConfiguration.java @@ -13,6 +13,7 @@ public class ParkourConfiguration extends MiniGameConfiguration { private final static String rootNode = "parkour."; + private boolean enforceCheckpointOrder; private boolean mustDoGroupedInSequence; private boolean ignoreRecordsUntilGroupBeatenOnce; private boolean makePlayersInvisible; @@ -27,6 +28,15 @@ public class ParkourConfiguration extends MiniGameConfiguration { super(configuration); } + /** + * Gets whether all checkpoints must be triggered in the order they are set when configuring the parkour arena + * + * @return

Whether checkpoints must be triggered in order

+ */ + public boolean enforceCheckpointOrder() { + return this.enforceCheckpointOrder; + } + /** * Gets whether grouped arenas must be done in the set sequence * @@ -65,6 +75,7 @@ public class ParkourConfiguration extends MiniGameConfiguration { @Override protected void load() { + this.enforceCheckpointOrder = configuration.getBoolean(rootNode + "enforceCheckpointOrder", false); this.mustDoGroupedInSequence = configuration.getBoolean(rootNode + "mustDoGroupedInSequence", true); this.ignoreRecordsUntilGroupBeatenOnce = configuration.getBoolean(rootNode + "ignoreRecordsUntilGroupBeatenOnce", false); this.makePlayersInvisible = configuration.getBoolean(rootNode + "makePlayersInvisible", false); diff --git a/src/main/java/net/knarcraft/minigames/listener/CommandListener.java b/src/main/java/net/knarcraft/minigames/listener/CommandListener.java index 4a89d85..05391d8 100644 --- a/src/main/java/net/knarcraft/minigames/listener/CommandListener.java +++ b/src/main/java/net/knarcraft/minigames/listener/CommandListener.java @@ -26,6 +26,8 @@ public class CommandListener implements Listener { List allowedCommands = new ArrayList<>(); allowedCommands.add("/miniGamesLeave"); allowedCommands.add("/mLeave"); + allowedCommands.add("/dLeave"); + allowedCommands.add("/pLeave"); String message = event.getMessage(); if (!message.startsWith("/")) { diff --git a/src/main/java/net/knarcraft/minigames/listener/MoveListener.java b/src/main/java/net/knarcraft/minigames/listener/MoveListener.java index 89c55a2..c9c2120 100644 --- a/src/main/java/net/knarcraft/minigames/listener/MoveListener.java +++ b/src/main/java/net/knarcraft/minigames/listener/MoveListener.java @@ -5,8 +5,10 @@ import net.knarcraft.minigames.arena.Arena; import net.knarcraft.minigames.arena.ArenaSession; import net.knarcraft.minigames.arena.dropper.DropperArenaGameMode; import net.knarcraft.minigames.arena.dropper.DropperArenaSession; +import net.knarcraft.minigames.arena.parkour.ParkourArena; import net.knarcraft.minigames.arena.parkour.ParkourArenaSession; import net.knarcraft.minigames.config.DropperConfiguration; +import net.knarcraft.minigames.config.ParkourConfiguration; import net.knarcraft.minigames.config.SharedConfiguration; import org.bukkit.Location; import org.bukkit.block.Block; @@ -19,6 +21,7 @@ import org.jetbrains.annotations.NotNull; import java.util.Calendar; import java.util.HashSet; +import java.util.List; import java.util.Set; /** @@ -26,15 +29,18 @@ import java.util.Set; */ public class MoveListener implements Listener { - private final DropperConfiguration configuration; + private final DropperConfiguration dropperConfiguration; + private final ParkourConfiguration parkourConfiguration; /** * Instantiates a new move listener * - * @param configuration

The configuration to use

+ * @param dropperConfiguration

The dropper configuration to use

+ * @param parkourConfiguration

The parkour configuration to use

*/ - public MoveListener(DropperConfiguration configuration) { - this.configuration = configuration; + public MoveListener(DropperConfiguration dropperConfiguration, ParkourConfiguration parkourConfiguration) { + this.dropperConfiguration = dropperConfiguration; + this.parkourConfiguration = parkourConfiguration; } @EventHandler @@ -70,9 +76,19 @@ public class MoveListener implements Listener { } // Check if the player reached one of the checkpoints for the arena - for (Location checkpoint : arenaSession.getArena().getCheckpoints()) { - if (checkpoint.getBlock().equals(event.getTo().getBlock()) && - !checkpoint.equals(arenaSession.getRegisteredCheckpoint())) { + ParkourArena arena = arenaSession.getArena(); + List checkpoints = arena.getCheckpoints(); + for (Location checkpoint : checkpoints) { + Location previousCheckpoint = arenaSession.getRegisteredCheckpoint(); + if (checkpoint.getBlock().equals(event.getTo().getBlock()) && !checkpoint.equals(previousCheckpoint)) { + if (parkourConfiguration.enforceCheckpointOrder()) { + int checkpointIndex = checkpoints.indexOf(checkpoint); + int previousIndex = previousCheckpoint == null ? -1 : checkpoints.indexOf(previousCheckpoint); + if (checkpointIndex - previousIndex != 1) { + continue; + } + } + arenaSession.registerCheckpoint(checkpoint.clone()); event.getPlayer().sendMessage("Checkpoint reached!"); return; @@ -92,8 +108,8 @@ public class MoveListener implements Listener { } // Prevent the player from flying upwards while in flight mode if (event.getFrom().getY() < event.getTo().getY() || - (configuration.blockSneaking() && event.getPlayer().isSneaking()) || - (configuration.blockSprinting() && event.getPlayer().isSprinting())) { + (dropperConfiguration.blockSneaking() && event.getPlayer().isSneaking()) || + (dropperConfiguration.blockSprinting() && event.getPlayer().isSprinting())) { event.setCancelled(true); return; } @@ -189,7 +205,7 @@ public class MoveListener implements Listener { } Player player = session.getPlayer(); float horizontalVelocity = session.getArena().getPlayerHorizontalVelocity(); - float secondsBetweenToggle = configuration.getRandomlyInvertedTimer(); + float secondsBetweenToggle = dropperConfiguration.getRandomlyInvertedTimer(); int seconds = Calendar.getInstance().get(Calendar.SECOND); /* diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index f8470e1..b138669 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,5 +1,10 @@ # Configuration values for mini-games parkour: + # Whether to enforce the order in which a player must reach checkpoints. Enabling this ensures that a player cannot + # trigger a previous checkpoint by accident. It also ensures players cannot skip a checkpoint, even if the arena + # layout makes it possible. + enforceCheckpointOrder: false + # Whether grouped dropper arenas must be played in the correct sequence mustDoGroupedInSequence: true