From 0704e138ecc6ec7c5d4ffab6a53d9ab33e8d7280 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 8 May 2023 18:14:37 +0200 Subject: [PATCH 01/13] Adds a command for returning to checkpoint by forcing a loss #28 --- README.md | 1 + .../net/knarcraft/minigames/MiniGames.java | 2 + .../parkour/ParkourCheckpointCommand.java | 44 +++++++++++++++++++ .../minigames/listener/CommandListener.java | 3 ++ src/main/resources/plugin.yml | 38 +++++++++------- 5 files changed, 72 insertions(+), 16 deletions(-) create mode 100644 src/main/java/net/knarcraft/minigames/command/parkour/ParkourCheckpointCommand.java diff --git a/README.md b/README.md index 8817a2e..bc4a93b 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ The only permission normal players will need is `minigames.join` which is set to | /parkourGroupSet | /pgset | \ \ | Puts the given arena in the given group. Use "none" to remove an existing group. | | /parkourGroupList | /pglist | \[group] | Lists groups, or the stages of a group if a group is specified. | | [/parkourGroupSwap](#droppergroupswap) | /pgswap | \ \ | Swaps the two arenas in the group's ordered list. | +| /parkourCheckpoint | /pcheck | | Triggers a teleportation to your previous checkpoint. | ### Command explanation dropper diff --git a/src/main/java/net/knarcraft/minigames/MiniGames.java b/src/main/java/net/knarcraft/minigames/MiniGames.java index c6ca215..4a8e36e 100644 --- a/src/main/java/net/knarcraft/minigames/MiniGames.java +++ b/src/main/java/net/knarcraft/minigames/MiniGames.java @@ -39,6 +39,7 @@ import net.knarcraft.minigames.command.parkour.EditParkourArenaTabCompleter; import net.knarcraft.minigames.command.parkour.JoinParkourArenaCommand; import net.knarcraft.minigames.command.parkour.JoinParkourArenaTabCompleter; import net.knarcraft.minigames.command.parkour.ListParkourArenaCommand; +import net.knarcraft.minigames.command.parkour.ParkourCheckpointCommand; import net.knarcraft.minigames.command.parkour.ParkourGroupListCommand; import net.knarcraft.minigames.command.parkour.ParkourGroupSetCommand; import net.knarcraft.minigames.command.parkour.ParkourGroupSwapCommand; @@ -267,6 +268,7 @@ public final class MiniGames extends JavaPlugin { registerCommand("parkourGroupSet", new ParkourGroupSetCommand(), null); registerCommand("parkourGroupSwap", new ParkourGroupSwapCommand(), null); registerCommand("parkourGroupList", new ParkourGroupListCommand(), null); + registerCommand("parkourCheckpoint", new ParkourCheckpointCommand(), null); if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { this.dropperRecordExpansion = new DropperRecordExpansion(this); diff --git a/src/main/java/net/knarcraft/minigames/command/parkour/ParkourCheckpointCommand.java b/src/main/java/net/knarcraft/minigames/command/parkour/ParkourCheckpointCommand.java new file mode 100644 index 0000000..335fb02 --- /dev/null +++ b/src/main/java/net/knarcraft/minigames/command/parkour/ParkourCheckpointCommand.java @@ -0,0 +1,44 @@ +package net.knarcraft.minigames.command.parkour; + +import net.knarcraft.minigames.MiniGames; +import net.knarcraft.minigames.arena.ArenaSession; +import net.knarcraft.minigames.arena.parkour.ParkourArenaSession; +import net.knarcraft.minigames.config.Message; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabExecutor; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +/** + * The command for returning to the previous checkpoint + */ +public class ParkourCheckpointCommand implements TabExecutor { + + @Override + public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, + @NotNull String[] strings) { + if (!(commandSender instanceof Player player)) { + commandSender.sendMessage(Message.ERROR_PLAYER_ONLY.getMessage()); + return false; + } + + ArenaSession session = MiniGames.getInstance().getSession(player.getUniqueId()); + if (session instanceof ParkourArenaSession) { + session.triggerLoss(); + } + return true; + } + + @Nullable + @Override + public List onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, + @NotNull String[] strings) { + return new ArrayList<>(); + } + +} diff --git a/src/main/java/net/knarcraft/minigames/listener/CommandListener.java b/src/main/java/net/knarcraft/minigames/listener/CommandListener.java index 112231d..44b0eed 100644 --- a/src/main/java/net/knarcraft/minigames/listener/CommandListener.java +++ b/src/main/java/net/knarcraft/minigames/listener/CommandListener.java @@ -29,6 +29,9 @@ public class CommandListener implements Listener { allowedCommands.add("/mLeave"); allowedCommands.add("/dLeave"); allowedCommands.add("/pLeave"); + allowedCommands.add("/parkourCheckpoint"); + allowedCommands.add("/pCheckpoint"); + allowedCommands.add("/pCheck"); String message = event.getMessage(); if (!message.startsWith("/")) { diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 8fbd03b..ed35ed8 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -20,13 +20,12 @@ commands: - mleave - dleave - pleave - permission: minigames.join usage: / description: Used to leave the current dropper arena dropperGroupSet: aliases: - dgset - permission: minigames.edit + permission: minigames.edit.dropper usage: | / - The group will be created if it doesn't already exist @@ -35,7 +34,7 @@ commands: dropperGroupSwap: aliases: - dgswap - permission: minigames.edit + permission: minigames.edit.dropper usage: | / - The two arenas must be in the same group @@ -43,7 +42,7 @@ commands: dropperGroupList: aliases: - dglist - permission: minigames.edit + permission: minigames.edit.dropper usage: | / [group] - Existing groups will be listed if used without an argument @@ -52,13 +51,13 @@ commands: dropperList: aliases: - dlist - permission: minigames.join + permission: minigames.join.dropper usage: / description: Used to list all current dropper arenas dropperJoin: aliases: - djoin - permission: minigames.join + permission: minigames.join.dropper usage: | / [mode] - Mode can be used to select challenge modes which can be played after beating the arena. @@ -68,7 +67,7 @@ commands: dropperCreate: aliases: - dcreate - permission: minigames.create + permission: minigames.create.dropper usage: | / [new value] - Valid properties: name, spawnLocation, exitLocation, verticalVelocity, horizontalVelocity, winBlockType @@ -76,13 +75,13 @@ commands: dropperEdit: aliases: - dedit - permission: minigames.edit + permission: minigames.edit.dropper usage: / (Details not finalized) description: Used to edit an existing dropper arena dropperRemove: aliases: - dremove - permission: minigames.remove + permission: minigames.remove.dropper usage: / description: Used to remove an existing dropper arena parkourGroupSet: @@ -97,7 +96,7 @@ commands: parkourGroupSwap: aliases: - pgswap - permission: minigames.edit + permission: minigames.edit.parkour usage: | / - The two arenas must be in the same group @@ -105,7 +104,7 @@ commands: parkourGroupList: aliases: - pglist - permission: minigames.edit + permission: minigames.edit.parkour usage: | / [group] - Existing groups will be listed if used without an argument @@ -114,13 +113,13 @@ commands: parkourList: aliases: - plist - permission: minigames.join + permission: minigames.join.parkour usage: / description: Used to list all current parkour arenas parkourJoin: aliases: - pjoin - permission: minigames.join + permission: minigames.join.parkour usage: | / [mode] - Mode can be used to select challenge modes which can be played after beating the arena. @@ -129,7 +128,7 @@ commands: parkourCreate: aliases: - pcreate - permission: minigames.create + permission: minigames.create.parkour usage: | / [new value] - Valid properties: name, spawnLocation, exitLocation, winBlockType, winLocation, checkpointAdd, checkpointClear, killPlaneBlocks @@ -137,15 +136,22 @@ commands: parkourEdit: aliases: - pedit - permission: minigames.edit + permission: minigames.edit.parkour usage: / (Details not finalized) description: Used to edit an existing parkour arena parkourRemove: aliases: - dremove - permission: minigames.remove + permission: minigames.remove.parkour usage: / description: Used to remove an existing parkour arena + parkourCheckpoint: + aliases: + - pcheckpoint + - pcheck + permission: minigames.join.parkour + usage: / + description: Used to teleport to the previous checkpoint while in a parkour arena permissions: minigames.*: description: Gives all permissions From 00ac0582f45c90f8c5a6254cbce8444456251cf9 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 9 May 2023 15:47:54 +0200 Subject: [PATCH 02/13] Adds a partially usable arena menu openable through a command --- README.md | 1 + pom.xml | 24 +++ .../net/knarcraft/minigames/MiniGames.java | 138 ++++++++++++------ .../minigames/arena/ArenaSession.java | 8 + .../arena/dropper/DropperArenaSession.java | 9 ++ .../arena/parkour/ParkourArenaSession.java | 9 ++ .../minigames/command/MenuCommand.java | 46 ++++++ .../net/knarcraft/minigames/gui/ArenaGUI.java | 96 ++++++++++++ .../knarcraft/minigames/gui/DropperGUI.java | 19 +++ .../knarcraft/minigames/gui/ParkourGUI.java | 58 ++++++++ .../minigames/listener/CommandListener.java | 2 + src/main/resources/plugin.yml | 5 + 12 files changed, 371 insertions(+), 44 deletions(-) create mode 100644 src/main/java/net/knarcraft/minigames/command/MenuCommand.java create mode 100644 src/main/java/net/knarcraft/minigames/gui/ArenaGUI.java create mode 100644 src/main/java/net/knarcraft/minigames/gui/DropperGUI.java create mode 100644 src/main/java/net/knarcraft/minigames/gui/ParkourGUI.java diff --git a/README.md b/README.md index bc4a93b..bc284d5 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ The only permission normal players will need is `minigames.join` which is set to |----------------------------------------|----------|-----------------------------|-------------------------------------------------------------------------------------| | /miniGamesReload | /mreload | | Reloads all data from disk. | | /miniGamesLeave | /mleave | | Leaves the current mini-game. | +| /miniGamesMenu | /mmenu | | Shows a menu of actions if used while in an arena | | /dropperList | /dlist | | Lists available dropper arenas. | | [/dropperJoin](#dropperjoin) | /djoin | \ \[mode] | Joins the selected arena. | | /dropperCreate | /dcreate | \ | Creates a new dropper arena with the given name. The spawn is set to your location. | diff --git a/pom.xml b/pom.xml index 6565d30..bc3dac7 100644 --- a/pom.xml +++ b/pom.xml @@ -40,6 +40,20 @@ false + + + net.knarcraft:knargui + + net/knarcraft/knargui/** + + + + + *.MF + *.yml + + + @@ -62,6 +76,10 @@ placeholderapi https://repo.extendedclip.com/content/repositories/placeholderapi/ + + knarcraft-repo + https://git.knarcraft.net/api/packages/EpicKnarvik97/maven + @@ -89,5 +107,11 @@ 2.10.0 provided + + net.knarcraft + knargui + 1.0-SNAPSHOT + compile + diff --git a/src/main/java/net/knarcraft/minigames/MiniGames.java b/src/main/java/net/knarcraft/minigames/MiniGames.java index 4a8e36e..a4ac1c4 100644 --- a/src/main/java/net/knarcraft/minigames/MiniGames.java +++ b/src/main/java/net/knarcraft/minigames/MiniGames.java @@ -1,5 +1,6 @@ package net.knarcraft.minigames; +import net.knarcraft.knargui.GUIListener; import net.knarcraft.minigames.arena.ArenaPlayerRegistry; import net.knarcraft.minigames.arena.ArenaSession; import net.knarcraft.minigames.arena.dropper.DropperArena; @@ -21,6 +22,7 @@ import net.knarcraft.minigames.arena.parkour.ParkourPlayerEntryState; import net.knarcraft.minigames.arena.record.IntegerRecord; import net.knarcraft.minigames.arena.record.LongRecord; import net.knarcraft.minigames.command.LeaveArenaCommand; +import net.knarcraft.minigames.command.MenuCommand; import net.knarcraft.minigames.command.ReloadCommand; import net.knarcraft.minigames.command.dropper.CreateDropperArenaCommand; import net.knarcraft.minigames.command.dropper.DropperGroupListCommand; @@ -228,6 +230,51 @@ public final class MiniGames extends JavaPlugin { public void onEnable() { // Plugin startup logic instance = this; + + // Load configuration + loadConfiguration(); + + // Register all listeners + registerListeners(); + + // Register all commands + registerCommands(); + + // Integrate with other plugins + doPluginIntegration(); + } + + @Override + public void onDisable() { + // Kill all sessions before exiting + for (DropperArena arena : dropperArenaHandler.getArenas().values()) { + dropperArenaPlayerRegistry.removeForArena(arena, true); + } + for (ParkourArena arena : parkourArenaHandler.getArenas().values()) { + parkourArenaPlayerRegistry.removeForArena(arena, true); + } + } + + /** + * Sets up integration with third-party plugins + */ + private void doPluginIntegration() { + if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { + this.dropperRecordExpansion = new DropperRecordExpansion(this); + if (!this.dropperRecordExpansion.register()) { + log(Level.WARNING, "Unable to register PlaceholderAPI dropper expansion!"); + } + this.parkourRecordExpansion = new ParkourRecordExpansion(this); + if (!this.parkourRecordExpansion.register()) { + log(Level.WARNING, "Unable to register PlaceholderAPI parkour expansion!"); + } + } + } + + /** + * Loads all configuration values used by this plugin + */ + private void loadConfiguration() { this.saveDefaultConfig(); getConfig().options().copyDefaults(true); saveConfig(); @@ -241,56 +288,18 @@ public final class MiniGames extends JavaPlugin { this.parkourArenaPlayerRegistry = new ParkourArenaPlayerRegistry(); this.parkourArenaHandler = new ParkourArenaHandler(this.parkourArenaPlayerRegistry); this.parkourArenaHandler.load(); + } + /** + * Registers all listeners used by this plugin + */ + private void registerListeners() { PluginManager pluginManager = getServer().getPluginManager(); pluginManager.registerEvents(new DamageListener(), this); pluginManager.registerEvents(new MoveListener(this.dropperConfiguration, this.parkourConfiguration), this); pluginManager.registerEvents(new PlayerStateChangeListener(), this); pluginManager.registerEvents(new CommandListener(), this); - - registerCommand("miniGamesReload", new ReloadCommand(), null); - registerCommand("miniGamesLeave", new LeaveArenaCommand(), null); - - registerCommand("dropperCreate", new CreateDropperArenaCommand(), null); - registerCommand("dropperList", new ListDropperArenaCommand(), null); - registerCommand("dropperJoin", new JoinDropperArenaCommand(), new JoinDropperArenaTabCompleter()); - registerCommand("dropperEdit", new EditDropperArenaCommand(this.dropperConfiguration), new EditDropperArenaTabCompleter()); - registerCommand("dropperRemove", new RemoveDropperArenaCommand(), new RemoveDropperArenaTabCompleter()); - registerCommand("dropperGroupSet", new DropperGroupSetCommand(), null); - registerCommand("dropperGroupSwap", new DropperGroupSwapCommand(), null); - registerCommand("dropperGroupList", new DropperGroupListCommand(), null); - - registerCommand("parkourCreate", new CreateParkourArenaCommand(), null); - registerCommand("parkourList", new ListParkourArenaCommand(), null); - registerCommand("parkourJoin", new JoinParkourArenaCommand(), new JoinParkourArenaTabCompleter()); - registerCommand("parkourEdit", new EditParkourArenaCommand(), new EditParkourArenaTabCompleter()); - registerCommand("parkourRemove", new RemoveParkourArenaCommand(), new RemoveParkourArenaTabCompleter()); - registerCommand("parkourGroupSet", new ParkourGroupSetCommand(), null); - registerCommand("parkourGroupSwap", new ParkourGroupSwapCommand(), null); - registerCommand("parkourGroupList", new ParkourGroupListCommand(), null); - registerCommand("parkourCheckpoint", new ParkourCheckpointCommand(), null); - - if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { - this.dropperRecordExpansion = new DropperRecordExpansion(this); - if (!this.dropperRecordExpansion.register()) { - log(Level.WARNING, "Unable to register PlaceholderAPI dropper expansion!"); - } - this.parkourRecordExpansion = new ParkourRecordExpansion(this); - if (!this.parkourRecordExpansion.register()) { - log(Level.WARNING, "Unable to register PlaceholderAPI parkour expansion!"); - } - } - } - - @Override - public void onDisable() { - // Kill all sessions before exiting - for (DropperArena arena : dropperArenaHandler.getArenas().values()) { - dropperArenaPlayerRegistry.removeForArena(arena, true); - } - for (ParkourArena arena : parkourArenaHandler.getArenas().values()) { - parkourArenaPlayerRegistry.removeForArena(arena, true); - } + pluginManager.registerEvents(new GUIListener(false), this); } /** @@ -313,4 +322,45 @@ public final class MiniGames extends JavaPlugin { } } + /** + * Registers all commands used by this plugin + */ + private void registerCommands() { + registerCommand("miniGamesReload", new ReloadCommand(), null); + registerCommand("miniGamesLeave", new LeaveArenaCommand(), null); + registerCommand("miniGamesMenu", new MenuCommand(), null); + + registerDropperCommands(); + registerParkourCommands(); + } + + /** + * Registers all commands related to droppers + */ + private void registerDropperCommands() { + registerCommand("dropperCreate", new CreateDropperArenaCommand(), null); + registerCommand("dropperList", new ListDropperArenaCommand(), null); + registerCommand("dropperJoin", new JoinDropperArenaCommand(), new JoinDropperArenaTabCompleter()); + registerCommand("dropperEdit", new EditDropperArenaCommand(this.dropperConfiguration), new EditDropperArenaTabCompleter()); + registerCommand("dropperRemove", new RemoveDropperArenaCommand(), new RemoveDropperArenaTabCompleter()); + registerCommand("dropperGroupSet", new DropperGroupSetCommand(), null); + registerCommand("dropperGroupSwap", new DropperGroupSwapCommand(), null); + registerCommand("dropperGroupList", new DropperGroupListCommand(), null); + } + + /** + * Registers all commands related to parkour + */ + private void registerParkourCommands() { + registerCommand("parkourCreate", new CreateParkourArenaCommand(), null); + registerCommand("parkourList", new ListParkourArenaCommand(), null); + registerCommand("parkourJoin", new JoinParkourArenaCommand(), new JoinParkourArenaTabCompleter()); + registerCommand("parkourEdit", new EditParkourArenaCommand(), new EditParkourArenaTabCompleter()); + registerCommand("parkourRemove", new RemoveParkourArenaCommand(), new RemoveParkourArenaTabCompleter()); + registerCommand("parkourGroupSet", new ParkourGroupSetCommand(), null); + registerCommand("parkourGroupSwap", new ParkourGroupSwapCommand(), null); + registerCommand("parkourGroupList", new ParkourGroupListCommand(), null); + registerCommand("parkourCheckpoint", new ParkourCheckpointCommand(), null); + } + } diff --git a/src/main/java/net/knarcraft/minigames/arena/ArenaSession.java b/src/main/java/net/knarcraft/minigames/arena/ArenaSession.java index f1afd43..d3a3595 100644 --- a/src/main/java/net/knarcraft/minigames/arena/ArenaSession.java +++ b/src/main/java/net/knarcraft/minigames/arena/ArenaSession.java @@ -1,5 +1,6 @@ package net.knarcraft.minigames.arena; +import net.knarcraft.minigames.gui.ArenaGUI; import org.jetbrains.annotations.NotNull; /** @@ -38,4 +39,11 @@ public interface ArenaSession { */ @NotNull Arena getArena(); + /** + * Gets the GUI with this arena's options + * + * @return

This arena's GUI

