aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsowgro <tpoke.ferrari@gmail.com>2024-08-01 17:38:44 -0400
committersowgro <tpoke.ferrari@gmail.com>2024-08-01 17:38:44 -0400
commitf049b84bbd3d9354f9cba949cf71dc4a6fba0786 (patch)
treeb04bf87a5939c362c5c43d4a380adeedec02fed1
parent8c9889930cf61f959cc60e5a0098ece4215c59f2 (diff)
parentcadddd7499f92b4529ce34231ff4a379011515ff (diff)
downloadTumble-f049b84bbd3d9354f9cba949cf71dc4a6fba0786.tar.gz
Tumble-f049b84bbd3d9354f9cba949cf71dc4a6fba0786.tar.bz2
Tumble-f049b84bbd3d9354f9cba949cf71dc4a6fba0786.zip
Merge remote-tracking branch 'origin/main'
# Conflicts: # src/main/java/com/MylesAndMore/Tumble/game/Generator.java # src/main/java/com/MylesAndMore/Tumble/game/Layers.java
-rw-r--r--OG_GUIDE.md20
-rw-r--r--README.md91
-rw-r--r--build.gradle10
-rw-r--r--src/main/java/com/MylesAndMore/Tumble/Main.java4
-rw-r--r--src/main/java/com/MylesAndMore/Tumble/commands/Create.java2
-rw-r--r--src/main/java/com/MylesAndMore/Tumble/commands/ForceStart.java7
-rw-r--r--src/main/java/com/MylesAndMore/Tumble/commands/ForceStop.java5
-rw-r--r--src/main/java/com/MylesAndMore/Tumble/commands/Join.java41
-rw-r--r--src/main/java/com/MylesAndMore/Tumble/commands/Reload.java1
-rw-r--r--src/main/java/com/MylesAndMore/Tumble/commands/Remove.java2
-rw-r--r--src/main/java/com/MylesAndMore/Tumble/commands/SetGameSpawn.java2
-rw-r--r--src/main/java/com/MylesAndMore/Tumble/commands/SetKillYLevel.java2
-rw-r--r--src/main/java/com/MylesAndMore/Tumble/commands/SetLobby.java2
-rw-r--r--src/main/java/com/MylesAndMore/Tumble/commands/SetWaitArea.java2
-rw-r--r--src/main/java/com/MylesAndMore/Tumble/commands/SetWinnerLobby.java2
-rw-r--r--src/main/java/com/MylesAndMore/Tumble/commands/Tumble.java9
-rw-r--r--src/main/java/com/MylesAndMore/Tumble/config/ArenaManager.java39
-rw-r--r--src/main/java/com/MylesAndMore/Tumble/config/ConfigManager.java7
-rw-r--r--src/main/java/com/MylesAndMore/Tumble/game/Arena.java1
-rw-r--r--src/main/java/com/MylesAndMore/Tumble/game/EventListener.java25
-rw-r--r--src/main/java/com/MylesAndMore/Tumble/game/Game.java126
-rw-r--r--src/main/java/com/MylesAndMore/Tumble/game/Generator.java85
-rw-r--r--src/main/java/com/MylesAndMore/Tumble/plugin/GameState.java2
-rw-r--r--src/main/resources/arenas.yml4
-rw-r--r--src/main/resources/config.yml10
-rw-r--r--src/main/resources/language.yml48
-rw-r--r--src/main/resources/plugin.yml16
27 files changed, 277 insertions, 288 deletions
diff --git a/OG_GUIDE.md b/OG_GUIDE.md
index f7302a1..da75d93 100644
--- a/OG_GUIDE.md
+++ b/OG_GUIDE.md
@@ -16,7 +16,7 @@ In this guide, I'll go over how to set up the Tumble plugin with the original ga
Tip: set a specific directory to store your worlds in with the `world-container` setting in `bukkit.yml`
-3. Set `level-name` in server.properities to `lobby`
+3. Set `level-name` in server.properties to `lobby`
4. Take note of the names of the world folders, we will need this in a moment.
5. Start and join your server.
6. Import your arena worlds. This can be done with the multiverse command `/mv import <your-world-name> normal`
@@ -93,25 +93,25 @@ In this guide, I'll go over how to set up the Tumble plugin with the original ga
z: -340.5
world: lobby
```
-8. Reload the plugin with `/tmbl reload`.
+8. Reload the plugin with `/tumble reload`.
-9. Join the game using `/tmbl join basic mixed`
+9. Join the game using `/tumble join basic mixed`
(swap the arena and game type for whichever one you want to play).
You're done! Happy playing!
## Recommended plugins
+These plugins, while not required, can help to provide a more thorough minigame experience.
+
- [WorldGuard](https://dev.bukkit.org/projects/worldguard) and [CyberWorldReset](https://www.spigotmc.org/resources/cyberworldreset-standard-%E2%9C%A8-regenerate-worlds-scheduled-resets-lag-optimized%E3%80%8C1-8-1-19%E3%80%8D.96834/)
-Protect players from breaking blocks in the lobby and reset any redstone they activated.
+ - Protect players from breaking blocks in the lobby and reset any redstone they activated.
- [ViaVersion](https://www.spigotmc.org/resources/viaversion.19254/) and [ViaBackwards](https://www.spigotmc.org/resources/viabackwards.27448/)
-Allow older and newer clients to connect to your server.
+ - Allow older and newer players to connect to your server.
- [Geyser](https://geysermc.org/download#geyser) and [Floodgate](https://geysermc.org/download#floodgate)
-Allow Bedrock clients to connect to your server.
-
-- [ProtectEnviromnemt](https://www.spigotmc.org/resources/protectenvironment.82736/)
-Stop water and lava flow (useful for Halloween map)
-
+ - Allow Bedrock clients to connect to your server.
+- [ProtectEnvironment](https://www.spigotmc.org/resources/protectenvironment.82736/)
+ - Stop water and lava flow (useful for Halloween map).
diff --git a/README.md b/README.md
index 525e01f..52dc9c2 100644
--- a/README.md
+++ b/README.md
@@ -11,73 +11,73 @@ But in Tumble, you play on randomly generated layers of blocks, using shovels, s
## Features
-- Choose from three different game modes present in the original game: shovels, snowballs, and mixed
-- Four types of random layer generation
+- 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
-- Support for 2-8 players
-- Highly customizable
-- Open-source codebase
+- Support for 2-8 players
- Multiple arenas and concurrent games
-- Heavily configurable
+- Highly customizable, heavily configurable
+- Open-source codebase
## Setup
-1. [Download](https://github.com/MylesAndMore/tmbl/releases) the plugin's JAR file and place it in your server's plugins directory.
-2. Place the worlds for your lobby and arenas in your plugins worlds directory.
+1. [Download](https://github.com/MylesAndMore/tumble/releases) the plugin's JAR file and place it in your server's plugins directory.
+2. Place the worlds for your lobby and arenas in your server's worlds directory.
- If you would like an experience similar to the original game, see [my guide](OG_GUIDE.md) for using the original worlds.
3. Start your server.
4. Import your worlds using a plugin like Multiverse. ```/mv import myWorld normal```.
-5. Create your first arena `/tmbl create myArena`
-6. Set the spawn point of the arena `/tmbl setgamespawn myArena`
+5. Create your first arena `/tumble create myArena`
+6. Set the spawn point of the arena `/tumble setgamespawn myArena`
- **Note**: The layers will generate relative to this location. Ensure that the area is clear, 20 blocks in each direction.
-7. You're done! You can now join the game ```/tmbl join myArena mixed```.
+7. You're done! You can now join the game ```/tumble join myArena mixed```.
Scroll down for more options to configure your game.
## Commands / Permissions
-| Command | Description | Permission |
-|-------------------------------------|------------------------------------------------------------------------------------|-------------------------|
-| `/tmbl join <arenaName> [gameType]` | Join a Tumble match. Can infer game type if a game is already started in the arena | `tumble.join` |
-| `/tmbl leave` | Quit a Tumble match | `tumble.leave` |
-| `/tmbl forcestart [arenaName]` | Force start a Tumble match. Can infer arena if you are in one | `tumble.forcestart` |
-| `/tmbl forcestop [arenaName]` | Force stop a Tumble match. Can infer arena if you are in one | `tumble.forcestop` |
-| `/tmbl reload` | Reload the plugin's configs. | `tumble.reload` |
-| `/tmbl create <arenaName>` | Create a new arena | `tumble.create` |
-| `/tmbl remove <arenaName>` | Remove an arena | `tumble.remove` |
-| `/tmbl setgamespawn <arenaName>` | Set game spawn to your current position | `tumble.setgamespawn` |
-| `/tmbl setkillylevel <arenaName>` | Set the arena's Y-level to kill players at to current Y coordinate | `tumble.setkillylevel` |
-| `/tmbl setlobby <arenaName>` | Set the arena's lobby to current location | `tumble.setlobby` |
-| `/tmbl setwaitarea <arenaName>` | Set the arena's wait area to the current location | `tumble.setwaitarea` |
-| `/tmbl setwinnerlobby <arenaName>` | Set the arena's lobby to the current location | `tumble.setwinnerlobby` |
-
+| Command | Description | Permission |
+|---------------------------------------|-------------------------------------------------------------------------------------|-------------------------|
+| `/tumble join <arenaName> [gameType]` | Join a Tumble match. Can infer game type if a game is already started in the arena. | `tumble.join` |
+| `/tumble leave` | Leave a Tumble match. | `tumble.leave` |
+| `/tumble forcestart [arenaName]` | Force start a Tumble match. Can infer arena if you are in one. | `tumble.forcestart` |
+| `/tumble forcestop [arenaName]` | Force stop a Tumble match. Can infer arena if you are in one. | `tumble.forcestop` |
+| `/tumble reload` | Reload the plugin's configuration. | `tumble.reload` |
+| `/tumble create <arenaName>` | Create a new arena. | `tumble.create` |
+| `/tumble remove <arenaName>` | Remove an arena. | `tumble.remove` |
+| `/tumble setgamespawn <arenaName>` | Set the arena's game spawn to your current position. | `tumble.setgamespawn` |
+| `/tumble setkillylevel <arenaName>` | Set the arena's Y-level to kill players at to current Y coordinate. | `tumble.setkillylevel` |
+| `/tumble setlobby <arenaName>` | Set the arena's lobby to current location. | `tumble.setlobby` |
+| `/tumble setwaitarea <arenaName>` | Set the arena's wait area to the current location. | `tumble.setwaitarea` |
+| `/tumble setwinnerlobby <arenaName>` | Set the arena's lobby to the current location. | `tumble.setwinnerlobby` |
+
+Note that the `/tmbl` command can be used as a shorter alias to `/tumble`.
## Configuration
-Configuration for this plugin is stored in three files.
+Configuration for this plugin is stored in three files:
### config.yml
-Stores common settings
-
-| Option | Type | Default value |
-|----------------------------|-------------------|---------------|
-| `hide-join-leave-messages` | Boolean | `false` |
-| `wait-duration` | Integer (seconds) | `15` |
+Stores general settings.
+| Option | Type | Description | Default value |
+|----------------------------|---------|--------------------------------------------------------------------------------|---------------|
+| `hide-join-leave-messages` | Boolean | Hides player join and leave messages in public chat. | `false` |
+| `wait-duration` | Integer | Duration (in seconds) to wait for more players to join a game before starting. | `15` |
### arenas.yml
-Stores data for each arena. You may add and remove arenas as you wish.
+Stores data about each arena.
+Arenas may be added and removed as you wish, either via the commands detailed above or by editing the `arenas.yml` file directly.
Each arena can contain the following locations:
| Location | Description |
|--------------------------|-------------------------------------------------------------------------------------|
| `game-spawn` **Required* | The location where players will be teleported, and the layers will generate around. |
-| `wait-area` | The location where players will be teleported to before the game begins |
-| `lobby` | The location where players will be teleported to after the game |
-| `winner-lobby` | The location where the winner will be teleported after the game |
+| `wait-area` | The location where players will be teleported to before the game begins. |
+| `lobby` | The location where players will be teleported to after the game. |
+| `winner-lobby` | The location where the winner will be teleported after the game. |
Locations are stored using the following format:
```yaml
@@ -87,24 +87,21 @@ Locations are stored using the following format:
z: 0.5
world: worldName
```
+If a location is not specified, players will not be teleported by the plugin.
Each arena can also contain the following option:
-| Option | Type | Description |
-|-------------|---------|-----------------------------------------------------------------|
-| `kill-at-y` | Integer | When a player falls below this Y-level, they will be eliminated |
+| Option | Type | Description |
+|-------------|---------|------------------------------------------------------------------|
+| `kill-at-y` | Integer | When a player falls below this Y-level, they will be eliminated. |
### language.yml
-Most of this plugin's strings are configurable through this file. (Excluding from some console errors)
+Most of this plugin's messages are configurable through this file (excluding some console errors).
All plugin chat messages will have the `prefix` prepended to them.
-Colors can be added using alternate color codes:
-```
-&cRed Text
-```
-
+Colors can be added using alternate color codes; for example, `&cRed Text` will appear red in-game.
## 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/tmbl/issues/new)!
+Feel free to report any bugs, leave feedback, ask questions, or submit ideas for new features on the Tumble [GitHub issues page](https://github.com/MylesAndMore/tumble/issues/new)!
diff --git a/build.gradle b/build.gradle
index 58b2dc8..41f2c92 100644
--- a/build.gradle
+++ b/build.gradle
@@ -10,18 +10,15 @@ java {
}
repositories {
- mavenCentral() // Use Maven Central for resolving dependencies.
+ mavenCentral() // Use Maven Central for resolving dependencies
maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
maven { url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' }
- maven { url "https://repo.onarandombox.com/content/groups/public/" }
- maven { url "https://repo.jeff-media.com/public/"}
}
dependencies {
+ compileOnly('org.jetbrains:annotations:24.1.0')
compileOnly('org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT')
- compileOnly('com.onarandombox.multiversecore:Multiverse-Core:4.3.1')
implementation('org.bstats:bstats-bukkit:3.0.2')
- implementation('com.jeff_media:SpigotUpdateChecker:3.0.3')
}
// Disable generation of the normal JAR to reduce confusion and only generate the correctly shadowed JAR including bStats
@@ -30,7 +27,6 @@ jar.finalizedBy(shadowJar)
shadowJar {
archiveBaseName.set('Tumble')
archiveClassifier.set('')
- archiveVersion.set('1.0.4')
+ archiveVersion.set('2.0.0')
relocate 'org.bstats', 'com.MylesAndMore.bstats'
- relocate 'com.jeff_media.updatechecker', 'com.MylesAndMore.updatechecker'
}
diff --git a/src/main/java/com/MylesAndMore/Tumble/Main.java b/src/main/java/com/MylesAndMore/Tumble/Main.java
index b85636d..56a46c1 100644
--- a/src/main/java/com/MylesAndMore/Tumble/Main.java
+++ b/src/main/java/com/MylesAndMore/Tumble/Main.java
@@ -14,7 +14,7 @@ import org.bukkit.plugin.java.JavaPlugin;
import java.util.Objects;
-public class Main extends JavaPlugin{
+public class Main extends JavaPlugin {
public static Main plugin;
@Override
@@ -34,7 +34,7 @@ public class Main extends JavaPlugin{
@Override
public void onDisable() {
- // stop running games
+ // Stop any running games
for (Arena a : ArenaManager.arenas.values()) {
if (a.game != null) {
a.game.stopGame();
diff --git a/src/main/java/com/MylesAndMore/Tumble/commands/Create.java b/src/main/java/com/MylesAndMore/Tumble/commands/Create.java
index 667be5e..d60ca64 100644
--- a/src/main/java/com/MylesAndMore/Tumble/commands/Create.java
+++ b/src/main/java/com/MylesAndMore/Tumble/commands/Create.java
@@ -33,7 +33,7 @@ public class Create implements SubCommand, CommandExecutor, TabCompleter {
String arenaName = args[0];
ArenaManager.arenas.put(arenaName, new Arena(arenaName));
- ArenaManager.WriteConfig();
+ ArenaManager.writeConfig();
sender.sendMessage(LanguageManager.fromKey("create-success"));
return true;
}
diff --git a/src/main/java/com/MylesAndMore/Tumble/commands/ForceStart.java b/src/main/java/com/MylesAndMore/Tumble/commands/ForceStart.java
index 3953bea..29583a4 100644
--- a/src/main/java/com/MylesAndMore/Tumble/commands/ForceStart.java
+++ b/src/main/java/com/MylesAndMore/Tumble/commands/ForceStart.java
@@ -29,17 +29,16 @@ public class ForceStart implements SubCommand, CommandExecutor, TabCompleter {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
-
Game game;
+
if (args.length < 1 || args[0] == null) {
- // no arena passed in, try to infer from game player is in
+ // No arena passed in, try to infer from game player is in
game = ArenaManager.findGamePlayerIsIn((Player)sender);
if (game == null) {
sender.sendMessage(LanguageManager.fromKey("missing-arena-parameter"));
return false;
}
- }
- else {
+ } else {
String arenaName = args[0];
if (!ArenaManager.arenas.containsKey(arenaName)) {
sender.sendMessage(LanguageManager.fromKey("invalid-arena").replace("%arena%",arenaName));
diff --git a/src/main/java/com/MylesAndMore/Tumble/commands/ForceStop.java b/src/main/java/com/MylesAndMore/Tumble/commands/ForceStop.java
index 37d3465..f308979 100644
--- a/src/main/java/com/MylesAndMore/Tumble/commands/ForceStop.java
+++ b/src/main/java/com/MylesAndMore/Tumble/commands/ForceStop.java
@@ -31,14 +31,13 @@ public class ForceStop implements SubCommand, CommandExecutor, TabCompleter {
Game game;
if (args.length < 1 || args[0] == null) {
- // no arena passed in, try to infer from game player is in
+ // No arena passed in, try to infer from game player is in
game = ArenaManager.findGamePlayerIsIn((Player)sender);
if (game == null) {
sender.sendMessage(LanguageManager.fromKey("missing-arena-parameter"));
return false;
}
- }
- else {
+ } else {
String arenaName = args[0];
if (!ArenaManager.arenas.containsKey(arenaName)) {
sender.sendMessage(LanguageManager.fromKey("invalid-arena").replace("%arena%",arenaName));
diff --git a/src/main/java/com/MylesAndMore/Tumble/commands/Join.java b/src/main/java/com/MylesAndMore/Tumble/commands/Join.java
index 6ce33c3..f26d4e5 100644
--- a/src/main/java/com/MylesAndMore/Tumble/commands/Join.java
+++ b/src/main/java/com/MylesAndMore/Tumble/commands/Join.java
@@ -50,26 +50,34 @@ public class Join implements SubCommand, CommandExecutor, TabCompleter {
return false;
}
String arenaName = args[0];
- if (!ArenaManager.arenas.containsKey(arenaName))
- {
+ if (!ArenaManager.arenas.containsKey(arenaName)) {
sender.sendMessage(LanguageManager.fromKey("invalid-arena").replace("%arena%", arenaName));
return false;
}
Arena arena = ArenaManager.arenas.get(arenaName);
+ // Check to make sure this arena has a game spawn
+ if (arena.gameSpawn == null) {
+ if (p.isOp()) {
+ sender.sendMessage(LanguageManager.fromKey("arena-not-ready-op"));
+ } else {
+ sender.sendMessage(LanguageManager.fromKey("arena-not-ready"));
+ }
+ return false;
+ }
+
Game game;
if (args.length < 2 || args[1] == null) {
- // no type specified: try to infer game type from game taking place in the arena
+ // No type specified: try to infer game type from game taking place in the arena
if (arena.game == null) {
- // cant infer if no game is taking place
+ // Can't infer if no game is taking place
sender.sendMessage(LanguageManager.fromKey("specify-game-type"));
return false;
}
game = arena.game;
- }
- else {
- // type specified
+ } else {
+ // Game type specified
GameType type;
switch (args[1]) {
case "shovels", "shovel" -> type = GameType.SHOVELS;
@@ -82,12 +90,10 @@ public class Join implements SubCommand, CommandExecutor, TabCompleter {
}
if (arena.game == null) {
- // no game is taking place in this arena, start one
+ // No game is taking place in this arena, start one
game = arena.game = new Game(arena, type);
- }
- else
- {
- // a game is taking place in this arena, check that it is the right type
+ } else {
+ // A game is taking place in this arena, check that it is the right type
if (arena.game.type == type) {
game = arena.game;
}
@@ -100,16 +106,7 @@ public class Join implements SubCommand, CommandExecutor, TabCompleter {
}
}
- // check to make sure the arena has a game spawn
- if (game.arena.gameSpawn == null) {
- if (p.isOp()) {
- sender.sendMessage(LanguageManager.fromKey("arena-not-ready-op"));
- } else {
- sender.sendMessage(LanguageManager.fromKey("arena-not-ready"));
- }
- return false;
- }
-
+ // Make sure the game isn't in progress before adding the player
if (game.gameState != GameState.WAITING) {
sender.sendMessage(LanguageManager.fromKey("game-in-progress"));
return false;
diff --git a/src/main/java/com/MylesAndMore/Tumble/commands/Reload.java b/src/main/java/com/MylesAndMore/Tumble/commands/Reload.java
index 79faef9..588755f 100644
--- a/src/main/java/com/MylesAndMore/Tumble/commands/Reload.java
+++ b/src/main/java/com/MylesAndMore/Tumble/commands/Reload.java
@@ -29,7 +29,6 @@ public class Reload implements SubCommand, CommandExecutor, TabCompleter {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
-
for (Arena a : ArenaManager.arenas.values()) {
if (a.game != null) {
a.game.stopGame();
diff --git a/src/main/java/com/MylesAndMore/Tumble/commands/Remove.java b/src/main/java/com/MylesAndMore/Tumble/commands/Remove.java
index c2aa149..9abc784 100644
--- a/src/main/java/com/MylesAndMore/Tumble/commands/Remove.java
+++ b/src/main/java/com/MylesAndMore/Tumble/commands/Remove.java
@@ -38,7 +38,7 @@ public class Remove implements SubCommand, CommandExecutor, TabCompleter {
}
ArenaManager.arenas.remove(arenaName);
- ArenaManager.WriteConfig();
+ ArenaManager.writeConfig();
sender.sendMessage(LanguageManager.fromKey("remove-success"));
return true;
}
diff --git a/src/main/java/com/MylesAndMore/Tumble/commands/SetGameSpawn.java b/src/main/java/com/MylesAndMore/Tumble/commands/SetGameSpawn.java
index 21bdfe8..817a1a4 100644
--- a/src/main/java/com/MylesAndMore/Tumble/commands/SetGameSpawn.java
+++ b/src/main/java/com/MylesAndMore/Tumble/commands/SetGameSpawn.java
@@ -45,7 +45,7 @@ public class SetGameSpawn implements SubCommand, CommandExecutor, TabCompleter {
Arena arena = ArenaManager.arenas.get(arenaName);
arena.gameSpawn = ((Player)sender).getLocation();
- ArenaManager.WriteConfig();
+ ArenaManager.writeConfig();
sender.sendMessage(LanguageManager.fromKey("set-success"));
return true;
}
diff --git a/src/main/java/com/MylesAndMore/Tumble/commands/SetKillYLevel.java b/src/main/java/com/MylesAndMore/Tumble/commands/SetKillYLevel.java
index 142ffdd..27cc410 100644
--- a/src/main/java/com/MylesAndMore/Tumble/commands/SetKillYLevel.java
+++ b/src/main/java/com/MylesAndMore/Tumble/commands/SetKillYLevel.java
@@ -46,7 +46,7 @@ public class SetKillYLevel implements SubCommand, CommandExecutor, TabCompleter
Arena arena = ArenaManager.arenas.get(arenaName);
arena.killAtY = ((int) ((Player) sender).getLocation().getY());
- ArenaManager.WriteConfig();
+ ArenaManager.writeConfig();
sender.sendMessage(LanguageManager.fromKey("set-success"));
return true;
}
diff --git a/src/main/java/com/MylesAndMore/Tumble/commands/SetLobby.java b/src/main/java/com/MylesAndMore/Tumble/commands/SetLobby.java
index a080d08..5708643 100644
--- a/src/main/java/com/MylesAndMore/Tumble/commands/SetLobby.java
+++ b/src/main/java/com/MylesAndMore/Tumble/commands/SetLobby.java
@@ -45,7 +45,7 @@ public class SetLobby implements SubCommand, CommandExecutor, TabCompleter {
Arena arena = ArenaManager.arenas.get(arenaName);
arena.lobby = ((Player)sender).getLocation();
- ArenaManager.WriteConfig();
+ ArenaManager.writeConfig();
sender.sendMessage(LanguageManager.fromKey("set-success"));
return true;
}
diff --git a/src/main/java/com/MylesAndMore/Tumble/commands/SetWaitArea.java b/src/main/java/com/MylesAndMore/Tumble/commands/SetWaitArea.java
index a96e1a9..7b90099 100644
--- a/src/main/java/com/MylesAndMore/Tumble/commands/SetWaitArea.java
+++ b/src/main/java/com/MylesAndMore/Tumble/commands/SetWaitArea.java
@@ -45,7 +45,7 @@ public class SetWaitArea implements SubCommand, CommandExecutor, TabCompleter {
Arena arena = ArenaManager.arenas.get(arenaName);
arena.waitArea = ((Player)sender).getLocation();
- ArenaManager.WriteConfig();
+ ArenaManager.writeConfig();
sender.sendMessage(LanguageManager.fromKey("set-success"));
return true;
}
diff --git a/src/main/java/com/MylesAndMore/Tumble/commands/SetWinnerLobby.java b/src/main/java/com/MylesAndMore/Tumble/commands/SetWinnerLobby.java
index 98a535b..e0d2bea 100644
--- a/src/main/java/com/MylesAndMore/Tumble/commands/SetWinnerLobby.java
+++ b/src/main/java/com/MylesAndMore/Tumble/commands/SetWinnerLobby.java
@@ -45,7 +45,7 @@ public class SetWinnerLobby implements SubCommand, CommandExecutor, TabCompleter
Arena arena = ArenaManager.arenas.get(arenaName);
arena.winnerLobby = ((Player)sender).getLocation();
- ArenaManager.WriteConfig();
+ ArenaManager.writeConfig();
sender.sendMessage(LanguageManager.fromKey("set-success"));
return true;
}
diff --git a/src/main/java/com/MylesAndMore/Tumble/commands/Tumble.java b/src/main/java/com/MylesAndMore/Tumble/commands/Tumble.java
index 8b4f925..e7d1cf4 100644
--- a/src/main/java/com/MylesAndMore/Tumble/commands/Tumble.java
+++ b/src/main/java/com/MylesAndMore/Tumble/commands/Tumble.java
@@ -44,7 +44,7 @@ public class Tumble implements CommandExecutor, TabCompleter {
return false;
}
- // pass command action through to subCommand
+ // Pass command action through to subCommand
subCmd.onCommand(sender, command, args[0], removeFirst(args));
return true;
}
@@ -52,7 +52,7 @@ public class Tumble implements CommandExecutor, TabCompleter {
@Override
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
if (args.length == 1) {
- // show only subCommands the user has permission for
+ // Show only subCommands the user has permission for
ArrayList<String> PermittedSubCmds = new ArrayList<>();
for (SubCommand subCmd: subCommands.values()) {
if (sender.hasPermission(subCmd.getPermission())) {
@@ -67,11 +67,10 @@ public class Tumble implements CommandExecutor, TabCompleter {
return Collections.emptyList();
}
- // pass tab complete through to subCommand
+ // Pass tab complete through to subCommand
if (subCommands.get(args[0]) instanceof TabCompleter tcmp) {
return tcmp.onTabComplete(sender, command, args[0], removeFirst(args));
- }
- else {
+ } else {
return null;
}
}
diff --git a/src/main/java/com/MylesAndMore/Tumble/config/ArenaManager.java b/src/main/java/com/MylesAndMore/Tumble/config/ArenaManager.java
index 5e6e571..af85b9f 100644
--- a/src/main/java/com/MylesAndMore/Tumble/config/ArenaManager.java
+++ b/src/main/java/com/MylesAndMore/Tumble/config/ArenaManager.java
@@ -58,44 +58,51 @@ public class ArenaManager {
arena.waitArea = readWorld("arenas." + arenaName + ".wait-area");
}
- // validate
- if (arena.gameSpawn == null) {
- plugin.getLogger().severe("arenas.yml: Arena " + arenaName + " is missing a game spawn, before you can join you must set it with '/tmbl setgamespawn'.");
- }
- if (arena.gameSpawn == null) {
- plugin.getLogger().severe("arenas.yml: Arena " + arenaName + " is missing a lobby location. The spawn point of the default world will be used.");
- }
-
arenas.put(arena.name, arena);
}
+ validate(); // Validate arenas
}
/**
* Write arenas from this.arenas to arenas.yml
*/
- public static void WriteConfig() {
- config.set("arenas", null); // clear everything
+ public static void writeConfig() {
+ config.set("arenas", null); // Clear everything
for (Arena arena: arenas.values()) {
if (arena.killAtY != null) {
config.set("arenas." + arena.name + ".kill-at-y", arena.killAtY);
}
if (arena.gameSpawn != null) {
- WriteWorld("arenas." + arena.name + ".game-spawn", arena.gameSpawn);
+ writeWorld("arenas." + arena.name + ".game-spawn", arena.gameSpawn);
}
if (arena.lobby != null) {
- WriteWorld("arenas." + arena.name + ".lobby", arena.lobby);
+ writeWorld("arenas." + arena.name + ".lobby", arena.lobby);
}
if (arena.winnerLobby != null) {
- WriteWorld("arenas." + arena.name + ".winner-lobby", arena.winnerLobby);
+ writeWorld("arenas." + arena.name + ".winner-lobby", arena.winnerLobby);
}
if (arena.waitArea != null) {
- WriteWorld("arenas." + arena.name + ".wait-area", arena.waitArea);
+ writeWorld("arenas." + arena.name + ".wait-area", arena.waitArea);
}
}
+ validate();
arenasYml.saveConfig();
+ }
+ /**
+ * Check that all arenas are valid
+ */
+ public static void validate() {
+ for (Arena arena: arenas.values()) {
+ if (arena.gameSpawn == null) {
+ plugin.getLogger().severe("arenas.yml: Arena '" + arena.name + "' is missing a game spawn, before it is usable you must set a spawn with '/tumble setgamespawn'.");
+ }
+ if (arena.lobby == null) {
+ plugin.getLogger().warning("arenas.yml: Arena '" + arena.name + "' is missing a lobby location. The spawn point of the default world will be used.");
+ }
+ }
}
/**
@@ -123,7 +130,6 @@ public class ArenaManager {
* @return The location specified by the section, or null if the location is not valid
*/
private static Location readWorld(String path) {
-
ConfigurationSection section = config.getConfigurationSection(path);
if (section == null) {
plugin.getLogger().warning("arenas.yml: Error loading location at '" + path + "' - " + "Section is null");
@@ -163,8 +169,7 @@ public class ArenaManager {
* @param path The path of the section to write
* @param location The location to write
*/
- private static void WriteWorld(String path, @NotNull Location location) {
-
+ private static void writeWorld(String path, @NotNull Location location) {
ConfigurationSection section = config.getConfigurationSection(path);
if (section == null) {
diff --git a/src/main/java/com/MylesAndMore/Tumble/config/ConfigManager.java b/src/main/java/com/MylesAndMore/Tumble/config/ConfigManager.java
index 59d653a..c279a22 100644
--- a/src/main/java/com/MylesAndMore/Tumble/config/ConfigManager.java
+++ b/src/main/java/com/MylesAndMore/Tumble/config/ConfigManager.java
@@ -11,7 +11,8 @@ import static com.MylesAndMore.Tumble.Main.plugin;
* Manages config.yml and stores its options
*/
public class ConfigManager {
- public static boolean HideLeaveJoin;
+ public static boolean hideLeaveJoin;
+ public static boolean hideDeathMessages;
public static int waitDuration;
private static Configuration config;
@@ -25,8 +26,10 @@ public class ConfigManager {
configYml.saveDefaultConfig();
config = configYml.getConfig();
defaultConfig = Objects.requireNonNull(config.getDefaults());
- HideLeaveJoin = config.getBoolean("hide-join-leave-messages", false);
+ hideLeaveJoin = config.getBoolean("hide-join-leave-messages", false);
+ hideDeathMessages = config.getBoolean("hide-death-messages", false);
waitDuration = config.getInt("wait-duration", 15);
+
validate();
}
diff --git a/src/main/java/com/MylesAndMore/Tumble/game/Arena.java b/src/main/java/com/MylesAndMore/Tumble/game/Arena.java
index 71849e6..157c59c 100644
--- a/src/main/java/com/MylesAndMore/Tumble/game/Arena.java
+++ b/src/main/java/com/MylesAndMore/Tumble/game/Arena.java
@@ -1,7 +1,6 @@
package com.MylesAndMore.Tumble.game;
import org.bukkit.Location;
-import org.bukkit.World;
import org.jetbrains.annotations.NotNull;
/**
diff --git a/src/main/java/com/MylesAndMore/Tumble/game/EventListener.java b/src/main/java/com/MylesAndMore/Tumble/game/EventListener.java
index 9f1456e..0b23779 100644
--- a/src/main/java/com/MylesAndMore/Tumble/game/EventListener.java
+++ b/src/main/java/com/MylesAndMore/Tumble/game/EventListener.java
@@ -26,10 +26,10 @@ import java.util.Objects;
import static com.MylesAndMore.Tumble.Main.plugin;
/**
- * An event listener for a game of tumble.
+ * An event listener for a game of Tumble.
*/
public class EventListener implements Listener {
- Game game;
+ final Game game;
/**
* Create a new EventListener for a game.
@@ -43,7 +43,7 @@ public class EventListener implements Listener {
@EventHandler
public void PlayerJoinEvent(PlayerJoinEvent event) {
// Hide/show join message accordingly
- if (ConfigManager.HideLeaveJoin) {
+ if (event.getPlayer().getWorld() == game.arena.gameSpawn.getWorld() && ConfigManager.hideLeaveJoin) {
event.setJoinMessage(null);
}
}
@@ -51,11 +51,11 @@ public class EventListener implements Listener {
@EventHandler
public void PlayerQuitEvent(PlayerQuitEvent event) {
// Hide/show leave message accordingly
- if (ConfigManager.HideLeaveJoin) {
+ if (event.getPlayer().getWorld() == game.arena.gameSpawn.getWorld() && ConfigManager.hideLeaveJoin) {
event.setQuitMessage(null);
}
- // remove player from game if they leave during a game
+ // Remove player from game if they leave during a game
if (game.gamePlayers.contains(event.getPlayer())) {
game.removePlayer(event.getPlayer());
}
@@ -63,7 +63,12 @@ public class EventListener implements Listener {
@EventHandler
public void PlayerDeathEvent(PlayerDeathEvent event) {
- // inform the game that the player died and respawn them
+ // Hide death messages if configured
+ if (event.getEntity().getWorld() == game.arena.gameSpawn.getWorld() && ConfigManager.hideDeathMessages) {
+ event.setDeathMessage(null);
+ }
+
+ // Inform the game that the player died and respawn them
if (game.gamePlayers.contains(event.getEntity()) && game.gameState == GameState.RUNNING) {
game.playerDeath(event.getEntity());
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, () -> event.getEntity().spigot().respawn(), 10);
@@ -109,8 +114,7 @@ public class EventListener implements Listener {
event.getHitBlock().getType());
event.getHitBlock().setType(Material.AIR);
}
- }
- else if (event.getHitEntity() != null) {
+ } else if (event.getHitEntity() != null) {
if (event.getHitEntity() instanceof Player hitPlayer) {
// Also cancel any knockback
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, () -> hitPlayer.setVelocity(new Vector()));
@@ -134,7 +138,7 @@ public class EventListener implements Listener {
if (Objects.equals(game.gameState, GameState.STARTING) && !equalPosition(event.getFrom(),event.getTo())) {
event.setCancelled(true);
}
- // kill player if they are below a Y level
+ // Kill player if they are below configured Y level
if (game.arena.killAtY != null && game.gameState == GameState.RUNNING) {
if (event.getPlayer().getLocation().getY() <= game.arena.killAtY) {
event.getPlayer().setHealth(0);
@@ -204,7 +208,7 @@ public class EventListener implements Listener {
}
@EventHandler
- public void PlayerRespwanEvent(PlayerRespawnEvent event) {
+ public void PlayerRespawnEvent(PlayerRespawnEvent event) {
// Make sure players respawn in the correct location
if (game.gamePlayers.contains(event.getPlayer())) {
event.setRespawnLocation(game.arena.gameSpawn);
@@ -226,5 +230,4 @@ public class EventListener implements Listener {
(l1.getY() == l2.getY()) &&
(l1.getZ() == l2.getZ());
}
-
} \ No newline at end of file
diff --git a/src/main/java/com/MylesAndMore/Tumble/game/Game.java b/src/main/java/com/MylesAndMore/Tumble/game/Game.java
index e9b7223..b309d42 100644
--- a/src/main/java/com/MylesAndMore/Tumble/game/Game.java
+++ b/src/main/java/com/MylesAndMore/Tumble/game/Game.java
@@ -48,7 +48,7 @@ public class Game {
}
/**
- * Adds a player to the wait area. Called from /tmbl join
+ * Adds a player to the wait area. Called from /tumble join
* Precondition: the game is in state WAITING
* @param p Player to add
*/
@@ -62,15 +62,14 @@ public class Game {
}
if (gamePlayers.size() >= 2 && gameState == GameState.WAITING) {
autoStart();
- }
- else {
+ } else {
displayActionbar(Collections.singletonList(p), LanguageManager.fromKeyNoPrefix("waiting-for-players"));
}
}
/**
* Starts the game
- * Called from /tmbl forceStart or after the wait counter finishes
+ * Called from /tumble forceStart or after the wait counter finishes
*/
public void gameStart() {
@@ -79,15 +78,15 @@ public class Game {
return;
}
- // cancel wait timer
+ // Cancel wait timer
Bukkit.getServer().getScheduler().cancelTask(autoStartID);
autoStartID = -1;
- // register event listener
+ // Register event listener
eventListener = new EventListener(this);
Bukkit.getServer().getPluginManager().registerEvents(eventListener, plugin);
- // save inventories (if not already done)
+ // Save inventories (if not already done)
for (Player p : gamePlayers) {
if (!inventories.containsKey(p)) {
inventories.put(p, p.getInventory().getContents());
@@ -107,22 +106,18 @@ public class Game {
scatterPlayers(gamePlayers);
// Put all players in spectator to prevent them from getting kicked for flying
setGamemode(gamePlayers, GameMode.SPECTATOR);
- // do it again in case they were not in the world yet
- Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, () -> {
- setGamemode(gamePlayers, GameMode.SPECTATOR);
- }, 10);
+ // Do it again in a bit in case they were not in the world yet
+ Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, () -> setGamemode(gamePlayers, GameMode.SPECTATOR), 10);
clearInventories(gamePlayers);
clearArena();
prepareGameType(type);
// Begin the countdown sequence
- Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, () -> {
- countdown(() -> {
- setGamemode(gamePlayers, GameMode.SURVIVAL);
- gameState = GameState.RUNNING;
- });
- }, 100);
+ Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, () -> countdown(() -> {
+ setGamemode(gamePlayers, GameMode.SURVIVAL);
+ gameState = GameState.RUNNING;
+ }), 100);
}
/**
@@ -140,7 +135,7 @@ public class Game {
giveItems(gamePlayers, shovel);
// Schedule a process to give snowballs after 2m30s (so people can't island, the OG game had this);
- // add 160t because of the countdown
+ // Also add 160t because of the countdown
gameID = Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, () -> {
clearInventories(gamePlayers);
giveItems(gamePlayers, new ItemStack(Material.SNOWBALL));
@@ -191,13 +186,11 @@ public class Game {
if (gameWins.get(winner) == 3) {
gameEnd();
- }
- else { // If that player doesn't have three wins, nobody else does, so we need another round
+ } else { // If that player doesn't have three wins, nobody else does, so we need another round
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 {
+ } else {
displayTitles(gamePlayers, LanguageManager.fromKeyNoPrefix("round-over"), LanguageManager.fromKeyNoPrefix("round-draw"), 5, 60, 5);
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, this::roundStart, 100);
}
@@ -207,40 +200,24 @@ public class Game {
* Ends game: Displays overall winner and teleports players to lobby
*/
private void gameEnd() {
-
if (!gamePlayers.isEmpty()) {
setGamemode(gamePlayers, GameMode.SPECTATOR);
clearInventories(gamePlayers);
- // display winner
+ // Display winner
Player winner = getPlayerWithMostWins(gameWins);
if (winner != null) {
displayTitles(gamePlayers, LanguageManager.fromKeyNoPrefix("game-over"), LanguageManager.fromKeyNoPrefix("game-winner").replace("%winner%",winner.getDisplayName()), 5, 60, 5);
}
displayActionbar(gamePlayers, LanguageManager.fromKeyNoPrefix("lobby-in-10"));
-
- // Wait 10s (200t), then
+ // Wait 10s (200t), then clear the arena and teleport players back
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, () -> {
clearArena();
-
- // teleport player back and restore inventory
for (Player p : gamePlayers) {
- p.getInventory().clear();
- p.setGameMode(GameMode.SURVIVAL);
- if (p == winner && arena.winnerLobby != null) {
- p.teleport(arena.winnerLobby);
- }
- else {
- p.teleport(Objects.requireNonNull(arena.lobby));
- }
-
- if (inventories.containsKey(p)) {
- p.getInventory().setContents(inventories.get(p));
- }
+ sendToLobby(p, p == winner);
}
-
}, 200);
}
@@ -254,10 +231,12 @@ public class Game {
/**
* Stops the game, usually while it is still going
- * called if too many players leave, or from /tmbl forceStop
+ * Called if too many players leave, or from /tumble forceStop
*/
public void stopGame() {
- gamePlayers.forEach(this::removePlayer);
+ // A new list must be created to avoid removing elements while iterating
+ List<Player> players = new ArrayList<>(gamePlayers);
+ players.forEach(this::removePlayer);
Bukkit.getServer().getScheduler().cancelTask(gameID);
gameID = -1;
@@ -275,50 +254,34 @@ public class Game {
public void removePlayer(Player p) {
gamePlayers.remove(p);
- // check if the game has not started yet
+ // Check if the game has not started yet
if (gameState == GameState.WAITING) {
-
- // inform player that there are no longer enough players to start
+ // Inform player that there are no longer enough players to start
if (gamePlayers.size() < 2) {
displayActionbar(gamePlayers, LanguageManager.fromKeyNoPrefix("waiting-for-players"));
}
- // teleport player back and restore inventory
- if (arena.waitArea != null) {
- p.getInventory().clear();
- p.setGameMode(GameMode.SURVIVAL);
- p.teleport(arena.lobby);
- if (inventories.containsKey(p)) {
- p.getInventory().setContents(inventories.get(p));
- }
- }
- }
- else {
- // stop the game if there are not enough players
+ sendToLobby(p, false);
+ } else {
+ // Stop the game if there are no longer enough players
if (gamePlayers.size() < 2) {
stopGame();
}
- // teleport player back and restore inventory
- p.getInventory().clear();
- p.setGameMode(GameMode.SURVIVAL);
- p.teleport(arena.lobby);
- if (inventories.containsKey(p)) {
- p.getInventory().setContents(inventories.get(p));
- }
+ sendToLobby(p, false); // You can never win if you quit, remember that kids!!
}
}
/**
- * Initiates an automatic start of a Tumble game
+ * Attempts to initiate an automatic start of a Tumble game
*/
public void autoStart() {
- // Wait for the player to load in
int waitDuration = ConfigManager.waitDuration;
+ if (waitDuration <= 0) { return; }
Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, () -> {
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
+ // Schedule a process to start the game in the specified waitDuration and save the PID so we can cancel it later if needed
autoStartID = Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(plugin, this::gameStart, waitDuration * 20L);
}, 50);
}
@@ -329,7 +292,7 @@ public class Game {
*/
public void playerDeath(Player player) {
player.setGameMode(GameMode.SPECTATOR);
- // remove that player (who just died) from the roundPlayersArray, effectively eliminating them,
+ // Remove that player (who just died) from the alive players, effectively eliminating them,
playersAlive.remove(player);
// If there are less than 2 players in the game (1 just died),
if (playersAlive.size() < 2 && gameState == GameState.RUNNING) {
@@ -337,7 +300,7 @@ public class Game {
}
}
- // utility functions
+ // -- Utility functions --
/**
* Teleports a list of players to the specified scatter locations in the gameWorld
@@ -482,4 +445,27 @@ public class Game {
new Location(gameSpawn.getWorld(), gameSpawn.getX() + 20, gameSpawn.getY(), gameSpawn.getZ() + 20),
Material.AIR);
}
+
+ /**
+ * Teleports a player to the lobby and restores their inventory
+ * @param p Player to teleport
+ * @param winner Whether the player is the winner
+ */
+ private void sendToLobby(Player p, boolean winner) {
+ p.getInventory().clear();
+ p.setGameMode(GameMode.SURVIVAL);
+ if (winner && arena.winnerLobby != null) {
+ p.teleport(arena.winnerLobby);
+ } else {
+ // Use default world spawn if lobby is not set
+ if (arena.lobby == null) {
+ p.teleport(Objects.requireNonNull(Bukkit.getWorlds().get(0)).getSpawnLocation());
+ } else {
+ p.teleport(Objects.requireNonNull(arena.lobby));
+ }
+ }
+ if (inventories.containsKey(p)) {
+ p.getInventory().setContents(inventories.get(p));
+ }
+ }
}
diff --git a/src/main/java/com/MylesAndMore/Tumble/game/Generator.java b/src/main/java/com/MylesAndMore/Tumble/game/Generator.java
index 2ef0957..dac0162 100644
--- a/src/main/java/com/MylesAndMore/Tumble/game/Generator.java
+++ b/src/main/java/com/MylesAndMore/Tumble/game/Generator.java
@@ -7,6 +7,8 @@ import org.bukkit.block.BlockFace;
import java.util.*;
+// TODO: clean up generator (when layers refactor is done)
+
/**
* Holds the methods that generate blocks in-game such as cylinders, cuboids, and block clumps.
*/
@@ -23,31 +25,28 @@ public class Generator {
// Choose a random type of generation; a circular layer, a square layer, or a multi-tiered layer of either variety
if (random.nextInt(4) == 0) {
// Circular layer
- Generator.generateClumps(Generator.generateLayer(layer, 17, 1, Material.SNOW_BLOCK), LayerManager.getRandom());
- }
- else if (random.nextInt(4) == 1) {
+ Generator.generateClumps(Generator.generateLayer(layer, 17, 1, Material.AIR), LayerManager.getRandom());
+ } else if (random.nextInt(4) == 1) {
// Square layer
- Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 17, layer.getY(), layer.getZ() - 17), new Location(layer.getWorld(), layer.getX() + 17, layer.getY(), layer.getZ() + 17), Material.SNOW_BLOCK), LayerManager.getRandom());
- }
- else if (random.nextInt(4) == 2) {
+ Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 17, layer.getY(), layer.getZ() - 17), new Location(layer.getWorld(), layer.getX() + 17, layer.getY(), layer.getZ() + 17), Material.AIR), LayerManager.getRandom());
+ } else if (random.nextInt(4) == 2) {
// Multi-tiered circle
- Generator.generateClumps(Generator.generateLayer(layer, 17, 1, Material.SNOW_BLOCK), LayerManager.getRandom());
+ Generator.generateClumps(Generator.generateLayer(layer, 17, 1, Material.AIR), LayerManager.getRandom());
Generator.generateLayer(layer, 13, 1, Material.AIR);
layer.setY(layer.getY() - 1);
- Generator.generateClumps(Generator.generateLayer(layer, 13, 1, Material.GRASS_BLOCK), LayerManager.getRandom());
+ Generator.generateClumps(Generator.generateLayer(layer, 13, 1, Material.AIR), LayerManager.getRandom());
Generator.generateLayer(layer, 4, 1, Material.AIR);
layer.setY(layer.getY() - 1);
- Generator.generateClumps(Generator.generateLayer(layer, 4, 1, Material.PODZOL), LayerManager.getRandom());
- }
- else {
+ Generator.generateClumps(Generator.generateLayer(layer, 4, 1, Material.AIR), LayerManager.getRandom());
+ } else {
// Multi-tiered square
- Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 17, layer.getY(), layer.getZ() - 17), new Location(layer.getWorld(), layer.getX() + 17, layer.getY(), layer.getZ() + 17), Material.SNOW_BLOCK), LayerManager.getRandom());
+ Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 17, layer.getY(), layer.getZ() - 17), new Location(layer.getWorld(), layer.getX() + 17, layer.getY(), layer.getZ() + 17), Material.AIR), LayerManager.getRandom());
Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 13, layer.getY(), layer.getZ() - 13), new Location(layer.getWorld(), layer.getX() + 13, layer.getY(), layer.getZ() + 13), Material.AIR);
layer.setY(layer.getY() - 1);
- Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 13, layer.getY(), layer.getZ() - 13), new Location(layer.getWorld(), layer.getX() + 13, layer.getY(), layer.getZ() + 13), Material.GRASS_BLOCK), LayerManager.getRandom());
+ Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 13, layer.getY(), layer.getZ() - 13), new Location(layer.getWorld(), layer.getX() + 13, layer.getY(), layer.getZ() + 13), Material.AIR), LayerManager.getRandom());
Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 7, layer.getY(), layer.getZ() - 7), new Location(layer.getWorld(), layer.getX() + 7, layer.getY(), layer.getZ() + 7), Material.AIR);
layer.setY(layer.getY() - 1);
- Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 7, layer.getY(), layer.getZ() - 7), new Location(layer.getWorld(), layer.getX() + 7, layer.getY(), layer.getZ() + 7), Material.PODZOL), LayerManager.getRandom());
+ Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 7, layer.getY(), layer.getZ() - 7), new Location(layer.getWorld(), layer.getX() + 7, layer.getY(), layer.getZ() + 7), Material.AIR), LayerManager.getRandom());
}
}
@@ -57,80 +56,78 @@ public class Generator {
*/
public static void generateLayersSnowballs(Location layer) {
Random random = new Random();
+ Layers layers = new Layers();
layer.setY(layer.getY() - 1);
// Similar generation to shovels, except there are three layers
if (random.nextInt(4) == 0) {
// Circular layer
- Generator.generateClumps(Generator.generateLayer(layer, 17, 1, Material.STONE), LayerManager.getRandom());
+ Generator.generateClumps(Generator.generateLayer(layer, 17, 1, Material.AIR), LayerManager.getRandom());
layer.setY(layer.getY() - 6);
- Generator.generateClumps(Generator.generateLayer(layer, 17, 1, Material.STONE), LayerManager.getRandom());
+ Generator.generateClumps(Generator.generateLayer(layer, 17, 1, Material.AIR), LayerManager.getRandom());
layer.setY(layer.getY() - 6);
- Generator.generateClumps(Generator.generateLayer(layer, 17, 1, Material.STONE), LayerManager.getRandom());
- }
- else if (random.nextInt(4) == 1) {
+ Generator.generateClumps(Generator.generateLayer(layer, 17, 1, Material.AIR), LayerManager.getRandom());
+ } else if (random.nextInt(4) == 1) {
// Square layer
- Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 17, layer.getY(), layer.getZ() - 17), new Location(layer.getWorld(), layer.getX() + 17, layer.getY(), layer.getZ() + 17), Material.STONE), LayerManager.getRandom());
+ Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 17, layer.getY(), layer.getZ() - 17), new Location(layer.getWorld(), layer.getX() + 17, layer.getY(), layer.getZ() + 17), Material.AIR), LayerManager.getRandom());
layer.setY(layer.getY() - 6);
- Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 17, layer.getY(), layer.getZ() - 17), new Location(layer.getWorld(), layer.getX() + 17, layer.getY(), layer.getZ() + 17), Material.STONE), LayerManager.getRandom());
+ Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 17, layer.getY(), layer.getZ() - 17), new Location(layer.getWorld(), layer.getX() + 17, layer.getY(), layer.getZ() + 17), Material.AIR), LayerManager.getRandom());
layer.setY(layer.getY() - 6);
- Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 17, layer.getY(), layer.getZ() - 17), new Location(layer.getWorld(), layer.getX() + 17, layer.getY(), layer.getZ() + 17), Material.STONE), LayerManager.getRandom());
- }
- else if (random.nextInt(4) == 2) {
+ Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 17, layer.getY(), layer.getZ() - 17), new Location(layer.getWorld(), layer.getX() + 17, layer.getY(), layer.getZ() + 17), Material.AIR), LayerManager.getRandom());
+ } else if (random.nextInt(4) == 2) {
// Multi-tiered circle
- Generator.generateClumps(Generator.generateLayer(layer, 17, 1, Material.STONE), LayerManager.getRandom());
+ Generator.generateClumps(Generator.generateLayer(layer, 17, 1, Material.AIR), LayerManager.getRandom());
Generator.generateLayer(layer, 13, 1, Material.AIR);
layer.setY(layer.getY() - 1);
- Generator.generateClumps(Generator.generateLayer(layer, 13, 1, Material.GRANITE), LayerManager.getRandom());
+ Generator.generateClumps(Generator.generateLayer(layer, 13, 1, Material.AIR), LayerManager.getRandom());
Generator.generateLayer(layer, 4, 1, Material.AIR);
layer.setY(layer.getY() - 1);
- Generator.generateClumps(Generator.generateLayer(layer, 4, 1, Material.LIME_GLAZED_TERRACOTTA), LayerManager.getRandom());
+ Generator.generateClumps(Generator.generateLayer(layer, 4, 1, Material.AIR), LayerManager.getRandom());
layer.setY(layer.getY() - 6);
- Generator.generateClumps(Generator.generateLayer(layer, 17, 1, Material.STONE), LayerManager.getRandom());
+ Generator.generateClumps(Generator.generateLayer(layer, 17, 1, Material.AIR), LayerManager.getRandom());
Generator.generateLayer(layer, 13, 1, Material.AIR);
layer.setY(layer.getY() - 1);
- Generator.generateClumps(Generator.generateLayer(layer, 13, 1, Material.GRANITE), LayerManager.getRandom());
+ Generator.generateClumps(Generator.generateLayer(layer, 13, 1, Material.AIR), LayerManager.getRandom());
Generator.generateLayer(layer, 4, 1, Material.AIR);
layer.setY(layer.getY() - 1);
- Generator.generateClumps(Generator.generateLayer(layer, 4, 1, Material.LIME_GLAZED_TERRACOTTA), LayerManager.getRandom());
+ Generator.generateClumps(Generator.generateLayer(layer, 4, 1, Material.AIR), LayerManager.getRandom());
layer.setY(layer.getY() - 6);
- Generator.generateClumps(Generator.generateLayer(layer, 17, 1, Material.STONE), LayerManager.getRandom());
+ Generator.generateClumps(Generator.generateLayer(layer, 17, 1, Material.AIR), LayerManager.getRandom());
Generator.generateLayer(layer, 13, 1, Material.AIR);
layer.setY(layer.getY() - 1);
- Generator.generateClumps(Generator.generateLayer(layer, 13, 1, Material.GRANITE), LayerManager.getRandom());
+ Generator.generateClumps(Generator.generateLayer(layer, 13, 1, Material.AIR), LayerManager.getRandom());
Generator.generateLayer(layer, 4, 1, Material.AIR);
layer.setY(layer.getY() - 1);
- Generator.generateClumps(Generator.generateLayer(layer, 4, 1, Material.LIME_GLAZED_TERRACOTTA), LayerManager.getRandom());
- }
- else {
+ Generator.generateClumps(Generator.generateLayer(layer, 4, 1, Material.AIR), LayerManager.getRandom());
+ } else {
// Multi-tiered square
- Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 17, layer.getY(), layer.getZ() - 17), new Location(layer.getWorld(), layer.getX() + 17, layer.getY(), layer.getZ() + 17), Material.STONE), LayerManager.getRandom());
+ Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 17, layer.getY(), layer.getZ() - 17), new Location(layer.getWorld(), layer.getX() + 17, layer.getY(), layer.getZ() + 17), Material.AIR), LayerManager.getRandom());
Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 13, layer.getY(), layer.getZ() - 13), new Location(layer.getWorld(), layer.getX() + 13, layer.getY(), layer.getZ() + 13), Material.AIR);
layer.setY(layer.getY() - 1);
- Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 13, layer.getY(), layer.getZ() - 13), new Location(layer.getWorld(), layer.getX() + 13, layer.getY(), layer.getZ() + 13), Material.GRANITE), LayerManager.getRandom());
+ Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 13, layer.getY(), layer.getZ() - 13), new Location(layer.getWorld(), layer.getX() + 13, layer.getY(), layer.getZ() + 13), Material.AIR), LayerManager.getRandom());
Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 7, layer.getY(), layer.getZ() - 7), new Location(layer.getWorld(), layer.getX() + 7, layer.getY(), layer.getZ() + 7), Material.AIR);
layer.setY(layer.getY() - 1);
- Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 7, layer.getY(), layer.getZ() - 7), new Location(layer.getWorld(), layer.getX() + 7, layer.getY(), layer.getZ() + 7), Material.LIME_GLAZED_TERRACOTTA), LayerManager.getRandom());
+ Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 7, layer.getY(), layer.getZ() - 7), new Location(layer.getWorld(), layer.getX() + 7, layer.getY(), layer.getZ() + 7), Material.AIR), LayerManager.getRandom());
layer.setY(layer.getY() - 6);
- Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 17, layer.getY(), layer.getZ() - 17), new Location(layer.getWorld(), layer.getX() + 17, layer.getY(), layer.getZ() + 17), Material.STONE), LayerManager.getRandom());
+ Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 17, layer.getY(), layer.getZ() - 17), new Location(layer.getWorld(), layer.getX() + 17, layer.getY(), layer.getZ() + 17), Material.AIR), LayerManager.getRandom());
Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 13, layer.getY(), layer.getZ() - 13), new Location(layer.getWorld(), layer.getX() + 13, layer.getY(), layer.getZ() + 13), Material.AIR);
layer.setY(layer.getY() - 1);
- Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 13, layer.getY(), layer.getZ() - 13), new Location(layer.getWorld(), layer.getX() + 13, layer.getY(), layer.getZ() + 13), Material.GRANITE), LayerManager.getRandom());
+ Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 13, layer.getY(), layer.getZ() - 13), new Location(layer.getWorld(), layer.getX() + 13, layer.getY(), layer.getZ() + 13), Material.AIR), LayerManager.getRandom());
Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 7, layer.getY(), layer.getZ() - 7), new Location(layer.getWorld(), layer.getX() + 7, layer.getY(), layer.getZ() + 7), Material.AIR);
layer.setY(layer.getY() - 1);
- Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 7, layer.getY(), layer.getZ() - 7), new Location(layer.getWorld(), layer.getX() + 7, layer.getY(), layer.getZ() + 7), Material.LIME_GLAZED_TERRACOTTA), LayerManager.getRandom());
+ Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 7, layer.getY(), layer.getZ() - 7), new Location(layer.getWorld(), layer.getX() + 7, layer.getY(), layer.getZ() + 7), Material.AIR), LayerManager.getRandom());
layer.setY(layer.getY() - 6);
- Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 17, layer.getY(), layer.getZ() - 17), new Location(layer.getWorld(), layer.getX() + 17, layer.getY(), layer.getZ() + 17), Material.STONE), LayerManager.getRandom());
+ Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 17, layer.getY(), layer.getZ() - 17), new Location(layer.getWorld(), layer.getX() + 17, layer.getY(), layer.getZ() + 17), Material.AIR), LayerManager.getRandom());
Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 13, layer.getY(), layer.getZ() - 13), new Location(layer.getWorld(), layer.getX() + 13, layer.getY(), layer.getZ() + 13), Material.AIR);
layer.setY(layer.getY() - 1);
- Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 13, layer.getY(), layer.getZ() - 13), new Location(layer.getWorld(), layer.getX() + 13, layer.getY(), layer.getZ() + 13), Material.GRANITE), LayerManager.getRandom());
+ Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 13, layer.getY(), layer.getZ() - 13), new Location(layer.getWorld(), layer.getX() + 13, layer.getY(), layer.getZ() + 13), Material.AIR), LayerManager.getRandom());
Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 7, layer.getY(), layer.getZ() - 7), new Location(layer.getWorld(), layer.getX() + 7, layer.getY(), layer.getZ() + 7), Material.AIR);
layer.setY(layer.getY() - 1);
- Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 7, layer.getY(), layer.getZ() - 7), new Location(layer.getWorld(), layer.getX() + 7, layer.getY(), layer.getZ() + 7), Material.LIME_GLAZED_TERRACOTTA), LayerManager.getRandom());
+ Generator.generateClumps(Generator.generateCuboid(new Location(layer.getWorld(), layer.getX() - 7, layer.getY(), layer.getZ() - 7), new Location(layer.getWorld(), layer.getX() + 7, layer.getY(), layer.getZ() + 7), Material.AIR), LayerManager.getRandom());
}
}
diff --git a/src/main/java/com/MylesAndMore/Tumble/plugin/GameState.java b/src/main/java/com/MylesAndMore/Tumble/plugin/GameState.java
index 06b2abe..e27c728 100644
--- a/src/main/java/com/MylesAndMore/Tumble/plugin/GameState.java
+++ b/src/main/java/com/MylesAndMore/Tumble/plugin/GameState.java
@@ -4,5 +4,5 @@ public enum GameState {
WAITING,
STARTING,
RUNNING,
- ENDING
+ ENDING,
}
diff --git a/src/main/resources/arenas.yml b/src/main/resources/arenas.yml
index 3b755c3..7c26e08 100644
--- a/src/main/resources/arenas.yml
+++ b/src/main/resources/arenas.yml
@@ -1,2 +1,2 @@
-# NOTE: Coordinates cannot be zero! Use something like 0.5
-arenas: {} \ No newline at end of file
+# NOTE: No coordinate can be equal to zero! Use 0.5 instead if needed.
+arenas:
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index ded50ef..28cc4e2 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -1,7 +1,9 @@
-# Hides player join/leave messages in public chat
+# Hides player join and leave messages in public chat during games
hide-join-leave-messages: false
-# Duration in seconds to wait for more players to join
-wait-duration: 15
-
+# Hides player death messages in public chat during games
+hide-death-messages: false
+# Duration (in seconds) to wait for more players to join a game before starting
+# Set to 0 to disable
+wait-duration: 15
diff --git a/src/main/resources/language.yml b/src/main/resources/language.yml
index 835d577..388c975 100644
--- a/src/main/resources/language.yml
+++ b/src/main/resources/language.yml
@@ -1,32 +1,36 @@
+# All plugin chat messages will have this message prepended to them
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 '/tmbl join %arena% %type%'."
-already-in-game: "&4You are already in a game! Leave it to join another one."
-arena-not-ready: "&4This arena is not finished being set up!"
-arena-not-ready-op: "&4Incomplete arena. &7Set a game spawn with '/tmbl setGameSpawn'."
-specify-game-type: "&4No game is currently taking place in this arena! &7Provide the game type to start one."
-
-create-success: "&aArena created successfully! &eBefore you can join, you must set a game spawn location with '/tmbl setgamespawn'."
-forcestart-success: "&aStarting game."
+# Error messages
+unknown-command: "&cUnknown command '%command%'"
+no-permission: "&cYou do not have permission to perform this command! &7Required permission: '%permission%.'"
+missing-arena-parameter: "&cMissing arena name!"
+invalid-arena: "&carena '%arena%' does not exist!"
+invalid-type: "&cInvalid game type!"
+no-game-in-arena: "&cNo game is currently running in this arena!"
+player-not-in-game: "&cYou are not in a game!"
+not-for-console: "&cThis cannot be run by the console!"
+game-in-progress: "&cThis 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 '/tumble join %arena% %type%'."
+already-in-game: "&cYou are already in a game! Leave it to join another one."
+arena-not-ready: "&cThis arena is not yet set up!"
+arena-not-ready-op: "&cIncomplete arena. &7Set a game spawn with '/tumble setGameSpawn'."
+specify-game-type: "&cNo game is currently taking place in this arena! &7Provide the game type to start one."
+
+# Success messages
+create-success: "&aArena created successfully! &eBefore this arena is usable, you must set a game spawn location with '/tumble 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: "&aConfig files reloaded. &eCheck console for errors."
+reload-success: "&aConfig files reloaded. &eCheck console for possible errors."
remove-success: "&aArena removed."
set-success: "&aLocation set."
+# Game messages
showdown: "&4Showdown!"
lobby-in-10: "&9Returning to lobby in ten seconds..."
-waiting-for-players: "&aWaiting for players"
+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!"
@@ -37,9 +41,3 @@ 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 c8085b8..da7f8bd 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -1,6 +1,6 @@
main: com.MylesAndMore.Tumble.Main
name: Tumble
-version: 1.0.4
+version: 2.0.0
description: 'A Minecraft: Java Edition plugin recreating the Tumble minigame from Minecraft Legacy Console Edition.'
api-version: 1.16
load: POSTWORLD
@@ -10,8 +10,8 @@ softdepend: [Multiverse-Core]
commands:
tumble:
- description: Base command for Rumble
- usage: "/tmbl <subCommand> ..."
+ description: Base command for Tumble
+ usage: "/tumble <subCommand> ..."
aliases: tmbl
permissions:
@@ -22,23 +22,33 @@ permissions:
description: Allows you to leave a Tumble match.
default: true
tumble.forcestart:
+ description: Allows you to forcibly start a Tumble match.
default: op
tumble.forcestop:
+ description: Allows you to forcibly stop a Tumble match.
default: op
tumble.reload:
+ description: Allows you to reload the Tumble configuration.
default: op
tumble.create:
+ description: Allows you to create Tumble arenas.
default: op
tumble.remove:
+ description: Allows you to remove Tumble arenas.
default: op
tumble.setgamespawn:
+ description: Allows you to set the game spawn location for Tumble arenas.
default: op
tumble.setkillylevel:
+ description: Allows you to set the kill Y-level for Tumble arenas.
default: op
tumble.setlobby:
+ description: Allows you to set the lobby location for Tumble arenas.
default: op
tumble.setwaitarea:
+ description: Allows you to set the wait area location for Tumble arenas.
default: op
tumble.setwinnerlobby:
+ description: Allows you to set the winner lobby location for Tumble arenas.
default: op