From 02cc74cc5ac06a69ec59d6277234ce69031402f4 Mon Sep 17 00:00:00 2001 From: sowgro Date: Thu, 27 Jun 2024 02:40:06 -0400 Subject: overhaul command and config formats (again) --- README.md | 68 ++++---- src/main/java/com/MylesAndMore/Tumble/Main.java | 15 +- .../com/MylesAndMore/Tumble/commands/Config.java | 122 ------------- .../com/MylesAndMore/Tumble/commands/Create.java | 44 +++++ .../MylesAndMore/Tumble/commands/ForceStart.java | 33 ++-- .../MylesAndMore/Tumble/commands/ForceStop.java | 35 ++-- .../com/MylesAndMore/Tumble/commands/Join.java | 50 ++++-- .../com/MylesAndMore/Tumble/commands/Leave.java | 33 ++-- .../com/MylesAndMore/Tumble/commands/Reload.java | 27 +-- .../com/MylesAndMore/Tumble/commands/Remove.java | 53 ++++++ .../MylesAndMore/Tumble/commands/SetGameSpawn.java | 60 +++++++ .../Tumble/commands/SetKillYCordinate.java | 61 +++++++ .../com/MylesAndMore/Tumble/commands/SetLobby.java | 60 +++++++ .../MylesAndMore/Tumble/commands/SetWaitArea.java | 60 +++++++ .../Tumble/commands/SetWinnerLobby.java | 60 +++++++ .../com/MylesAndMore/Tumble/commands/Tumble.java | 85 +++++++++ .../MylesAndMore/Tumble/config/ArenaManager.java | 178 +++++++++++++++++++ .../MylesAndMore/Tumble/config/ConfigManager.java | 23 +++ .../Tumble/config/LanguageManager.java | 50 ++++++ .../java/com/MylesAndMore/Tumble/game/Arena.java | 19 +- .../MylesAndMore/Tumble/game/EventListener.java | 13 +- .../java/com/MylesAndMore/Tumble/game/Game.java | 48 ++--- .../MylesAndMore/Tumble/plugin/ConfigManager.java | 194 --------------------- .../com/MylesAndMore/Tumble/plugin/SubCommand.java | 8 + src/main/resources/arenas.yml | 23 +++ src/main/resources/config.yml | 37 ---- src/main/resources/language.yml | 42 +++++ src/main/resources/plugin.yml | 27 +-- 28 files changed, 1005 insertions(+), 523 deletions(-) delete mode 100644 src/main/java/com/MylesAndMore/Tumble/commands/Config.java create mode 100644 src/main/java/com/MylesAndMore/Tumble/commands/Create.java create mode 100644 src/main/java/com/MylesAndMore/Tumble/commands/Remove.java create mode 100644 src/main/java/com/MylesAndMore/Tumble/commands/SetGameSpawn.java create mode 100644 src/main/java/com/MylesAndMore/Tumble/commands/SetKillYCordinate.java create mode 100644 src/main/java/com/MylesAndMore/Tumble/commands/SetLobby.java create mode 100644 src/main/java/com/MylesAndMore/Tumble/commands/SetWaitArea.java create mode 100644 src/main/java/com/MylesAndMore/Tumble/commands/SetWinnerLobby.java create mode 100644 src/main/java/com/MylesAndMore/Tumble/commands/Tumble.java create mode 100644 src/main/java/com/MylesAndMore/Tumble/config/ArenaManager.java create mode 100644 src/main/java/com/MylesAndMore/Tumble/config/ConfigManager.java create mode 100644 src/main/java/com/MylesAndMore/Tumble/config/LanguageManager.java delete mode 100644 src/main/java/com/MylesAndMore/Tumble/plugin/ConfigManager.java create mode 100644 src/main/java/com/MylesAndMore/Tumble/plugin/SubCommand.java create mode 100644 src/main/resources/arenas.yml create mode 100644 src/main/resources/language.yml diff --git a/README.md b/README.md index a034629..878e08f 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,17 @@ +## temporary stuff (not ready for merge) +### known issues +- [ ] file writing not fully implemented (just need to call ArenaManager.write() somewhere) +- [ ] issues with join command +- [ ] no config validation + +### todo +- [ ] improve inventory saving +- [ ] improve Game.leave() method +- [ ] perhaps replace spectator mode with survival flight +- [ ] clean up and make config managers uniform in structure +- [ ] improve language flow +- [ ] put javadoc comments everywhere + # Tumble ## Overview @@ -6,11 +20,11 @@ Tumble is a Spigot/Paper plugin that aims to recreate the Tumble minigame from t ## What *is* Tumble? -If you've never heard of it, [Tumble](https://minecraft.wiki/w/Tumble) is a twist on the classic Minecraft minigame of spleef, where the objective is to break the blocks under your opponents. But in Tumble, you play on randomly generated layers of blocks, using shovels, snowballs, or both to try and eliminate your opponents. +If you've never heard of it, [Tumble](https://minecraft.wiki/w/tmbl) is a twist on the classic Minecraft minigame of spleef, where the objective is to break the blocks under your opponents. But in Tumble, you play on randomly generated layers of blocks, using shovels, snowballs, or both to try and eliminate your opponents. ## Features -- Choose from three different game modes present in the original game--shovels, snowballs, and mixed +- Choose from three different game modes present in the original game: shovels, snowballs, and mixed - Four types of random layer generation - 15 unique, themed layer varieties - Quick and easy setup and use @@ -21,51 +35,35 @@ If you've never heard of it, [Tumble](https://minecraft.wiki/w/Tumble) is a twis ## Setup -1. Simply [download](https://github.com/MylesAndMore/Tumble/releases) the plugin's JAR file and place it in your server's plugins directory. -2. Make sure that you have at least two worlds in your world directory! One is for your lobby world, and the other is for your game arena. +1. Simply [download](https://github.com/MylesAndMore/tmbl/releases) the plugin's JAR file and place it in your server's plugins directory. +2. Load the worlds for your lobby and arenas. - - If you would like an experience similar to the original game, see [my guide](https://github.com/MylesAndMore/tumble/blob/main/og-guide.md) for using the original worlds. + - If you would like an experience similar to the original game, see [my guide](https://github.com/MylesAndMore/tmbl/blob/main/OG-GUIDE.md) for using the original worlds. 3. Start your server. The plugin will generate a couple of warnings, these are normal. 4. Ensure that you have imported your worlds using a plugin like Multiverse. This can be done with the command ```/mv import normal```. -5. Now you need to tell Tumble where your lobby is and where your game arena is. You can do this by going to the center positions and running ```/tumble-config set lobbyWorld``` and ```/tumble-config add ``` respectively. +5. Now you need to tell Tumble where your lobby is and where your game arena is. You can do this by going to the center positions and running ```/tmbl-config set lobbyWorld``` and ```/tmbl-config add ``` respectively. 6. **VERY IMPORTANT:** The plugin will teleport players to the world and generate the game's blocks around the point you set. Ensure that your spawn points are clear of any obstructions, and that a 20x20x20 cube is cleared out **Any blocks in this area will be destroyed when the game begins.** -7. You're done! You can now start games with the command ```/tumble-start mixed```. +7. You're done! You can now start games with the command ```/tmbl start mixed```. Scroll down for more options to configure your game. -## Commands/Permissions - -- **tumble-join**: - - Description: Joins a Tumble match. - - Usage: `/tumble-join [gameType]` - - Permission: tumble.join -- **tumble-leave**: - - Description: Quits a Tumble match. - - Usage: `/tumble-leave` - - Permission: tumble.leave -- **tumble-forcestart**: - - Description: Force starts a Tumble match. - - Usage: `/tumble-forcestart [arenaName]` - - Permission: tumble.forcestart -- **tumble-forcestop**: - - Description: Force stops a Tumble match. - - Usage: `/tumble-forcestop [arenaName]` - - Permission: tumble.forcestop -- **tumble-config**: - - Description: Modify arenas and worlds. - - Usage: `/tumble-config ` - - Permission: tumble.config -- **tumble-reload**: - - Description: Reloads the plugin's config. - - Usage: `/tumble-reload` - - Permission: tumble.reload +## Commands / Permissions + +| Command | Description | Permission | +|------------------------------------------------|-----------------------------------|---------------------| +| `/tmbl join [gameType]` | Join a Tumble match. | `tumble.join` | +| `/tmbl leave` | Quit a Tumble match. | `tumble.leave` | +| `/tmbl forcestart [arenaName]` | Force start a Tumble match. | `tumble.forcestart` | +| `/tmbl forcestop [arenaName]` | Force stop a Tumble match. | `tumble.forcestop` | +| `/tmbl config ` | Modify arenas and worlds in game. | `tumble.config` | +| `/tmbl reload` | Reload the plugin's config. | `tumble.reload` | ## Configuration -Use `/tumble-config` for modifying the config in-game. See available options with the tab auto complete feature +Use `/tmbl config` for modifying the config in-game. See available options with the tab auto complete feature See the comments inside config,yml for manual editing ## Issues & Feedback -Feel free to report any bugs, leave feedback, ask questions, or submit ideas for new features on our [GitHub issues page](https://github.com/MylesAndMore/tumble/issues/new)! +Feel free to report any bugs, leave feedback, ask questions, or submit ideas for new features on our [GitHub issues page](https://github.com/MylesAndMore/tmbl/issues/new)! diff --git a/src/main/java/com/MylesAndMore/Tumble/Main.java b/src/main/java/com/MylesAndMore/Tumble/Main.java index 274765e..f098a12 100644 --- a/src/main/java/com/MylesAndMore/Tumble/Main.java +++ b/src/main/java/com/MylesAndMore/Tumble/Main.java @@ -1,8 +1,10 @@ package com.MylesAndMore.Tumble; import com.MylesAndMore.Tumble.commands.*; -import com.MylesAndMore.Tumble.plugin.ConfigManager; +import com.MylesAndMore.Tumble.config.ArenaManager; +import com.MylesAndMore.Tumble.config.ConfigManager; +import com.MylesAndMore.Tumble.config.LanguageManager; import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; @@ -16,17 +18,14 @@ public class Main extends JavaPlugin{ @Override public void onEnable() { plugin = this; + new ArenaManager(); + new ConfigManager(); + new LanguageManager(); - Objects.requireNonNull(this.getCommand("tumble-reload")).setExecutor(new Reload()); - Objects.requireNonNull(this.getCommand("tumble-config")).setExecutor(new Config()); - Objects.requireNonNull(this.getCommand("tumble-forcestart")).setExecutor(new ForceStart()); - Objects.requireNonNull(this.getCommand("tumble-join")).setExecutor(new Join()); - Objects.requireNonNull(this.getCommand("tumble-leave")).setExecutor(new Leave()); - Objects.requireNonNull(this.getCommand("tumble-forcestop")).setExecutor(new ForceStop()); + Objects.requireNonNull(this.getCommand("tumble")).setExecutor(new Tumble()); new Metrics(this, 16940); this.saveDefaultConfig(); // Saves the default config file (packaged in the JAR) if we haven't already - ConfigManager.readConfig(); Bukkit.getServer().getLogger().info("[Tumble] Tumble successfully enabled!"); } diff --git a/src/main/java/com/MylesAndMore/Tumble/commands/Config.java b/src/main/java/com/MylesAndMore/Tumble/commands/Config.java deleted file mode 100644 index 5fc2de6..0000000 --- a/src/main/java/com/MylesAndMore/Tumble/commands/Config.java +++ /dev/null @@ -1,122 +0,0 @@ -package com.MylesAndMore.Tumble.commands; - -import com.MylesAndMore.Tumble.game.Arena; -import com.MylesAndMore.Tumble.plugin.ConfigManager; -import org.bukkit.ChatColor; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.command.TabCompleter; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -public class Config implements CommandExecutor, TabCompleter { - @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { - if (!(sender instanceof Player)) { - sender.sendMessage(ChatColor.RED + "This cannot be run by the console"); - return false; - } - - if (!sender.hasPermission("tumble.config")) { - sender.sendMessage(ChatColor.RED + "You do not have permission to perform this command!"); - return false; - } - - if (args.length < 2 || args[0] == null || args[1] == null) { - sender.sendMessage(ChatColor.RED + "Missing arguments"); - return false; - } - - switch (args[0]) { - case "add" -> { - String arenaName = args[1]; - ConfigManager.arenas.put(arenaName, new Arena(arenaName, ((Player)sender).getLocation(), null)); - sender.sendMessage(ChatColor.GREEN + "Arena added."); - } - case "set" -> { - String world = args[1]; - if (ConfigManager.arenas.containsKey(world)) { - ConfigManager.arenas.get(world).location = ((Player)sender).getLocation(); - } - else if (world.equals("waitArea")) { - ConfigManager.waitArea = ((Player)sender).getLocation(); - } - else if (world.equals("lobbySpawn")) { - ConfigManager.lobby = ((Player)sender).getLocation(); - } - else if (world.equals("winnerLobbySpawn")) { - ConfigManager.winnerLobby = ((Player)sender).getLocation(); - } - else { - sender.sendMessage(ChatColor.RED + "Invalid parameter"); - return false; - } - sender.sendMessage(ChatColor.GREEN + "Location set."); - } - case "disable" -> { - String world = args[1]; - if (world.equals("waitArea")) { - ConfigManager.waitArea = null; - } - else if (world.equals("winnerLobbySpawn")) { - ConfigManager.winnerLobby = null; - } - else { - sender.sendMessage(ChatColor.RED + "Invalid parameter"); - return false; - } - sender.sendMessage(ChatColor.GREEN + "World disabled."); - } - case "remove" -> { - String world = args[1]; - if (ConfigManager.arenas.containsKey(world)) { - ConfigManager.arenas.remove(world); - } - else { - sender.sendMessage(ChatColor.RED + "Invalid parameter"); - return false; - } - sender.sendMessage(ChatColor.GREEN + "Location set"); - } - default -> { - sender.sendMessage(ChatColor.RED + "Invalid parameter"); - return false; - } - } - - ConfigManager.WriteConfig(); - sender.sendMessage(ChatColor.GREEN + "Wrote changes to file."); - return true; - } - - @Override - public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { - if (args.length == 1) { - return new ArrayList<>(Arrays.asList("add", "set", "disable", "remove")); - } - if (args.length == 2) { - switch (args[0]) { - case "set" -> { - ArrayList temp = new ArrayList<>(ConfigManager.arenas.keySet()); - temp.addAll(Arrays.asList("waitArea", "lobbySpawn", "winnerLobbySpawn")); - return temp; - } - case "disable" -> { - return Arrays.asList("waitArea", "winnerLobbySpawn"); - } - case "delete" -> { - return ConfigManager.arenas.keySet().stream().toList(); - } - default -> { - return new ArrayList<>(); - } - } - } - return new ArrayList<>(); - } -} diff --git a/src/main/java/com/MylesAndMore/Tumble/commands/Create.java b/src/main/java/com/MylesAndMore/Tumble/commands/Create.java new file mode 100644 index 0000000..3340cc6 --- /dev/null +++ b/src/main/java/com/MylesAndMore/Tumble/commands/Create.java @@ -0,0 +1,44 @@ +package com.MylesAndMore.Tumble.commands; + +import com.MylesAndMore.Tumble.game.Arena; +import com.MylesAndMore.Tumble.config.LanguageManager; +import com.MylesAndMore.Tumble.config.ArenaManager; +import com.MylesAndMore.Tumble.plugin.SubCommand; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.List; + +public class Create implements SubCommand, CommandExecutor, TabCompleter { + @Override + public String getCommandName() { + return "create"; + } + + @Override + public String getPermission() { + return "tumble.create"; + } + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { + if (args.length == 0 || args[0] == null || args[0].isEmpty()) { + sender.sendMessage(LanguageManager.fromKey("missing-arena-parameter")); + return false; + } + + String arenaName = args[0]; + ArenaManager.arenas.put(arenaName, new Arena(arenaName)); + sender.sendMessage(LanguageManager.fromKey("create-success")); + return true; + } + + @Override + public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { + return Collections.emptyList(); + } +} diff --git a/src/main/java/com/MylesAndMore/Tumble/commands/ForceStart.java b/src/main/java/com/MylesAndMore/Tumble/commands/ForceStart.java index bdead44..c8042bc 100644 --- a/src/main/java/com/MylesAndMore/Tumble/commands/ForceStart.java +++ b/src/main/java/com/MylesAndMore/Tumble/commands/ForceStart.java @@ -1,8 +1,9 @@ package com.MylesAndMore.Tumble.commands; import com.MylesAndMore.Tumble.game.Game; -import com.MylesAndMore.Tumble.plugin.ConfigManager; -import org.bukkit.ChatColor; +import com.MylesAndMore.Tumble.config.LanguageManager; +import com.MylesAndMore.Tumble.config.ArenaManager; +import com.MylesAndMore.Tumble.plugin.SubCommand; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; @@ -13,36 +14,42 @@ import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; -public class ForceStart implements CommandExecutor, TabCompleter { +public class ForceStart implements SubCommand, CommandExecutor, TabCompleter { + @Override - public boolean onCommand(CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { + public String getCommandName() { + return "forceStart"; + } - if (!sender.hasPermission("tumble.forcestart")) { - sender.sendMessage(ChatColor.RED + "You do not have permission to perform this command!"); - return false; - } + @Override + public String getPermission() { + return "tumble.forceStart"; + } + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { Game game; if (args.length < 1 || args[0] == null) { - game = ConfigManager.findGamePlayerIsIn((Player)sender); + game = ArenaManager.findGamePlayerIsIn((Player)sender); if (game == null) { - sender.sendMessage(ChatColor.RED + "Missing arena name"); + sender.sendMessage(LanguageManager.fromKey("missing-arena-parameter")); return false; } } else { - game = ConfigManager.arenas.get(args[0]).game; + game = ArenaManager.arenas.get(args[0]).game; } game.gameStart(); - sender.sendMessage(ChatColor.GREEN + "Starting game"); + sender.sendMessage(LanguageManager.fromKey("forcestart-success")); return true; } @Override public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { if (args.length == 1) { - return ConfigManager.arenas.keySet().stream().toList(); + return ArenaManager.arenas.keySet().stream().toList(); } return new ArrayList<>(); } diff --git a/src/main/java/com/MylesAndMore/Tumble/commands/ForceStop.java b/src/main/java/com/MylesAndMore/Tumble/commands/ForceStop.java index ddd5826..96e8334 100644 --- a/src/main/java/com/MylesAndMore/Tumble/commands/ForceStop.java +++ b/src/main/java/com/MylesAndMore/Tumble/commands/ForceStop.java @@ -1,8 +1,9 @@ package com.MylesAndMore.Tumble.commands; import com.MylesAndMore.Tumble.game.Game; -import com.MylesAndMore.Tumble.plugin.ConfigManager; -import org.bukkit.ChatColor; +import com.MylesAndMore.Tumble.config.LanguageManager; +import com.MylesAndMore.Tumble.config.ArenaManager; +import com.MylesAndMore.Tumble.plugin.SubCommand; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; @@ -13,41 +14,47 @@ import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; -public class ForceStop implements CommandExecutor, TabCompleter { +public class ForceStop implements SubCommand, CommandExecutor, TabCompleter { + @Override - public boolean onCommand(CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { + public String getCommandName() { + return "forcestop"; + } - if (!sender.hasPermission("tumble.forcestop")) { - sender.sendMessage(ChatColor.RED + "You do not have permission to perform this command!"); - return false; - } + @Override + public String getPermission() { + return "tumble.forcestop"; + } + + @Override + public boolean onCommand(CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { Game game; if (args.length < 1 || args[0] == null) { - game = ConfigManager.findGamePlayerIsIn((Player)sender); + game = ArenaManager.findGamePlayerIsIn((Player)sender); if (game == null) { - sender.sendMessage(ChatColor.RED + "Missing arena name"); + sender.sendMessage(LanguageManager.fromKey("missing-arena-parameter")); return false; } } else { - game = ConfigManager.arenas.get(args[0]).game; + game = ArenaManager.arenas.get(args[0]).game; } if (game == null) { - sender.sendMessage(ChatColor.RED + "No game is currently running in this arena"); + sender.sendMessage(LanguageManager.fromKey("no-game-in-arena")); return false; } game.gameEnd(); - sender.sendMessage(ChatColor.GREEN + "Game stopped."); + sender.sendMessage(LanguageManager.fromKey("forcestop-success")); return true; } @Override public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { if (args.length == 1) { - return ConfigManager.arenas.keySet().stream().toList(); + return ArenaManager.arenas.keySet().stream().toList(); } return new ArrayList<>(); } diff --git a/src/main/java/com/MylesAndMore/Tumble/commands/Join.java b/src/main/java/com/MylesAndMore/Tumble/commands/Join.java index de44da1..a887c99 100644 --- a/src/main/java/com/MylesAndMore/Tumble/commands/Join.java +++ b/src/main/java/com/MylesAndMore/Tumble/commands/Join.java @@ -1,10 +1,12 @@ package com.MylesAndMore.Tumble.commands; import com.MylesAndMore.Tumble.game.Arena; -import com.MylesAndMore.Tumble.plugin.ConfigManager; +import com.MylesAndMore.Tumble.config.LanguageManager; +import com.MylesAndMore.Tumble.config.ArenaManager; import com.MylesAndMore.Tumble.game.Game; import com.MylesAndMore.Tumble.plugin.GameState; import com.MylesAndMore.Tumble.plugin.GameType; +import com.MylesAndMore.Tumble.plugin.SubCommand; import org.bukkit.ChatColor; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; @@ -19,35 +21,41 @@ import java.util.List; import java.util.Objects; import java.util.stream.Collectors; -public class Join implements CommandExecutor, TabCompleter { +public class Join implements SubCommand, CommandExecutor, TabCompleter { + + @Override + public String getCommandName() { + return "join"; + } + + @Override + public String getPermission() { + return "tumble.join"; + } + @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { if (!(sender instanceof Player)) { - sender.sendMessage(ChatColor.RED + "This cannot be run by the console"); - return false; - } - - if (!sender.hasPermission("tumble.join")) { - sender.sendMessage(ChatColor.RED + "You do not have permission to perform this command!"); + sender.sendMessage(LanguageManager.fromKey("not-for-console")); return false; } - if (ConfigManager.findGamePlayerIsIn((Player)sender) != null) { - sender.sendMessage(ChatColor.RED + "You are already in a game! Leave it to join another one"); + if (ArenaManager.findGamePlayerIsIn((Player)sender) != null) { + sender.sendMessage(LanguageManager.fromKey("already-in-game")); } if (args.length < 1 || args[0] == null) { - sender.sendMessage(ChatColor.RED + "Missing arena name"); + sender.sendMessage(LanguageManager.fromKey("missing-arena-parameter")); return false; } String arenaName = args[0]; - if (!ConfigManager.arenas.containsKey(arenaName)) + if (!ArenaManager.arenas.containsKey(arenaName)) { - sender.sendMessage(ChatColor.RED + "This arena does not exist"); + sender.sendMessage(LanguageManager.fromKey("invalid-arena").replace("%arena%", arenaName)); return false; } - Arena arena = ConfigManager.arenas.get(arenaName); + Arena arena = ArenaManager.arenas.get(arenaName); Game game; if (args.length < 2 || args[1] == null) { @@ -66,7 +74,7 @@ public class Join implements CommandExecutor, TabCompleter { case "snowballs", "snowball" -> type = GameType.SNOWBALLS; case "mix", "mixed" -> type = GameType.MIXED; default -> { - sender.sendMessage(ChatColor.RED + "Invalid game type"); + sender.sendMessage(LanguageManager.fromKey("invalid-type")); return false; } } @@ -80,26 +88,30 @@ public class Join implements CommandExecutor, TabCompleter { game = arena.game; } else { - sender.sendMessage(ChatColor.RED + "A game of "+type+" is currently taking place in this arena, choose another arena or join it with /tumble:join "+arena.name+" "+type); + sender.sendMessage(LanguageManager.fromKey("another-type-in-arena") + .replace("%type%",type.toString()) + .replace("%arena%",arenaName)); return false; } } } if (game.gameState != GameState.WAITING) { - sender.sendMessage(ChatColor.RED + "This game is still in progress, wait until it finishes or join another game"); + sender.sendMessage(LanguageManager.fromKey("game-in-progress")); return false; } game.addPlayer((Player)sender); - sender.sendMessage(ChatColor.GREEN + "Joined game " + arena.name + " - " + game.type); + sender.sendMessage(LanguageManager.fromKey("join-success") + .replace("%type%", game.type.toString()) + .replace("%arena%", arena.name)); return true; } @Override public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { if (args.length == 1) { - return ConfigManager.arenas.keySet().stream().toList(); + return ArenaManager.arenas.keySet().stream().toList(); } if (args.length == 2) { return Arrays.stream(GameType.values()).map(Objects::toString).collect(Collectors.toList()); diff --git a/src/main/java/com/MylesAndMore/Tumble/commands/Leave.java b/src/main/java/com/MylesAndMore/Tumble/commands/Leave.java index 1d00ca4..0250cc6 100644 --- a/src/main/java/com/MylesAndMore/Tumble/commands/Leave.java +++ b/src/main/java/com/MylesAndMore/Tumble/commands/Leave.java @@ -1,8 +1,9 @@ package com.MylesAndMore.Tumble.commands; import com.MylesAndMore.Tumble.game.Game; -import com.MylesAndMore.Tumble.plugin.ConfigManager; -import org.bukkit.ChatColor; +import com.MylesAndMore.Tumble.config.LanguageManager; +import com.MylesAndMore.Tumble.config.ArenaManager; +import com.MylesAndMore.Tumble.plugin.SubCommand; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; @@ -13,28 +14,36 @@ import org.jetbrains.annotations.NotNull; import java.util.ArrayList; import java.util.List; -public class Leave implements CommandExecutor, TabCompleter { +public class Leave implements SubCommand, CommandExecutor, TabCompleter { + + @Override + public String getCommandName() { + return "leave"; + } + + @Override + public String getPermission() { + return "tumble.leave"; + } + @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { if (!(sender instanceof Player)) { - sender.sendMessage(ChatColor.RED + "This cannot be run by the console"); - return false; - } - - if (!sender.hasPermission("tumble.leave")) { - sender.sendMessage(ChatColor.RED + "You do not have permission to perform this command!"); + sender.sendMessage(LanguageManager.fromKey("not-for-console")); return false; } - Game game = ConfigManager.findGamePlayerIsIn((Player)sender); + Game game = ArenaManager.findGamePlayerIsIn((Player)sender); if (game == null) { - sender.sendMessage(ChatColor.RED + "You are not in a game."); + sender.sendMessage(LanguageManager.fromKey("no-game-in-arena")); return false; } game.removePlayer((Player) sender); - sender.sendMessage(ChatColor.GREEN + "Game left."); + sender.sendMessage(LanguageManager.fromKey("leave-success") + .replace("%arena%", game.arena.name) + .replace("%type%", game.type.toString())); return true; } diff --git a/src/main/java/com/MylesAndMore/Tumble/commands/Reload.java b/src/main/java/com/MylesAndMore/Tumble/commands/Reload.java index ca67a2e..66535d5 100644 --- a/src/main/java/com/MylesAndMore/Tumble/commands/Reload.java +++ b/src/main/java/com/MylesAndMore/Tumble/commands/Reload.java @@ -1,8 +1,9 @@ package com.MylesAndMore.Tumble.commands; import com.MylesAndMore.Tumble.game.Arena; -import com.MylesAndMore.Tumble.plugin.ConfigManager; -import org.bukkit.ChatColor; +import com.MylesAndMore.Tumble.config.LanguageManager; +import com.MylesAndMore.Tumble.config.ArenaManager; +import com.MylesAndMore.Tumble.plugin.SubCommand; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; @@ -14,23 +15,29 @@ import java.util.List; import static com.MylesAndMore.Tumble.Main.plugin; -public class Reload implements CommandExecutor, TabCompleter { +public class Reload implements SubCommand, CommandExecutor, TabCompleter { @Override - public boolean onCommand(CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { - if (!sender.hasPermission("tumble.reload")) { - sender.sendMessage(ChatColor.RED + "You do not have permission to perform this command!"); - return false; - } + public String getCommandName() { + return "reload"; + } + + @Override + public String getPermission() { + return "tumble.reload"; + } + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { - for (Arena a : ConfigManager.arenas.values()) { + for (Arena a : ArenaManager.arenas.values()) { if (a.game != null) { a.game.gameEnd(); } } plugin.onEnable(); - sender.sendMessage(ChatColor.GREEN + "Tumble configuration reloaded. Check console for errors."); + sender.sendMessage(LanguageManager.fromKey("reload-success")); return true; } diff --git a/src/main/java/com/MylesAndMore/Tumble/commands/Remove.java b/src/main/java/com/MylesAndMore/Tumble/commands/Remove.java new file mode 100644 index 0000000..118aa77 --- /dev/null +++ b/src/main/java/com/MylesAndMore/Tumble/commands/Remove.java @@ -0,0 +1,53 @@ +package com.MylesAndMore.Tumble.commands; + +import com.MylesAndMore.Tumble.config.LanguageManager; +import com.MylesAndMore.Tumble.config.ArenaManager; +import com.MylesAndMore.Tumble.plugin.SubCommand; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.List; + +public class Remove implements SubCommand, CommandExecutor, TabCompleter { + + @Override + public String getCommandName() { + return "remove"; + } + + @Override + public String getPermission() { + return "tumble.remove"; + } + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { + if (args.length == 0 || args[0] == null || args[0].isEmpty()) { + sender.sendMessage(LanguageManager.fromKey("missing-arena-parameter")); + return false; + } + String arenaName = args[0]; + + if (!ArenaManager.arenas.containsKey(arenaName)) { + sender.sendMessage(LanguageManager.fromKey("invalid-arena").replace("%arena%",arenaName)); + return false; + } + + ArenaManager.arenas.remove(arenaName); + sender.sendMessage(LanguageManager.fromKey("set-success")); + return true; + } + + @Override + public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { + if (args.length == 1) { + return ArenaManager.arenas.keySet().stream().toList(); + } + + return Collections.emptyList(); + } +} diff --git a/src/main/java/com/MylesAndMore/Tumble/commands/SetGameSpawn.java b/src/main/java/com/MylesAndMore/Tumble/commands/SetGameSpawn.java new file mode 100644 index 0000000..62d22f8 --- /dev/null +++ b/src/main/java/com/MylesAndMore/Tumble/commands/SetGameSpawn.java @@ -0,0 +1,60 @@ +package com.MylesAndMore.Tumble.commands; + +import com.MylesAndMore.Tumble.game.Arena; +import com.MylesAndMore.Tumble.config.LanguageManager; +import com.MylesAndMore.Tumble.config.ArenaManager; +import com.MylesAndMore.Tumble.plugin.SubCommand; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.List; + +public class SetGameSpawn implements SubCommand, CommandExecutor, TabCompleter { + @Override + public String getCommandName() { + return "setGameSpawn"; + } + + @Override + public String getPermission() { + return "tumble.setGameSpawn"; + } + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage(LanguageManager.fromKey("not-for-console")); + return false; + } + + if (args.length == 0 || args[0] == null || args[0].isEmpty()) { + sender.sendMessage(LanguageManager.fromKey("missing-arena-parameter")); + return false; + } + String arenaName = args[0]; + + if (!ArenaManager.arenas.containsKey(arenaName)) { + sender.sendMessage(LanguageManager.fromKey("invalid-arena").replace("%arena%",arenaName)); + return false; + } + Arena arena = ArenaManager.arenas.get(arenaName); + + arena.gameSpawn = ((Player)sender).getLocation(); + sender.sendMessage(LanguageManager.fromKey("set-success")); + return true; + } + + @Override + public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { + if (args.length == 1) { + return ArenaManager.arenas.keySet().stream().toList(); + } + + return Collections.emptyList(); + } +} diff --git a/src/main/java/com/MylesAndMore/Tumble/commands/SetKillYCordinate.java b/src/main/java/com/MylesAndMore/Tumble/commands/SetKillYCordinate.java new file mode 100644 index 0000000..0be156f --- /dev/null +++ b/src/main/java/com/MylesAndMore/Tumble/commands/SetKillYCordinate.java @@ -0,0 +1,61 @@ +package com.MylesAndMore.Tumble.commands; + +import com.MylesAndMore.Tumble.game.Arena; +import com.MylesAndMore.Tumble.config.LanguageManager; +import com.MylesAndMore.Tumble.config.ArenaManager; +import com.MylesAndMore.Tumble.plugin.SubCommand; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.List; + +public class SetKillYCordinate implements SubCommand, CommandExecutor, TabCompleter { + + @Override + public String getCommandName() { + return "setKillYLevel"; + } + + @Override + public String getPermission() { + return "tumble.setKillYLevel"; + } + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage(LanguageManager.fromKey("not-for-console")); + return false; + } + + if (args.length == 0 || args[0] == null || args[0].isEmpty()) { + sender.sendMessage(LanguageManager.fromKey("missing-arena-parameter")); + return false; + } + String arenaName = args[0]; + + if (!ArenaManager.arenas.containsKey(arenaName)) { + sender.sendMessage(LanguageManager.fromKey("invalid-arena").replace("%arena%",arenaName)); + return false; + } + Arena arena = ArenaManager.arenas.get(arenaName); + + arena.killAtY = ((int) ((Player) sender).getLocation().getY()); + sender.sendMessage(LanguageManager.fromKey("set-success")); + return true; + } + + @Override + public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { + if (args.length == 1) { + return ArenaManager.arenas.keySet().stream().toList(); + } + + return Collections.emptyList(); + } +} diff --git a/src/main/java/com/MylesAndMore/Tumble/commands/SetLobby.java b/src/main/java/com/MylesAndMore/Tumble/commands/SetLobby.java new file mode 100644 index 0000000..dbb6b53 --- /dev/null +++ b/src/main/java/com/MylesAndMore/Tumble/commands/SetLobby.java @@ -0,0 +1,60 @@ +package com.MylesAndMore.Tumble.commands; + +import com.MylesAndMore.Tumble.game.Arena; +import com.MylesAndMore.Tumble.config.LanguageManager; +import com.MylesAndMore.Tumble.config.ArenaManager; +import com.MylesAndMore.Tumble.plugin.SubCommand; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.List; + +public class SetLobby implements SubCommand, CommandExecutor, TabCompleter { + @Override + public String getCommandName() { + return "setLobby"; + } + + @Override + public String getPermission() { + return "tumble.setLobby"; + } + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage(LanguageManager.fromKey("not-for-console")); + return false; + } + + if (args.length == 0 || args[0] == null || args[0].isEmpty()) { + sender.sendMessage(LanguageManager.fromKey("missing-arena-parameter")); + return false; + } + String arenaName = args[0]; + + if (!ArenaManager.arenas.containsKey(arenaName)) { + sender.sendMessage(LanguageManager.fromKey("invalid-arena").replace("%arena%",arenaName)); + return false; + } + Arena arena = ArenaManager.arenas.get(arenaName); + + arena.lobby = ((Player)sender).getLocation(); + sender.sendMessage(LanguageManager.fromKey("set-success")); + return true; + } + + @Override + public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { + if (args.length == 1) { + return ArenaManager.arenas.keySet().stream().toList(); + } + + return Collections.emptyList(); + } +} diff --git a/src/main/java/com/MylesAndMore/Tumble/commands/SetWaitArea.java b/src/main/java/com/MylesAndMore/Tumble/commands/SetWaitArea.java new file mode 100644 index 0000000..f789658 --- /dev/null +++ b/src/main/java/com/MylesAndMore/Tumble/commands/SetWaitArea.java @@ -0,0 +1,60 @@ +package com.MylesAndMore.Tumble.commands; + +import com.MylesAndMore.Tumble.game.Arena; +import com.MylesAndMore.Tumble.config.LanguageManager; +import com.MylesAndMore.Tumble.config.ArenaManager; +import com.MylesAndMore.Tumble.plugin.SubCommand; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.List; + +public class SetWaitArea implements SubCommand, CommandExecutor, TabCompleter { + @Override + public String getCommandName() { + return "setWaitArea"; + } + + @Override + public String getPermission() { + return "tumble.setWaitArea"; + } + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage(LanguageManager.fromKey("not-for-console")); + return false; + } + + if (args.length == 0 || args[0] == null || args[0].isEmpty()) { + sender.sendMessage(LanguageManager.fromKey("missing-arena-parameter")); + return false; + } + String arenaName = args[0]; + + if (!ArenaManager.arenas.containsKey(arenaName)) { + sender.sendMessage(LanguageManager.fromKey("invalid-arena").replace("%arena%",arenaName)); + return false; + } + Arena arena = ArenaManager.arenas.get(arenaName); + + arena.waitArea = ((Player)sender).getLocation(); + sender.sendMessage(LanguageManager.fromKey("set-success")); + return true; + } + + @Override + public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { + if (args.length == 1) { + return ArenaManager.arenas.keySet().stream().toList(); + } + + return Collections.emptyList(); + } +} diff --git a/src/main/java/com/MylesAndMore/Tumble/commands/SetWinnerLobby.java b/src/main/java/com/MylesAndMore/Tumble/commands/SetWinnerLobby.java new file mode 100644 index 0000000..01817b0 --- /dev/null +++ b/src/main/java/com/MylesAndMore/Tumble/commands/SetWinnerLobby.java @@ -0,0 +1,60 @@ +package com.MylesAndMore.Tumble.commands; + +import com.MylesAndMore.Tumble.game.Arena; +import com.MylesAndMore.Tumble.config.LanguageManager; +import com.MylesAndMore.Tumble.config.ArenaManager; +import com.MylesAndMore.Tumble.plugin.SubCommand; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; +import java.util.List; + +public class SetWinnerLobby implements SubCommand, CommandExecutor, TabCompleter { + @Override + public String getCommandName() { + return "setWinnerLobby"; + } + + @Override + public String getPermission() { + return "tumble.setWinnerLobby"; + } + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage(LanguageManager.fromKey("not-for-console")); + return false; + } + + if (args.length == 0 || args[0] == null || args[0].isEmpty()) { + sender.sendMessage(LanguageManager.fromKey("missing-arena-parameter")); + return false; + } + String arenaName = args[0]; + + if (!ArenaManager.arenas.containsKey(arenaName)) { + sender.sendMessage(LanguageManager.fromKey("invalid-arena").replace("%arena%",arenaName)); + return false; + } + Arena arena = ArenaManager.arenas.get(arenaName); + + arena.winnerLobby = ((Player)sender).getLocation(); + sender.sendMessage(LanguageManager.fromKey("set-success")); + return true; + } + + @Override + public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { + if (args.length == 1) { + return ArenaManager.arenas.keySet().stream().toList(); + } + + return Collections.emptyList(); + } +} diff --git a/src/main/java/com/MylesAndMore/Tumble/commands/Tumble.java b/src/main/java/com/MylesAndMore/Tumble/commands/Tumble.java new file mode 100644 index 0000000..6e44352 --- /dev/null +++ b/src/main/java/com/MylesAndMore/Tumble/commands/Tumble.java @@ -0,0 +1,85 @@ +package com.MylesAndMore.Tumble.commands; + +import com.MylesAndMore.Tumble.config.LanguageManager; +import com.MylesAndMore.Tumble.plugin.SubCommand; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.command.TabCompleter; +import org.jetbrains.annotations.NotNull; + +import java.util.*; + +public class Tumble implements CommandExecutor, TabCompleter { + + private static final Map subCommands = Map.ofEntries( + CmdNameAsKey(new Create()), + CmdNameAsKey(new ForceStart()), + CmdNameAsKey(new ForceStop()), + CmdNameAsKey(new Join()), + CmdNameAsKey(new Leave()), + CmdNameAsKey(new Reload()), + CmdNameAsKey(new Remove()), + CmdNameAsKey(new SetGameSpawn()), + CmdNameAsKey(new SetKillYCordinate()), + CmdNameAsKey(new SetLobby()), + CmdNameAsKey(new SetWaitArea()), + CmdNameAsKey(new SetWinnerLobby()) + ); + + @Override + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { + if (!subCommands.containsKey(args[0])) { + sender.sendMessage(LanguageManager.fromKey("unknown-command")); + return true; + } + + var subCmd = subCommands.get(args[0]); + + if (!sender.hasPermission(subCmd.getPermission())) { + sender.sendMessage(LanguageManager.fromKey("no-permission").replace("%permission%", subCmd.getPermission())); + return false; + } + + subCmd.onCommand(sender, command, args[0], removeFirst(args)); + return true; + } + + @Override + public List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) { + if (args.length == 1) { + ArrayList PermittedSubCmds = new ArrayList<>(); + for (SubCommand subCmd: subCommands.values()) { + if (sender.hasPermission(subCmd.getPermission())) { + PermittedSubCmds.add(subCmd.getCommandName()); + } + } + return PermittedSubCmds; + } + + if (args.length > 1) { + if (!subCommands.containsKey(args[0])) { + return Collections.emptyList(); + } + + if (subCommands.get(args[0]) instanceof TabCompleter tcmp) { + return tcmp.onTabComplete(sender, command, args[0], removeFirst(args)); + } + else { + return null; + } + } + + return Collections.emptyList(); + } + + private String[] removeFirst(String[] arr) { + ArrayList tmp = new ArrayList<>(List.of(arr)); + tmp.remove(0); + return tmp.toArray(new String[0]); + } + + private static Map.Entry CmdNameAsKey(SubCommand s) { + return Map.entry(s.getCommandName(),s); + } +} diff --git a/src/main/java/com/MylesAndMore/Tumble/config/ArenaManager.java b/src/main/java/com/MylesAndMore/Tumble/config/ArenaManager.java new file mode 100644 index 0000000..69a6c2c --- /dev/null +++ b/src/main/java/com/MylesAndMore/Tumble/config/ArenaManager.java @@ -0,0 +1,178 @@ +package com.MylesAndMore.Tumble.config; + +import com.MylesAndMore.Tumble.game.Arena; +import com.MylesAndMore.Tumble.game.Game; +import com.MylesAndMore.Tumble.plugin.Result; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.Nullable; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Objects; + +import static com.MylesAndMore.Tumble.Main.plugin; + +public class ArenaManager { + private static FileConfiguration config; + public static HashMap arenas; + + public ArenaManager() { + String fileName = "arenas.yml"; + // create config + File customConfigFile = new File(plugin.getDataFolder(), fileName); + if (!customConfigFile.exists()) { + customConfigFile.getParentFile().mkdirs(); + plugin.saveResource(fileName, false); + } + + config = new YamlConfiguration(); + try { + config.load(customConfigFile); + } catch (IOException | InvalidConfigurationException e) { + e.printStackTrace(); + } + /* User Edit: + Instead of the above Try/Catch, you can also use + YamlConfiguration.loadConfiguration(customConfigFile) + */ + readConfig(); + } + + /** + * Reads config file and populates values above + */ + public static void readConfig() { + plugin.reloadConfig(); + + // arenas + ConfigurationSection arenasSection = config.getConfigurationSection("arenas"); + if (arenasSection == null) { + plugin.getLogger().warning("Section 'arenas' is missing from config"); + return; + } + arenas = new HashMap<>(); + for (String arenaName: arenasSection.getKeys(false)) { + + ConfigurationSection anArenaSection = arenasSection.getConfigurationSection(arenaName); + if (anArenaSection == null) { + plugin.getLogger().warning("Failed to load arena "+arenaName+": Error loading config section"); + continue; + } + + Arena arena = new Arena(arenaName); + arenas.put(arena.name, arena); + + int killAtY = anArenaSection.getInt("kill-at-y", 0); + if (killAtY != 0) { + arena.killAtY = killAtY; + } + + Result res = readWorld(anArenaSection.getConfigurationSection("game-spawn")); + if (res.success) { + arena.gameSpawn = res.value; + } + + Result lobbyRes = readWorld(anArenaSection.getConfigurationSection("lobby")); + if (lobbyRes.success) { + arena.lobby = lobbyRes.value; + } + + Result winnerLobbyRes = readWorld(anArenaSection.getConfigurationSection("winner-lobby")); + if (winnerLobbyRes.success) { + arena.winnerLobby = winnerLobbyRes.value; + } + + Result waitAreaRes = readWorld(anArenaSection.getConfigurationSection("wait-area")); + if (waitAreaRes.success) { + arena.waitArea = waitAreaRes.value; + } + + } + } + + /** + * tries to convert a config section in the following format to a world + * section: + * x: + * y: + * z: + * world: + * @param section the section in the yaml with x, y, z, and world as its children + * @return result of either: + * success = true and a world + * success = false and an error string + */ + private static Result readWorld(@Nullable ConfigurationSection section) { + + if (section == null) { + return new Result<>("Section missing from config"); + } + + double x = section.getDouble("x"); + double y = section.getDouble("y"); + double z = section.getDouble("z"); + if (x == 0 || y == 0 || z == 0) { + return new Result<>("Arena coordinates are missing or are zero. Coordinates cannot be zero."); + } + + String worldName = section.getString("world"); + if (worldName == null) { + return new Result<>("World name is missing"); + } + + World world = Bukkit.getWorld(worldName); + if (world == null) { + return new Result<>("Failed to load world " + worldName); + } + + return new Result<>(new Location(world,x,y,z)); + } + + public static void WriteConfig() { + + for (Arena arena: arenas.values()) { + WriteWorld("arenas."+arena.name+".game-spawn", arena.gameSpawn); + WriteWorld("arenas."+arena.name+".lobby", arena.lobby); + WriteWorld("arenas."+arena.name+".winner-lobby", arena.winnerLobby); + WriteWorld("arenas."+arena.name+".wait-area", arena.waitArea); + } + + plugin.saveConfig(); + + } + + private static void WriteWorld(String path, Location location) { + ConfigurationSection section = config.getConfigurationSection(path); + + if (section == null) { + section = plugin.getConfig().createSection(path); + } + + section.set("x", location.getX()); + section.set("y", location.getY()); + section.set("z", location.getZ()); + section.set("world", Objects.requireNonNull(location.getWorld()).getName()); + } + + /** + * Searches all arenas for a game that player p is in + * @param p Player to search for + * @return the game the player is in, or null if not found + */ + public static Game findGamePlayerIsIn(Player p) { + for (Arena a : arenas.values()) { + if (a.game != null && a.game.gamePlayers.contains(p)) { + return a.game; + } + } + return null; + } +} diff --git a/src/main/java/com/MylesAndMore/Tumble/config/ConfigManager.java b/src/main/java/com/MylesAndMore/Tumble/config/ConfigManager.java new file mode 100644 index 0000000..ea7414a --- /dev/null +++ b/src/main/java/com/MylesAndMore/Tumble/config/ConfigManager.java @@ -0,0 +1,23 @@ +package com.MylesAndMore.Tumble.config; + +import org.bukkit.configuration.file.FileConfiguration; + +import static com.MylesAndMore.Tumble.Main.plugin; + +public class ConfigManager { + private static FileConfiguration config; + + public static boolean HideLeaveJoin; + public static int waitDuration; + + public ConfigManager() { + config = plugin.getConfig(); + } + + public static void readConfig() { + HideLeaveJoin = config.getBoolean("hideJoinLeaveMessages", false); + waitDuration = config.getInt("wait-duration", 15); + } + + +} diff --git a/src/main/java/com/MylesAndMore/Tumble/config/LanguageManager.java b/src/main/java/com/MylesAndMore/Tumble/config/LanguageManager.java new file mode 100644 index 0000000..c050d3c --- /dev/null +++ b/src/main/java/com/MylesAndMore/Tumble/config/LanguageManager.java @@ -0,0 +1,50 @@ +package com.MylesAndMore.Tumble.config; + +import org.bukkit.ChatColor; +import org.bukkit.configuration.InvalidConfigurationException; +import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.awt.*; +import java.io.File; +import java.io.IOException; + +import static com.MylesAndMore.Tumble.Main.plugin; + +public class LanguageManager { + private static FileConfiguration config; + + public LanguageManager() { + String fileName = "language.yml"; + // create config + File customConfigFile = new File(plugin.getDataFolder(), fileName); + if (!customConfigFile.exists()) { + customConfigFile.getParentFile().mkdirs(); + plugin.saveResource(fileName, false); + } + + config = new YamlConfiguration(); + try { + config.load(customConfigFile); + } catch (IOException | InvalidConfigurationException e) { + e.printStackTrace(); + } + /* User Edit: + Instead of the above Try/Catch, you can also use + YamlConfiguration.loadConfiguration(customConfigFile) + */ + } + + + public static String fromKey(String key) { + return fromKeyNoPrefix("prefix") + fromKeyNoPrefix(key); + } + + public static String fromKeyNoPrefix(String key) { + String tmp = config.getString(key, "LANG_ERR"); + if (tmp.equals("LANG_ERR")) { + plugin.getLogger().severe("There was an error getting key '"+ key +"' from language.yml"); + } + return ChatColor.translateAlternateColorCodes('&',tmp); + } +} diff --git a/src/main/java/com/MylesAndMore/Tumble/game/Arena.java b/src/main/java/com/MylesAndMore/Tumble/game/Arena.java index 831f251..71849e6 100644 --- a/src/main/java/com/MylesAndMore/Tumble/game/Arena.java +++ b/src/main/java/com/MylesAndMore/Tumble/game/Arena.java @@ -8,21 +8,22 @@ import org.jetbrains.annotations.NotNull; * An arena is the world and spawn location where a game can take place. An arena can only host one game at a time. */ public class Arena { - public Game game = null; - public final World world; - public Location location; + public final String name; - public Integer killAtY; + + public Integer killAtY = null; + public Location gameSpawn = null; + public Location lobby = null; + public Location winnerLobby = null; + public Location waitArea = null; + + public Game game = null; /** * Creates a new Arena * @param name Name of the arena - * @param location Center point / spawn point. */ - public Arena(@NotNull String name, @NotNull Location location, Integer killAtY) { - this.location = location; - this.world = location.getWorld(); + public Arena(@NotNull String name) { this.name = name; - this.killAtY = killAtY; } } diff --git a/src/main/java/com/MylesAndMore/Tumble/game/EventListener.java b/src/main/java/com/MylesAndMore/Tumble/game/EventListener.java index 28fb0d8..36d02b6 100644 --- a/src/main/java/com/MylesAndMore/Tumble/game/EventListener.java +++ b/src/main/java/com/MylesAndMore/Tumble/game/EventListener.java @@ -2,7 +2,8 @@ package com.MylesAndMore.Tumble.game; import java.util.Objects; -import com.MylesAndMore.Tumble.plugin.ConfigManager; +import com.MylesAndMore.Tumble.config.ArenaManager; +import com.MylesAndMore.Tumble.config.ConfigManager; import com.MylesAndMore.Tumble.plugin.GameState; import com.MylesAndMore.Tumble.plugin.GameType; import org.bukkit.*; @@ -32,7 +33,7 @@ public class EventListener implements Listener { Game game; public EventListener(Game game) { this.game = game; - this.gameWorld = game.gameWorld; + this.gameWorld = game.arena.gameSpawn.getWorld(); } @EventHandler @@ -43,7 +44,7 @@ public class EventListener implements Listener { } if (event.getPlayer().getWorld() == gameWorld) { // Send the player back to the lobby if they try to join in the middle of a game - event.getPlayer().teleport(Objects.requireNonNull(ConfigManager.lobby)); + event.getPlayer().teleport(Objects.requireNonNull(game.arena.lobby)); } } @@ -54,7 +55,7 @@ public class EventListener implements Listener { event.setQuitMessage(null); } if (event.getPlayer().getWorld() == gameWorld) { - event.getPlayer().teleport(ConfigManager.lobby); + event.getPlayer().teleport(game.arena.lobby); game.removePlayer(event.getPlayer()); } } @@ -101,7 +102,7 @@ public class EventListener implements Listener { if (event.getEntity() instanceof Snowball) { if (event.getEntity().getShooter() instanceof Player p) { if (event.getHitBlock() != null) { - if (event.getHitBlock().getLocation().distanceSquared(Objects.requireNonNull(game.arena.location)) < 579) { + if (event.getHitBlock().getLocation().distanceSquared(Objects.requireNonNull(game.arena.gameSpawn)) < 579) { p.playEffect( event.getHitBlock().getLocation(), Effect.STEP_SOUND, @@ -209,7 +210,7 @@ public class EventListener implements Listener { public void PlayerRespwanEvent(PlayerRespawnEvent event) { // Make sure players respawn in the correct location if (game.gamePlayers.contains(event.getPlayer())) { - event.setRespawnLocation(game.arena.location); + event.setRespawnLocation(game.arena.gameSpawn); } } diff --git a/src/main/java/com/MylesAndMore/Tumble/game/Game.java b/src/main/java/com/MylesAndMore/Tumble/game/Game.java index 113a5cd..dd13b31 100644 --- a/src/main/java/com/MylesAndMore/Tumble/game/Game.java +++ b/src/main/java/com/MylesAndMore/Tumble/game/Game.java @@ -1,6 +1,8 @@ package com.MylesAndMore.Tumble.game; -import com.MylesAndMore.Tumble.plugin.ConfigManager; +import com.MylesAndMore.Tumble.config.ArenaManager; +import com.MylesAndMore.Tumble.config.ConfigManager; +import com.MylesAndMore.Tumble.config.LanguageManager; import com.MylesAndMore.Tumble.plugin.GameState; import com.MylesAndMore.Tumble.plugin.GameType; import net.md_5.bungee.api.ChatMessageType; @@ -25,7 +27,6 @@ public class Game { public final GameType type; public final Arena arena; - public final World gameWorld; private final Location gameSpawn; public final List gamePlayers = new ArrayList<>(); private final HashMap gameWins = new HashMap<>(); @@ -40,8 +41,7 @@ public class Game { public Game(@NotNull Arena arena, @NotNull GameType type) { this.arena = arena; this.type = type; - this.gameWorld = arena.world; - this.gameSpawn = arena.location; + this.gameSpawn = arena.gameSpawn; } @@ -61,6 +61,10 @@ public class Game { eventListener = new EventListener(this); Bukkit.getServer().getPluginManager().registerEvents(eventListener, plugin); + for (Player p : gamePlayers) { + inventories.put(p, p.getInventory().getContents()); + } + roundStart(); } @@ -111,7 +115,7 @@ public class Game { gameID = Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, () -> { clearInventories(gamePlayers); giveItems(gamePlayers, new ItemStack(Material.SNOWBALL)); - displayActionbar(gamePlayers, ChatColor.DARK_RED + "Showdown!"); + displayActionbar(gamePlayers, LanguageManager.fromKeyNoPrefix("showdown")); playSound(gamePlayers, Sound.ENTITY_ELDER_GUARDIAN_CURSE, SoundCategory.HOSTILE, 1, 1); // End the round in another 2m30s gameID = Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, this::roundEnd, 3000); @@ -150,12 +154,12 @@ public class Game { } // If that player doesn't have three wins, nobody else does, so we need another round else { - displayTitles(gamePlayers, ChatColor.RED + "Round over!", ChatColor.GOLD + winner.getName() + " has won the round!", 5, 60, 5); + displayTitles(gamePlayers, LanguageManager.fromKeyNoPrefix("round-over"), LanguageManager.fromKeyNoPrefix("round-winner").replace("%winner%", winner.getDisplayName()), 5, 60, 5); Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, this::roundStart, 100); } } else { - displayTitles(gamePlayers, ChatColor.RED + "Round over!", ChatColor.GOLD + "Draw!", 5, 60, 5); + displayTitles(gamePlayers, LanguageManager.fromKeyNoPrefix("round-over"), LanguageManager.fromKeyNoPrefix("round-draw"), 5, 60, 5); Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, this::roundStart, 100); } } @@ -171,9 +175,9 @@ public class Game { Player winner = getPlayerWithMostWins(gameWins); if (winner != null) { - displayTitles(gamePlayers, ChatColor.RED + "Game over!", ChatColor.GOLD + winner.getName() + " has won the game!", 5, 60, 5); + displayTitles(gamePlayers, LanguageManager.fromKeyNoPrefix("game-over"), LanguageManager.fromKeyNoPrefix("game-winner").replace("%winner%",winner.getDisplayName()), 5, 60, 5); } - displayActionbar(gamePlayers, ChatColor.BLUE + "Returning to lobby in ten seconds..."); + displayActionbar(gamePlayers, LanguageManager.fromKeyNoPrefix("lobby-in-10")); // Wait 10s (200t), then Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, () -> { @@ -186,11 +190,11 @@ public class Game { p.getInventory().setContents(inventories.get(p)); } - if (p == winner && ConfigManager.winnerLobby != null) { - p.teleport(ConfigManager.winnerLobby); + if (p == winner && arena.winnerLobby != null) { + p.teleport(arena.winnerLobby); } else { - p.teleport(Objects.requireNonNull(ConfigManager.lobby)); + p.teleport(Objects.requireNonNull(arena.lobby)); } } @@ -218,7 +222,7 @@ public class Game { if (inventories.containsKey(p)) { p.getInventory().setContents(inventories.get(p)); } - p.teleport(ConfigManager.lobby); + p.teleport(arena.lobby); } /** @@ -229,16 +233,15 @@ public class Game { public void addPlayer(Player p) { gamePlayers.add(p); // save inventory - inventories.put(p, p.getInventory().getContents()); - if (ConfigManager.waitArea != null) { - p.teleport(ConfigManager.waitArea); + if (arena.waitArea != null) { + p.teleport(arena.waitArea); p.getInventory().clear(); } if (gamePlayers.size() >= 2 && gameState == GameState.WAITING) { autoStart(); } else { - displayActionbar(Collections.singletonList(p), ChatColor.YELLOW + "Waiting for players"); + displayActionbar(Collections.singletonList(p), LanguageManager.fromKeyNoPrefix("waiting-for-players")); } } @@ -249,7 +252,7 @@ public class Game { // Wait for the player to load in int waitDuration = ConfigManager.waitDuration; Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, () -> { - displayActionbar(gamePlayers, ChatColor.GREEN + "Game will begin in "+waitDuration+" seconds!"); + displayActionbar(gamePlayers, LanguageManager.fromKeyNoPrefix("time-till-start").replace("%wait%",waitDuration+"")); playSound(gamePlayers, Sound.BLOCK_NOTE_BLOCK_CHIME, SoundCategory.BLOCKS, 1, 1); // Schedule a process to start the game in 300t (15s) and save the PID so we can cancel it later if needed autoStartID = Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, this::gameStart, waitDuration * 20L); @@ -280,6 +283,7 @@ public class Game { double x = gameSpawn.getX(); double y = gameSpawn.getY(); double z = gameSpawn.getZ(); + World gameWorld = gameSpawn.getWorld(); // Create the scatter locations based off the game's spawn List scatterLocations = new ArrayList<>(List.of( new Location(gameWorld, (x - 14.5), y, (z + 0.5), -90, 0), @@ -303,16 +307,16 @@ public class Game { */ private void countdown(Runnable doAfter) { playSound(gamePlayers, Sound.ENTITY_EXPERIENCE_ORB_PICKUP, SoundCategory.NEUTRAL, 5, 1); - displayTitles(gamePlayers, ChatColor.DARK_GREEN + "3", null, 3, 10, 7); + displayTitles(gamePlayers, LanguageManager.fromKeyNoPrefix("count-3"), null, 3, 10, 7); Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, () -> { playSound(gamePlayers, Sound.ENTITY_EXPERIENCE_ORB_PICKUP, SoundCategory.NEUTRAL, 5, 1); - displayTitles(gamePlayers, ChatColor.YELLOW + "2", null, 3, 10, 7); + displayTitles(gamePlayers, LanguageManager.fromKeyNoPrefix("count-2"), null, 3, 10, 7); Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, () -> { playSound(gamePlayers, Sound.ENTITY_EXPERIENCE_ORB_PICKUP, SoundCategory.NEUTRAL, 5, 1); - displayTitles(gamePlayers, ChatColor.DARK_RED + "1", null, 3, 10, 7); + displayTitles(gamePlayers, LanguageManager.fromKeyNoPrefix("count-1"), null, 3, 10, 7); Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, () -> { playSound(gamePlayers, Sound.ENTITY_EXPERIENCE_ORB_PICKUP, SoundCategory.NEUTRAL, 5, 2); - displayTitles(gamePlayers, ChatColor.GREEN + "Go!", null, 1, 5, 1); + displayTitles(gamePlayers, LanguageManager.fromKeyNoPrefix("count-go"), null, 1, 5, 1); doAfter.run(); }, 20); }, 20); diff --git a/src/main/java/com/MylesAndMore/Tumble/plugin/ConfigManager.java b/src/main/java/com/MylesAndMore/Tumble/plugin/ConfigManager.java deleted file mode 100644 index c4c1943..0000000 --- a/src/main/java/com/MylesAndMore/Tumble/plugin/ConfigManager.java +++ /dev/null @@ -1,194 +0,0 @@ -package com.MylesAndMore.Tumble.plugin; - -import com.MylesAndMore.Tumble.game.Arena; -import com.MylesAndMore.Tumble.game.Game; -import org.bukkit.Bukkit; -import org.bukkit.Location; -import org.bukkit.World; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.Nullable; - -import java.util.HashMap; -import java.util.Objects; - -import static com.MylesAndMore.Tumble.Main.plugin; - -public class ConfigManager { - public static HashMap arenas; - public static Location lobby; - public static Location winnerLobby; - public static Location waitArea; - public static boolean HideLeaveJoin; - public static int waitDuration; - - /** - * Reads config file and populates values above - */ - public static void readConfig() { - plugin.reloadConfig(); - FileConfiguration config = plugin.getConfig(); - - HideLeaveJoin = config.getBoolean("hideJoinLeaveMessages", false); - waitDuration = config.getInt("wait-duration", 15); - - // wait area - if (config.getBoolean("wait-area.enable", false)) { - Resultres = readWorld(config.getConfigurationSection("wait-area.spawn")); - if (!res.success) { - plugin.getLogger().warning("Failed to load winner lobby: "+res.error); - waitArea = null; - } - else { - waitArea = res.value; - } - } - - // lobby - { - Resultres = readWorld(config.getConfigurationSection("lobby.spawn")); - if (!res.success) { - plugin.getLogger().warning("Failed to load lobby: "+res.error); - plugin.getLogger().severe("Lobby spawn is required! Lobby spawn will default to spawn in the default world. Run '/tumble-config set lobbyWorld' to change it"); - lobby = Bukkit.getServer().getWorlds().get(0).getSpawnLocation(); - } - else { - lobby = res.value; - } - } - - // winner lobby - if (config.getBoolean("winner-lobby.enable", false)) { - Resultres = readWorld(config.getConfigurationSection("winner-lobby.spawn")); - if (!res.success) { - plugin.getLogger().warning("Failed to load winner lobby: "+res.error); - winnerLobby = null; - } - else { - winnerLobby = res.value; - } - } - - // arenas - ConfigurationSection arenasSection = config.getConfigurationSection("arenas"); - if (arenasSection == null) { - plugin.getLogger().warning("Section 'arenas' is missing from config"); - return; - } - arenas = new HashMap<>(); - for (String arenaName: arenasSection.getKeys(false)) { - - ConfigurationSection anArenaSection = arenasSection.getConfigurationSection(arenaName); - if (anArenaSection == null) { - plugin.getLogger().warning("Failed to load arena "+arenaName+": Error loading config section"); - continue; - } - - Integer killAtY = anArenaSection.getInt("kill-at-y", 0); - if (killAtY == 0) { - killAtY = null; - } - - Result res = readWorld(anArenaSection.getConfigurationSection("spawn")); - if (!res.success) { - plugin.getLogger().warning("Failed to load arena "+arenaName+": "+res.error); - continue; - } - - arenas.put(arenaName, new Arena(arenaName, res.value, killAtY)); - } - } - - /** - * tries to convert a config section in the following format to a world - * section: - * x: - * y: - * z: - * world: - * @param section the section in the yaml with x, y, z, and world as its children - * @return result of either: - * success = true and a world - * success = false and an error string - */ - private static Result readWorld(@Nullable ConfigurationSection section) { - - if (section == null) { - return new Result<>("Section missing from config"); - } - - double x = section.getDouble("x"); - double y = section.getDouble("y"); - double z = section.getDouble("z"); - if (x == 0 || y == 0 || z == 0) { - return new Result<>("Arena coordinates are missing or are zero. Coordinates cannot be zero."); - } - - String worldName = section.getString("world"); - if (worldName == null) { - return new Result<>("World name is missing"); - } - - World world = Bukkit.getWorld(worldName); - if (world == null) { - return new Result<>("Failed to load world " + worldName); - } - - return new Result<>(new Location(world,x,y,z)); - } - - public static void WriteConfig() { - if (waitArea != null) { - WriteWorld(Objects.requireNonNull(plugin.getConfig().getConfigurationSection("wait-area")), waitArea); - plugin.getConfig().set("wait-area.enable", true); - } - else { - plugin.getConfig().set("wait-area.enable", false); - } - - if (lobby != null) { - WriteWorld(Objects.requireNonNull(plugin.getConfig().getConfigurationSection("lobby.spawn")), lobby); - } - - if (winnerLobby != null) { - WriteWorld(Objects.requireNonNull(plugin.getConfig().getConfigurationSection("winner-lobby.spawn")), winnerLobby); - plugin.getConfig().set("winner-lobby.enable", true); - } - else { - plugin.getConfig().set("winner-lobby.enable", false); - } - - for (String arenaName: arenas.keySet()) { - ConfigurationSection c = plugin.getConfig().getConfigurationSection("arenas."+arenaName+".spawn"); - if (c == null) { - c = plugin.getConfig().createSection("arenas."+arenaName+".spawn"); - } - WriteWorld(c, arenas.get(arenaName).location); - } - - plugin.saveConfig(); - - } - - private static void WriteWorld(ConfigurationSection section, Location location) { - section.set("x", location.getX()); - section.set("y", location.getY()); - section.set("z", location.getZ()); - section.set("world", Objects.requireNonNull(location.getWorld()).getName()); - } - - /** - * Searches all arenas for a game that player p is in - * @param p Player to search for - * @return the game the player is in, or null if not found - */ - public static Game findGamePlayerIsIn(Player p) { - for (Arena a : arenas.values()) { - if (a.game != null && a.game.gamePlayers.contains(p)) { - return a.game; - } - } - return null; - } -} diff --git a/src/main/java/com/MylesAndMore/Tumble/plugin/SubCommand.java b/src/main/java/com/MylesAndMore/Tumble/plugin/SubCommand.java new file mode 100644 index 0000000..2158584 --- /dev/null +++ b/src/main/java/com/MylesAndMore/Tumble/plugin/SubCommand.java @@ -0,0 +1,8 @@ +package com.MylesAndMore.Tumble.plugin; + +import org.bukkit.command.CommandExecutor; + +public interface SubCommand extends CommandExecutor { + public String getCommandName(); + public String getPermission(); +} diff --git a/src/main/resources/arenas.yml b/src/main/resources/arenas.yml new file mode 100644 index 0000000..7b902be --- /dev/null +++ b/src/main/resources/arenas.yml @@ -0,0 +1,23 @@ +arenas: + 'test': + kill-at-y: 5 + game-spawn: + x: 100 + y: 100 + z: 100 + world: world + lobby: + x: 0.5 + y: 100 + z: 0.5 + world: world + winner-lobby: + x: 0.5 + y: 100 + z: 0.5 + world: world + wait-arena: + x: 0.5 + y: 100 + z: 0.5 + world: world \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index b13570e..97f0a12 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -3,42 +3,5 @@ hideJoinLeaveMessages: false # Duration in seconds to wait for more players to join wait-duration: 15 -# Teleport players somewhere while waiting for the game to start -# Keep in mind that these coordinates cannot be zero! Use something like 0.5 instead -wait-area: - enable: false - spawn: - x: - y: - z: - world: -# Place where everyone is teleported to after a game ends REQUIRED -# Keep in mind that these coordinates cannot be zero! Use something like 0.5 instead -lobby: - spawn: - x: 0.5 - y: 100 - z: 0.5 - world: world -# Place that the winner is teleported after a game ends -# Keep in mind that these coordinates cannot be zero! Use something like 0.5 instead -winner-lobby: - enable: false - spawn: - x: - y: - z: - world: - -# Add/remove as you wish -# Keep in mind that these coordinates cannot be zero! Use something like 0.5 instead -arenas: - 'test': - kill-at-y: 5 - spawn: - x: 100 - y: 100 - z: 100 - world: world \ No newline at end of file diff --git a/src/main/resources/language.yml b/src/main/resources/language.yml new file mode 100644 index 0000000..fa57b1c --- /dev/null +++ b/src/main/resources/language.yml @@ -0,0 +1,42 @@ +prefix: "&f[&eTumble&f] " + +unknown-command: "&4Unknown command '%command%'" +no-permission: "&4You do not have permission to perform this command! &7Required permission: '%permission%.'" +missing-arena-parameter: "&4Missing arena name!" +invalid-arena: "&4arena '%arena%' does not exist!" +invalid-type: "&4Invalid game type" +no-game-in-arena: "&4No game is currently running in this arena" +player-not-in-game: "&4You are not in a game!" +not-for-console: "&4This cannot be run by the console" +game-in-progress: "&4This game is still in progress!&7 wait until it finishes or join another game" +another-type-in-arena: "A game of %type% is currently taking place in this arena!&7 choose another arena or join it with &a/tmbl join %arena% %type%" +already-in-game: "&4You are already in a game! Leave it to join another one." + +create-success: "&aArena created successfully! &eBefore you can join, you must set a game spawn location with /tmbl setGameSpawn" +forcestart-success: "&aStarting game." +forcestop-success: "&aGame stopped." +join-success: "&aJoined game &d%arena% - %type%" +leave-success: "&aLeft game &d%arena% - %type%" +reload-success: "&aConfiguration reloaded. &eCheck console for errors." +remove-success: "&aArena removed." +set-success: "&aLocation set." + +showdown: "&4Showdown!" +lobby-in-10: "&9Returning to lobby in ten seconds..." +waiting-for-players: "&aWaiting for players" +time-till-start: "&aGame will begin in %wait% seconds!" +round-over: "&cRound over!" +round-winner: "&6%winner% has won the round!" +round-draw: "&6Draw!" +game-over: "&Game over!" +game-winner: "&6%winner% has won the Game!" +count-3: "&23" +count-2: "&e2" +count-1: "&41" +count-go: "&aGo!" + + + + + + diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 486fccf..ed246c5 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -7,31 +7,14 @@ load: POSTWORLD author: MylesAndMore website: https://github.com/MylesAndMore/Tumble softdepend: [Multiverse-Core] + commands: - tumble-join: + tumble: description: Joins a Tumble match. - usage: '§cUsage: /tumble-join [gameType]' + usage: '§cUsage: /tumble' permission: tumble.join - tumble-leave: - description: Quits a Tumble match. - usage: '§cUsage: /tumble-leave' - permission: tumble.leave - tumble-forcestart: - description: Force starts a Tumble match. - usage: '§cUsage: /tumble-forcestart [arenaName]' - permission: tumble.forcestart - tumble-forcestop: - description: Force stops a Tumble match. - usage: '§cUsage: /tumble-forcestop [arenaName]' - permission: tumble.forcestop - tumble-config: - description: Modify arenas and worlds. - usage: '§cUsage: /tumble-config ' - permission: tumble.config - tumble-reload: - description: Reloads the plugin's config. - usage: '§cUsage: /tumble-reload' - permission: tumble.reload + aliases: tmbl + permissions: tumble.join: description: Allows you to join a Tumble match. -- cgit v1.2.3