+ */ + @NotNull ArenaGUI getGUI(); + } 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 9d995b5..b5f33ec 100644 --- a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaSession.java +++ b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaSession.java @@ -5,6 +5,8 @@ import net.knarcraft.minigames.arena.AbstractArenaSession; import net.knarcraft.minigames.arena.PlayerEntryState; import net.knarcraft.minigames.config.DropperConfiguration; import net.knarcraft.minigames.config.Message; +import net.knarcraft.minigames.gui.ArenaGUI; +import net.knarcraft.minigames.gui.DropperGUI; import net.knarcraft.minigames.util.PlayerTeleporter; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; @@ -16,6 +18,8 @@ import java.util.logging.Level; */ public class DropperArenaSession extends AbstractArenaSession { + private static final ArenaGUI gui = new DropperGUI(); + private final @NotNull DropperArena arena; private final @NotNull Player player; private final @NotNull DropperArenaGameMode gameMode; @@ -101,6 +105,11 @@ public class DropperArenaSession extends AbstractArenaSession { return this.arena; } + @Override + public @NotNull ArenaGUI getGUI() { + return gui; + } + @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/arena/parkour/ParkourArenaSession.java b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaSession.java index 74be9f5..8cfe823 100644 --- a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaSession.java +++ b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaSession.java @@ -5,6 +5,8 @@ import net.knarcraft.minigames.arena.AbstractArenaSession; import net.knarcraft.minigames.arena.PlayerEntryState; import net.knarcraft.minigames.config.Message; import net.knarcraft.minigames.config.ParkourConfiguration; +import net.knarcraft.minigames.gui.ArenaGUI; +import net.knarcraft.minigames.gui.ParkourGUI; import net.knarcraft.minigames.util.PlayerTeleporter; import org.bukkit.Location; import org.bukkit.entity.Player; @@ -18,6 +20,8 @@ import java.util.logging.Level; */ public class ParkourArenaSession extends AbstractArenaSession { + private static final ArenaGUI gui = new ParkourGUI(); + private final @NotNull ParkourArena arena; private final @NotNull Player player; private final @NotNull ParkourArenaGameMode gameMode; @@ -112,6 +116,11 @@ public class ParkourArenaSession extends AbstractArenaSession { return this.arena; } + @Override + public @NotNull ArenaGUI getGUI() { + return gui; + } + @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/command/MenuCommand.java b/src/main/java/net/knarcraft/minigames/command/MenuCommand.java new file mode 100644 index 0000000..ca97c3e --- /dev/null +++ b/src/main/java/net/knarcraft/minigames/command/MenuCommand.java @@ -0,0 +1,46 @@ +package net.knarcraft.minigames.command; + +import net.knarcraft.minigames.MiniGames; +import net.knarcraft.minigames.arena.ArenaSession; +import net.knarcraft.minigames.config.Message; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabExecutor; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +/** + * The command for opening up an arena's menu + */ +public class MenuCommand implements TabExecutor { + + @Override + public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, + @NotNull String[] arguments) { + if (!(commandSender instanceof Player player)) { + commandSender.sendMessage(Message.ERROR_PLAYER_ONLY.getMessage()); + return false; + } + + ArenaSession existingSession = MiniGames.getInstance().getSession(player.getUniqueId()); + if (existingSession == null) { + commandSender.sendMessage(Message.ERROR_NOT_IN_ARENA.getMessage()); + return false; + } + + existingSession.getGUI().openFor(player); + return true; + } + + @Nullable + @Override + public List onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, + @NotNull String[] strings) { + return new ArrayList<>(); + } + +} diff --git a/src/main/java/net/knarcraft/minigames/gui/ArenaGUI.java b/src/main/java/net/knarcraft/minigames/gui/ArenaGUI.java new file mode 100644 index 0000000..b0c7ab9 --- /dev/null +++ b/src/main/java/net/knarcraft/minigames/gui/ArenaGUI.java @@ -0,0 +1,96 @@ +package net.knarcraft.minigames.gui; + +import net.knarcraft.knargui.AbstractGUI; +import net.knarcraft.knargui.GUIAction; +import net.knarcraft.knargui.item.GUIItemFactory; +import net.knarcraft.minigames.MiniGames; +import net.knarcraft.minigames.arena.ArenaSession; +import net.md_5.bungee.api.ChatColor; +import org.bukkit.Material; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + +import java.util.ArrayList; +import java.util.List; + +/** + * A generic GUI for all arenas + */ +public abstract class ArenaGUI extends AbstractGUI { + + /** + * Instantiates a new arena gui + * + * @param inventorySize

The size of the GUI's inventory

+ * @param inventoryName

The name of the inventory

+ */ + public ArenaGUI(int inventorySize, String inventoryName) { + super(inventorySize, inventoryName, null); + } + + /** + * Gets an item describing player visibility toggling + * + * @return

A player toggle item

+ */ + protected ItemStack getTogglePlayersItem() { + GUIItemFactory togglePlayersItemFactory = new GUIItemFactory(Material.PLAYER_HEAD); + List loreLines = getLoreLines(); + loreLines.add(ChatColor.GRAY + "Use this item to toggle the visibility"); + loreLines.add(ChatColor.GRAY + "of other players"); + togglePlayersItemFactory.setName(ChatColor.BLUE + "Toggle Players"); + togglePlayersItemFactory.setLore(loreLines); + return togglePlayersItemFactory.build(); + } + + /** + * Gets an item describing a leave arena action + * + * @return

A leave item

+ */ + protected ItemStack getLeaveItem() { + GUIItemFactory leaveItemFactory = new GUIItemFactory(Material.BARRIER); + List loreLines = getLoreLines(); + loreLines.add(ChatColor.GRAY + "Use this item to leave the arena"); + leaveItemFactory.setName(ChatColor.DARK_RED + "Leave"); + leaveItemFactory.setLore(loreLines); + return leaveItemFactory.build(); + } + + /** + * Gets an arraylist with one blank line lore-lines can be added to + * + * @return

An arraylist with one blank line

+ */ + protected List getLoreLines() { + List loreLines = new ArrayList<>(); + loreLines.add(""); + return loreLines; + } + + /** + * Sets a click action for both right-click and left-click + * + * @param inventorySlot

The inventory slot the action should be added to

+ * @param action

The action to register

+ */ + protected void setAnyClickAction(int inventorySlot, GUIAction action) { + setClickAction(inventorySlot, ClickType.LEFT, action); + setClickAction(inventorySlot, ClickType.RIGHT, action); + } + + /** + * Gets the action to run when triggering the leave item + * + * @return

The leave action

+ */ + protected GUIAction getLeaveAction() { + return (player) -> { + ArenaSession session = MiniGames.getInstance().getSession(player.getUniqueId()); + if (session != null) { + session.triggerQuit(false); + } + }; + } + +} diff --git a/src/main/java/net/knarcraft/minigames/gui/DropperGUI.java b/src/main/java/net/knarcraft/minigames/gui/DropperGUI.java new file mode 100644 index 0000000..a7e4986 --- /dev/null +++ b/src/main/java/net/knarcraft/minigames/gui/DropperGUI.java @@ -0,0 +1,19 @@ +package net.knarcraft.minigames.gui; + +/** + * A GUI used in the dropper arena + */ +public class DropperGUI extends ArenaGUI { + + /** + * Instantiates a new dropper gui + */ + public DropperGUI() { + super(9, "Dropper"); + setItem(0, getTogglePlayersItem()); + setItem(2, getLeaveItem()); + + setAnyClickAction(2, getLeaveAction()); + } + +} diff --git a/src/main/java/net/knarcraft/minigames/gui/ParkourGUI.java b/src/main/java/net/knarcraft/minigames/gui/ParkourGUI.java new file mode 100644 index 0000000..eb6a263 --- /dev/null +++ b/src/main/java/net/knarcraft/minigames/gui/ParkourGUI.java @@ -0,0 +1,58 @@ +package net.knarcraft.minigames.gui; + +import net.knarcraft.knargui.GUIAction; +import net.knarcraft.knargui.item.GUIItemFactory; +import net.knarcraft.minigames.MiniGames; +import net.knarcraft.minigames.arena.ArenaSession; +import net.knarcraft.minigames.arena.parkour.ParkourArenaSession; +import net.md_5.bungee.api.ChatColor; +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +import java.util.List; + +/** + * A GUI used in the parkour arena + */ +public class ParkourGUI extends ArenaGUI { + + public ParkourGUI() { + super(9, "Parkour"); + setItem(0, getTogglePlayersItem()); + setItem(2, getGiveUpItem()); + setItem(4, getLeaveItem()); + + setAnyClickAction(2, getGiveUpAction()); + setAnyClickAction(4, getLeaveAction()); + } + + /** + * Gets an item describing a give up action + * + * @return

A give up item

+ */ + private ItemStack getGiveUpItem() { + GUIItemFactory giveUpItemFactory = new GUIItemFactory(Material.SKELETON_SKULL); + List loreLines = getLoreLines(); + loreLines.add(ChatColor.GRAY + "Use this item to give up"); + loreLines.add(ChatColor.GRAY + "and go to the last checkpoint"); + giveUpItemFactory.setName(ChatColor.RED + "Give up"); + giveUpItemFactory.setLore(loreLines); + return giveUpItemFactory.build(); + } + + /** + * Gets the action to run when triggering the give up item + * + * @return

The give up action

+ */ + private GUIAction getGiveUpAction() { + return (player) -> { + ArenaSession session = MiniGames.getInstance().getSession(player.getUniqueId()); + if (session instanceof ParkourArenaSession) { + session.triggerLoss(); + } + }; + } + +} diff --git a/src/main/java/net/knarcraft/minigames/listener/CommandListener.java b/src/main/java/net/knarcraft/minigames/listener/CommandListener.java index 44b0eed..c05f2b6 100644 --- a/src/main/java/net/knarcraft/minigames/listener/CommandListener.java +++ b/src/main/java/net/knarcraft/minigames/listener/CommandListener.java @@ -32,6 +32,8 @@ public class CommandListener implements Listener { allowedCommands.add("/parkourCheckpoint"); allowedCommands.add("/pCheckpoint"); allowedCommands.add("/pCheck"); + allowedCommands.add("/miniGamesMenu"); + allowedCommands.add("/mMenu"); String message = event.getMessage(); if (!message.startsWith("/")) { diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index ed35ed8..54f37a5 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -22,6 +22,11 @@ commands: - pleave usage: / description: Used to leave the current dropper arena + miniGamesMenu: + aliases: + - mmenu + usage: / + description: Used to display an actions menu while in an arena dropperGroupSet: aliases: - dgset From 7848a0a028fbe479613416b0617c7758e93e3e4b Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 10 May 2023 15:14:28 +0200 Subject: [PATCH 03/13] Implements #27 among other things It was found that the Spigot API's methods for cancelling player collisions won't work without changing the scoreboard. Because of that, the normal option has been disabled. The invisibility option has also been removed, as that's a bad idea if players can still push each-other. The toggle player option which is implemented in this commit does disable player collision, so that's the only working way right now. A potential ConcurrentModificationException has been fixed. The parkourCheckpoint command has been removed, as the functionality is now available through the API. --- README.md | 4 - .../net/knarcraft/minigames/MiniGames.java | 14 ++- .../arena/AbstractArenaPlayerRegistry.java | 11 ++- .../minigames/arena/AbstractArenaSession.java | 9 +- .../arena/AbstractPlayerEntryState.java | 38 +------- .../minigames/arena/ArenaPlayerRegistry.java | 8 ++ .../minigames/arena/ArenaSession.java | 5 +- .../arena/PlayerVisibilityManager.java | 95 +++++++++++++++++++ .../arena/dropper/DropperArenaSession.java | 7 +- .../dropper/DropperPlayerEntryState.java | 35 +++---- .../arena/parkour/ParkourArenaSession.java | 5 +- .../parkour/ParkourPlayerEntryState.java | 23 ++--- .../minigames/command/LeaveArenaCommand.java | 2 +- .../dropper/JoinDropperArenaCommand.java | 4 +- .../parkour/JoinParkourArenaCommand.java | 4 +- .../parkour/ParkourCheckpointCommand.java | 44 --------- .../config/DropperConfiguration.java | 24 ----- .../config/ParkourConfiguration.java | 12 --- .../net/knarcraft/minigames/gui/ArenaGUI.java | 23 ++++- .../knarcraft/minigames/gui/DropperGUI.java | 5 +- .../knarcraft/minigames/gui/ParkourGUI.java | 5 +- .../minigames/listener/CommandListener.java | 3 - src/main/resources/plugin.yml | 7 -- 23 files changed, 193 insertions(+), 194 deletions(-) create mode 100644 src/main/java/net/knarcraft/minigames/arena/PlayerVisibilityManager.java delete mode 100644 src/main/java/net/knarcraft/minigames/command/parkour/ParkourCheckpointCommand.java diff --git a/README.md b/README.md index bc284d5..2f525e2 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,6 @@ The only permission normal players will need is `minigames.join` which is set to | /parkourGroupSet | /pgset | \ \ | Puts the given arena in the given group. Use "none" to remove an existing group. | | /parkourGroupList | /pglist | \[group] | Lists groups, or the stages of a group if a group is specified. | | [/parkourGroupSwap](#droppergroupswap) | /pgswap | \ \ | Swaps the two arenas in the group's ordered list. | -| /parkourCheckpoint | /pcheck | | Triggers a teleportation to your previous checkpoint. | ### Command explanation dropper @@ -187,8 +186,6 @@ These are all the options that can be changed for an arena. | 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. | | mustDoNormalModeFirst | true/false | true | Whether a player must do the normal/default game-mode before playing any other game-modes | -| makePlayersInvisible | true/false | false | Whether players should be made invisible while playing in a dropper arena | -| disableHitCollision | true/false | true | Whether players should have their entity hit collision disabled while in an arena. This prevents players from pushing each-other if in the same arena. | | liquidHitBoxDepth | -1 < decimal < 0 | -0.8 | This decides how far inside a non-solid block the player must go before detection triggers (-1, 0). The closer to -1 it is, the more accurate it will seem to the player, but the likelihood of not detecting the hit increases. | | solidHitBoxDistance | 0 < decimal < 1 | 0.2 | This decides the distance the player must be from a block below them before a hit triggers (0, 1). If too low, the likelihood of detecting the hit decreases, but it won't look like the player hit the block without being near. | | blockWhitelist | list | [see this](#blockwhitelist-default) | A whitelist for which blocks won't trigger a loss when hit/passed through. The win block check happens before the loss check, so even blocks on the whitelist can be used as the win-block. "+" denotes a [material tag](#notes-about-material-tags). | @@ -200,7 +197,6 @@ These are all the options that can be changed for an arena. | 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 [material tags](#notes-about-material-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 a4ac1c4..b3cf612 100644 --- a/src/main/java/net/knarcraft/minigames/MiniGames.java +++ b/src/main/java/net/knarcraft/minigames/MiniGames.java @@ -3,6 +3,7 @@ package net.knarcraft.minigames; import net.knarcraft.knargui.GUIListener; import net.knarcraft.minigames.arena.ArenaPlayerRegistry; import net.knarcraft.minigames.arena.ArenaSession; +import net.knarcraft.minigames.arena.PlayerVisibilityManager; import net.knarcraft.minigames.arena.dropper.DropperArena; import net.knarcraft.minigames.arena.dropper.DropperArenaData; import net.knarcraft.minigames.arena.dropper.DropperArenaGameMode; @@ -41,7 +42,6 @@ import net.knarcraft.minigames.command.parkour.EditParkourArenaTabCompleter; import net.knarcraft.minigames.command.parkour.JoinParkourArenaCommand; import net.knarcraft.minigames.command.parkour.JoinParkourArenaTabCompleter; import net.knarcraft.minigames.command.parkour.ListParkourArenaCommand; -import net.knarcraft.minigames.command.parkour.ParkourCheckpointCommand; import net.knarcraft.minigames.command.parkour.ParkourGroupListCommand; import net.knarcraft.minigames.command.parkour.ParkourGroupSetCommand; import net.knarcraft.minigames.command.parkour.ParkourGroupSwapCommand; @@ -87,6 +87,7 @@ public final class MiniGames extends JavaPlugin { private ParkourRecordExpansion parkourRecordExpansion; private ParkourArenaHandler parkourArenaHandler; private ArenaPlayerRegistry parkourArenaPlayerRegistry; + private PlayerVisibilityManager playerVisibilityManager; /** * Gets an instance of this plugin @@ -162,6 +163,15 @@ public final class MiniGames extends JavaPlugin { return this.parkourConfiguration; } + /** + * Gets the manager keeping track of player visibility + * + * @return

The player visibility manager

+ */ + public PlayerVisibilityManager getPlayerVisibilityManager() { + return this.playerVisibilityManager; + } + /** * Gets the current session of the given player * @@ -288,6 +298,7 @@ public final class MiniGames extends JavaPlugin { this.parkourArenaPlayerRegistry = new ParkourArenaPlayerRegistry(); this.parkourArenaHandler = new ParkourArenaHandler(this.parkourArenaPlayerRegistry); this.parkourArenaHandler.load(); + this.playerVisibilityManager = new PlayerVisibilityManager(); } /** @@ -360,7 +371,6 @@ public final class MiniGames extends JavaPlugin { registerCommand("parkourGroupSet", new ParkourGroupSetCommand(), null); registerCommand("parkourGroupSwap", new ParkourGroupSwapCommand(), null); registerCommand("parkourGroupList", new ParkourGroupListCommand(), null); - registerCommand("parkourCheckpoint", new ParkourCheckpointCommand(), null); } } diff --git a/src/main/java/net/knarcraft/minigames/arena/AbstractArenaPlayerRegistry.java b/src/main/java/net/knarcraft/minigames/arena/AbstractArenaPlayerRegistry.java index c9b17d7..405cb76 100644 --- a/src/main/java/net/knarcraft/minigames/arena/AbstractArenaPlayerRegistry.java +++ b/src/main/java/net/knarcraft/minigames/arena/AbstractArenaPlayerRegistry.java @@ -29,6 +29,11 @@ public abstract class AbstractArenaPlayerRegistry implements Ar loadEntryStates(); } + @Override + public @NotNull Set getPlayingPlayers() { + return arenaPlayers.keySet(); + } + @Override public @Nullable PlayerEntryState getEntryState(@NotNull UUID playerId) { return this.entryStates.get(playerId); @@ -65,13 +70,15 @@ public abstract class AbstractArenaPlayerRegistry implements Ar @Override public void removeForArena(K arena, boolean immediately) { + Set removed = new HashSet<>(); for (Map.Entry entry : this.arenaPlayers.entrySet()) { if (entry.getValue().getArena() == arena) { // Kick the player gracefully - entry.getValue().triggerQuit(immediately); - this.arenaPlayers.remove(entry.getKey()); + entry.getValue().triggerQuit(immediately, false); + removed.add(entry.getKey()); } } + removed.forEach(this.arenaPlayers::remove); } /** diff --git a/src/main/java/net/knarcraft/minigames/arena/AbstractArenaSession.java b/src/main/java/net/knarcraft/minigames/arena/AbstractArenaSession.java index 79cff03..c298e04 100644 --- a/src/main/java/net/knarcraft/minigames/arena/AbstractArenaSession.java +++ b/src/main/java/net/knarcraft/minigames/arena/AbstractArenaSession.java @@ -1,5 +1,6 @@ package net.knarcraft.minigames.arena; +import net.knarcraft.minigames.MiniGames; import net.knarcraft.minigames.config.Message; import net.knarcraft.minigames.container.PlaceholderContainer; import net.knarcraft.minigames.property.RecordResult; @@ -33,11 +34,15 @@ public abstract class AbstractArenaSession implements ArenaSession { } @Override - public void triggerQuit(boolean immediately) { + public void triggerQuit(boolean immediately, boolean removeSession) { // Stop this session - removeSession(); + if (removeSession) { + removeSession(); + } // Teleport the player out of the arena teleportToExit(immediately); + // Make the player visible to everyone + MiniGames.getInstance().getPlayerVisibilityManager().showPlayersFor(player); player.sendMessage(Message.SUCCESS_ARENA_QUIT.getMessage()); } diff --git a/src/main/java/net/knarcraft/minigames/arena/AbstractPlayerEntryState.java b/src/main/java/net/knarcraft/minigames/arena/AbstractPlayerEntryState.java index d1bf53b..0823387 100644 --- a/src/main/java/net/knarcraft/minigames/arena/AbstractPlayerEntryState.java +++ b/src/main/java/net/knarcraft/minigames/arena/AbstractPlayerEntryState.java @@ -6,8 +6,6 @@ import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.entity.Player; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; import org.jetbrains.annotations.NotNull; import java.util.HashMap; @@ -21,59 +19,49 @@ import java.util.logging.Level; public abstract class AbstractPlayerEntryState implements PlayerEntryState { protected final UUID playerId; - private final boolean makePlayerInvisible; private final Location entryLocation; private final boolean originalIsFlying; private final GameMode originalGameMode; private final boolean originalAllowFlight; private final boolean originalInvulnerable; private final boolean originalIsSwimming; - private final boolean originalCollideAble; /** * Instantiates a new abstract player entry state * - * @param player

The player whose state this should keep track of

- * @param makePlayerInvisible

Whether players should be made invisible while in the arena

+ * @param player

The player whose state this should keep track of

*/ - public AbstractPlayerEntryState(@NotNull Player player, boolean makePlayerInvisible) { + public AbstractPlayerEntryState(@NotNull Player player) { this.playerId = player.getUniqueId(); - this.makePlayerInvisible = makePlayerInvisible; this.entryLocation = player.getLocation().clone(); this.originalIsFlying = player.isFlying(); this.originalGameMode = player.getGameMode(); this.originalAllowFlight = player.getAllowFlight(); this.originalInvulnerable = player.isInvulnerable(); this.originalIsSwimming = player.isSwimming(); - this.originalCollideAble = player.isCollidable(); } /** * Instantiates a new abstract player entry state * * @param playerId

The id of the player whose state this should keep track of

- * @param makePlayerInvisible

Whether players should be made invisible while in the arena

* @param entryLocation

The location the player entered from

* @param originalIsFlying

Whether the player was flying before entering the arena

* @param originalGameMode

The game-mode of the player before entering the arena

* @param originalAllowFlight

Whether the player was allowed flight before entering the arena

* @param originalInvulnerable

Whether the player was invulnerable before entering the arena

* @param originalIsSwimming

Whether the player was swimming before entering the arena

- * @param originalCollideAble

Whether the player was collide-able before entering the arena

*/ - public AbstractPlayerEntryState(@NotNull UUID playerId, boolean makePlayerInvisible, Location entryLocation, + public AbstractPlayerEntryState(@NotNull UUID playerId, Location entryLocation, boolean originalIsFlying, GameMode originalGameMode, boolean originalAllowFlight, - boolean originalInvulnerable, boolean originalIsSwimming, - boolean originalCollideAble) { + boolean originalInvulnerable, boolean originalIsSwimming) { this.playerId = playerId; - this.makePlayerInvisible = makePlayerInvisible; this.entryLocation = entryLocation; this.originalIsFlying = originalIsFlying; this.originalGameMode = originalGameMode; this.originalAllowFlight = originalAllowFlight; this.originalInvulnerable = originalInvulnerable; this.originalIsSwimming = originalIsSwimming; - this.originalCollideAble = originalCollideAble; } @Override @@ -81,18 +69,6 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState { return this.playerId; } - @Override - public void setArenaState() { - Player player = getPlayer(); - if (player == null) { - return; - } - if (this.makePlayerInvisible) { - player.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY, - PotionEffect.INFINITE_DURATION, 3)); - } - } - @Override public boolean restore() { Player player = getPlayer(); @@ -110,10 +86,6 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState { player.setAllowFlight(this.originalAllowFlight); player.setInvulnerable(this.originalInvulnerable); player.setSwimming(this.originalIsSwimming); - player.setCollidable(this.originalCollideAble); - if (this.makePlayerInvisible) { - player.removePotionEffect(PotionEffectType.INVISIBILITY); - } } @Override @@ -140,14 +112,12 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState { public Map serialize() { Map data = new HashMap<>(); data.put("playerId", new SerializableUUID(this.playerId)); - data.put("makePlayerInvisible", this.makePlayerInvisible); data.put("entryLocation", this.entryLocation); data.put("originalIsFlying", this.originalIsFlying); data.put("originalGameMode", this.originalGameMode.name()); data.put("originalAllowFlight", this.originalAllowFlight); data.put("originalInvulnerable", this.originalInvulnerable); data.put("originalIsSwimming", this.originalIsSwimming); - data.put("originalCollideAble", this.originalCollideAble); return data; } diff --git a/src/main/java/net/knarcraft/minigames/arena/ArenaPlayerRegistry.java b/src/main/java/net/knarcraft/minigames/arena/ArenaPlayerRegistry.java index cb10111..20f0db2 100644 --- a/src/main/java/net/knarcraft/minigames/arena/ArenaPlayerRegistry.java +++ b/src/main/java/net/knarcraft/minigames/arena/ArenaPlayerRegistry.java @@ -3,6 +3,7 @@ package net.knarcraft.minigames.arena; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Set; import java.util.UUID; /** @@ -12,6 +13,13 @@ import java.util.UUID; */ public interface ArenaPlayerRegistry { + /** + * Gets the ids of the players currently playing + * + * @return

The ids of the playing players

+ */ + @NotNull Set getPlayingPlayers(); + /** * Gets the current entry state for the given player * diff --git a/src/main/java/net/knarcraft/minigames/arena/ArenaSession.java b/src/main/java/net/knarcraft/minigames/arena/ArenaSession.java index d3a3595..22737bb 100644 --- a/src/main/java/net/knarcraft/minigames/arena/ArenaSession.java +++ b/src/main/java/net/knarcraft/minigames/arena/ArenaSession.java @@ -28,9 +28,10 @@ public interface ArenaSession { /** * Triggers a quit for the player playing in this session * - * @param immediately

Whether to to the teleportation immediately, not using any timers

+ * @param immediately

Whether to to the teleportation immediately, not using any timers

+ * @param removeSession

Whether to also remove the session. Should usually be true.

*/ - void triggerQuit(boolean immediately); + void triggerQuit(boolean immediately, boolean removeSession); /** * Gets the arena this session is being played in diff --git a/src/main/java/net/knarcraft/minigames/arena/PlayerVisibilityManager.java b/src/main/java/net/knarcraft/minigames/arena/PlayerVisibilityManager.java new file mode 100644 index 0000000..69c6c97 --- /dev/null +++ b/src/main/java/net/knarcraft/minigames/arena/PlayerVisibilityManager.java @@ -0,0 +1,95 @@ +package net.knarcraft.minigames.arena; + +import net.knarcraft.minigames.MiniGames; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; + +/** + * A manager for keeping track of which players have set other players as hidden + */ +public class PlayerVisibilityManager { + + private final Set hidingEnabledFor = new HashSet<>(); + + /** + * Toggles whether players should be hidden for the player with the given id + * + * @param player

The the player to update

+ */ + public void toggleHidePlayers(@NotNull ArenaPlayerRegistry playerRegistry, @NotNull Player player) { + if (hidingEnabledFor.contains(player.getUniqueId())) { + hidingEnabledFor.remove(player.getUniqueId()); + // Make all other players visible again + changeVisibilityFor(playerRegistry, player, false); + } else { + hidingEnabledFor.add(player.getUniqueId()); + // Make all other players hidden + changeVisibilityFor(playerRegistry, player, true); + } + + } + + /** + * Updates which players are seen as hidden + * + * @param playerRegistry

The registry containing all playing players

+ * @param player

The player that joined the arena

+ */ + public void updateHiddenPlayers(@NotNull ArenaPlayerRegistry playerRegistry, @NotNull Player player) { + boolean hideForPlayer = hidingEnabledFor.contains(player.getUniqueId()); + for (UUID playerId : playerRegistry.getPlayingPlayers()) { + Player otherPlayer = Bukkit.getPlayer(playerId); + if (otherPlayer == null) { + continue; + } + // Hide the arena player from the newly joined player + if (hideForPlayer) { + player.hidePlayer(MiniGames.getInstance(), otherPlayer); + } + // Hide the newly joined player from this player + if (hidingEnabledFor.contains(playerId)) { + otherPlayer.hidePlayer(MiniGames.getInstance(), player); + } + } + } + + /** + * Makes all players visible to the given player + * + * @param player

The player to update visibility for

+ */ + public void showPlayersFor(@NotNull Player player) { + for (Player otherPlayer : Bukkit.getOnlinePlayers()) { + player.showPlayer(MiniGames.getInstance(), otherPlayer); + otherPlayer.showPlayer(MiniGames.getInstance(), player); + } + } + + /** + * Changes whether the given player can see the other players in the arena + * + * @param playerRegistry

The player registry containing other players

+ * @param player

The player to change the visibility for

+ * @param hide

Whether to hide the players or show the players

+ */ + private void changeVisibilityFor(@NotNull ArenaPlayerRegistry playerRegistry, @NotNull Player player, boolean hide) { + for (UUID playerId : playerRegistry.getPlayingPlayers()) { + Player otherPlayer = Bukkit.getPlayer(playerId); + if (otherPlayer == null) { + continue; + } + + if (hide) { + player.hidePlayer(MiniGames.getInstance(), otherPlayer); + } else { + player.showPlayer(MiniGames.getInstance(), otherPlayer); + } + } + } + +} 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 b5f33ec..78a4911 100644 --- a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaSession.java +++ b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaSession.java @@ -3,7 +3,6 @@ package net.knarcraft.minigames.arena.dropper; import net.knarcraft.minigames.MiniGames; import net.knarcraft.minigames.arena.AbstractArenaSession; import net.knarcraft.minigames.arena.PlayerEntryState; -import net.knarcraft.minigames.config.DropperConfiguration; import net.knarcraft.minigames.config.Message; import net.knarcraft.minigames.gui.ArenaGUI; import net.knarcraft.minigames.gui.DropperGUI; @@ -38,11 +37,7 @@ public class DropperArenaSession extends AbstractArenaSession { this.player = player; this.gameMode = gameMode; - DropperConfiguration configuration = MiniGames.getInstance().getDropperConfiguration(); - boolean makeInvisible = configuration.makePlayersInvisible(); - boolean disableCollision = configuration.disableHitCollision(); - this.entryState = new DropperPlayerEntryState(player, gameMode, makeInvisible, disableCollision, - dropperArena.getPlayerHorizontalVelocity()); + this.entryState = new DropperPlayerEntryState(player, gameMode, dropperArena.getPlayerHorizontalVelocity()); this.entryState.setArenaState(); } diff --git a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperPlayerEntryState.java b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperPlayerEntryState.java index 3a8e993..9bec80a 100644 --- a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperPlayerEntryState.java +++ b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperPlayerEntryState.java @@ -16,7 +16,6 @@ import java.util.UUID; public class DropperPlayerEntryState extends AbstractPlayerEntryState { private final float originalFlySpeed; - private final boolean disableHitCollision; private final float horizontalVelocity; private final DropperArenaGameMode arenaGameMode; @@ -26,11 +25,10 @@ public class DropperPlayerEntryState extends AbstractPlayerEntryState { * @param player

The player whose state should be stored

*/ public DropperPlayerEntryState(@NotNull Player player, @NotNull DropperArenaGameMode arenaGameMode, - boolean makePlayerInvisible, boolean disableHitCollision, float horizontalVelocity) { - super(player, makePlayerInvisible); + float horizontalVelocity) { + super(player); this.originalFlySpeed = player.getFlySpeed(); this.arenaGameMode = arenaGameMode; - this.disableHitCollision = disableHitCollision; this.horizontalVelocity = horizontalVelocity; } @@ -38,31 +36,29 @@ public class DropperPlayerEntryState extends AbstractPlayerEntryState { * Instantiates a new parkour player entry state * * @param playerId

The id of the player whose state this should keep track of

- * @param makePlayerInvisible

Whether players should be made invisible while in the arena

* @param entryLocation

The location the player entered from

* @param originalIsFlying

Whether the player was flying before entering the arena

* @param originalGameMode

The game-mode of the player before entering the arena

* @param originalAllowFlight

Whether the player was allowed flight before entering the arena

* @param originalInvulnerable

Whether the player was invulnerable before entering the arena

* @param originalIsSwimming

Whether the player was swimming before entering the arena

- * @param originalCollideAble

Whether the player was collide-able before entering the arena

+ * @param originalFlySpeed

The fly-speed of the player before entering the arena

+ * @param horizontalVelocity

The horizontal velocity of the player before entering the arena

*/ - public DropperPlayerEntryState(@NotNull UUID playerId, boolean makePlayerInvisible, Location entryLocation, + public DropperPlayerEntryState(@NotNull UUID playerId, Location entryLocation, boolean originalIsFlying, GameMode originalGameMode, boolean originalAllowFlight, boolean originalInvulnerable, boolean originalIsSwimming, - boolean originalCollideAble, float originalFlySpeed, boolean disableHitCollision, - float horizontalVelocity, DropperArenaGameMode arenaGameMode) { - super(playerId, makePlayerInvisible, entryLocation, originalIsFlying, originalGameMode, originalAllowFlight, - originalInvulnerable, originalIsSwimming, originalCollideAble); + float originalFlySpeed, float horizontalVelocity, + DropperArenaGameMode arenaGameMode) { + super(playerId, entryLocation, originalIsFlying, originalGameMode, originalAllowFlight, + originalInvulnerable, originalIsSwimming); this.originalFlySpeed = originalFlySpeed; - this.disableHitCollision = disableHitCollision; this.horizontalVelocity = horizontalVelocity; this.arenaGameMode = arenaGameMode; } @Override public void setArenaState() { - super.setArenaState(); Player player = getPlayer(); if (player == null) { return; @@ -71,9 +67,6 @@ public class DropperPlayerEntryState extends AbstractPlayerEntryState { player.setFlying(true); player.setGameMode(GameMode.ADVENTURE); player.setSwimming(false); - if (this.disableHitCollision) { - player.setCollidable(false); - } // If playing on the inverted game-mode, negate the horizontal velocity to swap the controls if (this.arenaGameMode == DropperArenaGameMode.INVERTED) { @@ -104,7 +97,6 @@ public class DropperPlayerEntryState extends AbstractPlayerEntryState { public Map serialize() { Map data = super.serialize(); data.put("originalFlySpeed", this.originalFlySpeed); - data.put("disableHitCollision", this.disableHitCollision); data.put("horizontalVelocity", this.horizontalVelocity); data.put("arenaGameMode", this.arenaGameMode); return data; @@ -118,22 +110,19 @@ public class DropperPlayerEntryState extends AbstractPlayerEntryState { @SuppressWarnings("unused") public static DropperPlayerEntryState deserialize(Map data) { UUID playerId = ((SerializableUUID) data.get("playerId")).getRawValue(); - boolean makePlayerInvisible = (boolean) data.get("makePlayerInvisible"); Location entryLocation = (Location) data.get("entryLocation"); boolean originalIsFlying = (boolean) data.get("originalIsFlying"); GameMode originalGameMode = GameMode.valueOf((String) data.get("originalGameMode")); boolean originalAllowFlight = (boolean) data.get("originalAllowFlight"); boolean originalInvulnerable = (boolean) data.get("originalInvulnerable"); boolean originalIsSwimming = (boolean) data.get("originalIsSwimming"); - boolean originalCollideAble = (boolean) data.get("originalCollideAble"); float originalFlySpeed = ((Number) data.get("originalFlySpeed")).floatValue(); - boolean disableHitCollision = (boolean) data.get("disableHitCollision"); float horizontalVelocity = ((Number) data.get("horizontalVelocity")).floatValue(); DropperArenaGameMode arenaGameMode = (DropperArenaGameMode) data.get("arenaGameMode"); - return new DropperPlayerEntryState(playerId, makePlayerInvisible, entryLocation, originalIsFlying, - originalGameMode, originalAllowFlight, originalInvulnerable, originalIsSwimming, originalCollideAble, - originalFlySpeed, disableHitCollision, horizontalVelocity, arenaGameMode); + return new DropperPlayerEntryState(playerId, entryLocation, originalIsFlying, + originalGameMode, originalAllowFlight, originalInvulnerable, originalIsSwimming, + originalFlySpeed, horizontalVelocity, arenaGameMode); } } diff --git a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaSession.java b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaSession.java index 8cfe823..0bf3a4c 100644 --- a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaSession.java +++ b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaSession.java @@ -4,7 +4,6 @@ import net.knarcraft.minigames.MiniGames; import net.knarcraft.minigames.arena.AbstractArenaSession; import net.knarcraft.minigames.arena.PlayerEntryState; import net.knarcraft.minigames.config.Message; -import net.knarcraft.minigames.config.ParkourConfiguration; import net.knarcraft.minigames.gui.ArenaGUI; import net.knarcraft.minigames.gui.ParkourGUI; import net.knarcraft.minigames.util.PlayerTeleporter; @@ -41,9 +40,7 @@ public class ParkourArenaSession extends AbstractArenaSession { this.player = player; this.gameMode = gameMode; - ParkourConfiguration configuration = MiniGames.getInstance().getParkourConfiguration(); - boolean makeInvisible = configuration.makePlayersInvisible(); - this.entryState = new ParkourPlayerEntryState(player, makeInvisible); + this.entryState = new ParkourPlayerEntryState(player); this.entryState.setArenaState(); } diff --git a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourPlayerEntryState.java b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourPlayerEntryState.java index 10e229b..cc9904c 100644 --- a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourPlayerEntryState.java +++ b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourPlayerEntryState.java @@ -20,34 +20,30 @@ public class ParkourPlayerEntryState extends AbstractPlayerEntryState { * * @param player

The player whose state should be stored

*/ - public ParkourPlayerEntryState(@NotNull Player player, boolean makePlayerInvisible) { - super(player, makePlayerInvisible); + public ParkourPlayerEntryState(@NotNull Player player) { + super(player); } /** * Instantiates a new parkour player entry state * * @param playerId

The id of the player whose state this should keep track of

- * @param makePlayerInvisible

Whether players should be made invisible while in the arena

* @param entryLocation

The location the player entered from

* @param originalIsFlying

Whether the player was flying before entering the arena

* @param originalGameMode

The game-mode of the player before entering the arena

* @param originalAllowFlight

Whether the player was allowed flight before entering the arena

* @param originalInvulnerable

Whether the player was invulnerable before entering the arena

* @param originalIsSwimming

Whether the player was swimming before entering the arena

- * @param originalCollideAble

Whether the player was collide-able before entering the arena

*/ - public ParkourPlayerEntryState(@NotNull UUID playerId, boolean makePlayerInvisible, Location entryLocation, + public ParkourPlayerEntryState(@NotNull UUID playerId, Location entryLocation, boolean originalIsFlying, GameMode originalGameMode, boolean originalAllowFlight, - boolean originalInvulnerable, boolean originalIsSwimming, - boolean originalCollideAble) { - super(playerId, makePlayerInvisible, entryLocation, originalIsFlying, originalGameMode, originalAllowFlight, - originalInvulnerable, originalIsSwimming, originalCollideAble); + boolean originalInvulnerable, boolean originalIsSwimming) { + super(playerId, entryLocation, originalIsFlying, originalGameMode, originalAllowFlight, + originalInvulnerable, originalIsSwimming); } @Override public void setArenaState() { - super.setArenaState(); Player player = getPlayer(); if (player == null) { return; @@ -56,7 +52,6 @@ public class ParkourPlayerEntryState extends AbstractPlayerEntryState { player.setFlying(false); player.setGameMode(GameMode.ADVENTURE); player.setSwimming(false); - player.setCollidable(false); } /** @@ -67,17 +62,15 @@ public class ParkourPlayerEntryState extends AbstractPlayerEntryState { @SuppressWarnings("unused") public static ParkourPlayerEntryState deserialize(Map data) { UUID playerId = ((SerializableUUID) data.get("playerId")).getRawValue(); - boolean makePlayerInvisible = (boolean) data.get("makePlayerInvisible"); Location entryLocation = (Location) data.get("entryLocation"); boolean originalIsFlying = (boolean) data.get("originalIsFlying"); GameMode originalGameMode = GameMode.valueOf((String) data.get("originalGameMode")); boolean originalAllowFlight = (boolean) data.get("originalAllowFlight"); boolean originalInvulnerable = (boolean) data.get("originalInvulnerable"); boolean originalIsSwimming = (boolean) data.get("originalIsSwimming"); - boolean originalCollideAble = (boolean) data.get("originalCollideAble"); - return new ParkourPlayerEntryState(playerId, makePlayerInvisible, entryLocation, originalIsFlying, - originalGameMode, originalAllowFlight, originalInvulnerable, originalIsSwimming, originalCollideAble); + return new ParkourPlayerEntryState(playerId, entryLocation, originalIsFlying, + originalGameMode, originalAllowFlight, originalInvulnerable, originalIsSwimming); } } diff --git a/src/main/java/net/knarcraft/minigames/command/LeaveArenaCommand.java b/src/main/java/net/knarcraft/minigames/command/LeaveArenaCommand.java index 177508e..5d3db26 100644 --- a/src/main/java/net/knarcraft/minigames/command/LeaveArenaCommand.java +++ b/src/main/java/net/knarcraft/minigames/command/LeaveArenaCommand.java @@ -32,7 +32,7 @@ public class LeaveArenaCommand implements TabExecutor { return false; } - existingSession.triggerQuit(false); + existingSession.triggerQuit(false, true); return true; } diff --git a/src/main/java/net/knarcraft/minigames/command/dropper/JoinDropperArenaCommand.java b/src/main/java/net/knarcraft/minigames/command/dropper/JoinDropperArenaCommand.java index a5c4b6e..05637f0 100644 --- a/src/main/java/net/knarcraft/minigames/command/dropper/JoinDropperArenaCommand.java +++ b/src/main/java/net/knarcraft/minigames/command/dropper/JoinDropperArenaCommand.java @@ -94,11 +94,13 @@ public class JoinDropperArenaCommand implements CommandExecutor { boolean teleported = PlayerTeleporter.teleportPlayer(player, specifiedArena.getSpawnLocation(), false, false); if (!teleported) { player.sendMessage(Message.ERROR_ARENA_TELEPORT_FAILED.getMessage()); - newSession.triggerQuit(false); + newSession.triggerQuit(false, true); return false; } else { // Make sure to update the state again in the air to remove a potential swimming state newSession.getEntryState().setArenaState(); + // Update visibility for the player + MiniGames.getInstance().getPlayerVisibilityManager().updateHiddenPlayers(playerRegistry, player); player.sendMessage(Message.SUCCESS_ARENA_JOINED.getMessage()); return true; } diff --git a/src/main/java/net/knarcraft/minigames/command/parkour/JoinParkourArenaCommand.java b/src/main/java/net/knarcraft/minigames/command/parkour/JoinParkourArenaCommand.java index 0ae8189..1c3aa7e 100644 --- a/src/main/java/net/knarcraft/minigames/command/parkour/JoinParkourArenaCommand.java +++ b/src/main/java/net/knarcraft/minigames/command/parkour/JoinParkourArenaCommand.java @@ -92,11 +92,13 @@ public class JoinParkourArenaCommand implements CommandExecutor { boolean teleported = PlayerTeleporter.teleportPlayer(player, specifiedArena.getSpawnLocation(), false, false); if (!teleported) { player.sendMessage(Message.ERROR_ARENA_TELEPORT_FAILED.getMessage()); - newSession.triggerQuit(false); + newSession.triggerQuit(false, true); return false; } else { // Make sure to update the state again in the air to remove a potential swimming state newSession.getEntryState().setArenaState(); + // Update visibility for the player + MiniGames.getInstance().getPlayerVisibilityManager().updateHiddenPlayers(playerRegistry, player); player.sendMessage(Message.SUCCESS_ARENA_JOINED.getMessage()); return true; } diff --git a/src/main/java/net/knarcraft/minigames/command/parkour/ParkourCheckpointCommand.java b/src/main/java/net/knarcraft/minigames/command/parkour/ParkourCheckpointCommand.java deleted file mode 100644 index 335fb02..0000000 --- a/src/main/java/net/knarcraft/minigames/command/parkour/ParkourCheckpointCommand.java +++ /dev/null @@ -1,44 +0,0 @@ -package net.knarcraft.minigames.command.parkour; - -import net.knarcraft.minigames.MiniGames; -import net.knarcraft.minigames.arena.ArenaSession; -import net.knarcraft.minigames.arena.parkour.ParkourArenaSession; -import net.knarcraft.minigames.config.Message; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.command.TabExecutor; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.ArrayList; -import java.util.List; - -/** - * The command for returning to the previous checkpoint - */ -public class ParkourCheckpointCommand implements TabExecutor { - - @Override - public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, - @NotNull String[] strings) { - if (!(commandSender instanceof Player player)) { - commandSender.sendMessage(Message.ERROR_PLAYER_ONLY.getMessage()); - return false; - } - - ArenaSession session = MiniGames.getInstance().getSession(player.getUniqueId()); - if (session instanceof ParkourArenaSession) { - session.triggerLoss(); - } - return true; - } - - @Nullable - @Override - public List onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s, - @NotNull String[] strings) { - return new ArrayList<>(); - } - -} diff --git a/src/main/java/net/knarcraft/minigames/config/DropperConfiguration.java b/src/main/java/net/knarcraft/minigames/config/DropperConfiguration.java index d1d36ec..a238aec 100644 --- a/src/main/java/net/knarcraft/minigames/config/DropperConfiguration.java +++ b/src/main/java/net/knarcraft/minigames/config/DropperConfiguration.java @@ -19,8 +19,6 @@ public class DropperConfiguration extends MiniGameConfiguration { private boolean mustDoGroupedInSequence; private boolean ignoreRecordsUntilGroupBeatenOnce; private boolean mustDoNormalModeFirst; - private boolean makePlayersInvisible; - private boolean disableHitCollision; private boolean blockSneaking; private boolean blockSprinting; private Set blockWhitelist; @@ -97,24 +95,6 @@ public class DropperConfiguration extends MiniGameConfiguration { return this.ignoreRecordsUntilGroupBeatenOnce; } - /** - * Gets whether players should be made invisible while in an arena - * - * @return

Whether players should be made invisible

- */ - public boolean makePlayersInvisible() { - return this.makePlayersInvisible; - } - - /** - * Gets whether entity hit-collision of players in an arena should be disabled - * - * @return

Whether to disable hit collision

- */ - public boolean disableHitCollision() { - return this.disableHitCollision; - } - /** * Gets whether players trying to sneak while in a dropper arena to increase their downwards speed should be blocked * @@ -141,8 +121,6 @@ public class DropperConfiguration extends MiniGameConfiguration { this.mustDoGroupedInSequence = configuration.getBoolean(rootNode + "mustDoGroupedInSequence", true); this.ignoreRecordsUntilGroupBeatenOnce = configuration.getBoolean(rootNode + "ignoreRecordsUntilGroupBeatenOnce", false); this.mustDoNormalModeFirst = configuration.getBoolean(rootNode + "mustDoNormalModeFirst", true); - this.makePlayersInvisible = configuration.getBoolean(rootNode + "makePlayersInvisible", false); - this.disableHitCollision = configuration.getBoolean(rootNode + "disableHitCollision", true); this.blockSprinting = configuration.getBoolean(rootNode + "blockSprinting", true); this.blockSneaking = configuration.getBoolean(rootNode + "blockSneaking", true); this.blockWhitelist = loadMaterialList(rootNode + "blockWhitelist"); @@ -176,8 +154,6 @@ public class DropperConfiguration extends MiniGameConfiguration { "\n" + "Must do groups in sequence: " + mustDoGroupedInSequence + "\n" + "Ignore records until group beaten once: " + ignoreRecordsUntilGroupBeatenOnce + "\n" + "Must do normal mode first: " + mustDoNormalModeFirst + - "\n" + "Make players invisible: " + makePlayersInvisible + - "\n" + "Disable hit collision: " + disableHitCollision + "\n" + "Block whitelist: "); for (Material material : blockWhitelist) { builder.append("\n - ").append(material.name()); diff --git a/src/main/java/net/knarcraft/minigames/config/ParkourConfiguration.java b/src/main/java/net/knarcraft/minigames/config/ParkourConfiguration.java index eb8703d..c0f3848 100644 --- a/src/main/java/net/knarcraft/minigames/config/ParkourConfiguration.java +++ b/src/main/java/net/knarcraft/minigames/config/ParkourConfiguration.java @@ -16,7 +16,6 @@ public class ParkourConfiguration extends MiniGameConfiguration { private boolean enforceCheckpointOrder; private boolean mustDoGroupedInSequence; private boolean ignoreRecordsUntilGroupBeatenOnce; - private boolean makePlayersInvisible; private Set killPlaneBlocks; /** @@ -55,15 +54,6 @@ public class ParkourConfiguration extends MiniGameConfiguration { return this.ignoreRecordsUntilGroupBeatenOnce; } - /** - * Gets whether players should be made invisible while in an arena - * - * @return

Whether players should be made invisible

- */ - public boolean makePlayersInvisible() { - return this.makePlayersInvisible; - } - /** * Gets all types of blocks constituting parkour arenas' kill planes * @@ -78,7 +68,6 @@ public class ParkourConfiguration extends MiniGameConfiguration { 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); this.killPlaneBlocks = loadMaterialList(rootNode + "killPlaneBlocks"); } @@ -89,7 +78,6 @@ public class ParkourConfiguration extends MiniGameConfiguration { "Current configuration:" + "\n" + "Must do groups in sequence: " + mustDoGroupedInSequence + "\n" + "Ignore records until group beaten once: " + ignoreRecordsUntilGroupBeatenOnce + - "\n" + "Make players invisible: " + makePlayersInvisible + "\n" + "Kill plane blocks: "); for (Material material : killPlaneBlocks) { builder.append("\n - ").append(material.name()); diff --git a/src/main/java/net/knarcraft/minigames/gui/ArenaGUI.java b/src/main/java/net/knarcraft/minigames/gui/ArenaGUI.java index b0c7ab9..3d81696 100644 --- a/src/main/java/net/knarcraft/minigames/gui/ArenaGUI.java +++ b/src/main/java/net/knarcraft/minigames/gui/ArenaGUI.java @@ -4,6 +4,7 @@ import net.knarcraft.knargui.AbstractGUI; import net.knarcraft.knargui.GUIAction; import net.knarcraft.knargui.item.GUIItemFactory; import net.knarcraft.minigames.MiniGames; +import net.knarcraft.minigames.arena.ArenaPlayerRegistry; import net.knarcraft.minigames.arena.ArenaSession; import net.md_5.bungee.api.ChatColor; import org.bukkit.Material; @@ -18,14 +19,18 @@ import java.util.List; */ public abstract class ArenaGUI extends AbstractGUI { + protected final ArenaPlayerRegistry playerRegistry; + /** * Instantiates a new arena gui * - * @param inventorySize

The size of the GUI's inventory

- * @param inventoryName

The name of the inventory

+ * @param inventorySize

The size of the GUI's inventory

+ * @param inventoryName

The name of the inventory

+ * @param playerRegistry

The player registry used for this GUI

*/ - public ArenaGUI(int inventorySize, String inventoryName) { + public ArenaGUI(int inventorySize, String inventoryName, ArenaPlayerRegistry playerRegistry) { super(inventorySize, inventoryName, null); + this.playerRegistry = playerRegistry; } /** @@ -88,9 +93,19 @@ public abstract class ArenaGUI extends AbstractGUI { return (player) -> { ArenaSession session = MiniGames.getInstance().getSession(player.getUniqueId()); if (session != null) { - session.triggerQuit(false); + session.triggerQuit(false, true); } }; } + /** + * Gets the action to run when triggering the toggle players action + * + * @return

The action for triggering player visibility

+ */ + protected GUIAction getTogglePlayersAction() { + return (player) -> MiniGames.getInstance().getPlayerVisibilityManager().toggleHidePlayers(playerRegistry, + player); + } + } diff --git a/src/main/java/net/knarcraft/minigames/gui/DropperGUI.java b/src/main/java/net/knarcraft/minigames/gui/DropperGUI.java index a7e4986..78d0f12 100644 --- a/src/main/java/net/knarcraft/minigames/gui/DropperGUI.java +++ b/src/main/java/net/knarcraft/minigames/gui/DropperGUI.java @@ -1,5 +1,7 @@ package net.knarcraft.minigames.gui; +import net.knarcraft.minigames.MiniGames; + /** * A GUI used in the dropper arena */ @@ -9,10 +11,11 @@ public class DropperGUI extends ArenaGUI { * Instantiates a new dropper gui */ public DropperGUI() { - super(9, "Dropper"); + super(9, "Dropper", MiniGames.getInstance().getDropperArenaPlayerRegistry()); setItem(0, getTogglePlayersItem()); setItem(2, getLeaveItem()); + setAnyClickAction(0, getTogglePlayersAction()); setAnyClickAction(2, getLeaveAction()); } diff --git a/src/main/java/net/knarcraft/minigames/gui/ParkourGUI.java b/src/main/java/net/knarcraft/minigames/gui/ParkourGUI.java index eb6a263..760ad97 100644 --- a/src/main/java/net/knarcraft/minigames/gui/ParkourGUI.java +++ b/src/main/java/net/knarcraft/minigames/gui/ParkourGUI.java @@ -17,11 +17,12 @@ import java.util.List; public class ParkourGUI extends ArenaGUI { public ParkourGUI() { - super(9, "Parkour"); + super(9, "Parkour", MiniGames.getInstance().getParkourArenaPlayerRegistry()); setItem(0, getTogglePlayersItem()); setItem(2, getGiveUpItem()); setItem(4, getLeaveItem()); + setAnyClickAction(0, getTogglePlayersAction()); setAnyClickAction(2, getGiveUpAction()); setAnyClickAction(4, getLeaveAction()); } @@ -32,7 +33,7 @@ public class ParkourGUI extends ArenaGUI { * @return

A give up item

*/ private ItemStack getGiveUpItem() { - GUIItemFactory giveUpItemFactory = new GUIItemFactory(Material.SKELETON_SKULL); + GUIItemFactory giveUpItemFactory = new GUIItemFactory(Material.RESPAWN_ANCHOR); List loreLines = getLoreLines(); loreLines.add(ChatColor.GRAY + "Use this item to give up"); loreLines.add(ChatColor.GRAY + "and go to the last checkpoint"); diff --git a/src/main/java/net/knarcraft/minigames/listener/CommandListener.java b/src/main/java/net/knarcraft/minigames/listener/CommandListener.java index c05f2b6..7557242 100644 --- a/src/main/java/net/knarcraft/minigames/listener/CommandListener.java +++ b/src/main/java/net/knarcraft/minigames/listener/CommandListener.java @@ -29,9 +29,6 @@ public class CommandListener implements Listener { allowedCommands.add("/mLeave"); allowedCommands.add("/dLeave"); allowedCommands.add("/pLeave"); - allowedCommands.add("/parkourCheckpoint"); - allowedCommands.add("/pCheckpoint"); - allowedCommands.add("/pCheck"); allowedCommands.add("/miniGamesMenu"); allowedCommands.add("/mMenu"); diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 54f37a5..3a2dafd 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -150,13 +150,6 @@ commands: permission: minigames.remove.parkour usage: / description: Used to remove an existing parkour arena - parkourCheckpoint: - aliases: - - pcheckpoint - - pcheck - permission: minigames.join.parkour - usage: / - description: Used to teleport to the previous checkpoint while in a parkour arena permissions: minigames.*: description: Gives all permissions From d6fb9ab0b99e03c77177a3abe56f702b06887cd9 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 10 May 2023 16:33:01 +0200 Subject: [PATCH 04/13] Makes some GUI changes Makes the current state of the player toggle visible. Makes it possible to toggle player visibility outside arenas. --- .../net/knarcraft/minigames/MiniGames.java | 2 +- .../arena/PlayerVisibilityManager.java | 16 ++++++++- .../arena/dropper/DropperArenaSession.java | 4 +-- .../arena/parkour/ParkourArenaSession.java | 4 +-- .../minigames/command/MenuCommand.java | 9 ++--- .../net/knarcraft/minigames/gui/ArenaGUI.java | 36 ++++++++++++++++--- .../knarcraft/minigames/gui/DropperGUI.java | 11 ++++-- .../knarcraft/minigames/gui/MiniGamesGUI.java | 27 ++++++++++++++ .../knarcraft/minigames/gui/ParkourGUI.java | 14 ++++++-- 9 files changed, 102 insertions(+), 21 deletions(-) create mode 100644 src/main/java/net/knarcraft/minigames/gui/MiniGamesGUI.java diff --git a/src/main/java/net/knarcraft/minigames/MiniGames.java b/src/main/java/net/knarcraft/minigames/MiniGames.java index b3cf612..baea40d 100644 --- a/src/main/java/net/knarcraft/minigames/MiniGames.java +++ b/src/main/java/net/knarcraft/minigames/MiniGames.java @@ -310,7 +310,7 @@ public final class MiniGames extends JavaPlugin { pluginManager.registerEvents(new MoveListener(this.dropperConfiguration, this.parkourConfiguration), this); pluginManager.registerEvents(new PlayerStateChangeListener(), this); pluginManager.registerEvents(new CommandListener(), this); - pluginManager.registerEvents(new GUIListener(false), this); + pluginManager.registerEvents(new GUIListener(true), this); } /** diff --git a/src/main/java/net/knarcraft/minigames/arena/PlayerVisibilityManager.java b/src/main/java/net/knarcraft/minigames/arena/PlayerVisibilityManager.java index 69c6c97..fbd18c9 100644 --- a/src/main/java/net/knarcraft/minigames/arena/PlayerVisibilityManager.java +++ b/src/main/java/net/knarcraft/minigames/arena/PlayerVisibilityManager.java @@ -4,6 +4,7 @@ import net.knarcraft.minigames.MiniGames; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.HashSet; import java.util.Set; @@ -34,6 +35,16 @@ public class PlayerVisibilityManager { } + /** + * Gets whether the given player is currently hiding other players + * + * @param player

The player to check

+ * @return

True if currently hiding other players

+ */ + public boolean isHidingPlayers(Player player) { + return this.hidingEnabledFor.contains(player.getUniqueId()); + } + /** * Updates which players are seen as hidden * @@ -77,7 +88,10 @@ public class PlayerVisibilityManager { * @param player

The player to change the visibility for

* @param hide

Whether to hide the players or show the players

*/ - private void changeVisibilityFor(@NotNull ArenaPlayerRegistry playerRegistry, @NotNull Player player, boolean hide) { + private void changeVisibilityFor(@Nullable ArenaPlayerRegistry playerRegistry, @NotNull Player player, boolean hide) { + if (playerRegistry == null) { + return; + } for (UUID playerId : playerRegistry.getPlayingPlayers()) { Player otherPlayer = Bukkit.getPlayer(playerId); if (otherPlayer == null) { 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 78a4911..f20457f 100644 --- a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaSession.java +++ b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaSession.java @@ -17,8 +17,6 @@ import java.util.logging.Level; */ public class DropperArenaSession extends AbstractArenaSession { - private static final ArenaGUI gui = new DropperGUI(); - private final @NotNull DropperArena arena; private final @NotNull Player player; private final @NotNull DropperArenaGameMode gameMode; @@ -102,7 +100,7 @@ public class DropperArenaSession extends AbstractArenaSession { @Override public @NotNull ArenaGUI getGUI() { - return gui; + return new DropperGUI(player); } @Override diff --git a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaSession.java b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaSession.java index 0bf3a4c..1a1ae73 100644 --- a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaSession.java +++ b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaSession.java @@ -19,8 +19,6 @@ import java.util.logging.Level; */ public class ParkourArenaSession extends AbstractArenaSession { - private static final ArenaGUI gui = new ParkourGUI(); - private final @NotNull ParkourArena arena; private final @NotNull Player player; private final @NotNull ParkourArenaGameMode gameMode; @@ -115,7 +113,7 @@ public class ParkourArenaSession extends AbstractArenaSession { @Override public @NotNull ArenaGUI getGUI() { - return gui; + return new ParkourGUI(player); } @Override diff --git a/src/main/java/net/knarcraft/minigames/command/MenuCommand.java b/src/main/java/net/knarcraft/minigames/command/MenuCommand.java index ca97c3e..9a9135e 100644 --- a/src/main/java/net/knarcraft/minigames/command/MenuCommand.java +++ b/src/main/java/net/knarcraft/minigames/command/MenuCommand.java @@ -3,6 +3,7 @@ package net.knarcraft.minigames.command; import net.knarcraft.minigames.MiniGames; import net.knarcraft.minigames.arena.ArenaSession; import net.knarcraft.minigames.config.Message; +import net.knarcraft.minigames.gui.MiniGamesGUI; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.TabExecutor; @@ -28,12 +29,12 @@ public class MenuCommand implements TabExecutor { ArenaSession existingSession = MiniGames.getInstance().getSession(player.getUniqueId()); if (existingSession == null) { - commandSender.sendMessage(Message.ERROR_NOT_IN_ARENA.getMessage()); + new MiniGamesGUI(player).openFor(player); return false; + } else { + existingSession.getGUI().openFor(player); + return true; } - - existingSession.getGUI().openFor(player); - return true; } @Nullable diff --git a/src/main/java/net/knarcraft/minigames/gui/ArenaGUI.java b/src/main/java/net/knarcraft/minigames/gui/ArenaGUI.java index 3d81696..fdca5c8 100644 --- a/src/main/java/net/knarcraft/minigames/gui/ArenaGUI.java +++ b/src/main/java/net/knarcraft/minigames/gui/ArenaGUI.java @@ -3,9 +3,11 @@ package net.knarcraft.minigames.gui; import net.knarcraft.knargui.AbstractGUI; import net.knarcraft.knargui.GUIAction; import net.knarcraft.knargui.item.GUIItemFactory; +import net.knarcraft.knargui.item.PlayerHeadGUIItemFactory; import net.knarcraft.minigames.MiniGames; import net.knarcraft.minigames.arena.ArenaPlayerRegistry; import net.knarcraft.minigames.arena.ArenaSession; +import net.knarcraft.minigames.arena.PlayerVisibilityManager; import net.md_5.bungee.api.ChatColor; import org.bukkit.Material; import org.bukkit.event.inventory.ClickType; @@ -38,16 +40,33 @@ public abstract class ArenaGUI extends AbstractGUI { * * @return

A player toggle item

*/ - protected ItemStack getTogglePlayersItem() { + protected ItemStack getTogglePlayersItemDisabled() { GUIItemFactory togglePlayersItemFactory = new GUIItemFactory(Material.PLAYER_HEAD); List loreLines = getLoreLines(); - loreLines.add(ChatColor.GRAY + "Use this item to toggle the visibility"); + loreLines.add(ChatColor.GRAY + "Use this item to disable the visibility"); loreLines.add(ChatColor.GRAY + "of other players"); - togglePlayersItemFactory.setName(ChatColor.BLUE + "Toggle Players"); + togglePlayersItemFactory.setName(ChatColor.BLUE + "Disable Players"); togglePlayersItemFactory.setLore(loreLines); return togglePlayersItemFactory.build(); } + /** + * Gets an item describing player visibility toggling + * + * @return

A player toggle item

+ */ + protected ItemStack getTogglePlayersItemEnabled() { + PlayerHeadGUIItemFactory togglePlayersItemFactory = new PlayerHeadGUIItemFactory(); + togglePlayersItemFactory.useSkin("c10591e6909e6a281b371836e462d67a2c78fa0952e910f32b41a26c48c1757c"); + List loreLines = getLoreLines(); + loreLines.add(ChatColor.GRAY + "Use this item to enable the visibility"); + loreLines.add(ChatColor.GRAY + "of other players"); + togglePlayersItemFactory.setName(ChatColor.BLUE + "Enable Players"); + togglePlayersItemFactory.setLore(loreLines); + return togglePlayersItemFactory.build(); + } + + /** * Gets an item describing a leave arena action * @@ -104,8 +123,15 @@ public abstract class ArenaGUI extends AbstractGUI { * @return

The action for triggering player visibility

*/ protected GUIAction getTogglePlayersAction() { - return (player) -> MiniGames.getInstance().getPlayerVisibilityManager().toggleHidePlayers(playerRegistry, - player); + return (player) -> { + PlayerVisibilityManager visibilityManager = MiniGames.getInstance().getPlayerVisibilityManager(); + visibilityManager.toggleHidePlayers(playerRegistry, player); + if (MiniGames.getInstance().getPlayerVisibilityManager().isHidingPlayers(player)) { + setItem(0, getTogglePlayersItemEnabled()); + } else { + setItem(0, getTogglePlayersItemDisabled()); + } + }; } } diff --git a/src/main/java/net/knarcraft/minigames/gui/DropperGUI.java b/src/main/java/net/knarcraft/minigames/gui/DropperGUI.java index 78d0f12..a280166 100644 --- a/src/main/java/net/knarcraft/minigames/gui/DropperGUI.java +++ b/src/main/java/net/knarcraft/minigames/gui/DropperGUI.java @@ -1,6 +1,7 @@ package net.knarcraft.minigames.gui; import net.knarcraft.minigames.MiniGames; +import org.bukkit.entity.Player; /** * A GUI used in the dropper arena @@ -9,10 +10,16 @@ public class DropperGUI extends ArenaGUI { /** * Instantiates a new dropper gui + * + * @param player

The player the GUI is created for

*/ - public DropperGUI() { + public DropperGUI(Player player) { super(9, "Dropper", MiniGames.getInstance().getDropperArenaPlayerRegistry()); - setItem(0, getTogglePlayersItem()); + if (MiniGames.getInstance().getPlayerVisibilityManager().isHidingPlayers(player)) { + setItem(0, getTogglePlayersItemEnabled()); + } else { + setItem(0, getTogglePlayersItemDisabled()); + } setItem(2, getLeaveItem()); setAnyClickAction(0, getTogglePlayersAction()); diff --git a/src/main/java/net/knarcraft/minigames/gui/MiniGamesGUI.java b/src/main/java/net/knarcraft/minigames/gui/MiniGamesGUI.java new file mode 100644 index 0000000..7b8f34e --- /dev/null +++ b/src/main/java/net/knarcraft/minigames/gui/MiniGamesGUI.java @@ -0,0 +1,27 @@ +package net.knarcraft.minigames.gui; + +import net.knarcraft.minigames.MiniGames; +import org.bukkit.entity.Player; + +/** + * A GUI used outside arenas + */ +public class MiniGamesGUI extends ArenaGUI { + + /** + * Instantiates a new mini games gui + * + * @param player

The player the GUI is created for

+ */ + public MiniGamesGUI(Player player) { + super(9, "MiniGames", null); + if (MiniGames.getInstance().getPlayerVisibilityManager().isHidingPlayers(player)) { + setItem(0, getTogglePlayersItemEnabled()); + } else { + setItem(0, getTogglePlayersItemDisabled()); + } + + setAnyClickAction(0, getTogglePlayersAction()); + } + +} diff --git a/src/main/java/net/knarcraft/minigames/gui/ParkourGUI.java b/src/main/java/net/knarcraft/minigames/gui/ParkourGUI.java index 760ad97..ac6d4d0 100644 --- a/src/main/java/net/knarcraft/minigames/gui/ParkourGUI.java +++ b/src/main/java/net/knarcraft/minigames/gui/ParkourGUI.java @@ -7,6 +7,7 @@ import net.knarcraft.minigames.arena.ArenaSession; import net.knarcraft.minigames.arena.parkour.ParkourArenaSession; import net.md_5.bungee.api.ChatColor; import org.bukkit.Material; +import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import java.util.List; @@ -16,9 +17,18 @@ import java.util.List; */ public class ParkourGUI extends ArenaGUI { - public ParkourGUI() { + /** + * Instantiates a new parkour gui + * + * @param player

The player the GUI is created for

+ */ + public ParkourGUI(Player player) { super(9, "Parkour", MiniGames.getInstance().getParkourArenaPlayerRegistry()); - setItem(0, getTogglePlayersItem()); + if (MiniGames.getInstance().getPlayerVisibilityManager().isHidingPlayers(player)) { + setItem(0, getTogglePlayersItemEnabled()); + } else { + setItem(0, getTogglePlayersItemDisabled()); + } setItem(2, getGiveUpItem()); setItem(4, getLeaveItem()); From 7900eb691f444a3d95d2f736513059cede6e9d9b Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Wed, 10 May 2023 16:44:30 +0200 Subject: [PATCH 05/13] Makes hiding players default to true --- .../arena/PlayerVisibilityManager.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/net/knarcraft/minigames/arena/PlayerVisibilityManager.java b/src/main/java/net/knarcraft/minigames/arena/PlayerVisibilityManager.java index fbd18c9..9e2e342 100644 --- a/src/main/java/net/knarcraft/minigames/arena/PlayerVisibilityManager.java +++ b/src/main/java/net/knarcraft/minigames/arena/PlayerVisibilityManager.java @@ -15,7 +15,7 @@ import java.util.UUID; */ public class PlayerVisibilityManager { - private final Set hidingEnabledFor = new HashSet<>(); + private final Set displayingEnabledFor = new HashSet<>(); /** * Toggles whether players should be hidden for the player with the given id @@ -23,14 +23,14 @@ public class PlayerVisibilityManager { * @param player

The the player to update

*/ public void toggleHidePlayers(@NotNull ArenaPlayerRegistry playerRegistry, @NotNull Player player) { - if (hidingEnabledFor.contains(player.getUniqueId())) { - hidingEnabledFor.remove(player.getUniqueId()); - // Make all other players visible again - changeVisibilityFor(playerRegistry, player, false); - } else { - hidingEnabledFor.add(player.getUniqueId()); + if (displayingEnabledFor.contains(player.getUniqueId())) { + displayingEnabledFor.remove(player.getUniqueId()); // Make all other players hidden changeVisibilityFor(playerRegistry, player, true); + } else { + displayingEnabledFor.add(player.getUniqueId()); + // Make all other players visible again + changeVisibilityFor(playerRegistry, player, false); } } @@ -42,7 +42,7 @@ public class PlayerVisibilityManager { * @return

True if currently hiding other players

*/ public boolean isHidingPlayers(Player player) { - return this.hidingEnabledFor.contains(player.getUniqueId()); + return !this.displayingEnabledFor.contains(player.getUniqueId()); } /** @@ -52,7 +52,7 @@ public class PlayerVisibilityManager { * @param player

The player that joined the arena

*/ public void updateHiddenPlayers(@NotNull ArenaPlayerRegistry playerRegistry, @NotNull Player player) { - boolean hideForPlayer = hidingEnabledFor.contains(player.getUniqueId()); + boolean hideForPlayer = !displayingEnabledFor.contains(player.getUniqueId()); for (UUID playerId : playerRegistry.getPlayingPlayers()) { Player otherPlayer = Bukkit.getPlayer(playerId); if (otherPlayer == null) { @@ -63,7 +63,7 @@ public class PlayerVisibilityManager { player.hidePlayer(MiniGames.getInstance(), otherPlayer); } // Hide the newly joined player from this player - if (hidingEnabledFor.contains(playerId)) { + if (!displayingEnabledFor.contains(playerId)) { otherPlayer.hidePlayer(MiniGames.getInstance(), player); } } From 4513fc2de7d57feec262f2cb51ffa6678cb831de Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 11 May 2023 00:47:48 +0200 Subject: [PATCH 06/13] Removes some un-used configuration options --- src/main/resources/config.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index b138669..c57c19e 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -12,9 +12,6 @@ parkour: # are required to do a second play-through to register a record for a grouped arena. ignoreRecordsUntilGroupBeatenOnce: false - # Whether players should be made invisible while playing in a dropper arena - makePlayersInvisible: false - # The blocks compromising parkour arenas' kill planes. Add any materials you want to use for the "bottom" of your # parkour arenas. killPlaneBlocks: @@ -48,13 +45,6 @@ dropper: # Whether a player must do the normal/default game-mode before playing any other game-modes mustDoNormalModeFirst: true - # Whether players should be made invisible while playing in a dropper arena - makePlayersInvisible: false - - # Whether players should have their entity hit collision disabled while in an arena. This prevents players from - # pushing each-other if in the same arena. - disableHitCollision: true - # A whitelist for which blocks won't trigger a loss when hit/passed through. The win block check happens before the # loss check, so even blocks on the whitelist can be used as the win-block. "+" denotes a material tag. blockWhitelist: From 9c91e11780424cd91999c090efaceec68a5adc48 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Thu, 11 May 2023 17:52:49 +0200 Subject: [PATCH 07/13] Gives players an item to open the arena menu --- .../net/knarcraft/minigames/MiniGames.java | 2 + .../arena/AbstractPlayerEntryState.java | 34 +++++++++++ .../minigames/command/MenuCommand.java | 14 +---- .../dropper/JoinDropperArenaCommand.java | 2 + .../parkour/JoinParkourArenaCommand.java | 2 + .../minigames/listener/InteractListener.java | 39 +++++++++++++ .../minigames/property/PersistentDataKey.java | 43 ++++++++++++++ .../knarcraft/minigames/util/GUIHelper.java | 58 +++++++++++++++++++ 8 files changed, 183 insertions(+), 11 deletions(-) create mode 100644 src/main/java/net/knarcraft/minigames/listener/InteractListener.java create mode 100644 src/main/java/net/knarcraft/minigames/property/PersistentDataKey.java create mode 100644 src/main/java/net/knarcraft/minigames/util/GUIHelper.java diff --git a/src/main/java/net/knarcraft/minigames/MiniGames.java b/src/main/java/net/knarcraft/minigames/MiniGames.java index baea40d..2a34c74 100644 --- a/src/main/java/net/knarcraft/minigames/MiniGames.java +++ b/src/main/java/net/knarcraft/minigames/MiniGames.java @@ -54,6 +54,7 @@ import net.knarcraft.minigames.container.SerializableMaterial; import net.knarcraft.minigames.container.SerializableUUID; import net.knarcraft.minigames.listener.CommandListener; import net.knarcraft.minigames.listener.DamageListener; +import net.knarcraft.minigames.listener.InteractListener; import net.knarcraft.minigames.listener.MoveListener; import net.knarcraft.minigames.listener.PlayerStateChangeListener; import net.knarcraft.minigames.placeholder.DropperRecordExpansion; @@ -311,6 +312,7 @@ public final class MiniGames extends JavaPlugin { pluginManager.registerEvents(new PlayerStateChangeListener(), this); pluginManager.registerEvents(new CommandListener(), this); pluginManager.registerEvents(new GUIListener(true), this); + pluginManager.registerEvents(new InteractListener(), this); } /** diff --git a/src/main/java/net/knarcraft/minigames/arena/AbstractPlayerEntryState.java b/src/main/java/net/knarcraft/minigames/arena/AbstractPlayerEntryState.java index 0823387..27e6ec9 100644 --- a/src/main/java/net/knarcraft/minigames/arena/AbstractPlayerEntryState.java +++ b/src/main/java/net/knarcraft/minigames/arena/AbstractPlayerEntryState.java @@ -2,14 +2,21 @@ package net.knarcraft.minigames.arena; import net.knarcraft.minigames.MiniGames; import net.knarcraft.minigames.container.SerializableUUID; +import net.knarcraft.minigames.property.PersistentDataKey; import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.Location; +import org.bukkit.NamespacedKey; import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.persistence.PersistentDataType; import org.jetbrains.annotations.NotNull; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import java.util.UUID; import java.util.logging.Level; @@ -86,6 +93,7 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState { player.setAllowFlight(this.originalAllowFlight); player.setInvulnerable(this.originalInvulnerable); player.setSwimming(this.originalIsSwimming); + removeMenuItem(player); } @Override @@ -121,4 +129,30 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState { return data; } + /** + * Removes the menu item from the given player's inventory + * + * @param player

The player to remove the menu item from

+ */ + private void removeMenuItem(Player player) { + Set itemsToRemove = new HashSet<>(); + player.getInventory().forEach((item) -> { + if (item == null) { + return; + } + ItemMeta meta = item.getItemMeta(); + if (meta == null) { + return; + } + Integer persistentData = meta.getPersistentDataContainer().get(new NamespacedKey(MiniGames.getInstance(), + PersistentDataKey.MENU_ITEM.getKeyName()), PersistentDataType.INTEGER); + if (persistentData != null && persistentData == PersistentDataKey.MENU_ITEM.getDataValue()) { + itemsToRemove.add(item); + } + }); + for (ItemStack toRemove : itemsToRemove) { + player.getInventory().remove(toRemove); + } + } + } diff --git a/src/main/java/net/knarcraft/minigames/command/MenuCommand.java b/src/main/java/net/knarcraft/minigames/command/MenuCommand.java index 9a9135e..ac7a0e4 100644 --- a/src/main/java/net/knarcraft/minigames/command/MenuCommand.java +++ b/src/main/java/net/knarcraft/minigames/command/MenuCommand.java @@ -1,9 +1,7 @@ package net.knarcraft.minigames.command; -import net.knarcraft.minigames.MiniGames; -import net.knarcraft.minigames.arena.ArenaSession; import net.knarcraft.minigames.config.Message; -import net.knarcraft.minigames.gui.MiniGamesGUI; +import net.knarcraft.minigames.util.GUIHelper; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.TabExecutor; @@ -27,14 +25,8 @@ public class MenuCommand implements TabExecutor { return false; } - ArenaSession existingSession = MiniGames.getInstance().getSession(player.getUniqueId()); - if (existingSession == null) { - new MiniGamesGUI(player).openFor(player); - return false; - } else { - existingSession.getGUI().openFor(player); - return true; - } + GUIHelper.openGUI(player); + return true; } @Nullable diff --git a/src/main/java/net/knarcraft/minigames/command/dropper/JoinDropperArenaCommand.java b/src/main/java/net/knarcraft/minigames/command/dropper/JoinDropperArenaCommand.java index 05637f0..192b569 100644 --- a/src/main/java/net/knarcraft/minigames/command/dropper/JoinDropperArenaCommand.java +++ b/src/main/java/net/knarcraft/minigames/command/dropper/JoinDropperArenaCommand.java @@ -8,6 +8,7 @@ import net.knarcraft.minigames.arena.dropper.DropperArenaGroup; import net.knarcraft.minigames.arena.dropper.DropperArenaSession; import net.knarcraft.minigames.config.DropperConfiguration; import net.knarcraft.minigames.config.Message; +import net.knarcraft.minigames.util.GUIHelper; import net.knarcraft.minigames.util.PlayerTeleporter; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; @@ -101,6 +102,7 @@ public class JoinDropperArenaCommand implements CommandExecutor { newSession.getEntryState().setArenaState(); // Update visibility for the player MiniGames.getInstance().getPlayerVisibilityManager().updateHiddenPlayers(playerRegistry, player); + player.getInventory().addItem(GUIHelper.getGUIOpenItem()); player.sendMessage(Message.SUCCESS_ARENA_JOINED.getMessage()); return true; } diff --git a/src/main/java/net/knarcraft/minigames/command/parkour/JoinParkourArenaCommand.java b/src/main/java/net/knarcraft/minigames/command/parkour/JoinParkourArenaCommand.java index 1c3aa7e..2d78d1c 100644 --- a/src/main/java/net/knarcraft/minigames/command/parkour/JoinParkourArenaCommand.java +++ b/src/main/java/net/knarcraft/minigames/command/parkour/JoinParkourArenaCommand.java @@ -8,6 +8,7 @@ import net.knarcraft.minigames.arena.parkour.ParkourArenaGroup; import net.knarcraft.minigames.arena.parkour.ParkourArenaSession; import net.knarcraft.minigames.config.Message; import net.knarcraft.minigames.config.ParkourConfiguration; +import net.knarcraft.minigames.util.GUIHelper; import net.knarcraft.minigames.util.PlayerTeleporter; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; @@ -99,6 +100,7 @@ public class JoinParkourArenaCommand implements CommandExecutor { newSession.getEntryState().setArenaState(); // Update visibility for the player MiniGames.getInstance().getPlayerVisibilityManager().updateHiddenPlayers(playerRegistry, player); + player.getInventory().addItem(GUIHelper.getGUIOpenItem()); player.sendMessage(Message.SUCCESS_ARENA_JOINED.getMessage()); return true; } diff --git a/src/main/java/net/knarcraft/minigames/listener/InteractListener.java b/src/main/java/net/knarcraft/minigames/listener/InteractListener.java new file mode 100644 index 0000000..f476b68 --- /dev/null +++ b/src/main/java/net/knarcraft/minigames/listener/InteractListener.java @@ -0,0 +1,39 @@ +package net.knarcraft.minigames.listener; + +import net.knarcraft.minigames.MiniGames; +import net.knarcraft.minigames.property.PersistentDataKey; +import net.knarcraft.minigames.util.GUIHelper; +import org.bukkit.NamespacedKey; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.persistence.PersistentDataType; + +/** + * A listener that listens for player interactions + */ +public class InteractListener implements Listener { + + @EventHandler + public void menuInteractListener(PlayerInteractEvent event) { + ItemStack item = event.getItem(); + if (item == null || !item.hasItemMeta()) { + return; + } + ItemMeta meta = item.getItemMeta(); + if (meta == null) { + return; + } + + Integer persistentData = meta.getPersistentDataContainer().get(new NamespacedKey(MiniGames.getInstance(), + PersistentDataKey.MENU_ITEM.getKeyName()), PersistentDataType.INTEGER); + + if (persistentData != null && persistentData == PersistentDataKey.MENU_ITEM.getDataValue()) { + event.setCancelled(true); + GUIHelper.openGUI(event.getPlayer()); + } + } + +} diff --git a/src/main/java/net/knarcraft/minigames/property/PersistentDataKey.java b/src/main/java/net/knarcraft/minigames/property/PersistentDataKey.java new file mode 100644 index 0000000..2965f89 --- /dev/null +++ b/src/main/java/net/knarcraft/minigames/property/PersistentDataKey.java @@ -0,0 +1,43 @@ +package net.knarcraft.minigames.property; + +/** + * An enum for all persistent data keys used by this plugin + */ +public enum PersistentDataKey { + + MENU_ITEM("MiniGamesMenu", 1799804), + ; + + private final String keyName; + private final int dataValue; + + /** + * Instantiates a new persistent data key + * + * @param keyName

The name of this key

+ * @param dataValue

The integer data value of this key

+ */ + PersistentDataKey(String keyName, int dataValue) { + this.keyName = keyName; + this.dataValue = dataValue; + } + + /** + * Gets the name of this persistent data key + * + * @return

The name of this key

+ */ + public String getKeyName() { + return this.keyName; + } + + /** + * Gets the integer data value of this persistent data key + * + * @return

The integer data value

+ */ + public int getDataValue() { + return this.dataValue; + } + +} diff --git a/src/main/java/net/knarcraft/minigames/util/GUIHelper.java b/src/main/java/net/knarcraft/minigames/util/GUIHelper.java new file mode 100644 index 0000000..90e4ecc --- /dev/null +++ b/src/main/java/net/knarcraft/minigames/util/GUIHelper.java @@ -0,0 +1,58 @@ +package net.knarcraft.minigames.util; + +import net.knarcraft.knargui.item.PlayerHeadGUIItemFactory; +import net.knarcraft.minigames.MiniGames; +import net.knarcraft.minigames.arena.ArenaSession; +import net.knarcraft.minigames.gui.MiniGamesGUI; +import net.knarcraft.minigames.property.PersistentDataKey; +import org.bukkit.ChatColor; +import org.bukkit.NamespacedKey; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.persistence.PersistentDataType; + +/** + * A helper class for the in-arena GUI + */ +public final class GUIHelper { + + private GUIHelper() { + + } + + /** + * Gets the item used for opening the mini-games menu + * + * @return

The item used for opening the GUI

+ */ + public static ItemStack getGUIOpenItem() { + PlayerHeadGUIItemFactory factory = new PlayerHeadGUIItemFactory(); + factory.useSkin("3fdab40434ed5d01f58c45ca0c9fada4662e1772ff43e2974979440a5cfe15c9"); + factory.setName(ChatColor.AQUA + "§ MiniGames Menu §"); + ItemStack item = factory.build(); + ItemMeta meta = item.getItemMeta(); + if (meta != null) { + meta.getPersistentDataContainer().set(new NamespacedKey(MiniGames.getInstance(), + PersistentDataKey.MENU_ITEM.getKeyName()), + PersistentDataType.INTEGER, PersistentDataKey.MENU_ITEM.getDataValue()); + } + item.setItemMeta(meta); + return item; + } + + /** + * Opens the correct GUI for the given player + * + * @param player

The player to show a GUI for

+ */ + public static void openGUI(Player player) { + ArenaSession existingSession = MiniGames.getInstance().getSession(player.getUniqueId()); + if (existingSession == null) { + new MiniGamesGUI(player).openFor(player); + } else { + existingSession.getGUI().openFor(player); + } + } + +} From de5124c8dd76a4e24eebe04d227cb77bf2c77cc0 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 12 May 2023 13:16:32 +0200 Subject: [PATCH 08/13] Hopefully prevents an exception when restoring a player's fly state --- .../knarcraft/minigames/arena/AbstractPlayerEntryState.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/knarcraft/minigames/arena/AbstractPlayerEntryState.java b/src/main/java/net/knarcraft/minigames/arena/AbstractPlayerEntryState.java index 27e6ec9..bfbce94 100644 --- a/src/main/java/net/knarcraft/minigames/arena/AbstractPlayerEntryState.java +++ b/src/main/java/net/knarcraft/minigames/arena/AbstractPlayerEntryState.java @@ -88,9 +88,9 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState { @Override public void restore(@NotNull Player player) { - player.setFlying(this.originalIsFlying); - player.setGameMode(this.originalGameMode); player.setAllowFlight(this.originalAllowFlight); + player.setFlying(player.getAllowFlight() && this.originalIsFlying); + player.setGameMode(this.originalGameMode); player.setInvulnerable(this.originalInvulnerable); player.setSwimming(this.originalIsSwimming); removeMenuItem(player); From 38839c0287e0b58630684c20a7a1bed71d5ab052 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Fri, 12 May 2023 14:31:30 +0200 Subject: [PATCH 09/13] Re-implements the collision removal to fix a severe bug --- .../arena/AbstractPlayerEntryState.java | 22 ++++++++++++++++++- .../dropper/DropperPlayerEntryState.java | 16 ++++++++------ .../parkour/ParkourPlayerEntryState.java | 16 ++++++++------ .../dropper/JoinDropperArenaCommand.java | 8 ++++--- .../parkour/JoinParkourArenaCommand.java | 8 ++++--- 5 files changed, 49 insertions(+), 21 deletions(-) diff --git a/src/main/java/net/knarcraft/minigames/arena/AbstractPlayerEntryState.java b/src/main/java/net/knarcraft/minigames/arena/AbstractPlayerEntryState.java index bfbce94..8c06be1 100644 --- a/src/main/java/net/knarcraft/minigames/arena/AbstractPlayerEntryState.java +++ b/src/main/java/net/knarcraft/minigames/arena/AbstractPlayerEntryState.java @@ -16,6 +16,7 @@ import org.jetbrains.annotations.NotNull; import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import java.util.Objects; import java.util.Set; import java.util.UUID; import java.util.logging.Level; @@ -32,6 +33,7 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState { private final boolean originalAllowFlight; private final boolean originalInvulnerable; private final boolean originalIsSwimming; + private final boolean originalCollideAble; /** * Instantiates a new abstract player entry state @@ -46,6 +48,7 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState { this.originalAllowFlight = player.getAllowFlight(); this.originalInvulnerable = player.isInvulnerable(); this.originalIsSwimming = player.isSwimming(); + this.originalCollideAble = player.isCollidable(); } /** @@ -58,10 +61,12 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState { * @param originalAllowFlight

Whether the player was allowed flight before entering the arena

* @param originalInvulnerable

Whether the player was invulnerable before entering the arena

* @param originalIsSwimming

Whether the player was swimming before entering the arena

+ * @param originalCollideAble

Whether the player was collide-able before entering the arena

*/ public AbstractPlayerEntryState(@NotNull UUID playerId, Location entryLocation, boolean originalIsFlying, GameMode originalGameMode, boolean originalAllowFlight, - boolean originalInvulnerable, boolean originalIsSwimming) { + boolean originalInvulnerable, boolean originalIsSwimming, + boolean originalCollideAble) { this.playerId = playerId; this.entryLocation = entryLocation; this.originalIsFlying = originalIsFlying; @@ -69,6 +74,7 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState { this.originalAllowFlight = originalAllowFlight; this.originalInvulnerable = originalInvulnerable; this.originalIsSwimming = originalIsSwimming; + this.originalCollideAble = originalCollideAble; } @Override @@ -88,6 +94,7 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState { @Override public void restore(@NotNull Player player) { + player.setCollidable(this.originalCollideAble); player.setAllowFlight(this.originalAllowFlight); player.setFlying(player.getAllowFlight() && this.originalIsFlying); player.setGameMode(this.originalGameMode); @@ -126,6 +133,7 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState { data.put("originalAllowFlight", this.originalAllowFlight); data.put("originalInvulnerable", this.originalInvulnerable); data.put("originalIsSwimming", this.originalIsSwimming); + data.put("originalCollideAble", this.originalCollideAble); return data; } @@ -155,4 +163,16 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState { } } + /** + * Gets a boolean value from a serialization map + * + * @param data

The serialization data to look through

+ * @param key

The key to get

+ * @return

The boolean value of the key

+ */ + protected static boolean getBoolean(Map data, String key) { + Boolean value = (Boolean) data.get(key); + return Objects.requireNonNullElse(value, false); + } + } diff --git a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperPlayerEntryState.java b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperPlayerEntryState.java index 9bec80a..48e764c 100644 --- a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperPlayerEntryState.java +++ b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperPlayerEntryState.java @@ -44,14 +44,15 @@ public class DropperPlayerEntryState extends AbstractPlayerEntryState { * @param originalIsSwimming

Whether the player was swimming before entering the arena

* @param originalFlySpeed

The fly-speed of the player before entering the arena

* @param horizontalVelocity

The horizontal velocity of the player before entering the arena

+ * @param originalCollideAble

Whether the player was collide-able before entering the arena

*/ public DropperPlayerEntryState(@NotNull UUID playerId, Location entryLocation, boolean originalIsFlying, GameMode originalGameMode, boolean originalAllowFlight, boolean originalInvulnerable, boolean originalIsSwimming, float originalFlySpeed, float horizontalVelocity, - DropperArenaGameMode arenaGameMode) { + DropperArenaGameMode arenaGameMode, boolean originalCollideAble) { super(playerId, entryLocation, originalIsFlying, originalGameMode, originalAllowFlight, - originalInvulnerable, originalIsSwimming); + originalInvulnerable, originalIsSwimming, originalCollideAble); this.originalFlySpeed = originalFlySpeed; this.horizontalVelocity = horizontalVelocity; this.arenaGameMode = arenaGameMode; @@ -111,18 +112,19 @@ public class DropperPlayerEntryState extends AbstractPlayerEntryState { public static DropperPlayerEntryState deserialize(Map data) { UUID playerId = ((SerializableUUID) data.get("playerId")).getRawValue(); Location entryLocation = (Location) data.get("entryLocation"); - boolean originalIsFlying = (boolean) data.get("originalIsFlying"); + boolean originalIsFlying = getBoolean(data, "originalIsFlying"); GameMode originalGameMode = GameMode.valueOf((String) data.get("originalGameMode")); - boolean originalAllowFlight = (boolean) data.get("originalAllowFlight"); - boolean originalInvulnerable = (boolean) data.get("originalInvulnerable"); - boolean originalIsSwimming = (boolean) data.get("originalIsSwimming"); + boolean originalAllowFlight = getBoolean(data, "originalAllowFlight"); + boolean originalInvulnerable = getBoolean(data, "originalInvulnerable"); + boolean originalIsSwimming = getBoolean(data, "originalIsSwimming"); float originalFlySpeed = ((Number) data.get("originalFlySpeed")).floatValue(); float horizontalVelocity = ((Number) data.get("horizontalVelocity")).floatValue(); DropperArenaGameMode arenaGameMode = (DropperArenaGameMode) data.get("arenaGameMode"); + boolean originalCollideAble = getBoolean(data, "originalCollideAble"); return new DropperPlayerEntryState(playerId, entryLocation, originalIsFlying, originalGameMode, originalAllowFlight, originalInvulnerable, originalIsSwimming, - originalFlySpeed, horizontalVelocity, arenaGameMode); + originalFlySpeed, horizontalVelocity, arenaGameMode, originalCollideAble); } } diff --git a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourPlayerEntryState.java b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourPlayerEntryState.java index cc9904c..fa00dff 100644 --- a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourPlayerEntryState.java +++ b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourPlayerEntryState.java @@ -34,12 +34,13 @@ public class ParkourPlayerEntryState extends AbstractPlayerEntryState { * @param originalAllowFlight

Whether the player was allowed flight before entering the arena

* @param originalInvulnerable

Whether the player was invulnerable before entering the arena

* @param originalIsSwimming

Whether the player was swimming before entering the arena

+ * @param originalCollideAble

Whether the player was collide-able before entering the arena

*/ public ParkourPlayerEntryState(@NotNull UUID playerId, Location entryLocation, boolean originalIsFlying, GameMode originalGameMode, boolean originalAllowFlight, - boolean originalInvulnerable, boolean originalIsSwimming) { + boolean originalInvulnerable, boolean originalIsSwimming, boolean originalCollideAble) { super(playerId, entryLocation, originalIsFlying, originalGameMode, originalAllowFlight, - originalInvulnerable, originalIsSwimming); + originalInvulnerable, originalIsSwimming, originalCollideAble); } @Override @@ -63,14 +64,15 @@ public class ParkourPlayerEntryState extends AbstractPlayerEntryState { public static ParkourPlayerEntryState deserialize(Map data) { UUID playerId = ((SerializableUUID) data.get("playerId")).getRawValue(); Location entryLocation = (Location) data.get("entryLocation"); - boolean originalIsFlying = (boolean) data.get("originalIsFlying"); + boolean originalIsFlying = getBoolean(data, "originalIsFlying"); GameMode originalGameMode = GameMode.valueOf((String) data.get("originalGameMode")); - boolean originalAllowFlight = (boolean) data.get("originalAllowFlight"); - boolean originalInvulnerable = (boolean) data.get("originalInvulnerable"); - boolean originalIsSwimming = (boolean) data.get("originalIsSwimming"); + boolean originalAllowFlight = getBoolean(data, "originalAllowFlight"); + boolean originalInvulnerable = getBoolean(data, "originalInvulnerable"); + boolean originalIsSwimming = getBoolean(data, "originalIsSwimming"); + boolean originalCollideAble = getBoolean(data, "originalCollideAble"); return new ParkourPlayerEntryState(playerId, entryLocation, originalIsFlying, - originalGameMode, originalAllowFlight, originalInvulnerable, originalIsSwimming); + originalGameMode, originalAllowFlight, originalInvulnerable, originalIsSwimming, originalCollideAble); } } diff --git a/src/main/java/net/knarcraft/minigames/command/dropper/JoinDropperArenaCommand.java b/src/main/java/net/knarcraft/minigames/command/dropper/JoinDropperArenaCommand.java index 192b569..320c4bc 100644 --- a/src/main/java/net/knarcraft/minigames/command/dropper/JoinDropperArenaCommand.java +++ b/src/main/java/net/knarcraft/minigames/command/dropper/JoinDropperArenaCommand.java @@ -91,6 +91,9 @@ public class JoinDropperArenaCommand implements CommandExecutor { ArenaPlayerRegistry playerRegistry = MiniGames.getInstance().getDropperArenaPlayerRegistry(); playerRegistry.registerPlayer(player.getUniqueId(), newSession); + // Update visibility and hit-box for the player + MiniGames.getInstance().getPlayerVisibilityManager().updateHiddenPlayers(playerRegistry, player); + // Try to teleport the player to the arena boolean teleported = PlayerTeleporter.teleportPlayer(player, specifiedArena.getSpawnLocation(), false, false); if (!teleported) { @@ -98,10 +101,9 @@ public class JoinDropperArenaCommand implements CommandExecutor { newSession.triggerQuit(false, true); return false; } else { - // Make sure to update the state again in the air to remove a potential swimming state + // Update the player's state to follow the arena's rules newSession.getEntryState().setArenaState(); - // Update visibility for the player - MiniGames.getInstance().getPlayerVisibilityManager().updateHiddenPlayers(playerRegistry, player); + player.getInventory().addItem(GUIHelper.getGUIOpenItem()); player.sendMessage(Message.SUCCESS_ARENA_JOINED.getMessage()); return true; diff --git a/src/main/java/net/knarcraft/minigames/command/parkour/JoinParkourArenaCommand.java b/src/main/java/net/knarcraft/minigames/command/parkour/JoinParkourArenaCommand.java index 2d78d1c..1d536db 100644 --- a/src/main/java/net/knarcraft/minigames/command/parkour/JoinParkourArenaCommand.java +++ b/src/main/java/net/knarcraft/minigames/command/parkour/JoinParkourArenaCommand.java @@ -89,6 +89,9 @@ public class JoinParkourArenaCommand implements CommandExecutor { ArenaPlayerRegistry playerRegistry = MiniGames.getInstance().getParkourArenaPlayerRegistry(); playerRegistry.registerPlayer(player.getUniqueId(), newSession); + // Update visibility and hit-box for the player + MiniGames.getInstance().getPlayerVisibilityManager().updateHiddenPlayers(playerRegistry, player); + // Try to teleport the player to the arena boolean teleported = PlayerTeleporter.teleportPlayer(player, specifiedArena.getSpawnLocation(), false, false); if (!teleported) { @@ -96,10 +99,9 @@ public class JoinParkourArenaCommand implements CommandExecutor { newSession.triggerQuit(false, true); return false; } else { - // Make sure to update the state again in the air to remove a potential swimming state + // Update the player's state to follow the arena's rules newSession.getEntryState().setArenaState(); - // Update visibility for the player - MiniGames.getInstance().getPlayerVisibilityManager().updateHiddenPlayers(playerRegistry, player); + player.getInventory().addItem(GUIHelper.getGUIOpenItem()); player.sendMessage(Message.SUCCESS_ARENA_JOINED.getMessage()); return true; From 57b3b85fbce35f8b4b271f181be7559134e01b48 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 12 Jun 2023 23:17:48 +0200 Subject: [PATCH 10/13] Adds a new item to allow arena re-tries Prevents a NumberFormatException if the record number is invalid Updates Spigot to 1.20 --- pom.xml | 2 +- .../minigames/arena/AbstractArenaSession.java | 10 ++++- .../minigames/arena/ArenaSession.java | 5 +++ .../arena/parkour/ParkourArenaSession.java | 6 +++ .../parkour/JoinParkourArenaCommand.java | 2 +- .../net/knarcraft/minigames/gui/ArenaGUI.java | 44 +++++++++++++++---- .../knarcraft/minigames/gui/DropperGUI.java | 6 ++- .../knarcraft/minigames/gui/MiniGamesGUI.java | 4 +- .../knarcraft/minigames/gui/ParkourGUI.java | 8 ++-- .../minigames/listener/InteractListener.java | 16 +++++++ .../placeholder/RecordExpansion.java | 11 ++++- .../minigames/property/PersistentDataKey.java | 3 ++ 12 files changed, 97 insertions(+), 20 deletions(-) diff --git a/pom.xml b/pom.xml index bc3dac7..7f7c102 100644 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,7 @@ org.spigotmc spigot-api - 1.19.4-R0.1-SNAPSHOT + 1.20-R0.1-SNAPSHOT provided diff --git a/src/main/java/net/knarcraft/minigames/arena/AbstractArenaSession.java b/src/main/java/net/knarcraft/minigames/arena/AbstractArenaSession.java index c298e04..971eece 100644 --- a/src/main/java/net/knarcraft/minigames/arena/AbstractArenaSession.java +++ b/src/main/java/net/knarcraft/minigames/arena/AbstractArenaSession.java @@ -15,7 +15,7 @@ public abstract class AbstractArenaSession implements ArenaSession { private final @NotNull ArenaGameMode gameMode; private final @NotNull Player player; protected int deaths; - protected final long startTime; + protected long startTime; protected PlayerEntryState entryState; /** @@ -47,6 +47,14 @@ public abstract class AbstractArenaSession implements ArenaSession { player.sendMessage(Message.SUCCESS_ARENA_QUIT.getMessage()); } + @Override + public void reset() { + this.deaths = 0; + this.startTime = System.currentTimeMillis(); + PlayerTeleporter.teleportPlayer(this.player, this.arena.getSpawnLocation(), false, false); + this.entryState.setArenaState(); + } + /** * Announces a record set by this player * diff --git a/src/main/java/net/knarcraft/minigames/arena/ArenaSession.java b/src/main/java/net/knarcraft/minigames/arena/ArenaSession.java index 22737bb..8003b62 100644 --- a/src/main/java/net/knarcraft/minigames/arena/ArenaSession.java +++ b/src/main/java/net/knarcraft/minigames/arena/ArenaSession.java @@ -47,4 +47,9 @@ public interface ArenaSession { */ @NotNull ArenaGUI getGUI(); + /** + * Resets the session to allow a player to try again + */ + void reset(); + } diff --git a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaSession.java b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaSession.java index 1a1ae73..0f3d694 100644 --- a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaSession.java +++ b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaSession.java @@ -116,6 +116,12 @@ public class ParkourArenaSession extends AbstractArenaSession { return new ParkourGUI(player); } + @Override + public void reset() { + this.reachedCheckpoint = null; + 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/command/parkour/JoinParkourArenaCommand.java b/src/main/java/net/knarcraft/minigames/command/parkour/JoinParkourArenaCommand.java index 1d536db..26f9792 100644 --- a/src/main/java/net/knarcraft/minigames/command/parkour/JoinParkourArenaCommand.java +++ b/src/main/java/net/knarcraft/minigames/command/parkour/JoinParkourArenaCommand.java @@ -101,7 +101,7 @@ public class JoinParkourArenaCommand implements CommandExecutor { } else { // Update the player's state to follow the arena's rules newSession.getEntryState().setArenaState(); - + player.getInventory().addItem(GUIHelper.getGUIOpenItem()); player.sendMessage(Message.SUCCESS_ARENA_JOINED.getMessage()); return true; diff --git a/src/main/java/net/knarcraft/minigames/gui/ArenaGUI.java b/src/main/java/net/knarcraft/minigames/gui/ArenaGUI.java index fdca5c8..a00dc43 100644 --- a/src/main/java/net/knarcraft/minigames/gui/ArenaGUI.java +++ b/src/main/java/net/knarcraft/minigames/gui/ArenaGUI.java @@ -21,18 +21,29 @@ import java.util.List; */ public abstract class ArenaGUI extends AbstractGUI { - protected final ArenaPlayerRegistry playerRegistry; - /** * Instantiates a new arena gui * - * @param inventorySize

The size of the GUI's inventory

- * @param inventoryName

The name of the inventory

- * @param playerRegistry

The player registry used for this GUI

+ * @param inventorySize

The size of the GUI's inventory

+ * @param inventoryName

The name of the inventory

*/ - public ArenaGUI(int inventorySize, String inventoryName, ArenaPlayerRegistry playerRegistry) { + public ArenaGUI(int inventorySize, String inventoryName) { super(inventorySize, inventoryName, null); - this.playerRegistry = playerRegistry; + } + + /** + * Gets an item describing a retry arena action + * + * @return

An arena restart item

+ */ + protected ItemStack getRestartItem() { + PlayerHeadGUIItemFactory restartItemFactory = new PlayerHeadGUIItemFactory(); + restartItemFactory.useSkin("e23b225ed0443c4eec7cf30a034490485904e6eb3d53ef2ab9e39c73bdf22c30"); + List loreLines = getLoreLines(); + loreLines.add(ChatColor.GRAY + "Use this item to retry the arena"); + restartItemFactory.setName(ChatColor.BLUE + "Retry arena"); + restartItemFactory.setLore(loreLines); + return restartItemFactory.build(); } /** @@ -108,7 +119,7 @@ public abstract class ArenaGUI extends AbstractGUI { * * @return

The leave action

*/ - protected GUIAction getLeaveAction() { + public static GUIAction getLeaveAction() { return (player) -> { ArenaSession session = MiniGames.getInstance().getSession(player.getUniqueId()); if (session != null) { @@ -117,12 +128,27 @@ public abstract class ArenaGUI extends AbstractGUI { }; } + /** + * Gets the action to run when triggering the restart action + * + * @return

The action for triggering a session restart

+ */ + public static GUIAction getRestartAction() { + return (player -> { + ArenaSession session = MiniGames.getInstance().getSession(player.getUniqueId()); + if (session != null) { + session.reset(); + } + }); + } + /** * Gets the action to run when triggering the toggle players action * + * @param playerRegistry

The registry containing relevant players

* @return

The action for triggering player visibility

*/ - protected GUIAction getTogglePlayersAction() { + public GUIAction getTogglePlayersAction(ArenaPlayerRegistry playerRegistry) { return (player) -> { PlayerVisibilityManager visibilityManager = MiniGames.getInstance().getPlayerVisibilityManager(); visibilityManager.toggleHidePlayers(playerRegistry, player); diff --git a/src/main/java/net/knarcraft/minigames/gui/DropperGUI.java b/src/main/java/net/knarcraft/minigames/gui/DropperGUI.java index a280166..acf2324 100644 --- a/src/main/java/net/knarcraft/minigames/gui/DropperGUI.java +++ b/src/main/java/net/knarcraft/minigames/gui/DropperGUI.java @@ -14,16 +14,18 @@ public class DropperGUI extends ArenaGUI { * @param player

The player the GUI is created for

*/ public DropperGUI(Player player) { - super(9, "Dropper", MiniGames.getInstance().getDropperArenaPlayerRegistry()); + super(9, "Dropper"); if (MiniGames.getInstance().getPlayerVisibilityManager().isHidingPlayers(player)) { setItem(0, getTogglePlayersItemEnabled()); } else { setItem(0, getTogglePlayersItemDisabled()); } setItem(2, getLeaveItem()); + setItem(4, getRestartItem()); - setAnyClickAction(0, getTogglePlayersAction()); + setAnyClickAction(0, getTogglePlayersAction(MiniGames.getInstance().getDropperArenaPlayerRegistry())); setAnyClickAction(2, getLeaveAction()); + setAnyClickAction(4, getRestartAction()); } } diff --git a/src/main/java/net/knarcraft/minigames/gui/MiniGamesGUI.java b/src/main/java/net/knarcraft/minigames/gui/MiniGamesGUI.java index 7b8f34e..4dca1f4 100644 --- a/src/main/java/net/knarcraft/minigames/gui/MiniGamesGUI.java +++ b/src/main/java/net/knarcraft/minigames/gui/MiniGamesGUI.java @@ -14,14 +14,14 @@ public class MiniGamesGUI extends ArenaGUI { * @param player

The player the GUI is created for

*/ public MiniGamesGUI(Player player) { - super(9, "MiniGames", null); + super(9, "MiniGames"); if (MiniGames.getInstance().getPlayerVisibilityManager().isHidingPlayers(player)) { setItem(0, getTogglePlayersItemEnabled()); } else { setItem(0, getTogglePlayersItemDisabled()); } - setAnyClickAction(0, getTogglePlayersAction()); + setAnyClickAction(0, getTogglePlayersAction(null)); } } diff --git a/src/main/java/net/knarcraft/minigames/gui/ParkourGUI.java b/src/main/java/net/knarcraft/minigames/gui/ParkourGUI.java index ac6d4d0..1783cc3 100644 --- a/src/main/java/net/knarcraft/minigames/gui/ParkourGUI.java +++ b/src/main/java/net/knarcraft/minigames/gui/ParkourGUI.java @@ -23,7 +23,7 @@ public class ParkourGUI extends ArenaGUI { * @param player

The player the GUI is created for

*/ public ParkourGUI(Player player) { - super(9, "Parkour", MiniGames.getInstance().getParkourArenaPlayerRegistry()); + super(9, "Parkour"); if (MiniGames.getInstance().getPlayerVisibilityManager().isHidingPlayers(player)) { setItem(0, getTogglePlayersItemEnabled()); } else { @@ -31,10 +31,12 @@ public class ParkourGUI extends ArenaGUI { } setItem(2, getGiveUpItem()); setItem(4, getLeaveItem()); + setItem(6, getRestartItem()); - setAnyClickAction(0, getTogglePlayersAction()); + setAnyClickAction(0, getTogglePlayersAction(MiniGames.getInstance().getParkourArenaPlayerRegistry())); setAnyClickAction(2, getGiveUpAction()); setAnyClickAction(4, getLeaveAction()); + setAnyClickAction(6, getRestartAction()); } /** @@ -57,7 +59,7 @@ public class ParkourGUI extends ArenaGUI { * * @return

The give up action

*/ - private GUIAction getGiveUpAction() { + public static GUIAction getGiveUpAction() { return (player) -> { ArenaSession session = MiniGames.getInstance().getSession(player.getUniqueId()); if (session instanceof ParkourArenaSession) { diff --git a/src/main/java/net/knarcraft/minigames/listener/InteractListener.java b/src/main/java/net/knarcraft/minigames/listener/InteractListener.java index f476b68..fe96318 100644 --- a/src/main/java/net/knarcraft/minigames/listener/InteractListener.java +++ b/src/main/java/net/knarcraft/minigames/listener/InteractListener.java @@ -1,6 +1,8 @@ package net.knarcraft.minigames.listener; import net.knarcraft.minigames.MiniGames; +import net.knarcraft.minigames.gui.ArenaGUI; +import net.knarcraft.minigames.gui.ParkourGUI; import net.knarcraft.minigames.property.PersistentDataKey; import net.knarcraft.minigames.util.GUIHelper; import org.bukkit.NamespacedKey; @@ -33,6 +35,20 @@ public class InteractListener implements Listener { if (persistentData != null && persistentData == PersistentDataKey.MENU_ITEM.getDataValue()) { event.setCancelled(true); GUIHelper.openGUI(event.getPlayer()); + return; + } + + persistentData = meta.getPersistentDataContainer().get(new NamespacedKey(MiniGames.getInstance(), + PersistentDataKey.LEAVE_ITEM.getKeyName()), PersistentDataType.INTEGER); + if (persistentData != null) { + event.setCancelled(true); + if (persistentData == PersistentDataKey.LEAVE_ITEM.getDataValue()) { + ArenaGUI.getLeaveAction().run(event.getPlayer()); + } else if (persistentData == PersistentDataKey.GIVE_UP_ITEM.getDataValue()) { + ParkourGUI.getGiveUpAction().run(event.getPlayer()); + } else if (persistentData == PersistentDataKey.TOGGLE_PLAYERS_ITEM.getDataValue()) { + //TODO: Figure out how in the world this should be done, as the existing code cannot be re-used + } } } diff --git a/src/main/java/net/knarcraft/minigames/placeholder/RecordExpansion.java b/src/main/java/net/knarcraft/minigames/placeholder/RecordExpansion.java index 9dca66c..93a0822 100644 --- a/src/main/java/net/knarcraft/minigames/placeholder/RecordExpansion.java +++ b/src/main/java/net/knarcraft/minigames/placeholder/RecordExpansion.java @@ -1,6 +1,7 @@ package net.knarcraft.minigames.placeholder; import me.clip.placeholderapi.expansion.PlaceholderExpansion; +import net.knarcraft.minigames.MiniGames; import net.knarcraft.minigames.arena.Arena; import net.knarcraft.minigames.arena.ArenaGameMode; import net.knarcraft.minigames.arena.ArenaGroup; @@ -26,6 +27,7 @@ import java.util.Objects; import java.util.Set; import java.util.UUID; import java.util.function.Supplier; +import java.util.logging.Level; /** * A placeholder expansion for parkour record placeholders @@ -71,7 +73,14 @@ public abstract class RecordExpansion extends PlaceholderExpansion { ArenaGameMode gameMode = parseGameMode(parts[2]); SelectionType selectionType = SelectionType.getFromString(parts[3]); String identifier = parts[4]; - int recordNumber = Integer.parseInt(parts[5]) - 1; + int recordNumber; + try { + recordNumber = Integer.parseInt(parts[5]) - 1; + } catch (NumberFormatException exception) { + MiniGames.log(Level.WARNING, "Invalid placeholder given. " + parts[5] + + " supplied instead of record placement."); + return parameters; + } InfoType infoType = InfoType.getFromString(parts[6]); if (recordType == null || infoType == null) { diff --git a/src/main/java/net/knarcraft/minigames/property/PersistentDataKey.java b/src/main/java/net/knarcraft/minigames/property/PersistentDataKey.java index 2965f89..a3343ab 100644 --- a/src/main/java/net/knarcraft/minigames/property/PersistentDataKey.java +++ b/src/main/java/net/knarcraft/minigames/property/PersistentDataKey.java @@ -6,6 +6,9 @@ package net.knarcraft.minigames.property; public enum PersistentDataKey { MENU_ITEM("MiniGamesMenu", 1799804), + LEAVE_ITEM("MiniGamesAction", 1799871), + GIVE_UP_ITEM("MiniGamesAction", 1799872), + TOGGLE_PLAYERS_ITEM("MiniGamesAction", 1799873), ; private final String keyName; From ba1a7fff681d9dd6d7e5a38e087641bc2e166537 Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Mon, 12 Jun 2023 23:37:41 +0200 Subject: [PATCH 11/13] Adds note about underscores in arena names --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 2f525e2..4f084d8 100644 --- a/README.md +++ b/README.md @@ -154,16 +154,16 @@ This command allows editing the specified property for the specified parkour are These are all the options that can be changed for an arena. -| Option | Details | -|-----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| name | The name of the arena. Used mainly to select the arena in commands. | -| spawnLocation | The spawn location of any player joining the arena. Use `56.546,64.0,44.45` to specify coordinates, or `here`, `this` or any other string to select your current location. | -| exitLocation | The location players will be sent to when exiting the arena. If not set, the player will be sent to where they joined from. Valid values are the same as for spawnLocation. | -| winBlockType | The type of block players must hit to win the arena. It can be any material as long as it's a block, and not a type of air. | -| winLocation | The location players must reach to win the arena (see spawnLocation for valid values). If set, this overrides, and is used instead of, the win block type. | -| checkpointAdd | Adds a new checkpoint to the arena's checkpoints (see spawnLocation for valid values). | -| checkpointClear | Clears all current checkpoints. Give any value to execute. If not given a value, current checkpoints are shown. | -| killPlaneBlocks | A comma-separated list of materials which will force a loss on hit. +WOOL and other [material tags](#notes-about-material-tags) are supported as well. | +| Option | Details | +|-----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| name | The name of the arena. Used mainly to select the arena in commands. Note that underscore (_) cannot be used if you want to utilize placeholders, as it's used to split placeholder arguments. | +| spawnLocation | The spawn location of any player joining the arena. Use `56.546,64.0,44.45` to specify coordinates, or `here`, `this` or any other string to select your current location. | +| exitLocation | The location players will be sent to when exiting the arena. If not set, the player will be sent to where they joined from. Valid values are the same as for spawnLocation. | +| winBlockType | The type of block players must hit to win the arena. It can be any material as long as it's a block, and not a type of air. | +| winLocation | The location players must reach to win the arena (see spawnLocation for valid values). If set, this overrides, and is used instead of, the win block type. | +| checkpointAdd | Adds a new checkpoint to the arena's checkpoints (see spawnLocation for valid values). | +| checkpointClear | Clears all current checkpoints. Give any value to execute. If not given a value, current checkpoints are shown. | +| killPlaneBlocks | A comma-separated list of materials which will force a loss on hit. +WOOL and other [material tags](#notes-about-material-tags) are supported as well. | ## Configuration options From 57183b64f58f79a8a358f63c7924e6f7ab651ede Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Tue, 13 Jun 2023 18:42:20 +0200 Subject: [PATCH 12/13] Makes looking around a dropper arena possible --- .../arena/dropper/DropperArenaSession.java | 23 ++++++++++++++++ .../minigames/listener/MoveListener.java | 27 ++++++++++++++++++- 2 files changed, 49 insertions(+), 1 deletion(-) 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 arenaSession

The 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 location1

The first location to check

+ * @param location2

The second location to check

+ * @return

True 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 * From 8ea930a5f3ea3d68da0e340a443dfc16509a09fc Mon Sep 17 00:00:00 2001 From: EpicKnarvik97 Date: Sun, 9 Jul 2023 18:20:31 +0200 Subject: [PATCH 13/13] Makes all messages configurable --- README.md | 14 + pom.xml | 12 + .../net/knarcraft/minigames/MiniGames.java | 46 +++ .../minigames/arena/AbstractArenaSession.java | 21 +- .../minigames/arena/dropper/DropperArena.java | 2 +- .../arena/dropper/DropperArenaHandler.java | 13 +- .../arena/dropper/DropperArenaSession.java | 9 +- .../minigames/arena/parkour/ParkourArena.java | 9 +- .../arena/parkour/ParkourArenaHandler.java | 13 +- .../arena/parkour/ParkourArenaSession.java | 8 +- .../minigames/command/LeaveArenaCommand.java | 8 +- .../minigames/command/MenuCommand.java | 6 +- .../minigames/command/ReloadCommand.java | 5 +- .../dropper/CreateDropperArenaCommand.java | 11 +- .../dropper/DropperGroupListCommand.java | 11 +- .../dropper/DropperGroupSetCommand.java | 8 +- .../dropper/DropperGroupSwapCommand.java | 12 +- .../dropper/EditDropperArenaCommand.java | 21 +- .../dropper/JoinDropperArenaCommand.java | 25 +- .../dropper/ListDropperArenaCommand.java | 8 +- .../dropper/RemoveDropperArenaCommand.java | 9 +- .../parkour/CreateParkourArenaCommand.java | 10 +- .../parkour/EditParkourArenaCommand.java | 21 +- .../parkour/JoinParkourArenaCommand.java | 24 +- .../parkour/ListParkourArenaCommand.java | 8 +- .../parkour/ParkourGroupListCommand.java | 11 +- .../parkour/ParkourGroupSetCommand.java | 8 +- .../parkour/ParkourGroupSwapCommand.java | 12 +- .../parkour/RemoveParkourArenaCommand.java | 9 +- .../knarcraft/minigames/config/Message.java | 305 ------------------ .../config/MiniGameConfiguration.java | 5 +- .../minigames/config/MiniGameMessage.java | 238 ++++++++++++++ .../container/PlaceholderContainer.java | 41 --- .../minigames/listener/CommandListener.java | 4 +- .../minigames/listener/InteractListener.java | 2 - .../minigames/listener/MoveListener.java | 5 +- .../minigames/property/PersistentDataKey.java | 1 - .../minigames/util/ArenaStorageHelper.java | 2 +- .../knarcraft/minigames/util/ColorHelper.java | 29 -- .../util/DropperArenaStorageHelper.java | 12 +- .../minigames/util/MaterialHelper.java | 77 ----- .../util/ParkourArenaStorageHelper.java | 12 +- .../minigames/util/PlayerTeleporter.java | 8 +- src/main/resources/config.yml | 3 + src/main/resources/strings.yml | 43 +++ 45 files changed, 563 insertions(+), 598 deletions(-) delete mode 100644 src/main/java/net/knarcraft/minigames/config/Message.java create mode 100644 src/main/java/net/knarcraft/minigames/config/MiniGameMessage.java delete mode 100644 src/main/java/net/knarcraft/minigames/container/PlaceholderContainer.java delete mode 100644 src/main/java/net/knarcraft/minigames/util/ColorHelper.java delete mode 100644 src/main/java/net/knarcraft/minigames/util/MaterialHelper.java create mode 100644 src/main/resources/strings.yml diff --git a/README.md b/README.md index 4f084d8..85f68f7 100644 --- a/README.md +++ b/README.md @@ -259,6 +259,20 @@ Example tags: - +FENCE_GATES - +FENCES +## Language customization + +Most or all strings are customizable. If you place a strings.yml file in the plugin folder, it will take +priority over built-in languages. If you want to change strings, look at MiniGames/src/main/resources/strings.yml for +the proper keys. All strings have the format: ENUM: "Displayed string". The enum must be identical as it defines which +string you have changed. All strings belonging to a language are beneath the language code and indented with two spaces. + +The easiest way to add a new language is to copy an existing language and paste it into your custom strings.yml and +change strings as necessary. If you don't include all strings, the remaining will use the built-in English translation. +Remember to change the language code to whichever you use for your custom language. + +The interval messages are unique in that if several values are separated by comma (option1,option2,option3), a random +message will be chosen each time it's displayed. + ## License MiniGames is licensed under the GNU Public License Version 3.0. This includes every source and resource file. See the diff --git a/pom.xml b/pom.xml index 7f7c102..67c25eb 100644 --- a/pom.xml +++ b/pom.xml @@ -41,6 +41,12 @@ false + + net.knarcraft:knarlib + + net/knarcraft/knarlib/** + + net.knarcraft:knargui @@ -113,5 +119,11 @@ 1.0-SNAPSHOT compile
+ + net.knarcraft + knarlib + 1.2.3 + compile + diff --git a/src/main/java/net/knarcraft/minigames/MiniGames.java b/src/main/java/net/knarcraft/minigames/MiniGames.java index 2a34c74..6ee55b8 100644 --- a/src/main/java/net/knarcraft/minigames/MiniGames.java +++ b/src/main/java/net/knarcraft/minigames/MiniGames.java @@ -1,6 +1,9 @@ package net.knarcraft.minigames; import net.knarcraft.knargui.GUIListener; +import net.knarcraft.knarlib.formatting.StringFormatter; +import net.knarcraft.knarlib.formatting.Translator; +import net.knarcraft.knarlib.property.ColorConversion; import net.knarcraft.minigames.arena.ArenaPlayerRegistry; import net.knarcraft.minigames.arena.ArenaSession; import net.knarcraft.minigames.arena.PlayerVisibilityManager; @@ -48,6 +51,7 @@ import net.knarcraft.minigames.command.parkour.ParkourGroupSwapCommand; import net.knarcraft.minigames.command.parkour.RemoveParkourArenaCommand; import net.knarcraft.minigames.command.parkour.RemoveParkourArenaTabCompleter; import net.knarcraft.minigames.config.DropperConfiguration; +import net.knarcraft.minigames.config.MiniGameMessage; import net.knarcraft.minigames.config.ParkourConfiguration; import net.knarcraft.minigames.config.SharedConfiguration; import net.knarcraft.minigames.container.SerializableMaterial; @@ -59,6 +63,7 @@ import net.knarcraft.minigames.listener.MoveListener; import net.knarcraft.minigames.listener.PlayerStateChangeListener; import net.knarcraft.minigames.placeholder.DropperRecordExpansion; import net.knarcraft.minigames.placeholder.ParkourRecordExpansion; +import net.md_5.bungee.api.ChatColor; import org.bukkit.Bukkit; import org.bukkit.command.CommandExecutor; import org.bukkit.command.PluginCommand; @@ -89,6 +94,8 @@ public final class MiniGames extends JavaPlugin { private ParkourArenaHandler parkourArenaHandler; private ArenaPlayerRegistry parkourArenaPlayerRegistry; private PlayerVisibilityManager playerVisibilityManager; + private Translator translator; + private StringFormatter stringFormatter; /** * Gets an instance of this plugin @@ -173,6 +180,24 @@ public final class MiniGames extends JavaPlugin { return this.playerVisibilityManager; } + /** + * Gets the translator to get messages from + * + * @return

The translator

+ */ + public Translator getTranslator() { + return this.translator; + } + + /** + * Gets the string formatter to get formatted messages from + * + * @return

The string formatter

+ */ + public StringFormatter getStringFormatter() { + return this.stringFormatter; + } + /** * Gets the current session of the given player * @@ -208,6 +233,8 @@ public final class MiniGames extends JavaPlugin { // Reload configuration this.reloadConfig(); + translator.loadLanguages(this.getDataFolder(), "en", + getConfig().getString("language", "en")); this.sharedConfiguration.load(this.getConfig()); this.dropperConfiguration.load(this.getConfig()); this.parkourConfiguration.load(this.getConfig()); @@ -290,6 +317,9 @@ public final class MiniGames extends JavaPlugin { getConfig().options().copyDefaults(true); saveConfig(); reloadConfig(); + + setupStringFormatter(); + this.sharedConfiguration = new SharedConfiguration(this.getConfig()); this.dropperConfiguration = new DropperConfiguration(this.getConfig()); this.parkourConfiguration = new ParkourConfiguration(this.getConfig()); @@ -375,4 +405,20 @@ public final class MiniGames extends JavaPlugin { registerCommand("parkourGroupList", new ParkourGroupListCommand(), null); } + /** + * Sets up the translator and the string formatter + */ + private void setupStringFormatter() { + translator = new Translator(); + translator.registerMessageCategory(MiniGameMessage.ERROR_PLAYER_ONLY); + translator.loadLanguages(this.getDataFolder(), "en", + getConfig().getString("language", "en")); + stringFormatter = new StringFormatter(this.getDescription().getName(), translator); + stringFormatter.setColorConversion(ColorConversion.RGB); + stringFormatter.setNamePrefix("#546EED[&r&l"); + stringFormatter.setNameSuffix("#546EED]"); + stringFormatter.setErrorColor(ChatColor.RED); + stringFormatter.setSuccessColor(ChatColor.GREEN); + } + } diff --git a/src/main/java/net/knarcraft/minigames/arena/AbstractArenaSession.java b/src/main/java/net/knarcraft/minigames/arena/AbstractArenaSession.java index 971eece..16362fb 100644 --- a/src/main/java/net/knarcraft/minigames/arena/AbstractArenaSession.java +++ b/src/main/java/net/knarcraft/minigames/arena/AbstractArenaSession.java @@ -1,8 +1,8 @@ package net.knarcraft.minigames.arena; +import net.knarcraft.knarlib.formatting.StringFormatter; import net.knarcraft.minigames.MiniGames; -import net.knarcraft.minigames.config.Message; -import net.knarcraft.minigames.container.PlaceholderContainer; +import net.knarcraft.minigames.config.MiniGameMessage; import net.knarcraft.minigames.property.RecordResult; import net.knarcraft.minigames.util.PlayerTeleporter; import org.bukkit.Location; @@ -44,7 +44,7 @@ public abstract class AbstractArenaSession implements ArenaSession { // Make the player visible to everyone MiniGames.getInstance().getPlayerVisibilityManager().showPlayersFor(player); - player.sendMessage(Message.SUCCESS_ARENA_QUIT.getMessage()); + MiniGames.getInstance().getStringFormatter().displaySuccessMessage(player, MiniGameMessage.SUCCESS_ARENA_QUIT); } @Override @@ -69,16 +69,17 @@ public abstract class AbstractArenaSession implements ArenaSession { // Gets a string representation of the played game-mode String gameModeString = getGameModeString(); - Message recordInfoMessage = switch (recordResult) { - case WORLD_RECORD -> Message.RECORD_ACHIEVED_GLOBAL; - case PERSONAL_BEST -> Message.RECORD_ACHIEVED_PERSONAL; + MiniGameMessage recordInfoMiniGameMessage = switch (recordResult) { + case WORLD_RECORD -> MiniGameMessage.RECORD_ACHIEVED_GLOBAL; + case PERSONAL_BEST -> MiniGameMessage.RECORD_ACHIEVED_PERSONAL; default -> throw new IllegalStateException("Unexpected value: " + recordResult); }; - String recordInfo = recordInfoMessage.getPartialMessage("{recordType}", type); + StringFormatter stringFormatter = MiniGames.getInstance().getStringFormatter(); + String recordInfo = stringFormatter.replacePlaceholder(recordInfoMiniGameMessage, "{recordType}", type); - PlaceholderContainer placeholderContainer = new PlaceholderContainer().add("{gameMode}", gameModeString); - placeholderContainer.add("{recordInfo}", recordInfo); - player.sendMessage(Message.SUCCESS_RECORD_ACHIEVED.getMessage(placeholderContainer)); + stringFormatter.displaySuccessMessage(player, stringFormatter.replacePlaceholders( + MiniGameMessage.SUCCESS_RECORD_ACHIEVED, new String[]{"{gameMode}", "{recordInfo}"}, + new String[]{gameModeString, recordInfo})); } /** diff --git a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArena.java b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArena.java index eb5cbc0..ba3d627 100644 --- a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArena.java +++ b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArena.java @@ -206,7 +206,7 @@ public class DropperArena implements Arena { try { DropperArenaStorageHelper.saveDropperArenaData(getData()); return true; - } catch (IOException e) { + } catch (IOException exception) { return false; } } diff --git a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaHandler.java b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaHandler.java index bc07a47..1bb3f5b 100644 --- a/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaHandler.java +++ b/src/main/java/net/knarcraft/minigames/arena/dropper/DropperArenaHandler.java @@ -3,7 +3,7 @@ package net.knarcraft.minigames.arena.dropper; import net.knarcraft.minigames.MiniGames; import net.knarcraft.minigames.arena.ArenaHandler; import net.knarcraft.minigames.arena.ArenaPlayerRegistry; -import net.knarcraft.minigames.config.Message; +import net.knarcraft.minigames.config.MiniGameMessage; import net.knarcraft.minigames.util.DropperArenaStorageHelper; import java.io.IOException; @@ -32,9 +32,10 @@ public class DropperArenaHandler extends ArenaHandler(this.arenaGroups.values())); - } catch (IOException e) { - MiniGames.log(Level.SEVERE, Message.ERROR_CANNOT_SAVE_ARENA_GROUPS.getMessage()); - MiniGames.log(Level.SEVERE, e.getMessage()); + } catch (IOException exception) { + MiniGames.log(Level.SEVERE, MiniGames.getInstance().getTranslator().getTranslatedMessage( + MiniGameMessage.ERROR_CANNOT_SAVE_ARENA_GROUPS)); + MiniGames.log(Level.SEVERE, exception.getMessage()); } } @@ -54,10 +55,10 @@ public class DropperArenaHandler extends ArenaHandler(killPlaneBlockNames)); + new ArrayList<>(killPlaneBlockNames), "+", MiniGames.getInstance().getLogger()); this.checkpoints = checkpoints; this.parkourArenaData = parkourArenaData; this.parkourArenaHandler = arenaHandler; @@ -250,7 +250,7 @@ public class ParkourArena implements Arena { try { ParkourArenaStorageHelper.saveParkourArenaData(getData()); return true; - } catch (IOException e) { + } catch (IOException exception) { return false; } } @@ -366,7 +366,8 @@ public class ParkourArena implements Arena { if (killPlaneBlockNames.isEmpty()) { this.killPlaneBlocks = null; } else { - Set parsed = MaterialHelper.loadMaterialList(new ArrayList<>(killPlaneBlockNames)); + Set parsed = MaterialHelper.loadMaterialList(new ArrayList<>(killPlaneBlockNames), "+", + MiniGames.getInstance().getLogger()); if (parsed.isEmpty()) { return false; } diff --git a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaHandler.java b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaHandler.java index 7e52ff6..ba769da 100644 --- a/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaHandler.java +++ b/src/main/java/net/knarcraft/minigames/arena/parkour/ParkourArenaHandler.java @@ -3,7 +3,7 @@ package net.knarcraft.minigames.arena.parkour; import net.knarcraft.minigames.MiniGames; import net.knarcraft.minigames.arena.ArenaHandler; import net.knarcraft.minigames.arena.ArenaPlayerRegistry; -import net.knarcraft.minigames.config.Message; +import net.knarcraft.minigames.config.MiniGameMessage; import net.knarcraft.minigames.util.ParkourArenaStorageHelper; import java.io.IOException; @@ -32,9 +32,10 @@ public class ParkourArenaHandler extends ArenaHandler(this.arenaGroups.values())); - } catch (IOException e) { - MiniGames.log(Level.SEVERE, Message.ERROR_CANNOT_SAVE_ARENA_GROUPS.getMessage()); - MiniGames.log(Level.SEVERE, e.getMessage()); + } catch (IOException exception) { + MiniGames.log(Level.SEVERE, MiniGames.getInstance().getTranslator().getTranslatedMessage( + MiniGameMessage.ERROR_CANNOT_SAVE_ARENA_GROUPS)); + MiniGames.log(Level.SEVERE, exception.getMessage()); } } @@ -54,10 +55,10 @@ public class ParkourArenaHandler extends ArenaHandlerThis should in theory be impossible, as players cannot use any commands except /miniGamesLeave while playing - * in an arena.

- */ - ERROR_ALREADY_PLAYING("&cYou are already playing a mini-game!"), - - /** - * The message displayed if a player tries to join an arena with a passenger or riding a vehicle - */ - ERROR_JOIN_IN_VEHICLE_OR_PASSENGER("&cYou cannot join an arena while inside a vehicle or carrying a passenger."), - - /** - * The message displayed if the player tries to change an unrecognized arena property - */ - ERROR_UNKNOWN_PROPERTY("&cUnknown property specified."), - - /** - * The message displayed if the given input to /dEdit or /pEdit's value is invalid - */ - ERROR_PROPERTY_INPUT_INVALID("&cUnable to change the property. Make sure your input is valid!"), - - /** - * The message displayed if the first arena specified in /dgSwap or /pgSwap is invalid - */ - ERROR_ARENA_1_NOT_FOUND("&cUnable to find the first specified arena."), - - /** - * The message displayed if the second arena specified in /dgSwap or /pgSwap is invalid - */ - ERROR_ARENA_2_NOT_FOUND("&cUnable to find the second specified dropper arena."), - - /** - * The message displayed if the two groups specified for /dgSwap or /pgSwap are in different arenas - */ - ERROR_SWAP_DIFFERENT_GROUPS("&cYou cannot swap arenas in different groups!"), - - /** - * The message displayed if a player tries to use any command other than /mLeave while in an arena - */ - ERROR_ILLEGAL_COMMAND("&cYou cannot use that command while in an arena!"), - - /** - * The message displayed if the player is trying to join a parkour arena on hardcore which has no checkpoints - */ - ERROR_HARDCORE_NO_CHECKPOINTS("&cThis arena cannot be played in hardcore mode as it has no checkpoints!"), - - /* **************** * - * Success messages * - * **************** */ - - /** - * The message displayed if an arena's group has been changed - */ - SUCCESS_ARENA_GROUP_UPDATED("&aThe arena's group has been updated"), - - /** - * The message displayed if the MiniGames plugin is reloaded - */ - SUCCESS_PLUGIN_RELOADED("&aPlugin reloaded!"), - - /** - * The message displayed if a new arena has been created - */ - SUCCESS_ARENA_CREATED("&aThe arena was successfully created!"), - - /** - * The message displayed if a player clears/wins an arena for the first time - */ - SUCCESS_ARENA_FIRST_CLEAR("&aYou cleared the arena!"), - - /** - * The message displayed when a player wins an arena - */ - SUCCESS_ARENA_WIN("&aYou won!"), - - /** - * The message displayed when a player quits an arena - */ - SUCCESS_ARENA_QUIT("&aYou quit the arena!"), - - /** - * The message used to display the current value of an arena property - */ - SUCCESS_CURRENT_VALUE("&aCurrent value of {property} is: {value}"), - - /** - * The message used to announce that an arena property has been changed - */ - SUCCESS_PROPERTY_CHANGED("&aProperty {property} successfully changed"), - - /** - * The message displayed when two arenas' order in a group have been swapped - */ - SUCCESS_ARENAS_SWAPPED("&aThe arenas have been swapped!"), - - /** - * The message displayed when an arena has been removed - */ - SUCCESS_ARENA_REMOVED("&aThe specified arena has been successfully removed"), - - /** - * The header displayed before listing all dropper arenas - */ - SUCCESS_DROPPER_ARENAS_LIST("&aDropper arenas:&r"), - - /** - * The header displayed before listing all parkour arenas - */ - SUCCESS_PARKOUR_ARENAS_LIST("&aParkour arenas:&r"), - - /** - * The message displayed when a player reaches a new checkpoint in a parkour arena - */ - SUCCESS_CHECKPOINT_REACHED("&aCheckpoint reached!"), - - /** - * The header displayed before listing all arenas (stages) in a group - */ - SUCCESS_GROUP_STAGES("&a{group}'s stages:&r"), - - /** - * The message displayed when a new record has been achieved - */ - SUCCESS_RECORD_ACHIEVED("&aYou just set a {recordInfo} on the {gameMode} game-mode!"), - - /** - * The partial message used to describe that the player achieved a world record - */ - RECORD_ACHIEVED_GLOBAL("new {recordType} record"), - - /** - * The partial message used to describe that the player achieved a personal best record - */ - RECORD_ACHIEVED_PERSONAL("personal {recordType} record"), - - /** - * The message displayed when a player joins an arena - */ - SUCCESS_ARENA_JOINED("&aYou joined the arena."), - ; - - private final @NotNull String defaultMessage; - - /** - * Instantiates a new message - * - * @param defaultMessage

The default value of the message

- */ - Message(@NotNull String defaultMessage) { - this.defaultMessage = defaultMessage; - } - - /** - * Gets the message this enum represents - * - * @return

The formatted message

- */ - public @NotNull String getMessage() { - return formatMessage(this.defaultMessage); - } - - /** - * Gets the message this enum represents - * - * @param placeholder

The placeholder to replace

- * @param replacement

The replacement to use

- * @return

The formatted message

- */ - public @NotNull String getMessage(@NotNull String placeholder, @NotNull String replacement) { - return formatMessage(this.defaultMessage.replace(placeholder, replacement)); - } - - /** - * Gets the message this enum represents, intended for display within another message - * - * @param placeholder

The placeholder to replace

- * @param replacement

The replacement to use

- * @return

The formatted message

- */ - public @NotNull String getPartialMessage(@NotNull String placeholder, @NotNull String replacement) { - return ColorHelper.translateAllColorCodes(this.defaultMessage.replace(placeholder, replacement)); - } - - /** - * Gets the message this enum represents - * - * @param placeholders

The placeholder -> replacement map specifying necessary replacements

- * @return

The formatted message

- */ - public @NotNull String getMessage(@NotNull PlaceholderContainer placeholders) { - String replaced = this.defaultMessage; - for (Map.Entry entry : placeholders.getPlaceholders().entrySet()) { - replaced = replaced.replace(entry.getKey(), entry.getValue()); - } - return formatMessage(replaced); - } - - /** - * Gets the formatted version of the given message - * - * @param message

The message to format

- * @return

The formatted message

- */ - private @NotNull String formatMessage(@NotNull String message) { - String prefix = MiniGames.getInstance().getDescription().getPrefix(); - return ColorHelper.translateAllColorCodes("#546EED[&r&l" + prefix + "#546EED]&r " + message); - } - -} diff --git a/src/main/java/net/knarcraft/minigames/config/MiniGameConfiguration.java b/src/main/java/net/knarcraft/minigames/config/MiniGameConfiguration.java index 6786308..d9ba06e 100644 --- a/src/main/java/net/knarcraft/minigames/config/MiniGameConfiguration.java +++ b/src/main/java/net/knarcraft/minigames/config/MiniGameConfiguration.java @@ -1,6 +1,7 @@ package net.knarcraft.minigames.config; -import net.knarcraft.minigames.util.MaterialHelper; +import net.knarcraft.knarlib.util.MaterialHelper; +import net.knarcraft.minigames.MiniGames; import org.bukkit.Material; import org.bukkit.configuration.file.FileConfiguration; import org.jetbrains.annotations.NotNull; @@ -46,7 +47,7 @@ public abstract class MiniGameConfiguration { */ public @NotNull Set loadMaterialList(@NotNull String path) { List blockWhitelist = configuration.getList(path, new ArrayList<>()); - return MaterialHelper.loadMaterialList(blockWhitelist); + return MaterialHelper.loadMaterialList(blockWhitelist, "+", MiniGames.getInstance().getLogger()); } } diff --git a/src/main/java/net/knarcraft/minigames/config/MiniGameMessage.java b/src/main/java/net/knarcraft/minigames/config/MiniGameMessage.java new file mode 100644 index 0000000..4fb9d62 --- /dev/null +++ b/src/main/java/net/knarcraft/minigames/config/MiniGameMessage.java @@ -0,0 +1,238 @@ +package net.knarcraft.minigames.config; + +import net.knarcraft.knarlib.formatting.TranslatableMessage; +import org.jetbrains.annotations.NotNull; + +/** + * A message which ca be displayed to the user + */ +public enum MiniGameMessage implements TranslatableMessage { + + /* ************** * + * Error messages * + * ************** */ + + /** + * The message displayed if saving arena groups fails + */ + ERROR_CANNOT_SAVE_ARENA_GROUPS, + + /** + * The message displayed if an un-parse-able message is given by a user + */ + ERROR_MATERIAL_NOT_PARSE_ABLE, + + /** + * The message displayed if a player tries to be teleported to/from an arena with a passenger + */ + ERROR_TELEPORT_WITH_PASSENGER, + + /** + * The message displayed if a player tries to be teleported to/from an arena with a vehicle + */ + ERROR_TELEPORT_IN_VEHICLE, + + /** + * The message displayed if an arena cannot be loaded + */ + ERROR_ARENA_NOT_LOADED, + + /** + * The message displayed if an arena's data cannot be loaded + */ + ERROR_ARENA_DATA_NOT_LOADED, + + /** + * The message displayed if the user specifies an unrecognized arena + */ + ERROR_ARENA_NOT_FOUND, + + /** + * The message displayed if the user specifies an unrecognized group + */ + ERROR_GROUP_NOT_FOUND, + + /** + * The message displayed if the console tries to execute a player-only command + */ + ERROR_PLAYER_ONLY, + + /** + * The message displayed if the name of an arena is duplicated + */ + ERROR_ARENA_NAME_COLLISION, + + /** + * The message displayed if the player is required to win on the default difficulty first + */ + ERROR_NORMAL_MODE_REQUIRED, + + /** + * The message displayed if the player is required to win on the default difficulty for all arenas in the group first + */ + ERROR_GROUP_NORMAL_MODE_REQUIRED, + + /** + * The message displayed if the player is required to beat the previous arena in the group + */ + ERROR_PREVIOUS_ARENA_REQUIRED, + + /** + * The message displayed if player teleportation failed for some reason + */ + ERROR_ARENA_TELEPORT_FAILED, + + /** + * The message displayed if the player tries to quit the arena while not in an arena + */ + ERROR_NOT_IN_ARENA, + + /** + * The message displayed if the player tries to join an arena while already playing + * + *

This should in theory be impossible, as players cannot use any commands except /miniGamesLeave while playing + * in an arena.

+ */ + ERROR_ALREADY_PLAYING, + + /** + * The message displayed if a player tries to join an arena with a passenger or riding a vehicle + */ + ERROR_JOIN_IN_VEHICLE_OR_PASSENGER, + + /** + * The message displayed if the player tries to change an unrecognized arena property + */ + ERROR_UNKNOWN_PROPERTY, + + /** + * The message displayed if the given input to /dEdit or /pEdit's value is invalid + */ + ERROR_PROPERTY_INPUT_INVALID, + + /** + * The message displayed if the first arena specified in /dgSwap or /pgSwap is invalid + */ + ERROR_ARENA_1_NOT_FOUND, + + /** + * The message displayed if the second arena specified in /dgSwap or /pgSwap is invalid + */ + ERROR_ARENA_2_NOT_FOUND, + + /** + * The message displayed if the two groups specified for /dgSwap or /pgSwap are in different arenas + */ + ERROR_SWAP_DIFFERENT_GROUPS, + + /** + * The message displayed if a player tries to use any command other than /mLeave while in an arena + */ + ERROR_ILLEGAL_COMMAND, + + /** + * The message displayed if the player is trying to join a parkour arena on hardcore which has no checkpoints + */ + ERROR_HARDCORE_NO_CHECKPOINTS, + + /* **************** * + * Success messages * + * **************** */ + + /** + * The message displayed if an arena's group has been changed + */ + SUCCESS_ARENA_GROUP_UPDATED, + + /** + * The message displayed if the MiniGames plugin is reloaded + */ + SUCCESS_PLUGIN_RELOADED, + + /** + * The message displayed if a new arena has been created + */ + SUCCESS_ARENA_CREATED, + + /** + * The message displayed if a player clears/wins an arena for the first time + */ + SUCCESS_ARENA_FIRST_CLEAR, + + /** + * The message displayed when a player wins an arena + */ + SUCCESS_ARENA_WIN, + + /** + * The message displayed when a player quits an arena + */ + SUCCESS_ARENA_QUIT, + + /** + * The message used to display the current value of an arena property + */ + SUCCESS_CURRENT_VALUE, + + /** + * The message used to announce that an arena property has been changed + */ + SUCCESS_PROPERTY_CHANGED, + + /** + * The message displayed when two arenas' order in a group have been swapped + */ + SUCCESS_ARENAS_SWAPPED, + + /** + * The message displayed when an arena has been removed + */ + SUCCESS_ARENA_REMOVED, + + /** + * The header displayed before listing all dropper arenas + */ + SUCCESS_DROPPER_ARENAS_LIST, + + /** + * The header displayed before listing all parkour arenas + */ + SUCCESS_PARKOUR_ARENAS_LIST, + + /** + * The message displayed when a player reaches a new checkpoint in a parkour arena + */ + SUCCESS_CHECKPOINT_REACHED, + + /** + * The header displayed before listing all arenas (stages) in a group + */ + SUCCESS_GROUP_STAGES, + + /** + * The message displayed when a new record has been achieved + */ + SUCCESS_RECORD_ACHIEVED, + + /** + * The partial message used to describe that the player achieved a world record + */ + RECORD_ACHIEVED_GLOBAL, + + /** + * The partial message used to describe that the player achieved a personal best record + */ + RECORD_ACHIEVED_PERSONAL, + + /** + * The message displayed when a player joins an arena + */ + SUCCESS_ARENA_JOINED, + ; + + @Override + public @NotNull TranslatableMessage[] getAllMessages() { + return MiniGameMessage.values(); + } + +} diff --git a/src/main/java/net/knarcraft/minigames/container/PlaceholderContainer.java b/src/main/java/net/knarcraft/minigames/container/PlaceholderContainer.java deleted file mode 100644 index ca88158..0000000 --- a/src/main/java/net/knarcraft/minigames/container/PlaceholderContainer.java +++ /dev/null @@ -1,41 +0,0 @@ -package net.knarcraft.minigames.container; - -import java.util.HashMap; -import java.util.Map; - -/** - * A container for keeping track of several placeholder to value mappings - */ -public class PlaceholderContainer { - - private final Map placeholders; - - /** - * Instantiates a new placeholder container - */ - public PlaceholderContainer() { - this.placeholders = new HashMap<>(); - } - - /** - * Gets all placeholders - * - * @return

All placeholders

- */ - public Map getPlaceholders() { - return new HashMap<>(this.placeholders); - } - - /** - * Adds a new placeholder - * - * @param placeholder

The placeholder to register

- * @param value

The value of the placeholder

- * @return

This object

- */ - public PlaceholderContainer add(String placeholder, String value) { - this.placeholders.put(placeholder, value); - return this; - } - -} diff --git a/src/main/java/net/knarcraft/minigames/listener/CommandListener.java b/src/main/java/net/knarcraft/minigames/listener/CommandListener.java index 7557242..7d64d86 100644 --- a/src/main/java/net/knarcraft/minigames/listener/CommandListener.java +++ b/src/main/java/net/knarcraft/minigames/listener/CommandListener.java @@ -2,7 +2,7 @@ package net.knarcraft.minigames.listener; import net.knarcraft.minigames.MiniGames; import net.knarcraft.minigames.arena.ArenaSession; -import net.knarcraft.minigames.config.Message; +import net.knarcraft.minigames.config.MiniGameMessage; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -43,7 +43,7 @@ public class CommandListener implements Listener { } } - player.sendMessage(Message.ERROR_ILLEGAL_COMMAND.getMessage()); + MiniGames.getInstance().getStringFormatter().displayErrorMessage(player, MiniGameMessage.ERROR_ILLEGAL_COMMAND); event.setCancelled(true); } diff --git a/src/main/java/net/knarcraft/minigames/listener/InteractListener.java b/src/main/java/net/knarcraft/minigames/listener/InteractListener.java index fe96318..c16b95b 100644 --- a/src/main/java/net/knarcraft/minigames/listener/InteractListener.java +++ b/src/main/java/net/knarcraft/minigames/listener/InteractListener.java @@ -46,8 +46,6 @@ public class InteractListener implements Listener { ArenaGUI.getLeaveAction().run(event.getPlayer()); } else if (persistentData == PersistentDataKey.GIVE_UP_ITEM.getDataValue()) { ParkourGUI.getGiveUpAction().run(event.getPlayer()); - } else if (persistentData == PersistentDataKey.TOGGLE_PLAYERS_ITEM.getDataValue()) { - //TODO: Figure out how in the world this should be done, as the existing code cannot be re-used } } } diff --git a/src/main/java/net/knarcraft/minigames/listener/MoveListener.java b/src/main/java/net/knarcraft/minigames/listener/MoveListener.java index f11ee9f..5e50440 100644 --- a/src/main/java/net/knarcraft/minigames/listener/MoveListener.java +++ b/src/main/java/net/knarcraft/minigames/listener/MoveListener.java @@ -9,7 +9,7 @@ import net.knarcraft.minigames.arena.parkour.ParkourArena; import net.knarcraft.minigames.arena.parkour.ParkourArenaGameMode; import net.knarcraft.minigames.arena.parkour.ParkourArenaSession; import net.knarcraft.minigames.config.DropperConfiguration; -import net.knarcraft.minigames.config.Message; +import net.knarcraft.minigames.config.MiniGameMessage; import net.knarcraft.minigames.config.ParkourConfiguration; import net.knarcraft.minigames.config.SharedConfiguration; import org.bukkit.Bukkit; @@ -121,7 +121,8 @@ public class MoveListener implements Listener { // Register the checkpoint arenaSession.registerCheckpoint(checkpoint.clone()); - player.sendMessage(Message.SUCCESS_CHECKPOINT_REACHED.getMessage()); + MiniGames.getInstance().getStringFormatter().displaySuccessMessage(player, + MiniGameMessage.SUCCESS_CHECKPOINT_REACHED); return; } } diff --git a/src/main/java/net/knarcraft/minigames/property/PersistentDataKey.java b/src/main/java/net/knarcraft/minigames/property/PersistentDataKey.java index a3343ab..4536ded 100644 --- a/src/main/java/net/knarcraft/minigames/property/PersistentDataKey.java +++ b/src/main/java/net/knarcraft/minigames/property/PersistentDataKey.java @@ -8,7 +8,6 @@ public enum PersistentDataKey { MENU_ITEM("MiniGamesMenu", 1799804), LEAVE_ITEM("MiniGamesAction", 1799871), GIVE_UP_ITEM("MiniGamesAction", 1799872), - TOGGLE_PLAYERS_ITEM("MiniGamesAction", 1799873), ; private final String keyName; diff --git a/src/main/java/net/knarcraft/minigames/util/ArenaStorageHelper.java b/src/main/java/net/knarcraft/minigames/util/ArenaStorageHelper.java index 9abfd2d..34ac68a 100644 --- a/src/main/java/net/knarcraft/minigames/util/ArenaStorageHelper.java +++ b/src/main/java/net/knarcraft/minigames/util/ArenaStorageHelper.java @@ -35,7 +35,7 @@ public final class ArenaStorageHelper { try { configuration.save(new File(MiniGames.getInstance().getDataFolder(), key + "EntryStates.yml")); - } catch (IOException e) { + } catch (IOException exception) { MiniGames.log(Level.SEVERE, "Unable to save entry states to disk"); } } diff --git a/src/main/java/net/knarcraft/minigames/util/ColorHelper.java b/src/main/java/net/knarcraft/minigames/util/ColorHelper.java deleted file mode 100644 index 4b79d19..0000000 --- a/src/main/java/net/knarcraft/minigames/util/ColorHelper.java +++ /dev/null @@ -1,29 +0,0 @@ -package net.knarcraft.minigames.util; - -import net.md_5.bungee.api.ChatColor; - -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * A helper class for converting colors - */ -public class ColorHelper { - - /** - * Translates all found color codes to formatting in a string - * - * @param message

The string to search for color codes

- * @return

The message with color codes translated

- */ - public static String translateAllColorCodes(String message) { - message = ChatColor.translateAlternateColorCodes('&', message); - Pattern pattern = Pattern.compile("&?(#[a-fA-F0-9]{6})"); - Matcher matcher = pattern.matcher(message); - while (matcher.find()) { - message = message.replace(matcher.group(), "" + ChatColor.of(matcher.group(1))); - } - return message; - } - -} diff --git a/src/main/java/net/knarcraft/minigames/util/DropperArenaStorageHelper.java b/src/main/java/net/knarcraft/minigames/util/DropperArenaStorageHelper.java index 524b736..0b2c22d 100644 --- a/src/main/java/net/knarcraft/minigames/util/DropperArenaStorageHelper.java +++ b/src/main/java/net/knarcraft/minigames/util/DropperArenaStorageHelper.java @@ -9,8 +9,7 @@ import net.knarcraft.minigames.arena.dropper.DropperArenaGameMode; import net.knarcraft.minigames.arena.dropper.DropperArenaGroup; import net.knarcraft.minigames.arena.dropper.DropperArenaRecordsRegistry; import net.knarcraft.minigames.arena.dropper.DropperArenaStorageKey; -import net.knarcraft.minigames.config.Message; -import net.knarcraft.minigames.container.PlaceholderContainer; +import net.knarcraft.minigames.config.MiniGameMessage; import net.knarcraft.minigames.container.SerializableMaterial; import net.knarcraft.minigames.container.SerializableUUID; import org.bukkit.Location; @@ -161,8 +160,9 @@ public final class DropperArenaStorageHelper { DropperArenaStorageKey.WIN_BLOCK_TYPE.getKey()); if (arenaName == null || spawnLocation == null) { - MiniGames.log(Level.SEVERE, Message.ERROR_ARENA_NOT_LOADED.getMessage(new PlaceholderContainer().add( - "{section}", configurationSection.getName()).add("{file}", "dropper_arenas"))); + MiniGames.log(Level.SEVERE, MiniGames.getInstance().getStringFormatter().replacePlaceholders( + MiniGameMessage.ERROR_ARENA_NOT_LOADED, new String[]{"{section}", "{file}"}, + new String[]{configurationSection.getName(), "dropper_arenas"})); return null; } if (winBlockType == null) { @@ -172,8 +172,8 @@ public final class DropperArenaStorageHelper { // Generate new, empty arena data if not available DropperArenaData arenaData = loadDropperArenaData(arenaId); if (arenaData == null) { - MiniGames.log(Level.SEVERE, Message.ERROR_ARENA_DATA_NOT_LOADED.getMessage("{arena}", - arenaId.toString())); + MiniGames.log(Level.SEVERE, MiniGames.getInstance().getStringFormatter().replacePlaceholder( + MiniGameMessage.ERROR_ARENA_DATA_NOT_LOADED, "{arena}", arenaId.toString())); arenaData = getEmptyDropperData(arenaId); } diff --git a/src/main/java/net/knarcraft/minigames/util/MaterialHelper.java b/src/main/java/net/knarcraft/minigames/util/MaterialHelper.java deleted file mode 100644 index 2a50b5a..0000000 --- a/src/main/java/net/knarcraft/minigames/util/MaterialHelper.java +++ /dev/null @@ -1,77 +0,0 @@ -package net.knarcraft.minigames.util; - -import net.knarcraft.minigames.MiniGames; -import net.knarcraft.minigames.config.Message; -import org.bukkit.Bukkit; -import org.bukkit.Material; -import org.bukkit.NamespacedKey; -import org.bukkit.Tag; -import org.jetbrains.annotations.NotNull; - -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.logging.Level; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * A helper class for dealing with and parsing materials - */ -public final class MaterialHelper { - - private MaterialHelper() { - - } - - /** - * Loads the materials specified in the block whitelist - */ - public static @NotNull Set loadMaterialList(@NotNull List materials) { - Set parsedMaterials = new HashSet<>(); - for (Object value : materials) { - if (!(value instanceof String string)) { - continue; - } - - // Try to parse a material tag first - if (parseMaterialTag(parsedMaterials, string)) { - continue; - } - - // Try to parse a material name - Material matched = Material.matchMaterial(string); - if (matched != null) { - parsedMaterials.add(matched); - } else { - MiniGames.log(Level.WARNING, Message.ERROR_MATERIAL_NOT_PARSE_ABLE.getMessage("{material}", string)); - } - } - return parsedMaterials; - } - - /** - * Tries to parse the material tag in the specified material name - * - * @param targetSet

The set all parsed materials should be added to

- * @param materialName

The material name that might be a material tag

- * @return

True if a tag was found

- */ - private static boolean parseMaterialTag(@NotNull Set targetSet, @NotNull String materialName) { - Pattern pattern = Pattern.compile("^\\+([a-zA-Z_]+)"); - Matcher matcher = pattern.matcher(materialName); - if (matcher.find()) { - // The material is a material tag - Tag tag = Bukkit.getTag(Tag.REGISTRY_BLOCKS, NamespacedKey.minecraft( - matcher.group(1).toLowerCase()), Material.class); - if (tag != null) { - targetSet.addAll(tag.getValues()); - } else { - MiniGames.log(Level.WARNING, "Unable to parse: " + materialName); - } - return true; - } - return false; - } - -} diff --git a/src/main/java/net/knarcraft/minigames/util/ParkourArenaStorageHelper.java b/src/main/java/net/knarcraft/minigames/util/ParkourArenaStorageHelper.java index 375ab4b..1c00c64 100644 --- a/src/main/java/net/knarcraft/minigames/util/ParkourArenaStorageHelper.java +++ b/src/main/java/net/knarcraft/minigames/util/ParkourArenaStorageHelper.java @@ -9,8 +9,7 @@ import net.knarcraft.minigames.arena.parkour.ParkourArenaGameMode; import net.knarcraft.minigames.arena.parkour.ParkourArenaGroup; import net.knarcraft.minigames.arena.parkour.ParkourArenaRecordsRegistry; import net.knarcraft.minigames.arena.parkour.ParkourArenaStorageKey; -import net.knarcraft.minigames.config.Message; -import net.knarcraft.minigames.container.PlaceholderContainer; +import net.knarcraft.minigames.config.MiniGameMessage; import net.knarcraft.minigames.container.SerializableMaterial; import net.knarcraft.minigames.container.SerializableUUID; import org.bukkit.Location; @@ -166,8 +165,9 @@ public final class ParkourArenaStorageHelper { // The arena name and spawn location must be present if (arenaName == null || spawnLocation == null) { - MiniGames.log(Level.SEVERE, Message.ERROR_ARENA_NOT_LOADED.getMessage(new PlaceholderContainer().add( - "{section}", configurationSection.getName()).add("{file}", "parkour_arena"))); + MiniGames.log(Level.SEVERE, MiniGames.getInstance().getStringFormatter().replacePlaceholders( + MiniGameMessage.ERROR_ARENA_NOT_LOADED, new String[]{"{section}", "{file}"}, + new String[]{configurationSection.getName(), "parkour_arena"})); return null; } @@ -179,8 +179,8 @@ public final class ParkourArenaStorageHelper { // Generate new, empty arena data if not available ParkourArenaData arenaData = loadParkourArenaData(arenaId); if (arenaData == null) { - MiniGames.log(Level.SEVERE, Message.ERROR_ARENA_DATA_NOT_LOADED.getMessage("{arena}", - arenaId.toString())); + MiniGames.log(Level.SEVERE, MiniGames.getInstance().getStringFormatter().replacePlaceholder( + MiniGameMessage.ERROR_ARENA_DATA_NOT_LOADED, "{arena}", arenaId.toString())); arenaData = getEmptyParkourData(arenaId); } diff --git a/src/main/java/net/knarcraft/minigames/util/PlayerTeleporter.java b/src/main/java/net/knarcraft/minigames/util/PlayerTeleporter.java index 974a042..af700f7 100644 --- a/src/main/java/net/knarcraft/minigames/util/PlayerTeleporter.java +++ b/src/main/java/net/knarcraft/minigames/util/PlayerTeleporter.java @@ -1,7 +1,7 @@ package net.knarcraft.minigames.util; import net.knarcraft.minigames.MiniGames; -import net.knarcraft.minigames.config.Message; +import net.knarcraft.minigames.config.MiniGameMessage; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.Entity; @@ -36,7 +36,8 @@ public final class PlayerTeleporter { passenger.teleport(location); } } else { - player.sendMessage(Message.ERROR_TELEPORT_WITH_PASSENGER.getMessage()); + MiniGames.getInstance().getStringFormatter().displayErrorMessage(player, + MiniGameMessage.ERROR_TELEPORT_WITH_PASSENGER); return false; } } @@ -46,7 +47,8 @@ public final class PlayerTeleporter { player.eject(); vehicle.teleport(location); } else { - player.sendMessage(Message.ERROR_TELEPORT_IN_VEHICLE.getMessage()); + MiniGames.getInstance().getStringFormatter().displayErrorMessage(player, + MiniGameMessage.ERROR_TELEPORT_IN_VEHICLE); return false; } } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index c57c19e..63423cb 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,4 +1,7 @@ # Configuration values for mini-games + +# The chosen language for Launchpad. You can use "en" or any custom language specified in strings.yml +language: en 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 diff --git a/src/main/resources/strings.yml b/src/main/resources/strings.yml new file mode 100644 index 0000000..cf2062a --- /dev/null +++ b/src/main/resources/strings.yml @@ -0,0 +1,43 @@ +en: + ERROR_CANNOT_SAVE_ARENA_GROUPS: "Unable to save current arena groups! Data loss can occur!" + ERROR_MATERIAL_NOT_PARSE_ABLE: "Unable to parse material: {material}" + ERROR_TELEPORT_WITH_PASSENGER: "You cannot be teleported with a passenger!" + ERROR_TELEPORT_IN_VEHICLE: "You cannot be teleported while in a vehicle" + ERROR_ARENA_NOT_LOADED: "Could not load the arena at configuration section {section}. Please check the {file} storage file for issues." + ERROR_ARENA_DATA_NOT_LOADED: "Unable to load arena data for dropper arena: {arena}" + ERROR_ARENA_NOT_FOUND: "Unable to find the specified arena." + ERROR_GROUP_NOT_FOUND: "Unable to find the specified group!" + ERROR_PLAYER_ONLY: "This command must be used by a player" + ERROR_ARENA_NAME_COLLISION: "There already exists an arena with that name!" + ERROR_NORMAL_MODE_REQUIRED: "You must complete this arena in normal mode first!" + ERROR_GROUP_NORMAL_MODE_REQUIRED: "You have not yet beaten the default game-mode for all arenas in this group!" + ERROR_PREVIOUS_ARENA_REQUIRED: "You have not yet beaten the previous arena!" + ERROR_ARENA_TELEPORT_FAILED: "Unable to teleport you to the arena." + ERROR_NOT_IN_ARENA: "You are not in a mini-games arena!" + ERROR_ALREADY_PLAYING: "You are already playing a mini-game!" + ERROR_JOIN_IN_VEHICLE_OR_PASSENGER: "You cannot join an arena while inside a vehicle or carrying a passenger." + ERROR_UNKNOWN_PROPERTY: "Unknown property specified." + ERROR_PROPERTY_INPUT_INVALID: "Unable to change the property. Make sure your input is valid!" + ERROR_ARENA_1_NOT_FOUND: "Unable to find the first specified arena." + ERROR_ARENA_2_NOT_FOUND: "Unable to find the second specified dropper arena." + ERROR_SWAP_DIFFERENT_GROUPS: "You cannot swap arenas in different groups!" + ERROR_ILLEGAL_COMMAND: "You cannot use that command while in an arena!" + ERROR_HARDCORE_NO_CHECKPOINTS: "This arena cannot be played in hardcore mode as it has no checkpoints!" + SUCCESS_ARENA_GROUP_UPDATED: "The arena's group has been updated" + SUCCESS_PLUGIN_RELOADED: "Plugin reloaded!" + SUCCESS_ARENA_CREATED: "The arena was successfully created!" + SUCCESS_ARENA_FIRST_CLEAR: "You cleared the arena!" + SUCCESS_ARENA_WIN: "You won!" + SUCCESS_ARENA_QUIT: "You quit the arena!" + SUCCESS_CURRENT_VALUE: "Current value of {property} is: {value}" + SUCCESS_PROPERTY_CHANGED: "Property {property} successfully changed" + SUCCESS_ARENAS_SWAPPED: "The arenas have been swapped!" + SUCCESS_ARENA_REMOVED: "The specified arena has been successfully removed" + SUCCESS_DROPPER_ARENAS_LIST: "Dropper arenas:&r" + SUCCESS_PARKOUR_ARENAS_LIST: "Parkour arenas:&r" + SUCCESS_CHECKPOINT_REACHED: "Checkpoint reached!" + SUCCESS_GROUP_STAGES: "{group}'s stages:&r" + SUCCESS_RECORD_ACHIEVED: "You just set a {recordInfo} on the {gameMode} game-mode!" + RECORD_ACHIEVED_GLOBAL: "new {recordType} record" + RECORD_ACHIEVED_PERSONAL: "personal {recordType} record" + SUCCESS_ARENA_JOINED: "You joined the arena." \ No newline at end of file