mirror of
https://github.com/SunNetservers/MiniGames.git
synced 2025-04-02 09:46:26 +02:00
Compare commits
44 Commits
v1.0.4-bet
...
master
Author | SHA1 | Date | |
---|---|---|---|
d7e950c53e | |||
c8fbdec64f | |||
09f29e5f67 | |||
7213bd0c70 | |||
a23d0c769f | |||
142cd5339b | |||
b063bd1088 | |||
310802b42d | |||
fc6bd33e87 | |||
ccf43060dc | |||
a498e9bad0 | |||
d8bf77d317 | |||
162aff0c1f | |||
a7cfe36c72 | |||
407acf0ea2 | |||
b6bf22d1c7 | |||
67144fec06 | |||
e52732433a | |||
776fc5a757 | |||
1e7cdf02fc | |||
f3d8be8be2 | |||
4bf00243e6 | |||
ea439bfa33 | |||
003c9e8367 | |||
9dff407713 | |||
d7b1695cd9 | |||
2bc6c2c825 | |||
f24959c8d1 | |||
8ea930a5f3 | |||
57183b64f5 | |||
ba1a7fff68 | |||
57b3b85fbc | |||
38839c0287 | |||
de5124c8dd | |||
9c91e11780 | |||
4513fc2de7 | |||
7900eb691f | |||
d6fb9ab0b9 | |||
7848a0a028 | |||
00ac0582f4 | |||
0704e138ec | |||
05d647052b | |||
fc1902e86a | |||
e039840e89 |
155
README.md
155
README.md
@ -37,26 +37,77 @@ The only permission normal players will need is `minigames.join` which is set to
|
||||
|
||||
## Commands
|
||||
|
||||
| Command | Alias | Arguments | Description |
|
||||
|----------------------------------------|----------|-----------------------------|-------------------------------------------------------------------------------------|
|
||||
| /miniGamesReload | /mreload | | Reloads all data from disk. |
|
||||
| /miniGamesLeave | /mleave | | Leaves the current mini-game. |
|
||||
| /dropperList | /dlist | | Lists available dropper arenas. |
|
||||
| [/dropperJoin](#dropperjoin) | /djoin | \<arena> \[mode] | Joins the selected arena. |
|
||||
| /dropperCreate | /dcreate | \<name> | Creates a new dropper arena with the given name. The spawn is set to your location. |
|
||||
| /dropperRemove | /dremove | \<arena> | Removes the specified dropper arena. |
|
||||
| [/dropperEdit](#dropperedit) | /dedit | \<arena> \<option> \[value] | Gets or sets a dropper arena option. |
|
||||
| [/dropperGroupSet](#droppergroupset) | /dgset | \<arena> \<group> | Puts the given arena in the given group. Use "none" to remove an existing group. |
|
||||
| /dropperGroupList | /dglist | \[group] | Lists groups, or the stages of a group if a group is specified. |
|
||||
| [/dropperGroupSwap](#droppergroupswap) | /dgswap | \<arena1> \<arena2> | Swaps the two arenas in the group's ordered list. |
|
||||
| /parkourList | /plist | | Lists available parkour arenas. |
|
||||
| /parkourJoin | /pjoin | \<arena> | Joins the selected arena. |
|
||||
| /parkourCreate | /pcreate | \<name> | Creates a new parkour arena with the given name. The spawn is set to your location. |
|
||||
| /parkourRemove | /premove | \<arena> | Removes the specified parkour arena. |
|
||||
| [/parkourEdit](#parkouredit) | /pedit | \<arena> \<option> \[value] | Gets or sets a parkour arena option. |
|
||||
| /parkourGroupSet | /pgset | \<arena> \<group> | Puts the given arena in the given group. Use "none" to remove an existing group. |
|
||||
| /parkourGroupList | /pglist | \[group] | Lists groups, or the stages of a group if a group is specified. |
|
||||
| [/parkourGroupSwap](#droppergroupswap) | /pgswap | \<arena1> \<arena2> | Swaps the two arenas in the group's ordered list. |
|
||||
| Command | Alias | Arguments | Description |
|
||||
|----------------------------------------|----------|------------------------------|-------------------------------------------------------------------------------------|
|
||||
| /miniGamesReload | /mreload | | Reloads all data from disk. |
|
||||
| /miniGamesLeave | /mleave | | Leaves the current mini-game. |
|
||||
| /miniGamesMenu | /mmenu | | Shows a menu of actions if used while in an arena |
|
||||
| [/miniGamesReward](#minigamesreward) | /mreward | [See this](#minigamesreward) | Adds or removes rewards for an arena |
|
||||
| /dropperList | /dlist | | Lists available dropper arenas. |
|
||||
| [/dropperJoin](#dropperjoin) | /djoin | \<arena> \[mode] | Joins the selected arena. |
|
||||
| /dropperCreate | /dcreate | \<name> | Creates a new dropper arena with the given name. The spawn is set to your location. |
|
||||
| /dropperRemove | /dremove | \<arena> | Removes the specified dropper arena. |
|
||||
| [/dropperEdit](#dropperedit) | /dedit | \<arena> \<option> \[value] | Gets or sets a dropper arena option. |
|
||||
| [/dropperGroupSet](#droppergroupset) | /dgset | \<arena> \<group> | Puts the given arena in the given group. Use "none" to remove an existing group. |
|
||||
| /dropperGroupList | /dglist | \[group] | Lists groups, or the stages of a group if a group is specified. |
|
||||
| [/dropperGroupSwap](#droppergroupswap) | /dgswap | \<arena1> \<arena2> | Swaps the two arenas in the group's ordered list. |
|
||||
| /parkourList | /plist | | Lists available parkour arenas. |
|
||||
| [/parkourJoin](#parkourjoin) | /pjoin | \<arena> \[mode] | Joins the selected arena. |
|
||||
| /parkourCreate | /pcreate | \<name> | Creates a new parkour arena with the given name. The spawn is set to your location. |
|
||||
| /parkourRemove | /premove | \<arena> | Removes the specified parkour arena. |
|
||||
| [/parkourEdit](#parkouredit) | /pedit | \<arena> \<option> \[value] | Gets or sets a parkour arena option. |
|
||||
| /parkourGroupSet | /pgset | \<arena> \<group> | Puts the given arena in the given group. Use "none" to remove an existing group. |
|
||||
| /parkourGroupList | /pglist | \[group] | Lists groups, or the stages of a group if a group is specified. |
|
||||
| [/parkourGroupSwap](#droppergroupswap) | /pgswap | \<arena1> \<arena2> | Swaps the two arenas in the group's ordered list. |
|
||||
|
||||
### Command explanation mini-games
|
||||
|
||||
#### /miniGamesReward
|
||||
|
||||
This command is used to set the rewards for an arena. Rewards can be set for six conditions; a reward for each time the
|
||||
arena is cleared, a reward for the first time the arena is cleared, a reward for beating your own least deaths record, a
|
||||
reward for beating your own least time record, a record for beating the global least deaths record and a record for
|
||||
beating the global least time record. You can give an item, give money, give a permission or execute a console command
|
||||
with the winning player as an argument.
|
||||
|
||||
Note, you can add as many rewards as you want for each reward condition, so you can add a permission and an amount of
|
||||
currency on the player's first win for example.
|
||||
|
||||
`/mreward add dropper|parkour <name> <condition> <type> [value] [value] ...`
|
||||
|
||||
`/mreward clear dropper|parkour <name> <condition>`
|
||||
|
||||
| Argument | Type | Usage |
|
||||
|-----------|-----------------------------------------------------------------------------------------------------------|-------------------------------------------------------------|
|
||||
| action | add / clear | Whether you are adding a reward or clearing rewards. |
|
||||
| type | dropper / parkour | The type of arena to change rewards for |
|
||||
| name | _Arena name_ | The name of the arena to change rewards for |
|
||||
| condition | WIN / FIRST_WIN / PERSONAL_DEATH_RECORD / PERSONAL_TIME_RECORD / GLOBAL_DEATH_RECORD / GLOBAL_TIME_RECORD | The condition to change rewards for. |
|
||||
| type | COMMAND / ECONOMY / ITEM / PERMISSION | The type of reward to add |
|
||||
| value | [See reward types](#reward-types) | Input for the reward type. Valid values depend on the type. |
|
||||
|
||||
##### Reward types
|
||||
|
||||
###### Economy
|
||||
|
||||
This reward requires an argument which is a number above zero, which is the amount of currency granted to players.
|
||||
|
||||
###### Permission
|
||||
|
||||
This reward requires an argument which is the permission string you want to grant the player.
|
||||
|
||||
###### Command
|
||||
|
||||
The reward requires the command as an argument. Type the full command with spaces and everything, but omit the `/` at
|
||||
the beginning of the command. Use %player_name% or anything that matches the
|
||||
RegEx `[<%(\\[{]player[_\\-]?(name)?[>%)\\]}]` (\<player>. \<player-name>, %player_name%, {player}, etc.) as the
|
||||
placeholder for the rewarded player's name.
|
||||
|
||||
###### Item
|
||||
|
||||
If used with no arguments, the item in your main hand is used. You can specify a material in the first argument to give
|
||||
one item of the specified type. You can specify a positive whole number as the second argument to specify the amount of
|
||||
items to give.
|
||||
|
||||
### Command explanation dropper
|
||||
|
||||
@ -128,6 +179,17 @@ You could use `/droppergroupswap Sea Savanna` to change the order to:
|
||||
|
||||
### Command explanation parkour
|
||||
|
||||
#### /parkourJoin
|
||||
|
||||
This command is used for joining a dropper arena.
|
||||
|
||||
`/parkourjoin <arena> [mode]`
|
||||
|
||||
| Argument | Usage |
|
||||
|----------|-----------------------------------------------------------------------------------------------------------|
|
||||
| arena | The name of the arena to join. |
|
||||
| mode | Additional challenge modes can be played after an arena has been cleared once. Available modes: hardcore. |
|
||||
|
||||
#### /parkourEdit
|
||||
|
||||
This command allows editing the specified property for the specified parkour arena.
|
||||
@ -142,25 +204,26 @@ This command allows editing the specified property for the specified parkour are
|
||||
|
||||
These are all the options that can be changed for an arena.
|
||||
|
||||
| Option | Details |
|
||||
|-----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| name | The name of the arena. Used mainly to select the arena in commands. |
|
||||
| spawnLocation | The spawn location of any player joining the arena. Use `56.546,64.0,44.45` to specify coordinates, or `here`, `this` or any other string to select your current location. |
|
||||
| exitLocation | The location players will be sent to when exiting the arena. If not set, the player will be sent to where they joined from. Valid values are the same as for spawnLocation. |
|
||||
| winBlockType | The type of block players must hit to win the arena. It can be any material as long as it's a block, and not a type of air. |
|
||||
| winLocation | The location players must reach to win the arena (see spawnLocation for valid values). If set, this overrides, and is used instead of, the win block type. |
|
||||
| checkpointAdd | Adds a new checkpoint to the arena's checkpoints (see spawnLocation for valid values). |
|
||||
| checkpointClear | Clears all current checkpoints. Give any value to execute. If not given a value, current checkpoints are shown. |
|
||||
| killPlaneBlocks | A comma-separated list of materials which will force a loss on hit. +WOOL and other [material tags](#notes-about-material-tags) are supported as well. |
|
||||
| Option | Details |
|
||||
|-----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| name | The name of the arena. Used mainly to select the arena in commands. Note that underscore (_) cannot be used if you want to utilize placeholders, as it's used to split placeholder arguments. |
|
||||
| spawnLocation | The spawn location of any player joining the arena. Use `56.546,64.0,44.45` to specify coordinates, or `here`, `this` or any other string to select your current location. |
|
||||
| exitLocation | The location players will be sent to when exiting the arena. If not set, the player will be sent to where they joined from. Valid values are the same as for spawnLocation. |
|
||||
| winBlockType | The type of block players must hit to win the arena. It can be any material as long as it's a block, and not a type of air. |
|
||||
| winLocation | The location players must reach to win the arena (see spawnLocation for valid values). If set, this overrides, and is used instead of, the win block type. |
|
||||
| checkpointAdd | Adds a new checkpoint to the arena's checkpoints (see spawnLocation for valid values). |
|
||||
| checkpointClear | Clears all current checkpoints. Give any value to execute. If not given a value, current checkpoints are shown. |
|
||||
| killPlaneBlocks | A comma-separated list of materials which will force a loss when stepped on. +WOOL and other [material tags](#notes-about-material-tags) are supported as well. |
|
||||
| obstacleBlocks | A comma-separated list of materials which will force a loss when touched from any direction. +WOOL and other [material tags](#notes-about-material-tags) are supported as well. |
|
||||
|
||||
## Configuration options
|
||||
|
||||
### Shared
|
||||
|
||||
| Name | Type | Default | Description |
|
||||
|-----------------------------------|---------------------|-------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| liquidHitBoxDepth | -1 < decimal < 0 | -0.8 | This decides how far inside a non-solid block the player must go before detection triggers (-1, 0). The closer to -1 it is, the more accurate it will seem to the player, but the likelihood of not detecting the hit increases. |
|
||||
| solidHitBoxDistance | 0 < decimal < 1 | 0.2 | This decides the distance the player must be from a block below them before a hit triggers (0, 1). If too low, the likelihood of detecting the hit decreases, but it won't look like the player hit the block without being near. |
|
||||
| Name | Type | Default | Description |
|
||||
|---------------------|------------------|---------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| liquidHitBoxDepth | -1 < decimal < 0 | -0.8 | This decides how far inside a non-solid block the player must go before detection triggers (-1, 0). The closer to -1 it is, the more accurate it will seem to the player, but the likelihood of not detecting the hit increases. |
|
||||
| solidHitBoxDistance | 0 < decimal < 1 | 0.2 | This decides the distance the player must be from a block below them before a hit triggers (0, 1). If too low, the likelihood of detecting the hit decreases, but it won't look like the player hit the block without being near. |
|
||||
|
||||
### Dropper
|
||||
|
||||
@ -174,8 +237,6 @@ These are all the options that can be changed for an arena.
|
||||
| mustDoGroupedInSequence | true/false | true | Whether grouped dropper arenas must be played in the correct sequence |
|
||||
| ignoreRecordsUntilGroupBeatenOnce | true/false | false | Whether records won't be registered unless the player has already beaten all arenas in a group. That means players are required to do a second play-through to register a record for a grouped arena. |
|
||||
| mustDoNormalModeFirst | true/false | true | Whether a player must do the normal/default game-mode before playing any other game-modes |
|
||||
| makePlayersInvisible | true/false | false | Whether players should be made invisible while playing in a dropper arena |
|
||||
| disableHitCollision | true/false | true | Whether players should have their entity hit collision disabled while in an arena. This prevents players from pushing each-other if in the same arena. |
|
||||
| liquidHitBoxDepth | -1 < decimal < 0 | -0.8 | This decides how far inside a non-solid block the player must go before detection triggers (-1, 0). The closer to -1 it is, the more accurate it will seem to the player, but the likelihood of not detecting the hit increases. |
|
||||
| solidHitBoxDistance | 0 < decimal < 1 | 0.2 | This decides the distance the player must be from a block below them before a hit triggers (0, 1). If too low, the likelihood of detecting the hit decreases, but it won't look like the player hit the block without being near. |
|
||||
| blockWhitelist | list | [see this](#blockwhitelist-default) | A whitelist for which blocks won't trigger a loss when hit/passed through. The win block check happens before the loss check, so even blocks on the whitelist can be used as the win-block. "+" denotes a [material tag](#notes-about-material-tags). |
|
||||
@ -187,8 +248,8 @@ These are all the options that can be changed for an arena.
|
||||
| enforceCheckpointOrder | true/false | false | Whether to enforce the order in which a player must reach checkpoints. Enabling this ensures that a player cannot trigger a previous checkpoint by accident. It also ensures players cannot skip a checkpoint, even if the arena layout makes it possible. |
|
||||
| mustDoGroupedInSequence | true/false | true | Whether grouped dropper arenas must be played in the correct sequence |
|
||||
| ignoreRecordsUntilGroupBeatenOnce | true/false | false | Whether records won't be registered unless the player has already beaten all arenas in a group. That means players are required to do a second play-through to register a record for a grouped arena. |
|
||||
| makePlayersInvisible | true/false | false | Whether players should be made invisible while playing in a dropper arena |
|
||||
| killPlaneBlocks | list | [see this](#killplaneblocks-default) | The types of blocks compromising parkour arenas' kill planes. Add any materials you want to use for the "bottom" of your parkour arenas. +WOOL and other [material tags](#notes-about-material-tags) are supported. |
|
||||
| obstacleBlocks | list | [see this](#obstacleblocks-default) | The types of blocks treated as obstacles in every direction. +WOOL and other [material tags](#notes-about-material-tags) are supported. |
|
||||
|
||||
#### blockWhitelist default:
|
||||
|
||||
@ -210,6 +271,12 @@ These are all the options that can be changed for an arena.
|
||||
- LAVA
|
||||
- MAGMA_BLOCK
|
||||
|
||||
#### obstacleBlocks default:
|
||||
|
||||
- END_ROD
|
||||
- LIGHTNING_ROD
|
||||
- CHAIN
|
||||
|
||||
## Record placeholders
|
||||
|
||||
Player records can be displayed on a leaderboard by using PlaceholderAPI. If you want to display a sign-based
|
||||
@ -250,6 +317,20 @@ Example tags:
|
||||
- +FENCE_GATES
|
||||
- +FENCES
|
||||
|
||||
## Language customization
|
||||
|
||||
Most or all strings are customizable. If you place a strings.yml file in the plugin folder, it will take
|
||||
priority over built-in languages. If you want to change strings, look at MiniGames/src/main/resources/strings.yml for
|
||||
the proper keys. All strings have the format: ENUM: "Displayed string". The enum must be identical as it defines which
|
||||
string you have changed. All strings belonging to a language are beneath the language code and indented with two spaces.
|
||||
|
||||
The easiest way to add a new language is to copy an existing language and paste it into your custom strings.yml and
|
||||
change strings as necessary. If you don't include all strings, the remaining will use the built-in English translation.
|
||||
Remember to change the language code to whichever you use for your custom language.
|
||||
|
||||
The interval messages are unique in that if several values are separated by comma (option1,option2,option3), a random
|
||||
message will be chosen each time it's displayed.
|
||||
|
||||
## License
|
||||
|
||||
MiniGames is licensed under the GNU Public License Version 3.0. This includes every source and resource file. See the
|
||||
|
56
pom.xml
56
pom.xml
@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>net.knarcraft</groupId>
|
||||
<artifactId>MiniGames</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<version>1.2</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>MiniGames</name>
|
||||
@ -40,6 +40,26 @@
|
||||
</goals>
|
||||
<configuration>
|
||||
<createDependencyReducedPom>false</createDependencyReducedPom>
|
||||
<filters>
|
||||
<filter>
|
||||
<artifact>net.knarcraft:knarlib</artifact>
|
||||
<includes>
|
||||
<include>net/knarcraft/knarlib/**</include>
|
||||
</includes>
|
||||
</filter>
|
||||
<filter>
|
||||
<artifact>net.knarcraft:knargui</artifact>
|
||||
<includes>
|
||||
<include>net/knarcraft/knargui/**</include>
|
||||
</includes>
|
||||
</filter>
|
||||
<filter>
|
||||
<excludes>
|
||||
<exclude>*.MF</exclude>
|
||||
<exclude>*.yml</exclude>
|
||||
</excludes>
|
||||
</filter>
|
||||
</filters>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
@ -62,13 +82,21 @@
|
||||
<id>placeholderapi</id>
|
||||
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>knarcraft-repo</id>
|
||||
<url>https://git.knarcraft.net/api/packages/EpicKnarvik97/maven</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>jitpack.io</id>
|
||||
<url>https://jitpack.io</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.19.4-R0.1-SNAPSHOT</version>
|
||||
<version>1.20-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@ -77,17 +105,29 @@
|
||||
<version>24.0.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<version>5.9.2</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>me.clip</groupId>
|
||||
<artifactId>placeholderapi</artifactId>
|
||||
<version>2.10.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.knarcraft</groupId>
|
||||
<artifactId>knargui</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.knarcraft</groupId>
|
||||
<artifactId>knarlib</artifactId>
|
||||
<version>1.2.3-SNAPSHOT</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.MilkBowl</groupId>
|
||||
<artifactId>VaultAPI</artifactId>
|
||||
<version>1.7</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
@ -1,7 +1,12 @@
|
||||
package net.knarcraft.minigames;
|
||||
|
||||
import net.knarcraft.knargui.GUIListener;
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.knarlib.formatting.Translator;
|
||||
import net.knarcraft.knarlib.property.ColorConversion;
|
||||
import net.knarcraft.minigames.arena.ArenaPlayerRegistry;
|
||||
import net.knarcraft.minigames.arena.ArenaSession;
|
||||
import net.knarcraft.minigames.arena.PlayerVisibilityManager;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArena;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaData;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaGameMode;
|
||||
@ -20,8 +25,16 @@ import net.knarcraft.minigames.arena.parkour.ParkourArenaRecordsRegistry;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourPlayerEntryState;
|
||||
import net.knarcraft.minigames.arena.record.IntegerRecord;
|
||||
import net.knarcraft.minigames.arena.record.LongRecord;
|
||||
import net.knarcraft.minigames.arena.reward.CommandReward;
|
||||
import net.knarcraft.minigames.arena.reward.EconomyReward;
|
||||
import net.knarcraft.minigames.arena.reward.ItemReward;
|
||||
import net.knarcraft.minigames.arena.reward.PermissionReward;
|
||||
import net.knarcraft.minigames.arena.reward.RewardCondition;
|
||||
import net.knarcraft.minigames.command.LeaveArenaCommand;
|
||||
import net.knarcraft.minigames.command.MenuCommand;
|
||||
import net.knarcraft.minigames.command.ReloadCommand;
|
||||
import net.knarcraft.minigames.command.SetArenaRewardCommand;
|
||||
import net.knarcraft.minigames.command.SetArenaRewardTabCompleter;
|
||||
import net.knarcraft.minigames.command.dropper.CreateDropperArenaCommand;
|
||||
import net.knarcraft.minigames.command.dropper.DropperGroupListCommand;
|
||||
import net.knarcraft.minigames.command.dropper.DropperGroupSetCommand;
|
||||
@ -45,22 +58,31 @@ import net.knarcraft.minigames.command.parkour.ParkourGroupSwapCommand;
|
||||
import net.knarcraft.minigames.command.parkour.RemoveParkourArenaCommand;
|
||||
import net.knarcraft.minigames.command.parkour.RemoveParkourArenaTabCompleter;
|
||||
import net.knarcraft.minigames.config.DropperConfiguration;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import net.knarcraft.minigames.config.ParkourConfiguration;
|
||||
import net.knarcraft.minigames.config.SharedConfiguration;
|
||||
import net.knarcraft.minigames.container.SerializableMaterial;
|
||||
import net.knarcraft.minigames.container.SerializableUUID;
|
||||
import net.knarcraft.minigames.listener.CommandListener;
|
||||
import net.knarcraft.minigames.listener.DamageListener;
|
||||
import net.knarcraft.minigames.listener.InteractListener;
|
||||
import net.knarcraft.minigames.listener.MoveListener;
|
||||
import net.knarcraft.minigames.listener.PlayerStateChangeListener;
|
||||
import net.knarcraft.minigames.manager.EconomyManager;
|
||||
import net.knarcraft.minigames.manager.PermissionManager;
|
||||
import net.knarcraft.minigames.placeholder.DropperRecordExpansion;
|
||||
import net.knarcraft.minigames.placeholder.ParkourRecordExpansion;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.milkbowl.vault.economy.Economy;
|
||||
import net.milkbowl.vault.permission.Permission;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerialization;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
import org.bukkit.plugin.RegisteredServiceProvider;
|
||||
import org.bukkit.plugin.ServicesManager;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@ -84,6 +106,9 @@ public final class MiniGames extends JavaPlugin {
|
||||
private ParkourRecordExpansion parkourRecordExpansion;
|
||||
private ParkourArenaHandler parkourArenaHandler;
|
||||
private ArenaPlayerRegistry<ParkourArena> parkourArenaPlayerRegistry;
|
||||
private PlayerVisibilityManager playerVisibilityManager;
|
||||
private Translator translator;
|
||||
private StringFormatter stringFormatter;
|
||||
|
||||
/**
|
||||
* Gets an instance of this plugin
|
||||
@ -159,6 +184,33 @@ public final class MiniGames extends JavaPlugin {
|
||||
return this.parkourConfiguration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the manager keeping track of player visibility
|
||||
*
|
||||
* @return <p>The player visibility manager</p>
|
||||
*/
|
||||
public PlayerVisibilityManager getPlayerVisibilityManager() {
|
||||
return this.playerVisibilityManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the translator to get messages from
|
||||
*
|
||||
* @return <p>The translator</p>
|
||||
*/
|
||||
public Translator getTranslator() {
|
||||
return this.translator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the string formatter to get formatted messages from
|
||||
*
|
||||
* @return <p>The string formatter</p>
|
||||
*/
|
||||
public StringFormatter getStringFormatter() {
|
||||
return this.stringFormatter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current session of the given player
|
||||
*
|
||||
@ -194,6 +246,8 @@ public final class MiniGames extends JavaPlugin {
|
||||
|
||||
// Reload configuration
|
||||
this.reloadConfig();
|
||||
translator.loadLanguages(this.getDataFolder(), "en",
|
||||
getConfig().getString("language", "en"));
|
||||
this.sharedConfiguration.load(this.getConfig());
|
||||
this.dropperConfiguration.load(this.getConfig());
|
||||
this.parkourConfiguration.load(this.getConfig());
|
||||
@ -221,63 +275,29 @@ public final class MiniGames extends JavaPlugin {
|
||||
ConfigurationSerialization.registerClass(ParkourArenaGameMode.class);
|
||||
ConfigurationSerialization.registerClass(DropperPlayerEntryState.class);
|
||||
ConfigurationSerialization.registerClass(ParkourPlayerEntryState.class);
|
||||
ConfigurationSerialization.registerClass(CommandReward.class);
|
||||
ConfigurationSerialization.registerClass(EconomyReward.class);
|
||||
ConfigurationSerialization.registerClass(ItemReward.class);
|
||||
ConfigurationSerialization.registerClass(PermissionReward.class);
|
||||
ConfigurationSerialization.registerClass(RewardCondition.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
// Plugin startup logic
|
||||
instance = this;
|
||||
this.saveDefaultConfig();
|
||||
getConfig().options().copyDefaults(true);
|
||||
saveConfig();
|
||||
reloadConfig();
|
||||
this.sharedConfiguration = new SharedConfiguration(this.getConfig());
|
||||
this.dropperConfiguration = new DropperConfiguration(this.getConfig());
|
||||
this.parkourConfiguration = new ParkourConfiguration(this.getConfig());
|
||||
this.dropperArenaPlayerRegistry = new DropperArenaPlayerRegistry();
|
||||
this.dropperArenaHandler = new DropperArenaHandler(this.dropperArenaPlayerRegistry);
|
||||
this.dropperArenaHandler.load();
|
||||
this.parkourArenaPlayerRegistry = new ParkourArenaPlayerRegistry();
|
||||
this.parkourArenaHandler = new ParkourArenaHandler(this.parkourArenaPlayerRegistry);
|
||||
this.parkourArenaHandler.load();
|
||||
|
||||
PluginManager pluginManager = getServer().getPluginManager();
|
||||
pluginManager.registerEvents(new DamageListener(), this);
|
||||
pluginManager.registerEvents(new MoveListener(this.dropperConfiguration, this.parkourConfiguration), this);
|
||||
pluginManager.registerEvents(new PlayerStateChangeListener(), this);
|
||||
pluginManager.registerEvents(new CommandListener(), this);
|
||||
// Load configuration
|
||||
loadConfiguration();
|
||||
|
||||
registerCommand("miniGamesReload", new ReloadCommand(), null);
|
||||
registerCommand("miniGamesLeave", new LeaveArenaCommand(), null);
|
||||
// Register all listeners
|
||||
registerListeners();
|
||||
|
||||
registerCommand("dropperCreate", new CreateDropperArenaCommand(), null);
|
||||
registerCommand("dropperList", new ListDropperArenaCommand(), null);
|
||||
registerCommand("dropperJoin", new JoinDropperArenaCommand(), new JoinDropperArenaTabCompleter());
|
||||
registerCommand("dropperEdit", new EditDropperArenaCommand(this.dropperConfiguration), new EditDropperArenaTabCompleter());
|
||||
registerCommand("dropperRemove", new RemoveDropperArenaCommand(), new RemoveDropperArenaTabCompleter());
|
||||
registerCommand("dropperGroupSet", new DropperGroupSetCommand(), null);
|
||||
registerCommand("dropperGroupSwap", new DropperGroupSwapCommand(), null);
|
||||
registerCommand("dropperGroupList", new DropperGroupListCommand(), null);
|
||||
// Register all commands
|
||||
registerCommands();
|
||||
|
||||
registerCommand("parkourCreate", new CreateParkourArenaCommand(), null);
|
||||
registerCommand("parkourList", new ListParkourArenaCommand(), null);
|
||||
registerCommand("parkourJoin", new JoinParkourArenaCommand(), new JoinParkourArenaTabCompleter());
|
||||
registerCommand("parkourEdit", new EditParkourArenaCommand(), new EditParkourArenaTabCompleter());
|
||||
registerCommand("parkourRemove", new RemoveParkourArenaCommand(), new RemoveParkourArenaTabCompleter());
|
||||
registerCommand("parkourGroupSet", new ParkourGroupSetCommand(), null);
|
||||
registerCommand("parkourGroupSwap", new ParkourGroupSwapCommand(), null);
|
||||
registerCommand("parkourGroupList", new ParkourGroupListCommand(), null);
|
||||
|
||||
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
|
||||
this.dropperRecordExpansion = new DropperRecordExpansion(this);
|
||||
if (!this.dropperRecordExpansion.register()) {
|
||||
log(Level.WARNING, "Unable to register PlaceholderAPI dropper expansion!");
|
||||
}
|
||||
this.parkourRecordExpansion = new ParkourRecordExpansion(this);
|
||||
if (!this.parkourRecordExpansion.register()) {
|
||||
log(Level.WARNING, "Unable to register PlaceholderAPI parkour expansion!");
|
||||
}
|
||||
}
|
||||
// Integrate with other plugins
|
||||
doPluginIntegration();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -291,6 +311,63 @@ public final class MiniGames extends JavaPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up integration with third-party plugins
|
||||
*/
|
||||
private void doPluginIntegration() {
|
||||
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
|
||||
this.dropperRecordExpansion = new DropperRecordExpansion(this);
|
||||
if (!this.dropperRecordExpansion.register()) {
|
||||
log(Level.WARNING, "Unable to register PlaceholderAPI dropper expansion!");
|
||||
}
|
||||
this.parkourRecordExpansion = new ParkourRecordExpansion(this);
|
||||
if (!this.parkourRecordExpansion.register()) {
|
||||
log(Level.WARNING, "Unable to register PlaceholderAPI parkour expansion!");
|
||||
}
|
||||
}
|
||||
if (Bukkit.getPluginManager().getPlugin("Vault") != null) {
|
||||
setupVault();
|
||||
} else {
|
||||
log(Level.WARNING, "Vault not found. Economy and Permission rewards are unavailable.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all configuration values used by this plugin
|
||||
*/
|
||||
private void loadConfiguration() {
|
||||
this.saveDefaultConfig();
|
||||
getConfig().options().copyDefaults(true);
|
||||
saveConfig();
|
||||
reloadConfig();
|
||||
|
||||
setupStringFormatter();
|
||||
|
||||
this.sharedConfiguration = new SharedConfiguration(this.getConfig());
|
||||
this.dropperConfiguration = new DropperConfiguration(this.getConfig());
|
||||
this.parkourConfiguration = new ParkourConfiguration(this.getConfig());
|
||||
this.dropperArenaPlayerRegistry = new DropperArenaPlayerRegistry();
|
||||
this.dropperArenaHandler = new DropperArenaHandler(this.dropperArenaPlayerRegistry);
|
||||
this.dropperArenaHandler.load();
|
||||
this.parkourArenaPlayerRegistry = new ParkourArenaPlayerRegistry();
|
||||
this.parkourArenaHandler = new ParkourArenaHandler(this.parkourArenaPlayerRegistry);
|
||||
this.parkourArenaHandler.load();
|
||||
this.playerVisibilityManager = new PlayerVisibilityManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers all listeners used by this plugin
|
||||
*/
|
||||
private void registerListeners() {
|
||||
PluginManager pluginManager = getServer().getPluginManager();
|
||||
pluginManager.registerEvents(new DamageListener(), this);
|
||||
pluginManager.registerEvents(new MoveListener(this.dropperConfiguration, this.parkourConfiguration), this);
|
||||
pluginManager.registerEvents(new PlayerStateChangeListener(), this);
|
||||
pluginManager.registerEvents(new CommandListener(), this);
|
||||
pluginManager.registerEvents(new GUIListener(true), this);
|
||||
pluginManager.registerEvents(new InteractListener(), this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a command
|
||||
*
|
||||
@ -311,4 +388,82 @@ public final class MiniGames extends JavaPlugin {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers all commands used by this plugin
|
||||
*/
|
||||
private void registerCommands() {
|
||||
registerCommand("miniGamesReload", new ReloadCommand(), null);
|
||||
registerCommand("miniGamesLeave", new LeaveArenaCommand(), null);
|
||||
registerCommand("miniGamesMenu", new MenuCommand(), null);
|
||||
registerCommand("miniGamesReward", new SetArenaRewardCommand(), new SetArenaRewardTabCompleter());
|
||||
|
||||
registerDropperCommands();
|
||||
registerParkourCommands();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers all commands related to droppers
|
||||
*/
|
||||
private void registerDropperCommands() {
|
||||
registerCommand("dropperCreate", new CreateDropperArenaCommand(), null);
|
||||
registerCommand("dropperList", new ListDropperArenaCommand(), null);
|
||||
registerCommand("dropperJoin", new JoinDropperArenaCommand(), new JoinDropperArenaTabCompleter());
|
||||
registerCommand("dropperEdit", new EditDropperArenaCommand(this.dropperConfiguration), new EditDropperArenaTabCompleter());
|
||||
registerCommand("dropperRemove", new RemoveDropperArenaCommand(), new RemoveDropperArenaTabCompleter());
|
||||
registerCommand("dropperGroupSet", new DropperGroupSetCommand(), null);
|
||||
registerCommand("dropperGroupSwap", new DropperGroupSwapCommand(), null);
|
||||
registerCommand("dropperGroupList", new DropperGroupListCommand(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers all commands related to parkour
|
||||
*/
|
||||
private void registerParkourCommands() {
|
||||
registerCommand("parkourCreate", new CreateParkourArenaCommand(), null);
|
||||
registerCommand("parkourList", new ListParkourArenaCommand(), null);
|
||||
registerCommand("parkourJoin", new JoinParkourArenaCommand(), new JoinParkourArenaTabCompleter());
|
||||
registerCommand("parkourEdit", new EditParkourArenaCommand(), new EditParkourArenaTabCompleter());
|
||||
registerCommand("parkourRemove", new RemoveParkourArenaCommand(), new RemoveParkourArenaTabCompleter());
|
||||
registerCommand("parkourGroupSet", new ParkourGroupSetCommand(), null);
|
||||
registerCommand("parkourGroupSwap", new ParkourGroupSwapCommand(), null);
|
||||
registerCommand("parkourGroupList", new ParkourGroupListCommand(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the translator and the string formatter
|
||||
*/
|
||||
private void setupStringFormatter() {
|
||||
translator = new Translator();
|
||||
translator.registerMessageCategory(MiniGameMessage.ERROR_PLAYER_ONLY);
|
||||
translator.loadLanguages(this.getDataFolder(), "en",
|
||||
getConfig().getString("language", "en"));
|
||||
stringFormatter = new StringFormatter(this.getDescription().getName(), translator);
|
||||
stringFormatter.setColorConversion(ColorConversion.RGB);
|
||||
stringFormatter.setNamePrefix("#546EED[&r&l");
|
||||
stringFormatter.setNameSuffix("#546EED]");
|
||||
stringFormatter.setErrorColor(ChatColor.RED);
|
||||
stringFormatter.setSuccessColor(ChatColor.GREEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up Vault by getting plugins from their providers
|
||||
*/
|
||||
private void setupVault() {
|
||||
ServicesManager servicesManager = this.getServer().getServicesManager();
|
||||
RegisteredServiceProvider<Permission> permissionProvider = servicesManager.getRegistration(Permission.class);
|
||||
RegisteredServiceProvider<Economy> economyProvider = servicesManager.getRegistration(Economy.class);
|
||||
|
||||
if (permissionProvider != null) {
|
||||
PermissionManager.initialize(permissionProvider.getProvider());
|
||||
} else {
|
||||
log(Level.WARNING, "No Vault permission provider found. Permission rewards are unavailable.");
|
||||
}
|
||||
|
||||
if (economyProvider != null) {
|
||||
EconomyManager.initialize(economyProvider.getProvider());
|
||||
} else {
|
||||
log(Level.WARNING, "No Vault economy provider found. Economy rewards are unavailable.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -29,6 +29,11 @@ public abstract class AbstractArenaPlayerRegistry<K extends Arena> implements Ar
|
||||
loadEntryStates();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Set<UUID> getPlayingPlayers() {
|
||||
return arenaPlayers.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable PlayerEntryState getEntryState(@NotNull UUID playerId) {
|
||||
return this.entryStates.get(playerId);
|
||||
@ -65,13 +70,15 @@ public abstract class AbstractArenaPlayerRegistry<K extends Arena> implements Ar
|
||||
|
||||
@Override
|
||||
public void removeForArena(K arena, boolean immediately) {
|
||||
Set<UUID> removed = new HashSet<>();
|
||||
for (Map.Entry<UUID, ArenaSession> entry : this.arenaPlayers.entrySet()) {
|
||||
if (entry.getValue().getArena() == arena) {
|
||||
// Kick the player gracefully
|
||||
entry.getValue().triggerQuit(immediately);
|
||||
this.arenaPlayers.remove(entry.getKey());
|
||||
entry.getValue().triggerQuit(immediately, false);
|
||||
removed.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
removed.forEach(this.arenaPlayers::remove);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -97,7 +104,7 @@ public abstract class AbstractArenaPlayerRegistry<K extends Arena> implements Ar
|
||||
for (PlayerEntryState entryState : entryStates) {
|
||||
this.entryStates.put(entryState.getPlayerId(), entryState);
|
||||
}
|
||||
if (this.entryStates.size() > 0) {
|
||||
if (!this.entryStates.isEmpty()) {
|
||||
MiniGames.log(Level.WARNING, entryStates.size() + " un-exited sessions found. This happens if " +
|
||||
"players leave in the middle of a game, or if the server crashes. MiniGames will do its best " +
|
||||
"to fix the players' states.");
|
||||
|
@ -1,9 +1,13 @@
|
||||
package net.knarcraft.minigames.arena;
|
||||
|
||||
import net.knarcraft.minigames.config.Message;
|
||||
import net.knarcraft.minigames.container.PlaceholderContainer;
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.reward.RewardCondition;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import net.knarcraft.minigames.property.RecordResult;
|
||||
import net.knarcraft.minigames.property.RecordType;
|
||||
import net.knarcraft.minigames.util.PlayerTeleporter;
|
||||
import net.knarcraft.minigames.util.RewardHelper;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -14,7 +18,7 @@ public abstract class AbstractArenaSession implements ArenaSession {
|
||||
private final @NotNull ArenaGameMode gameMode;
|
||||
private final @NotNull Player player;
|
||||
protected int deaths;
|
||||
protected final long startTime;
|
||||
protected long startTime;
|
||||
protected PlayerEntryState entryState;
|
||||
|
||||
/**
|
||||
@ -33,22 +37,34 @@ public abstract class AbstractArenaSession implements ArenaSession {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void triggerQuit(boolean immediately) {
|
||||
public void triggerQuit(boolean immediately, boolean removeSession) {
|
||||
// Stop this session
|
||||
removeSession();
|
||||
if (removeSession) {
|
||||
removeSession();
|
||||
}
|
||||
// Teleport the player out of the arena
|
||||
teleportToExit(immediately);
|
||||
// Make the player visible to everyone
|
||||
MiniGames.getInstance().getPlayerVisibilityManager().showPlayersFor(player);
|
||||
|
||||
player.sendMessage(Message.SUCCESS_ARENA_QUIT.getMessage());
|
||||
MiniGames.getInstance().getStringFormatter().displaySuccessMessage(player, MiniGameMessage.SUCCESS_ARENA_QUIT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
this.deaths = 0;
|
||||
this.startTime = System.currentTimeMillis();
|
||||
PlayerTeleporter.teleportPlayer(this.player, this.arena.getSpawnLocation(), false, false);
|
||||
this.entryState.setArenaState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Announces a record set by this player
|
||||
*
|
||||
* @param recordResult <p>The result of the record</p>
|
||||
* @param type <p>The type of record set (time or deaths)</p>
|
||||
* @param recordType <p>The type of record set (time or deaths)</p>
|
||||
*/
|
||||
protected void announceRecord(@NotNull RecordResult recordResult, @NotNull String type) {
|
||||
protected void announceRecord(@NotNull RecordResult recordResult, @NotNull RecordType recordType) {
|
||||
if (recordResult == RecordResult.NONE) {
|
||||
return;
|
||||
}
|
||||
@ -56,16 +72,21 @@ public abstract class AbstractArenaSession implements ArenaSession {
|
||||
// Gets a string representation of the played game-mode
|
||||
String gameModeString = getGameModeString();
|
||||
|
||||
Message recordInfoMessage = switch (recordResult) {
|
||||
case WORLD_RECORD -> Message.RECORD_ACHIEVED_GLOBAL;
|
||||
case PERSONAL_BEST -> Message.RECORD_ACHIEVED_PERSONAL;
|
||||
MiniGameMessage recordInfoMiniGameMessage = switch (recordResult) {
|
||||
case WORLD_RECORD -> MiniGameMessage.RECORD_ACHIEVED_GLOBAL;
|
||||
case PERSONAL_BEST -> MiniGameMessage.RECORD_ACHIEVED_PERSONAL;
|
||||
default -> throw new IllegalStateException("Unexpected value: " + recordResult);
|
||||
};
|
||||
String recordInfo = recordInfoMessage.getPartialMessage("{recordType}", type);
|
||||
StringFormatter stringFormatter = MiniGames.getInstance().getStringFormatter();
|
||||
String recordInfo = stringFormatter.replacePlaceholder(recordInfoMiniGameMessage, "{recordType}",
|
||||
recordType.name().toLowerCase().replace("_", " "));
|
||||
|
||||
PlaceholderContainer placeholderContainer = new PlaceholderContainer().add("{gameMode}", gameModeString);
|
||||
placeholderContainer.add("{recordInfo}", recordInfo);
|
||||
player.sendMessage(Message.SUCCESS_RECORD_ACHIEVED.getMessage(placeholderContainer));
|
||||
stringFormatter.displaySuccessMessage(player, stringFormatter.replacePlaceholders(
|
||||
MiniGameMessage.SUCCESS_RECORD_ACHIEVED, new String[]{"{gameMode}", "{recordInfo}"},
|
||||
new String[]{gameModeString, recordInfo}));
|
||||
|
||||
// Reward the player
|
||||
rewardRecord(recordResult, recordType);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -74,8 +95,32 @@ public abstract class AbstractArenaSession implements ArenaSession {
|
||||
protected void registerRecord() {
|
||||
ArenaRecordsRegistry recordsRegistry = this.arena.getData().getRecordRegistries().get(this.gameMode);
|
||||
long timeElapsed = System.currentTimeMillis() - this.startTime;
|
||||
announceRecord(recordsRegistry.registerTimeRecord(this.player.getUniqueId(), timeElapsed), "time");
|
||||
announceRecord(recordsRegistry.registerDeathRecord(this.player.getUniqueId(), this.deaths), "least deaths");
|
||||
announceRecord(recordsRegistry.registerTimeRecord(this.player.getUniqueId(), timeElapsed), RecordType.TIME);
|
||||
announceRecord(recordsRegistry.registerDeathRecord(this.player.getUniqueId(), this.deaths), RecordType.DEATHS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewards the specified achieved record
|
||||
*
|
||||
* @param recordResult <p>The result of the record achieved</p>
|
||||
* @param recordType <p>The type of record achieved</p>
|
||||
*/
|
||||
protected void rewardRecord(RecordResult recordResult, RecordType recordType) {
|
||||
RewardCondition condition = null;
|
||||
if (recordResult == RecordResult.WORLD_RECORD) {
|
||||
if (recordType == RecordType.DEATHS) {
|
||||
condition = RewardCondition.GLOBAL_DEATH_RECORD;
|
||||
} else if (recordType == RecordType.TIME) {
|
||||
condition = RewardCondition.GLOBAL_TIME_RECORD;
|
||||
}
|
||||
} else if (recordResult == RecordResult.PERSONAL_BEST) {
|
||||
if (recordType == RecordType.DEATHS) {
|
||||
condition = RewardCondition.PERSONAL_DEATH_RECORD;
|
||||
} else if (recordType == RecordType.TIME) {
|
||||
condition = RewardCondition.PERSONAL_TIME_RECORD;
|
||||
}
|
||||
}
|
||||
RewardHelper.grantRewards(this.player, this.arena.getRewards(condition));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2,16 +2,22 @@ package net.knarcraft.minigames.arena;
|
||||
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.container.SerializableUUID;
|
||||
import net.knarcraft.minigames.property.PersistentDataKey;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
@ -21,7 +27,6 @@ import java.util.logging.Level;
|
||||
public abstract class AbstractPlayerEntryState implements PlayerEntryState {
|
||||
|
||||
protected final UUID playerId;
|
||||
private final boolean makePlayerInvisible;
|
||||
private final Location entryLocation;
|
||||
private final boolean originalIsFlying;
|
||||
private final GameMode originalGameMode;
|
||||
@ -33,12 +38,10 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState {
|
||||
/**
|
||||
* Instantiates a new abstract player entry state
|
||||
*
|
||||
* @param player <p>The player whose state this should keep track of</p>
|
||||
* @param makePlayerInvisible <p>Whether players should be made invisible while in the arena</p>
|
||||
* @param player <p>The player whose state this should keep track of</p>
|
||||
*/
|
||||
public AbstractPlayerEntryState(@NotNull Player player, boolean makePlayerInvisible) {
|
||||
public AbstractPlayerEntryState(@NotNull Player player) {
|
||||
this.playerId = player.getUniqueId();
|
||||
this.makePlayerInvisible = makePlayerInvisible;
|
||||
this.entryLocation = player.getLocation().clone();
|
||||
this.originalIsFlying = player.isFlying();
|
||||
this.originalGameMode = player.getGameMode();
|
||||
@ -52,7 +55,6 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState {
|
||||
* Instantiates a new abstract player entry state
|
||||
*
|
||||
* @param playerId <p>The id of the player whose state this should keep track of</p>
|
||||
* @param makePlayerInvisible <p>Whether players should be made invisible while in the arena</p>
|
||||
* @param entryLocation <p>The location the player entered from</p>
|
||||
* @param originalIsFlying <p>Whether the player was flying before entering the arena</p>
|
||||
* @param originalGameMode <p>The game-mode of the player before entering the arena</p>
|
||||
@ -61,12 +63,11 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState {
|
||||
* @param originalIsSwimming <p>Whether the player was swimming before entering the arena</p>
|
||||
* @param originalCollideAble <p>Whether the player was collide-able before entering the arena</p>
|
||||
*/
|
||||
public AbstractPlayerEntryState(@NotNull UUID playerId, boolean makePlayerInvisible, Location entryLocation,
|
||||
public AbstractPlayerEntryState(@NotNull UUID playerId, Location entryLocation,
|
||||
boolean originalIsFlying, GameMode originalGameMode, boolean originalAllowFlight,
|
||||
boolean originalInvulnerable, boolean originalIsSwimming,
|
||||
boolean originalCollideAble) {
|
||||
this.playerId = playerId;
|
||||
this.makePlayerInvisible = makePlayerInvisible;
|
||||
this.entryLocation = entryLocation;
|
||||
this.originalIsFlying = originalIsFlying;
|
||||
this.originalGameMode = originalGameMode;
|
||||
@ -81,18 +82,6 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState {
|
||||
return this.playerId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setArenaState() {
|
||||
Player player = getPlayer();
|
||||
if (player == null) {
|
||||
return;
|
||||
}
|
||||
if (this.makePlayerInvisible) {
|
||||
player.addPotionEffect(new PotionEffect(PotionEffectType.INVISIBILITY,
|
||||
PotionEffect.INFINITE_DURATION, 3));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean restore() {
|
||||
Player player = getPlayer();
|
||||
@ -105,15 +94,13 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState {
|
||||
|
||||
@Override
|
||||
public void restore(@NotNull Player player) {
|
||||
player.setFlying(this.originalIsFlying);
|
||||
player.setGameMode(this.originalGameMode);
|
||||
player.setCollidable(this.originalCollideAble);
|
||||
player.setAllowFlight(this.originalAllowFlight);
|
||||
player.setFlying(player.getAllowFlight() && this.originalIsFlying);
|
||||
player.setGameMode(this.originalGameMode);
|
||||
player.setInvulnerable(this.originalInvulnerable);
|
||||
player.setSwimming(this.originalIsSwimming);
|
||||
player.setCollidable(this.originalCollideAble);
|
||||
if (this.makePlayerInvisible) {
|
||||
player.removePotionEffect(PotionEffectType.INVISIBILITY);
|
||||
}
|
||||
removeMenuItem(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -140,7 +127,6 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState {
|
||||
public Map<String, Object> serialize() {
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("playerId", new SerializableUUID(this.playerId));
|
||||
data.put("makePlayerInvisible", this.makePlayerInvisible);
|
||||
data.put("entryLocation", this.entryLocation);
|
||||
data.put("originalIsFlying", this.originalIsFlying);
|
||||
data.put("originalGameMode", this.originalGameMode.name());
|
||||
@ -151,4 +137,42 @@ public abstract class AbstractPlayerEntryState implements PlayerEntryState {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the menu item from the given player's inventory
|
||||
*
|
||||
* @param player <p>The player to remove the menu item from</p>
|
||||
*/
|
||||
private void removeMenuItem(Player player) {
|
||||
Set<ItemStack> itemsToRemove = new HashSet<>();
|
||||
player.getInventory().forEach((item) -> {
|
||||
if (item == null) {
|
||||
return;
|
||||
}
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
if (meta == null) {
|
||||
return;
|
||||
}
|
||||
Integer persistentData = meta.getPersistentDataContainer().get(new NamespacedKey(MiniGames.getInstance(),
|
||||
PersistentDataKey.MENU_ITEM.getKeyName()), PersistentDataType.INTEGER);
|
||||
if (persistentData != null && persistentData == PersistentDataKey.MENU_ITEM.getDataValue()) {
|
||||
itemsToRemove.add(item);
|
||||
}
|
||||
});
|
||||
for (ItemStack toRemove : itemsToRemove) {
|
||||
player.getInventory().remove(toRemove);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a boolean value from a serialization map
|
||||
*
|
||||
* @param data <p>The serialization data to look through</p>
|
||||
* @param key <p>The key to get</p>
|
||||
* @return <p>The boolean value of the key</p>
|
||||
*/
|
||||
protected static boolean getBoolean(Map<String, Object> data, String key) {
|
||||
Boolean value = (Boolean) data.get(key);
|
||||
return Objects.requireNonNullElse(value, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,10 +1,13 @@
|
||||
package net.knarcraft.minigames.arena;
|
||||
|
||||
import net.knarcraft.minigames.arena.reward.Reward;
|
||||
import net.knarcraft.minigames.arena.reward.RewardCondition;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
@ -91,4 +94,27 @@ public interface Arena {
|
||||
*/
|
||||
@Nullable Location getExitLocation();
|
||||
|
||||
/**
|
||||
* Adds a reward to this arena
|
||||
*
|
||||
* @param rewardCondition <p>The condition for the reward to be granted</p>
|
||||
* @param reward <p>The reward to be granted</p>
|
||||
*/
|
||||
void addReward(@NotNull RewardCondition rewardCondition, @NotNull Reward reward);
|
||||
|
||||
/**
|
||||
* Clears this arena's rewards for the given condition
|
||||
*
|
||||
* @param rewardCondition <p>The reward condition to clear all rewards for</p>
|
||||
*/
|
||||
void clearRewards(@NotNull RewardCondition rewardCondition);
|
||||
|
||||
/**
|
||||
* Gets all rewards for the given reward condition
|
||||
*
|
||||
* @param rewardCondition <p>The condition to get the rewards for</p>
|
||||
* @return <p>All rewards</p>
|
||||
*/
|
||||
@NotNull Set<Reward> getRewards(RewardCondition rewardCondition);
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package net.knarcraft.minigames.arena;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
@ -12,6 +13,13 @@ import java.util.UUID;
|
||||
*/
|
||||
public interface ArenaPlayerRegistry<K extends Arena> {
|
||||
|
||||
/**
|
||||
* Gets the ids of the players currently playing
|
||||
*
|
||||
* @return <p>The ids of the playing players</p>
|
||||
*/
|
||||
@NotNull Set<UUID> getPlayingPlayers();
|
||||
|
||||
/**
|
||||
* Gets the current entry state for the given player
|
||||
*
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.knarcraft.minigames.arena;
|
||||
|
||||
import net.knarcraft.minigames.gui.ArenaGUI;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@ -27,9 +28,10 @@ public interface ArenaSession {
|
||||
/**
|
||||
* Triggers a quit for the player playing in this session
|
||||
*
|
||||
* @param immediately <p>Whether to to the teleportation immediately, not using any timers</p>
|
||||
* @param immediately <p>Whether to to the teleportation immediately, not using any timers</p>
|
||||
* @param removeSession <p>Whether to also remove the session. Should usually be true.</p>
|
||||
*/
|
||||
void triggerQuit(boolean immediately);
|
||||
void triggerQuit(boolean immediately, boolean removeSession);
|
||||
|
||||
/**
|
||||
* Gets the arena this session is being played in
|
||||
@ -38,4 +40,16 @@ public interface ArenaSession {
|
||||
*/
|
||||
@NotNull Arena getArena();
|
||||
|
||||
/**
|
||||
* Gets the GUI with this arena's options
|
||||
*
|
||||
* @return <p>This arena's GUI</p>
|
||||
*/
|
||||
@NotNull ArenaGUI getGUI();
|
||||
|
||||
/**
|
||||
* Resets the session to allow a player to try again
|
||||
*/
|
||||
void reset();
|
||||
|
||||
}
|
||||
|
@ -38,6 +38,11 @@ public enum EditablePropertyType {
|
||||
/**
|
||||
* The property is a comma-separated list of materials
|
||||
*/
|
||||
MATERIAL_LIST
|
||||
MATERIAL_LIST,
|
||||
|
||||
/**
|
||||
* The property is any double value
|
||||
*/
|
||||
DOUBLE,
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,109 @@
|
||||
package net.knarcraft.minigames.arena;
|
||||
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* A manager for keeping track of which players have set other players as hidden
|
||||
*/
|
||||
public class PlayerVisibilityManager {
|
||||
|
||||
private final Set<UUID> displayingEnabledFor = new HashSet<>();
|
||||
|
||||
/**
|
||||
* Toggles whether players should be hidden for the player with the given id
|
||||
*
|
||||
* @param player <p>The the player to update</p>
|
||||
*/
|
||||
public void toggleHidePlayers(@NotNull ArenaPlayerRegistry<?> playerRegistry, @NotNull Player player) {
|
||||
if (displayingEnabledFor.contains(player.getUniqueId())) {
|
||||
displayingEnabledFor.remove(player.getUniqueId());
|
||||
// Make all other players hidden
|
||||
changeVisibilityFor(playerRegistry, player, true);
|
||||
} else {
|
||||
displayingEnabledFor.add(player.getUniqueId());
|
||||
// Make all other players visible again
|
||||
changeVisibilityFor(playerRegistry, player, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether the given player is currently hiding other players
|
||||
*
|
||||
* @param player <p>The player to check</p>
|
||||
* @return <p>True if currently hiding other players</p>
|
||||
*/
|
||||
public boolean isHidingPlayers(Player player) {
|
||||
return !this.displayingEnabledFor.contains(player.getUniqueId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates which players are seen as hidden
|
||||
*
|
||||
* @param playerRegistry <p>The registry containing all playing players</p>
|
||||
* @param player <p>The player that joined the arena</p>
|
||||
*/
|
||||
public void updateHiddenPlayers(@NotNull ArenaPlayerRegistry<?> playerRegistry, @NotNull Player player) {
|
||||
boolean hideForPlayer = !displayingEnabledFor.contains(player.getUniqueId());
|
||||
for (UUID playerId : playerRegistry.getPlayingPlayers()) {
|
||||
Player otherPlayer = Bukkit.getPlayer(playerId);
|
||||
if (otherPlayer == null) {
|
||||
continue;
|
||||
}
|
||||
// Hide the arena player from the newly joined player
|
||||
if (hideForPlayer) {
|
||||
player.hidePlayer(MiniGames.getInstance(), otherPlayer);
|
||||
}
|
||||
// Hide the newly joined player from this player
|
||||
if (!displayingEnabledFor.contains(playerId)) {
|
||||
otherPlayer.hidePlayer(MiniGames.getInstance(), player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes all players visible to the given player
|
||||
*
|
||||
* @param player <p>The player to update visibility for</p>
|
||||
*/
|
||||
public void showPlayersFor(@NotNull Player player) {
|
||||
for (Player otherPlayer : Bukkit.getOnlinePlayers()) {
|
||||
player.showPlayer(MiniGames.getInstance(), otherPlayer);
|
||||
otherPlayer.showPlayer(MiniGames.getInstance(), player);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes whether the given player can see the other players in the arena
|
||||
*
|
||||
* @param playerRegistry <p>The player registry containing other players</p>
|
||||
* @param player <p>The player to change the visibility for</p>
|
||||
* @param hide <p>Whether to hide the players or show the players</p>
|
||||
*/
|
||||
private void changeVisibilityFor(@Nullable ArenaPlayerRegistry<?> playerRegistry, @NotNull Player player, boolean hide) {
|
||||
if (playerRegistry == null) {
|
||||
return;
|
||||
}
|
||||
for (UUID playerId : playerRegistry.getPlayingPlayers()) {
|
||||
Player otherPlayer = Bukkit.getPlayer(playerId);
|
||||
if (otherPlayer == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (hide) {
|
||||
player.hidePlayer(MiniGames.getInstance(), otherPlayer);
|
||||
} else {
|
||||
player.showPlayer(MiniGames.getInstance(), otherPlayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -4,6 +4,8 @@ import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.Arena;
|
||||
import net.knarcraft.minigames.arena.ArenaGameMode;
|
||||
import net.knarcraft.minigames.arena.ArenaRecordsRegistry;
|
||||
import net.knarcraft.minigames.arena.reward.Reward;
|
||||
import net.knarcraft.minigames.arena.reward.RewardCondition;
|
||||
import net.knarcraft.minigames.config.DropperConfiguration;
|
||||
import net.knarcraft.minigames.util.DropperArenaStorageHelper;
|
||||
import net.knarcraft.minigames.util.StringSanitizer;
|
||||
@ -15,8 +17,11 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static net.knarcraft.minigames.util.InputValidationHelper.isInvalid;
|
||||
|
||||
@ -70,6 +75,8 @@ public class DropperArena implements Arena {
|
||||
|
||||
private final DropperArenaHandler dropperArenaHandler;
|
||||
|
||||
private Map<RewardCondition, Set<Reward>> rewards = new HashMap<>();
|
||||
|
||||
private static final DropperConfiguration dropperConfiguration = MiniGames.getInstance().getDropperConfiguration();
|
||||
|
||||
/**
|
||||
@ -82,13 +89,14 @@ public class DropperArena implements Arena {
|
||||
* @param playerVerticalVelocity <p>The velocity to use for players' vertical velocity</p>
|
||||
* @param playerHorizontalVelocity <p>The velocity to use for players' horizontal velocity (-1 to 1)</p>
|
||||
* @param winBlockType <p>The material of the block players have to hit to win this dropper arena</p>
|
||||
* @param rewards <p>The rewards given by this arena</p>
|
||||
* @param dropperArenaData <p>The arena data keeping track of which players have done what in this arena</p>
|
||||
* @param arenaHandler <p>The arena handler used for saving any changes</p>
|
||||
*/
|
||||
public DropperArena(@NotNull UUID arenaId, @NotNull String arenaName, @NotNull Location spawnLocation,
|
||||
@Nullable Location exitLocation, double playerVerticalVelocity, float playerHorizontalVelocity,
|
||||
@NotNull Material winBlockType, @NotNull DropperArenaData dropperArenaData,
|
||||
@NotNull DropperArenaHandler arenaHandler) {
|
||||
@NotNull Material winBlockType, @NotNull Map<RewardCondition, Set<Reward>> rewards,
|
||||
@NotNull DropperArenaData dropperArenaData, @NotNull DropperArenaHandler arenaHandler) {
|
||||
this.arenaId = arenaId;
|
||||
this.arenaName = arenaName;
|
||||
this.spawnLocation = spawnLocation;
|
||||
@ -98,6 +106,7 @@ public class DropperArena implements Arena {
|
||||
this.winBlockType = winBlockType;
|
||||
this.dropperArenaData = dropperArenaData;
|
||||
this.dropperArenaHandler = arenaHandler;
|
||||
this.rewards = rewards;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -155,6 +164,28 @@ public class DropperArena implements Arena {
|
||||
return this.exitLocation != null ? this.exitLocation.clone() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addReward(@NotNull RewardCondition rewardCondition, @NotNull Reward reward) {
|
||||
this.rewards.computeIfAbsent(rewardCondition, k -> new HashSet<>());
|
||||
this.rewards.get(rewardCondition).add(reward);
|
||||
this.saveArena();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearRewards(@NotNull RewardCondition rewardCondition) {
|
||||
this.rewards.remove(rewardCondition);
|
||||
this.saveArena();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Set<Reward> getRewards(RewardCondition rewardCondition) {
|
||||
if (this.rewards.containsKey(rewardCondition) && this.rewards.get(rewardCondition) != null) {
|
||||
return this.rewards.get(rewardCondition);
|
||||
} else {
|
||||
return new HashSet<>();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the vertical velocity for players in this arena
|
||||
*
|
||||
@ -206,7 +237,7 @@ public class DropperArena implements Arena {
|
||||
try {
|
||||
DropperArenaStorageHelper.saveDropperArenaData(getData());
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
} catch (IOException exception) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -237,7 +268,7 @@ public class DropperArena implements Arena {
|
||||
return false;
|
||||
} else {
|
||||
this.spawnLocation = newLocation;
|
||||
dropperArenaHandler.saveArenas();
|
||||
this.saveArena();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -253,7 +284,7 @@ public class DropperArena implements Arena {
|
||||
return false;
|
||||
} else {
|
||||
this.exitLocation = newLocation;
|
||||
dropperArenaHandler.saveArenas();
|
||||
this.saveArena();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -269,8 +300,8 @@ public class DropperArena implements Arena {
|
||||
String oldName = this.getArenaNameSanitized();
|
||||
this.arenaName = arenaName;
|
||||
// Update the arena lookup map to make sure the new name can be used immediately
|
||||
dropperArenaHandler.updateLookupName(oldName, this.getArenaNameSanitized());
|
||||
dropperArenaHandler.saveArenas();
|
||||
this.dropperArenaHandler.updateLookupName(oldName, this.getArenaNameSanitized());
|
||||
this.saveArena();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@ -290,7 +321,7 @@ public class DropperArena implements Arena {
|
||||
return false;
|
||||
} else {
|
||||
this.winBlockType = material;
|
||||
dropperArenaHandler.saveArenas();
|
||||
this.saveArena();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -308,7 +339,7 @@ public class DropperArena implements Arena {
|
||||
return false;
|
||||
} else {
|
||||
this.playerHorizontalVelocity = horizontalVelocity;
|
||||
dropperArenaHandler.saveArenas();
|
||||
this.saveArena();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -324,11 +355,24 @@ public class DropperArena implements Arena {
|
||||
return false;
|
||||
} else {
|
||||
this.playerVerticalVelocity = verticalVelocity;
|
||||
dropperArenaHandler.saveArenas();
|
||||
this.saveArena();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves this arena to disk
|
||||
*/
|
||||
public void saveArena() {
|
||||
try {
|
||||
DropperArenaStorageHelper.saveSingleDropperArena(this);
|
||||
} catch (IOException exception) {
|
||||
MiniGames.log(Level.SEVERE, "Unable to save arena! " +
|
||||
"Data loss can occur!");
|
||||
MiniGames.log(Level.SEVERE, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof DropperArena otherArena)) {
|
||||
|
@ -34,11 +34,11 @@ public enum DropperArenaGameMode implements ConfigurationSerializable, ArenaGame
|
||||
* @param gameMode <p>The game-mode string to match</p>
|
||||
* @return <p>The specified arena game-mode</p>
|
||||
*/
|
||||
public static @NotNull DropperArenaGameMode matchGamemode(@NotNull String gameMode) {
|
||||
public static @NotNull DropperArenaGameMode matchGameMode(@NotNull String gameMode) {
|
||||
String sanitized = gameMode.trim().toLowerCase();
|
||||
if (sanitized.matches("(invert(ed)?|inverse)")) {
|
||||
return DropperArenaGameMode.INVERTED;
|
||||
} else if (sanitized.matches("rand(om)?")) {
|
||||
} else if (sanitized.matches("rand(om)?_?(inverted)?")) {
|
||||
return DropperArenaGameMode.RANDOM_INVERTED;
|
||||
} else {
|
||||
return DropperArenaGameMode.DEFAULT;
|
||||
|
@ -3,7 +3,7 @@ package net.knarcraft.minigames.arena.dropper;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.ArenaHandler;
|
||||
import net.knarcraft.minigames.arena.ArenaPlayerRegistry;
|
||||
import net.knarcraft.minigames.config.Message;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import net.knarcraft.minigames.util.DropperArenaStorageHelper;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -32,9 +32,10 @@ public class DropperArenaHandler extends ArenaHandler<DropperArena, DropperArena
|
||||
public void saveGroups() {
|
||||
try {
|
||||
DropperArenaStorageHelper.saveDropperArenaGroups(new HashSet<>(this.arenaGroups.values()));
|
||||
} catch (IOException e) {
|
||||
MiniGames.log(Level.SEVERE, Message.ERROR_CANNOT_SAVE_ARENA_GROUPS.getMessage());
|
||||
MiniGames.log(Level.SEVERE, e.getMessage());
|
||||
} catch (IOException exception) {
|
||||
MiniGames.log(Level.SEVERE, MiniGames.getInstance().getTranslator().getTranslatedMessage(
|
||||
MiniGameMessage.ERROR_CANNOT_SAVE_ARENA_GROUPS));
|
||||
MiniGames.log(Level.SEVERE, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,10 +55,10 @@ public class DropperArenaHandler extends ArenaHandler<DropperArena, DropperArena
|
||||
public void saveArenas() {
|
||||
try {
|
||||
DropperArenaStorageHelper.saveDropperArenas(this.arenas);
|
||||
} catch (IOException e) {
|
||||
} catch (IOException exception) {
|
||||
MiniGames.log(Level.SEVERE, "Unable to save current arenas! " +
|
||||
"Data loss can occur!");
|
||||
MiniGames.log(Level.SEVERE, e.getMessage());
|
||||
MiniGames.log(Level.SEVERE, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,15 @@
|
||||
package net.knarcraft.minigames.arena.dropper;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.AbstractArenaSession;
|
||||
import net.knarcraft.minigames.arena.PlayerEntryState;
|
||||
import net.knarcraft.minigames.config.DropperConfiguration;
|
||||
import net.knarcraft.minigames.config.Message;
|
||||
import net.knarcraft.minigames.arena.reward.RewardCondition;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import net.knarcraft.minigames.gui.ArenaGUI;
|
||||
import net.knarcraft.minigames.gui.DropperGUI;
|
||||
import net.knarcraft.minigames.util.PlayerTeleporter;
|
||||
import net.knarcraft.minigames.util.RewardHelper;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@ -19,6 +23,7 @@ public class DropperArenaSession extends AbstractArenaSession {
|
||||
private final @NotNull DropperArena arena;
|
||||
private final @NotNull Player player;
|
||||
private final @NotNull DropperArenaGameMode gameMode;
|
||||
private boolean startedMoving = false;
|
||||
|
||||
/**
|
||||
* Instantiates a new dropper arena session
|
||||
@ -34,14 +39,26 @@ public class DropperArenaSession extends AbstractArenaSession {
|
||||
this.player = player;
|
||||
this.gameMode = gameMode;
|
||||
|
||||
DropperConfiguration configuration = MiniGames.getInstance().getDropperConfiguration();
|
||||
boolean makeInvisible = configuration.makePlayersInvisible();
|
||||
boolean disableCollision = configuration.disableHitCollision();
|
||||
this.entryState = new DropperPlayerEntryState(player, gameMode, makeInvisible, disableCollision,
|
||||
dropperArena.getPlayerHorizontalVelocity());
|
||||
this.entryState = new DropperPlayerEntryState(player, gameMode, dropperArena.getPlayerHorizontalVelocity());
|
||||
this.entryState.setArenaState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks that this arena's player has started moving
|
||||
*/
|
||||
public void setStartedMoving() {
|
||||
this.startedMoving = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether the player of this session has started moving in the arena
|
||||
*
|
||||
* @return <p>True if the player has started moving</p>
|
||||
*/
|
||||
public boolean getStartedMoving() {
|
||||
return this.startedMoving;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the player playing in this session
|
||||
*
|
||||
@ -78,11 +95,15 @@ public class DropperArenaSession extends AbstractArenaSession {
|
||||
registerRecord();
|
||||
}
|
||||
|
||||
StringFormatter stringFormatter = MiniGames.getInstance().getStringFormatter();
|
||||
|
||||
// Mark the arena as cleared
|
||||
if (this.arena.getData().setCompleted(this.gameMode, this.player)) {
|
||||
this.player.sendMessage(Message.SUCCESS_ARENA_FIRST_CLEAR.getMessage());
|
||||
stringFormatter.displaySuccessMessage(this.player, MiniGameMessage.SUCCESS_ARENA_FIRST_CLEAR);
|
||||
RewardHelper.grantRewards(this.player, this.arena.getRewards(RewardCondition.FIRST_WIN));
|
||||
}
|
||||
this.player.sendMessage(Message.SUCCESS_ARENA_WIN.getMessage());
|
||||
stringFormatter.displaySuccessMessage(this.player, MiniGameMessage.SUCCESS_ARENA_WIN);
|
||||
RewardHelper.grantRewards(this.player, this.arena.getRewards(RewardCondition.WIN));
|
||||
|
||||
// Teleport the player out of the arena
|
||||
teleportToExit(false);
|
||||
@ -101,6 +122,17 @@ public class DropperArenaSession extends AbstractArenaSession {
|
||||
return this.arena;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ArenaGUI getGUI() {
|
||||
return new DropperGUI(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
this.startedMoving = false;
|
||||
super.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeSession() {
|
||||
// Remove this session for game sessions to stop listeners from fiddling more with the player
|
||||
|
@ -43,9 +43,14 @@ public enum DropperArenaStorageKey {
|
||||
WIN_BLOCK_TYPE("winBlockType"),
|
||||
|
||||
/**
|
||||
* The hey for this arena's data
|
||||
* The key for this arena's data
|
||||
*/
|
||||
DATA("arenaData"),
|
||||
|
||||
/**
|
||||
* The key for this arena's rewards
|
||||
*/
|
||||
REWARDS("rewards"),
|
||||
;
|
||||
|
||||
private final @NotNull String key;
|
||||
|
@ -16,7 +16,6 @@ import java.util.UUID;
|
||||
public class DropperPlayerEntryState extends AbstractPlayerEntryState {
|
||||
|
||||
private final float originalFlySpeed;
|
||||
private final boolean disableHitCollision;
|
||||
private final float horizontalVelocity;
|
||||
private final DropperArenaGameMode arenaGameMode;
|
||||
|
||||
@ -26,11 +25,10 @@ public class DropperPlayerEntryState extends AbstractPlayerEntryState {
|
||||
* @param player <p>The player whose state should be stored</p>
|
||||
*/
|
||||
public DropperPlayerEntryState(@NotNull Player player, @NotNull DropperArenaGameMode arenaGameMode,
|
||||
boolean makePlayerInvisible, boolean disableHitCollision, float horizontalVelocity) {
|
||||
super(player, makePlayerInvisible);
|
||||
float horizontalVelocity) {
|
||||
super(player);
|
||||
this.originalFlySpeed = player.getFlySpeed();
|
||||
this.arenaGameMode = arenaGameMode;
|
||||
this.disableHitCollision = disableHitCollision;
|
||||
this.horizontalVelocity = horizontalVelocity;
|
||||
}
|
||||
|
||||
@ -38,31 +36,30 @@ public class DropperPlayerEntryState extends AbstractPlayerEntryState {
|
||||
* Instantiates a new parkour player entry state
|
||||
*
|
||||
* @param playerId <p>The id of the player whose state this should keep track of</p>
|
||||
* @param makePlayerInvisible <p>Whether players should be made invisible while in the arena</p>
|
||||
* @param entryLocation <p>The location the player entered from</p>
|
||||
* @param originalIsFlying <p>Whether the player was flying before entering the arena</p>
|
||||
* @param originalGameMode <p>The game-mode of the player before entering the arena</p>
|
||||
* @param originalAllowFlight <p>Whether the player was allowed flight before entering the arena</p>
|
||||
* @param originalInvulnerable <p>Whether the player was invulnerable before entering the arena</p>
|
||||
* @param originalIsSwimming <p>Whether the player was swimming before entering the arena</p>
|
||||
* @param originalFlySpeed <p>The fly-speed of the player before entering the arena</p>
|
||||
* @param horizontalVelocity <p>The horizontal velocity of the player before entering the arena</p>
|
||||
* @param originalCollideAble <p>Whether the player was collide-able before entering the arena</p>
|
||||
*/
|
||||
public DropperPlayerEntryState(@NotNull UUID playerId, boolean makePlayerInvisible, Location entryLocation,
|
||||
public DropperPlayerEntryState(@NotNull UUID playerId, Location entryLocation,
|
||||
boolean originalIsFlying, GameMode originalGameMode, boolean originalAllowFlight,
|
||||
boolean originalInvulnerable, boolean originalIsSwimming,
|
||||
boolean originalCollideAble, float originalFlySpeed, boolean disableHitCollision,
|
||||
float horizontalVelocity, DropperArenaGameMode arenaGameMode) {
|
||||
super(playerId, makePlayerInvisible, entryLocation, originalIsFlying, originalGameMode, originalAllowFlight,
|
||||
float originalFlySpeed, float horizontalVelocity,
|
||||
DropperArenaGameMode arenaGameMode, boolean originalCollideAble) {
|
||||
super(playerId, entryLocation, originalIsFlying, originalGameMode, originalAllowFlight,
|
||||
originalInvulnerable, originalIsSwimming, originalCollideAble);
|
||||
this.originalFlySpeed = originalFlySpeed;
|
||||
this.disableHitCollision = disableHitCollision;
|
||||
this.horizontalVelocity = horizontalVelocity;
|
||||
this.arenaGameMode = arenaGameMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setArenaState() {
|
||||
super.setArenaState();
|
||||
Player player = getPlayer();
|
||||
if (player == null) {
|
||||
return;
|
||||
@ -71,9 +68,6 @@ public class DropperPlayerEntryState extends AbstractPlayerEntryState {
|
||||
player.setFlying(true);
|
||||
player.setGameMode(GameMode.ADVENTURE);
|
||||
player.setSwimming(false);
|
||||
if (this.disableHitCollision) {
|
||||
player.setCollidable(false);
|
||||
}
|
||||
|
||||
// If playing on the inverted game-mode, negate the horizontal velocity to swap the controls
|
||||
if (this.arenaGameMode == DropperArenaGameMode.INVERTED) {
|
||||
@ -104,7 +98,6 @@ public class DropperPlayerEntryState extends AbstractPlayerEntryState {
|
||||
public Map<String, Object> serialize() {
|
||||
Map<String, Object> data = super.serialize();
|
||||
data.put("originalFlySpeed", this.originalFlySpeed);
|
||||
data.put("disableHitCollision", this.disableHitCollision);
|
||||
data.put("horizontalVelocity", this.horizontalVelocity);
|
||||
data.put("arenaGameMode", this.arenaGameMode);
|
||||
return data;
|
||||
@ -118,22 +111,20 @@ public class DropperPlayerEntryState extends AbstractPlayerEntryState {
|
||||
@SuppressWarnings("unused")
|
||||
public static DropperPlayerEntryState deserialize(Map<String, Object> data) {
|
||||
UUID playerId = ((SerializableUUID) data.get("playerId")).getRawValue();
|
||||
boolean makePlayerInvisible = (boolean) data.get("makePlayerInvisible");
|
||||
Location entryLocation = (Location) data.get("entryLocation");
|
||||
boolean originalIsFlying = (boolean) data.get("originalIsFlying");
|
||||
boolean originalIsFlying = getBoolean(data, "originalIsFlying");
|
||||
GameMode originalGameMode = GameMode.valueOf((String) data.get("originalGameMode"));
|
||||
boolean originalAllowFlight = (boolean) data.get("originalAllowFlight");
|
||||
boolean originalInvulnerable = (boolean) data.get("originalInvulnerable");
|
||||
boolean originalIsSwimming = (boolean) data.get("originalIsSwimming");
|
||||
boolean originalCollideAble = (boolean) data.get("originalCollideAble");
|
||||
boolean originalAllowFlight = getBoolean(data, "originalAllowFlight");
|
||||
boolean originalInvulnerable = getBoolean(data, "originalInvulnerable");
|
||||
boolean originalIsSwimming = getBoolean(data, "originalIsSwimming");
|
||||
float originalFlySpeed = ((Number) data.get("originalFlySpeed")).floatValue();
|
||||
boolean disableHitCollision = (boolean) data.get("disableHitCollision");
|
||||
float horizontalVelocity = ((Number) data.get("horizontalVelocity")).floatValue();
|
||||
DropperArenaGameMode arenaGameMode = (DropperArenaGameMode) data.get("arenaGameMode");
|
||||
boolean originalCollideAble = getBoolean(data, "originalCollideAble");
|
||||
|
||||
return new DropperPlayerEntryState(playerId, makePlayerInvisible, entryLocation, originalIsFlying,
|
||||
originalGameMode, originalAllowFlight, originalInvulnerable, originalIsSwimming, originalCollideAble,
|
||||
originalFlySpeed, disableHitCollision, horizontalVelocity, arenaGameMode);
|
||||
return new DropperPlayerEntryState(playerId, entryLocation, originalIsFlying,
|
||||
originalGameMode, originalAllowFlight, originalInvulnerable, originalIsSwimming,
|
||||
originalFlySpeed, horizontalVelocity, arenaGameMode, originalCollideAble);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
package net.knarcraft.minigames.arena.parkour;
|
||||
|
||||
import net.knarcraft.knarlib.util.MaterialHelper;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.Arena;
|
||||
import net.knarcraft.minigames.arena.ArenaGameMode;
|
||||
import net.knarcraft.minigames.arena.ArenaRecordsRegistry;
|
||||
import net.knarcraft.minigames.util.MaterialHelper;
|
||||
import net.knarcraft.minigames.arena.reward.Reward;
|
||||
import net.knarcraft.minigames.arena.reward.RewardCondition;
|
||||
import net.knarcraft.minigames.util.ParkourArenaStorageHelper;
|
||||
import net.knarcraft.minigames.util.StringSanitizer;
|
||||
import org.bukkit.Location;
|
||||
@ -21,6 +23,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import static net.knarcraft.minigames.util.InputValidationHelper.isInvalid;
|
||||
|
||||
@ -70,6 +73,16 @@ public class ParkourArena implements Arena {
|
||||
*/
|
||||
private @Nullable Set<Material> killPlaneBlocks;
|
||||
|
||||
/**
|
||||
* The names of the block types serving as obstacles for this arena
|
||||
*/
|
||||
private @Nullable Set<String> obstacleBlockNames;
|
||||
|
||||
/**
|
||||
* The block types serving as obstacles for this arena
|
||||
*/
|
||||
private @Nullable Set<Material> obstacleBlocks;
|
||||
|
||||
/**
|
||||
* The checkpoints for this arena. Entering a checkpoint overrides the player's spawn location.
|
||||
*/
|
||||
@ -82,21 +95,29 @@ public class ParkourArena implements Arena {
|
||||
|
||||
private final @NotNull ParkourArenaHandler parkourArenaHandler;
|
||||
|
||||
private Map<RewardCondition, Set<Reward>> rewards = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Instantiates a new parkour arena
|
||||
*
|
||||
* @param arenaId <p>The id of the arena</p>
|
||||
* @param arenaName <p>The name of the arena</p>
|
||||
* @param spawnLocation <p>The location players spawn in when entering the arena</p>
|
||||
* @param exitLocation <p>The location the players are teleported to when exiting the arena, or null</p>
|
||||
* @param winBlockType <p>The material of the block players have to hit to win this parkour arena</p>
|
||||
* @param winLocation <p>The location a player has to reach to win this arena</p>
|
||||
* @param parkourArenaData <p>The arena data keeping track of which players have done what in this arena</p>
|
||||
* @param arenaHandler <p>The arena handler used for saving any changes</p>
|
||||
* @param arenaId <p>The id of the arena</p>
|
||||
* @param arenaName <p>The name of the arena</p>
|
||||
* @param spawnLocation <p>The location players spawn in when entering the arena</p>
|
||||
* @param exitLocation <p>The location the players are teleported to when exiting the arena, or null</p>
|
||||
* @param winBlockType <p>The material of the block players have to hit to win this parkour arena</p>
|
||||
* @param winLocation <p>The location a player has to reach to win this arena</p>
|
||||
* @param killPlaneBlockNames <p>The names of the types of blocks that trigger a loss when stepped on</p>
|
||||
* @param obstacleBlockNames <p>The names of the types of blocks that trigger a loss when touched</p>
|
||||
* @param checkpoints <p>The checkpoints set for this arena</p>
|
||||
* @param rewards <p>The rewards given by this arena</p>
|
||||
* @param parkourArenaData <p>The arena data keeping track of which players have done what in this arena</p>
|
||||
* @param arenaHandler <p>The arena handler used for saving any changes</p>
|
||||
*/
|
||||
public ParkourArena(@NotNull UUID arenaId, @NotNull String arenaName, @NotNull Location spawnLocation,
|
||||
@Nullable Location exitLocation, @NotNull Material winBlockType, @Nullable Location winLocation,
|
||||
@Nullable Set<String> killPlaneBlockNames, @NotNull List<Location> checkpoints,
|
||||
@Nullable Set<String> killPlaneBlockNames, @Nullable Set<String> obstacleBlockNames,
|
||||
@NotNull List<Location> checkpoints,
|
||||
@NotNull Map<RewardCondition, Set<Reward>> rewards,
|
||||
@NotNull ParkourArenaData parkourArenaData, @NotNull ParkourArenaHandler arenaHandler) {
|
||||
this.arenaId = arenaId;
|
||||
this.arenaName = arenaName;
|
||||
@ -106,10 +127,14 @@ public class ParkourArena implements Arena {
|
||||
this.winLocation = winLocation;
|
||||
this.killPlaneBlockNames = killPlaneBlockNames;
|
||||
this.killPlaneBlocks = this.killPlaneBlockNames == null ? null : MaterialHelper.loadMaterialList(
|
||||
new ArrayList<>(killPlaneBlockNames));
|
||||
new ArrayList<>(killPlaneBlockNames), "+", MiniGames.getInstance().getLogger());
|
||||
this.obstacleBlockNames = obstacleBlockNames;
|
||||
this.obstacleBlocks = this.obstacleBlockNames == null ? null : MaterialHelper.loadMaterialList(
|
||||
new ArrayList<>(obstacleBlockNames), "+", MiniGames.getInstance().getLogger());
|
||||
this.checkpoints = checkpoints;
|
||||
this.parkourArenaData = parkourArenaData;
|
||||
this.parkourArenaHandler = arenaHandler;
|
||||
this.rewards = rewards;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -138,6 +163,7 @@ public class ParkourArena implements Arena {
|
||||
this.parkourArenaData = new ParkourArenaData(this.arenaId, recordRegistries, new HashMap<>());
|
||||
this.winBlockType = Material.EMERALD_BLOCK;
|
||||
this.killPlaneBlocks = null;
|
||||
this.obstacleBlocks = null;
|
||||
this.checkpoints = new ArrayList<>();
|
||||
this.parkourArenaHandler = arenaHandler;
|
||||
}
|
||||
@ -167,6 +193,28 @@ public class ParkourArena implements Arena {
|
||||
return this.exitLocation;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addReward(@NotNull RewardCondition rewardCondition, @NotNull Reward reward) {
|
||||
this.rewards.computeIfAbsent(rewardCondition, k -> new HashSet<>());
|
||||
this.rewards.get(rewardCondition).add(reward);
|
||||
this.saveArena();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearRewards(@NotNull RewardCondition rewardCondition) {
|
||||
this.rewards.remove(rewardCondition);
|
||||
this.saveArena();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Set<Reward> getRewards(RewardCondition rewardCondition) {
|
||||
if (this.rewards.containsKey(rewardCondition)) {
|
||||
return this.rewards.get(rewardCondition);
|
||||
} else {
|
||||
return new HashSet<>();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type of block a player has to hit to win this arena
|
||||
*
|
||||
@ -209,6 +257,28 @@ public class ParkourArena implements Arena {
|
||||
return this.killPlaneBlockNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the block types used for this parkour arena's obstacle blocks
|
||||
*
|
||||
* @return <p>The types of blocks used as obstacles</p>
|
||||
*/
|
||||
public @NotNull Set<Material> getObstacleBlocks() {
|
||||
if (this.obstacleBlocks != null) {
|
||||
return new HashSet<>(this.obstacleBlocks);
|
||||
} else {
|
||||
return MiniGames.getInstance().getParkourConfiguration().getObstacleBlocks();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the names of the blocks used as this arena's obstacle blocks
|
||||
*
|
||||
* @return <p>The names of the blocks used as this arena's obstacle blocks</p>
|
||||
*/
|
||||
public @Nullable Set<String> getObstacleBlockNames() {
|
||||
return this.obstacleBlockNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all checkpoint locations for this arena
|
||||
*
|
||||
@ -222,6 +292,15 @@ public class ParkourArena implements Arena {
|
||||
return copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether this arena has no checkpoints
|
||||
*
|
||||
* @return <p>True if this arena has no checkpoints</p>
|
||||
*/
|
||||
public boolean hasNoCheckpoints() {
|
||||
return this.checkpoints.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this arena's sanitized name
|
||||
*
|
||||
@ -241,7 +320,7 @@ public class ParkourArena implements Arena {
|
||||
try {
|
||||
ParkourArenaStorageHelper.saveParkourArenaData(getData());
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
} catch (IOException exception) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -254,7 +333,7 @@ public class ParkourArena implements Arena {
|
||||
|
||||
@Override
|
||||
public boolean willCauseLoss(Block block) {
|
||||
return this.getKillPlaneBlocks().contains(block.getType());
|
||||
return this.getKillPlaneBlocks().contains(block.getType()) || this.getObstacleBlocks().contains(block.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -274,7 +353,7 @@ public class ParkourArena implements Arena {
|
||||
return false;
|
||||
} else {
|
||||
this.spawnLocation = newLocation;
|
||||
this.parkourArenaHandler.saveArenas();
|
||||
this.saveArena();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -290,7 +369,7 @@ public class ParkourArena implements Arena {
|
||||
return false;
|
||||
} else {
|
||||
this.exitLocation = newLocation;
|
||||
this.parkourArenaHandler.saveArenas();
|
||||
this.saveArena();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -307,7 +386,7 @@ public class ParkourArena implements Arena {
|
||||
this.arenaName = arenaName;
|
||||
// Update the arena lookup map to make sure the new name can be used immediately
|
||||
this.parkourArenaHandler.updateLookupName(oldName, this.getArenaNameSanitized());
|
||||
this.parkourArenaHandler.saveArenas();
|
||||
this.saveArena();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@ -327,7 +406,7 @@ public class ParkourArena implements Arena {
|
||||
return false;
|
||||
} else {
|
||||
this.winBlockType = material;
|
||||
this.parkourArenaHandler.saveArenas();
|
||||
this.saveArena();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -343,7 +422,7 @@ public class ParkourArena implements Arena {
|
||||
return false;
|
||||
} else {
|
||||
this.winLocation = newLocation.clone();
|
||||
this.parkourArenaHandler.saveArenas();
|
||||
this.saveArena();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -355,15 +434,40 @@ public class ParkourArena implements Arena {
|
||||
*/
|
||||
public boolean setKillPlaneBlocks(@NotNull Set<String> killPlaneBlockNames) {
|
||||
if (killPlaneBlockNames.isEmpty()) {
|
||||
this.killPlaneBlockNames = null;
|
||||
this.killPlaneBlocks = null;
|
||||
} else {
|
||||
Set<Material> parsed = MaterialHelper.loadMaterialList(new ArrayList<>(killPlaneBlockNames));
|
||||
Set<Material> parsed = MaterialHelper.loadMaterialList(new ArrayList<>(killPlaneBlockNames), "+",
|
||||
MiniGames.getInstance().getLogger());
|
||||
if (parsed.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
this.killPlaneBlockNames = killPlaneBlockNames;
|
||||
this.killPlaneBlocks = parsed;
|
||||
}
|
||||
this.parkourArenaHandler.saveArenas();
|
||||
this.saveArena();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type of blocks used as obstacle blocks
|
||||
*
|
||||
* @param obstacleBlockNames <p>The names of the obstacle blocks</p>
|
||||
*/
|
||||
public boolean setObstacleBlocks(@NotNull Set<String> obstacleBlockNames) {
|
||||
if (obstacleBlockNames.isEmpty()) {
|
||||
this.obstacleBlockNames = null;
|
||||
this.obstacleBlocks = null;
|
||||
} else {
|
||||
Set<Material> parsed = MaterialHelper.loadMaterialList(new ArrayList<>(obstacleBlockNames), "+",
|
||||
MiniGames.getInstance().getLogger());
|
||||
if (parsed.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
this.obstacleBlockNames = obstacleBlockNames;
|
||||
this.obstacleBlocks = parsed;
|
||||
}
|
||||
this.saveArena();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -379,7 +483,7 @@ public class ParkourArena implements Arena {
|
||||
}
|
||||
|
||||
this.checkpoints.add(checkpoint.clone());
|
||||
this.parkourArenaHandler.saveArenas();
|
||||
this.saveArena();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -394,10 +498,23 @@ public class ParkourArena implements Arena {
|
||||
}
|
||||
|
||||
this.checkpoints.clear();
|
||||
this.parkourArenaHandler.saveArenas();
|
||||
this.saveArena();
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves this arena to disk
|
||||
*/
|
||||
public void saveArena() {
|
||||
try {
|
||||
ParkourArenaStorageHelper.saveSingleParkourArena(this);
|
||||
} catch (IOException exception) {
|
||||
MiniGames.log(Level.SEVERE, "Unable to save arena! " +
|
||||
"Data loss can occur!");
|
||||
MiniGames.log(Level.SEVERE, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof ParkourArena otherArena)) {
|
||||
|
@ -62,6 +62,13 @@ public enum ParkourArenaEditableProperty {
|
||||
*/
|
||||
KILL_PLANE_BLOCKS("killPlaneBlocks", (arena) -> String.valueOf(arena.getKillPlaneBlockNames()),
|
||||
EditablePropertyType.MATERIAL_LIST),
|
||||
|
||||
/**
|
||||
* The blocks used as this arena's obstacle blocks
|
||||
*/
|
||||
OBSTACLE_BLOCKS("obstacleBlocks", (arena) -> String.valueOf(arena.getObstacleBlockNames()),
|
||||
EditablePropertyType.MATERIAL_LIST),
|
||||
|
||||
;
|
||||
|
||||
private final @NotNull String argumentString;
|
||||
|
@ -16,6 +16,11 @@ public enum ParkourArenaGameMode implements ConfigurationSerializable, ArenaGame
|
||||
* The default game-mode. Failing once throws the player out.
|
||||
*/
|
||||
DEFAULT,
|
||||
|
||||
/**
|
||||
* A hardcore game mode where no checkpoints are allowed
|
||||
*/
|
||||
HARDCORE,
|
||||
;
|
||||
|
||||
/**
|
||||
|
@ -3,7 +3,7 @@ package net.knarcraft.minigames.arena.parkour;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.ArenaHandler;
|
||||
import net.knarcraft.minigames.arena.ArenaPlayerRegistry;
|
||||
import net.knarcraft.minigames.config.Message;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import net.knarcraft.minigames.util.ParkourArenaStorageHelper;
|
||||
|
||||
import java.io.IOException;
|
||||
@ -32,9 +32,10 @@ public class ParkourArenaHandler extends ArenaHandler<ParkourArena, ParkourArena
|
||||
public void saveGroups() {
|
||||
try {
|
||||
ParkourArenaStorageHelper.saveParkourArenaGroups(new HashSet<>(this.arenaGroups.values()));
|
||||
} catch (IOException e) {
|
||||
MiniGames.log(Level.SEVERE, Message.ERROR_CANNOT_SAVE_ARENA_GROUPS.getMessage());
|
||||
MiniGames.log(Level.SEVERE, e.getMessage());
|
||||
} catch (IOException exception) {
|
||||
MiniGames.log(Level.SEVERE, MiniGames.getInstance().getTranslator().getTranslatedMessage(
|
||||
MiniGameMessage.ERROR_CANNOT_SAVE_ARENA_GROUPS));
|
||||
MiniGames.log(Level.SEVERE, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,10 +55,10 @@ public class ParkourArenaHandler extends ArenaHandler<ParkourArena, ParkourArena
|
||||
public void saveArenas() {
|
||||
try {
|
||||
ParkourArenaStorageHelper.saveParkourArenas(this.arenas);
|
||||
} catch (IOException e) {
|
||||
} catch (IOException exception) {
|
||||
MiniGames.log(Level.SEVERE, "Unable to save current arenas! " +
|
||||
"Data loss can occur!");
|
||||
MiniGames.log(Level.SEVERE, e.getMessage());
|
||||
MiniGames.log(Level.SEVERE, exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,15 @@
|
||||
package net.knarcraft.minigames.arena.parkour;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.AbstractArenaSession;
|
||||
import net.knarcraft.minigames.arena.PlayerEntryState;
|
||||
import net.knarcraft.minigames.config.Message;
|
||||
import net.knarcraft.minigames.config.ParkourConfiguration;
|
||||
import net.knarcraft.minigames.arena.reward.RewardCondition;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import net.knarcraft.minigames.gui.ArenaGUI;
|
||||
import net.knarcraft.minigames.gui.ParkourGUI;
|
||||
import net.knarcraft.minigames.util.PlayerTeleporter;
|
||||
import net.knarcraft.minigames.util.RewardHelper;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -37,12 +41,19 @@ public class ParkourArenaSession extends AbstractArenaSession {
|
||||
this.player = player;
|
||||
this.gameMode = gameMode;
|
||||
|
||||
ParkourConfiguration configuration = MiniGames.getInstance().getParkourConfiguration();
|
||||
boolean makeInvisible = configuration.makePlayersInvisible();
|
||||
this.entryState = new ParkourPlayerEntryState(player, makeInvisible);
|
||||
this.entryState = new ParkourPlayerEntryState(player);
|
||||
this.entryState.setArenaState();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the game-mode the player is playing in this session
|
||||
*
|
||||
* @return <p>The game-mode for this session</p>
|
||||
*/
|
||||
public @NotNull ParkourArenaGameMode getGameMode() {
|
||||
return this.gameMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the checkpoint this session's player has reached
|
||||
*
|
||||
@ -79,11 +90,15 @@ public class ParkourArenaSession extends AbstractArenaSession {
|
||||
registerRecord();
|
||||
}
|
||||
|
||||
StringFormatter stringFormatter = MiniGames.getInstance().getStringFormatter();
|
||||
|
||||
// Mark the arena as cleared
|
||||
if (this.arena.getData().setCompleted(this.gameMode, this.player)) {
|
||||
this.player.sendMessage(Message.SUCCESS_ARENA_FIRST_CLEAR.getMessage());
|
||||
stringFormatter.displaySuccessMessage(this.player, MiniGameMessage.SUCCESS_ARENA_FIRST_CLEAR);
|
||||
RewardHelper.grantRewards(this.player, this.arena.getRewards(RewardCondition.FIRST_WIN));
|
||||
}
|
||||
this.player.sendMessage(Message.SUCCESS_ARENA_WIN.getMessage());
|
||||
stringFormatter.displaySuccessMessage(this.player, MiniGameMessage.SUCCESS_ARENA_WIN);
|
||||
RewardHelper.grantRewards(this.player, this.arena.getRewards(RewardCondition.WIN));
|
||||
|
||||
// Teleport the player out of the arena
|
||||
teleportToExit(false);
|
||||
@ -103,6 +118,17 @@ public class ParkourArenaSession extends AbstractArenaSession {
|
||||
return this.arena;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ArenaGUI getGUI() {
|
||||
return new ParkourGUI(player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
this.reachedCheckpoint = null;
|
||||
super.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeSession() {
|
||||
// Remove this session for game sessions to stop listeners from fiddling more with the player
|
||||
@ -118,6 +144,7 @@ public class ParkourArenaSession extends AbstractArenaSession {
|
||||
protected String getGameModeString() {
|
||||
return switch (this.gameMode) {
|
||||
case DEFAULT -> "default";
|
||||
case HARDCORE -> "hardcore";
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,11 @@ public enum ParkourArenaStorageKey {
|
||||
*/
|
||||
KILL_PLANE_BLOCKS("killPlaneBlocks"),
|
||||
|
||||
/**
|
||||
* The key for this arena's obstacle blocks (overrides the config)
|
||||
*/
|
||||
OBSTACLE_BLOCKS("obstacleBlocks"),
|
||||
|
||||
/**
|
||||
* The key for this arena's checkpoint locations
|
||||
*/
|
||||
@ -51,6 +56,11 @@ public enum ParkourArenaStorageKey {
|
||||
* The hey for this arena's data
|
||||
*/
|
||||
DATA("arenaData"),
|
||||
|
||||
/**
|
||||
* The key for this arena's rewards
|
||||
*/
|
||||
REWARDS("rewards"),
|
||||
;
|
||||
|
||||
private final @NotNull String key;
|
||||
|
@ -20,15 +20,14 @@ public class ParkourPlayerEntryState extends AbstractPlayerEntryState {
|
||||
*
|
||||
* @param player <p>The player whose state should be stored</p>
|
||||
*/
|
||||
public ParkourPlayerEntryState(@NotNull Player player, boolean makePlayerInvisible) {
|
||||
super(player, makePlayerInvisible);
|
||||
public ParkourPlayerEntryState(@NotNull Player player) {
|
||||
super(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new parkour player entry state
|
||||
*
|
||||
* @param playerId <p>The id of the player whose state this should keep track of</p>
|
||||
* @param makePlayerInvisible <p>Whether players should be made invisible while in the arena</p>
|
||||
* @param entryLocation <p>The location the player entered from</p>
|
||||
* @param originalIsFlying <p>Whether the player was flying before entering the arena</p>
|
||||
* @param originalGameMode <p>The game-mode of the player before entering the arena</p>
|
||||
@ -37,17 +36,15 @@ public class ParkourPlayerEntryState extends AbstractPlayerEntryState {
|
||||
* @param originalIsSwimming <p>Whether the player was swimming before entering the arena</p>
|
||||
* @param originalCollideAble <p>Whether the player was collide-able before entering the arena</p>
|
||||
*/
|
||||
public ParkourPlayerEntryState(@NotNull UUID playerId, boolean makePlayerInvisible, Location entryLocation,
|
||||
public ParkourPlayerEntryState(@NotNull UUID playerId, Location entryLocation,
|
||||
boolean originalIsFlying, GameMode originalGameMode, boolean originalAllowFlight,
|
||||
boolean originalInvulnerable, boolean originalIsSwimming,
|
||||
boolean originalCollideAble) {
|
||||
super(playerId, makePlayerInvisible, entryLocation, originalIsFlying, originalGameMode, originalAllowFlight,
|
||||
boolean originalInvulnerable, boolean originalIsSwimming, boolean originalCollideAble) {
|
||||
super(playerId, entryLocation, originalIsFlying, originalGameMode, originalAllowFlight,
|
||||
originalInvulnerable, originalIsSwimming, originalCollideAble);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setArenaState() {
|
||||
super.setArenaState();
|
||||
Player player = getPlayer();
|
||||
if (player == null) {
|
||||
return;
|
||||
@ -56,7 +53,6 @@ public class ParkourPlayerEntryState extends AbstractPlayerEntryState {
|
||||
player.setFlying(false);
|
||||
player.setGameMode(GameMode.ADVENTURE);
|
||||
player.setSwimming(false);
|
||||
player.setCollidable(false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -67,16 +63,15 @@ public class ParkourPlayerEntryState extends AbstractPlayerEntryState {
|
||||
@SuppressWarnings("unused")
|
||||
public static ParkourPlayerEntryState deserialize(Map<String, Object> data) {
|
||||
UUID playerId = ((SerializableUUID) data.get("playerId")).getRawValue();
|
||||
boolean makePlayerInvisible = (boolean) data.get("makePlayerInvisible");
|
||||
Location entryLocation = (Location) data.get("entryLocation");
|
||||
boolean originalIsFlying = (boolean) data.get("originalIsFlying");
|
||||
boolean originalIsFlying = getBoolean(data, "originalIsFlying");
|
||||
GameMode originalGameMode = GameMode.valueOf((String) data.get("originalGameMode"));
|
||||
boolean originalAllowFlight = (boolean) data.get("originalAllowFlight");
|
||||
boolean originalInvulnerable = (boolean) data.get("originalInvulnerable");
|
||||
boolean originalIsSwimming = (boolean) data.get("originalIsSwimming");
|
||||
boolean originalCollideAble = (boolean) data.get("originalCollideAble");
|
||||
boolean originalAllowFlight = getBoolean(data, "originalAllowFlight");
|
||||
boolean originalInvulnerable = getBoolean(data, "originalInvulnerable");
|
||||
boolean originalIsSwimming = getBoolean(data, "originalIsSwimming");
|
||||
boolean originalCollideAble = getBoolean(data, "originalCollideAble");
|
||||
|
||||
return new ParkourPlayerEntryState(playerId, makePlayerInvisible, entryLocation, originalIsFlying,
|
||||
return new ParkourPlayerEntryState(playerId, entryLocation, originalIsFlying,
|
||||
originalGameMode, originalAllowFlight, originalInvulnerable, originalIsSwimming, originalCollideAble);
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,13 @@ public abstract class ArenaRecord<K extends Comparable<K>> implements Comparable
|
||||
return record;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets this as a string that should be printed on a sign
|
||||
*
|
||||
* @return <p>This as a string</p>
|
||||
*/
|
||||
public abstract String getAsString();
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return other instanceof ArenaRecord<?> && userId.equals(((ArenaRecord<?>) other).userId);
|
||||
@ -70,7 +77,7 @@ public abstract class ArenaRecord<K extends Comparable<K>> implements Comparable
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return userId + ": " + record;
|
||||
return userId + ":" + record;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,6 +19,11 @@ public class IntegerRecord extends SummableArenaRecord<Integer> {
|
||||
super(userId, record);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAsString() {
|
||||
return String.valueOf(this.getRecord());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SummableArenaRecord<Integer> sum(Integer value) {
|
||||
return new IntegerRecord(this.getUserId(), this.getRecord() + value);
|
||||
|
@ -7,7 +7,7 @@ import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* A record storing a Long
|
||||
* A record storing a Long time
|
||||
*/
|
||||
public class LongRecord extends SummableArenaRecord<Long> {
|
||||
|
||||
@ -29,6 +29,22 @@ public class LongRecord extends SummableArenaRecord<Long> {
|
||||
return new LongRecord(this.getUserId(), this.getRecord() + value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAsString() {
|
||||
int seconds = (int) Math.floor(getRecord() / 1000.0);
|
||||
int minutes = 0;
|
||||
if (seconds > 60) {
|
||||
minutes = (int) Math.floor(seconds / 60.0);
|
||||
seconds = seconds % 60;
|
||||
}
|
||||
|
||||
if (minutes > 0) {
|
||||
return minutes + "m" + seconds + "s";
|
||||
} else {
|
||||
return seconds + "s";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes the saved arena record
|
||||
*
|
||||
|
@ -0,0 +1,69 @@
|
||||
package net.knarcraft.minigames.arena.reward;
|
||||
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A reward that executes a specified command when it's granted
|
||||
*/
|
||||
public class CommandReward implements Reward {
|
||||
|
||||
private final @NotNull String command;
|
||||
|
||||
/**
|
||||
* Instantiates a new command reward
|
||||
*
|
||||
* @param command <p>The command to execute when granting this reward</p>
|
||||
*/
|
||||
public CommandReward(@NotNull String command) {
|
||||
this.command = command;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean grant(@NotNull Player player) {
|
||||
return Bukkit.dispatchCommand(Bukkit.getServer().getConsoleSender(), replaceNamePlaceholder(player, command));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getGrantMessage() {
|
||||
return MiniGames.getInstance().getStringFormatter().replacePlaceholder(
|
||||
MiniGameMessage.SUCCESS_COMMAND_REWARDED, "{command}", command);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Map<String, Object> serialize() {
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("command", command);
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the name placeholder in the given input with the given player's name
|
||||
*
|
||||
* @param player <p>The player whose name should be used</p>
|
||||
* @param input <p>The input containing a name placeholder</p>
|
||||
* @return <p>The input with the placeholder replaced</p>
|
||||
*/
|
||||
private String replaceNamePlaceholder(@NotNull Player player, @NotNull String input) {
|
||||
return input.replaceAll("[<%(\\[{]player[_\\-]?(name)?[>%)\\]}]", player.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes the command reward defined in the given data
|
||||
*
|
||||
* @param data <p>The data to deserialize from</p>
|
||||
* @return <p>The deserialized data</p>
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public static CommandReward deserialize(Map<String, Object> data) {
|
||||
return new CommandReward((String) data.get("command"));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package net.knarcraft.minigames.arena.reward;
|
||||
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import net.knarcraft.minigames.manager.EconomyManager;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* A reward that gives an amount of currency when it's granted
|
||||
*/
|
||||
public class EconomyReward implements Reward {
|
||||
|
||||
private final double amount;
|
||||
|
||||
/**
|
||||
* Instantiates a new economy reward
|
||||
*
|
||||
* @param amount <p>The amount of currency granted</p>
|
||||
*/
|
||||
public EconomyReward(double amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean grant(@NotNull Player player) {
|
||||
if (!EconomyManager.isInitialized()) {
|
||||
MiniGames.log(Level.SEVERE, "An economy reward has been set, but no Vault-compatible economy" +
|
||||
" plugin has been initialized.");
|
||||
return false;
|
||||
}
|
||||
EconomyManager.deposit(player, amount);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getGrantMessage() {
|
||||
return MiniGames.getInstance().getStringFormatter().replacePlaceholder(MiniGameMessage.SUCCESS_ECONOMY_REWARDED,
|
||||
"{currency}", EconomyManager.format(amount));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Map<String, Object> serialize() {
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("amount", amount);
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes the economy reward defined in the given data
|
||||
*
|
||||
* @param data <p>The data to deserialize from</p>
|
||||
* @return <p>The deserialized data</p>
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public static EconomyReward deserialize(Map<String, Object> data) {
|
||||
return new EconomyReward((Double) data.get("amount"));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,108 @@
|
||||
package net.knarcraft.minigames.arena.reward;
|
||||
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A reward that gives an item stack when granted
|
||||
*/
|
||||
public class ItemReward implements Reward {
|
||||
|
||||
private final ItemStack item;
|
||||
|
||||
/**
|
||||
* Instantiates a new item reward
|
||||
*
|
||||
* @param item <p>The item rewarded</p>
|
||||
*/
|
||||
public ItemReward(@NotNull ItemStack item) {
|
||||
if (item.getAmount() > item.getMaxStackSize()) {
|
||||
throw new IllegalArgumentException("Item stack exceeds the maximum stack size");
|
||||
}
|
||||
this.item = item;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean grant(@NotNull Player player) {
|
||||
Inventory inventory = player.getInventory();
|
||||
if (canFitItem(inventory)) {
|
||||
inventory.addItem(item);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getGrantMessage() {
|
||||
return MiniGames.getInstance().getStringFormatter().replacePlaceholders(MiniGameMessage.SUCCESS_ITEM_REWARDED,
|
||||
new String[]{"{amount}", "{item}"}, new String[]{String.valueOf(item.getAmount()),
|
||||
item.getType().getKey().getKey().replace("_", " ")});
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Map<String, Object> serialize() {
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("item", item);
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes the item reward defined in the given data
|
||||
*
|
||||
* @param data <p>The data to deserialize from</p>
|
||||
* @return <p>The deserialized data</p>
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public static ItemReward deserialize(Map<String, Object> data) {
|
||||
return new ItemReward((ItemStack) data.get("item"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given inventory is able to fit this item reward
|
||||
*
|
||||
* @param inventory <p>The inventory to check</p>
|
||||
* @return <p>True if the inventory can fit the item</p>
|
||||
*/
|
||||
private boolean canFitItem(Inventory inventory) {
|
||||
// If a slot is available, there is no problem
|
||||
if (inventory.firstEmpty() != -1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the inventory doesn't contain the correct type of item, stacking is impossible
|
||||
if (!inventory.contains(item.getType())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the item stack can fit in the inventory if stacked with existing items
|
||||
int availableSlots = 0;
|
||||
for (ItemStack itemStack : inventory.getStorageContents()) {
|
||||
ItemMeta itemMeta = itemStack.getItemMeta();
|
||||
ItemMeta targetMeta = item.getItemMeta();
|
||||
// Skip items of a different type, or with metadata that would prevent stacking
|
||||
if (itemStack.getType() != item.getType() ||
|
||||
(itemMeta != null && targetMeta != null && !itemMeta.equals(targetMeta))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
availableSlots += itemStack.getMaxStackSize() - itemStack.getAmount();
|
||||
|
||||
if (availableSlots < item.getAmount()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
package net.knarcraft.minigames.arena.reward;
|
||||
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import net.knarcraft.minigames.manager.PermissionManager;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* A reward that grants a specified permission when granted
|
||||
*/
|
||||
public class PermissionReward implements Reward {
|
||||
|
||||
private final @NotNull String permission;
|
||||
private final @Nullable World world;
|
||||
|
||||
/**
|
||||
* Instantiates a new permission reward
|
||||
*
|
||||
* @param world <p>The world to grant the permission for, or null</p>
|
||||
* @param permission <p>The permission to grant</p>
|
||||
*/
|
||||
public PermissionReward(@Nullable World world, @NotNull String permission) {
|
||||
this.world = world;
|
||||
this.permission = permission;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean grant(@NotNull Player player) {
|
||||
if (!PermissionManager.isInitialized()) {
|
||||
MiniGames.log(Level.SEVERE, "A permission reward has been set, but no Vault-compatible permission" +
|
||||
" plugin has been initialized.");
|
||||
return false;
|
||||
}
|
||||
if (PermissionManager.hasPermission(player, this.permission, this.world != null ? this.world.getName() : null)) {
|
||||
return false;
|
||||
} else {
|
||||
PermissionManager.addPermission(player, this.permission, this.world);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getGrantMessage() {
|
||||
if (world == null) {
|
||||
return MiniGames.getInstance().getStringFormatter().replacePlaceholder(
|
||||
MiniGameMessage.SUCCESS_PERMISSION_REWARDED, "{permission}", permission);
|
||||
} else {
|
||||
return MiniGames.getInstance().getStringFormatter().replacePlaceholders(
|
||||
MiniGameMessage.SUCCESS_PERMISSION_REWARDED_WORLD, new String[]{"{permission}", "{world}"},
|
||||
new String[]{permission, world.getName()});
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Map<String, Object> serialize() {
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
if (world != null) {
|
||||
data.put("world", world);
|
||||
}
|
||||
data.put("permission", permission);
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes the permission reward defined in the given data
|
||||
*
|
||||
* @param data <p>The data to deserialize from</p>
|
||||
* @return <p>The deserialized data</p>
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public static PermissionReward deserialize(Map<String, Object> data) {
|
||||
World world = (World) data.getOrDefault("world", null);
|
||||
String permission = (String) data.get("permission");
|
||||
return new PermissionReward(world, permission);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package net.knarcraft.minigames.arena.reward;
|
||||
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A reward a player can be awarded
|
||||
*/
|
||||
public interface Reward extends ConfigurationSerializable {
|
||||
|
||||
/**
|
||||
* Grants this reward to the given player
|
||||
*
|
||||
* @param player <p>The player this reward should be granted to</p>
|
||||
* @return <p>True if the item was granted. False if not possible.</p>
|
||||
*/
|
||||
boolean grant(@NotNull Player player);
|
||||
|
||||
/**
|
||||
* Gets the message to display to a user when granting this reward
|
||||
*
|
||||
* @return <p>The message to display when this reward is granted</p>
|
||||
*/
|
||||
@NotNull String getGrantMessage();
|
||||
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
package net.knarcraft.minigames.arena.reward;
|
||||
|
||||
import org.bukkit.configuration.serialization.ConfigurationSerializable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* The condition for granting a reward
|
||||
*/
|
||||
public enum RewardCondition implements ConfigurationSerializable {
|
||||
|
||||
/**
|
||||
* The reward is granted each time the player wins/clears the arena
|
||||
*/
|
||||
WIN,
|
||||
|
||||
/**
|
||||
* The reward is granted the first time the player wins/clears the arena
|
||||
*/
|
||||
FIRST_WIN,
|
||||
|
||||
/**
|
||||
* The reward is granted if the player beats their personal least deaths record
|
||||
*/
|
||||
PERSONAL_DEATH_RECORD,
|
||||
|
||||
/**
|
||||
* The reward is granted if the player beats their personal least time record
|
||||
*/
|
||||
PERSONAL_TIME_RECORD,
|
||||
|
||||
/**
|
||||
* The reward is granted if the player beats the global least deaths record
|
||||
*/
|
||||
GLOBAL_DEATH_RECORD,
|
||||
|
||||
/**
|
||||
* The reward is granted if the player beats the global least time record
|
||||
*/
|
||||
GLOBAL_TIME_RECORD,
|
||||
;
|
||||
|
||||
/**
|
||||
* Gets a reward condition from the given string
|
||||
*
|
||||
* @param condition <p>The string specifying a reward condition</p>
|
||||
* @return <p>The matching reward condition, or null if not found</p>
|
||||
*/
|
||||
public static @Nullable RewardCondition getFromString(@NotNull String condition) {
|
||||
for (RewardCondition rewardCondition : RewardCondition.values()) {
|
||||
if (rewardCondition.name().equalsIgnoreCase(condition.replace("-", "_"))) {
|
||||
return rewardCondition;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Map<String, Object> serialize() {
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("condition", this.name());
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserializes a reward condition from the given data
|
||||
*
|
||||
* @param data <p>The data to deserialize</p>
|
||||
* @return <p>The deserialized reward condition</p>
|
||||
*/
|
||||
@SuppressWarnings({"unused"})
|
||||
public static @NotNull RewardCondition deserialize(@NotNull Map<String, Object> data) {
|
||||
RewardCondition rewardCondition = getFromString(String.valueOf(data.get("condition")));
|
||||
return Objects.requireNonNullElse(rewardCondition, RewardCondition.FIRST_WIN);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,47 @@
|
||||
package net.knarcraft.minigames.arena.reward;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* The type of a specific reward
|
||||
*/
|
||||
public enum RewardType {
|
||||
|
||||
/**
|
||||
* A command reward
|
||||
*/
|
||||
COMMAND,
|
||||
|
||||
/**
|
||||
* An economy reward
|
||||
*/
|
||||
ECONOMY,
|
||||
|
||||
/**
|
||||
* An item reward
|
||||
*/
|
||||
ITEM,
|
||||
|
||||
/**
|
||||
* A permission reward
|
||||
*/
|
||||
PERMISSION,
|
||||
;
|
||||
|
||||
/**
|
||||
* Gets a reward type from the given string
|
||||
*
|
||||
* @param condition <p>The string specifying a reward type</p>
|
||||
* @return <p>The matching reward type, or null if not found</p>
|
||||
*/
|
||||
public static RewardType getFromString(@NotNull String condition) {
|
||||
for (RewardType rewardType : RewardType.values()) {
|
||||
if (rewardType.name().equalsIgnoreCase(condition.replace("-", "_"))) {
|
||||
return rewardType;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -11,7 +11,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains;
|
||||
import static net.knarcraft.knarlib.util.TabCompletionHelper.filterMatchingContains;
|
||||
|
||||
/**
|
||||
* An abstract class for an arena joining tab-completer
|
||||
|
@ -2,7 +2,7 @@ package net.knarcraft.minigames.command;
|
||||
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.ArenaSession;
|
||||
import net.knarcraft.minigames.config.Message;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
@ -22,17 +22,19 @@ public class LeaveArenaCommand implements TabExecutor {
|
||||
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
|
||||
@NotNull String[] strings) {
|
||||
if (!(commandSender instanceof Player player)) {
|
||||
commandSender.sendMessage(Message.ERROR_PLAYER_ONLY.getMessage());
|
||||
MiniGames.getInstance().getStringFormatter().displayErrorMessage(commandSender,
|
||||
MiniGameMessage.ERROR_PLAYER_ONLY);
|
||||
return false;
|
||||
}
|
||||
|
||||
ArenaSession existingSession = MiniGames.getInstance().getSession(player.getUniqueId());
|
||||
if (existingSession == null) {
|
||||
commandSender.sendMessage(Message.ERROR_NOT_IN_ARENA.getMessage());
|
||||
MiniGames.getInstance().getStringFormatter().displayErrorMessage(commandSender,
|
||||
MiniGameMessage.ERROR_NOT_IN_ARENA);
|
||||
return false;
|
||||
}
|
||||
|
||||
existingSession.triggerQuit(false);
|
||||
existingSession.triggerQuit(false, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,41 @@
|
||||
package net.knarcraft.minigames.command;
|
||||
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import net.knarcraft.minigames.util.GUIHelper;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The command for opening up an arena's menu
|
||||
*/
|
||||
public class MenuCommand implements TabExecutor {
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
|
||||
@NotNull String[] arguments) {
|
||||
if (!(commandSender instanceof Player player)) {
|
||||
MiniGames.getInstance().getStringFormatter().displayErrorMessage(commandSender,
|
||||
MiniGameMessage.ERROR_PLAYER_ONLY);
|
||||
return false;
|
||||
}
|
||||
|
||||
GUIHelper.openGUI(player);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
|
||||
@NotNull String[] strings) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package net.knarcraft.minigames.command;
|
||||
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.config.Message;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
@ -20,7 +20,8 @@ public class ReloadCommand implements TabExecutor {
|
||||
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
|
||||
@NotNull String[] arguments) {
|
||||
MiniGames.getInstance().reload();
|
||||
commandSender.sendMessage(Message.SUCCESS_PLUGIN_RELOADED.getMessage());
|
||||
MiniGames.getInstance().getStringFormatter().displaySuccessMessage(commandSender,
|
||||
MiniGameMessage.SUCCESS_PLUGIN_RELOADED);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,90 @@
|
||||
package net.knarcraft.minigames.command;
|
||||
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.Arena;
|
||||
import net.knarcraft.minigames.arena.reward.Reward;
|
||||
import net.knarcraft.minigames.arena.reward.RewardCondition;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import net.knarcraft.minigames.util.RewardHelper;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* The command used for setting arena rewards
|
||||
*/
|
||||
public class SetArenaRewardCommand implements CommandExecutor {
|
||||
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
|
||||
@NotNull String[] arguments) {
|
||||
if (!(commandSender instanceof Player player)) {
|
||||
MiniGames.getInstance().getStringFormatter().displayErrorMessage(commandSender,
|
||||
MiniGameMessage.ERROR_PLAYER_ONLY);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (arguments.length < 4) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
/MiniGamesReward add dropper <name> <condition> <type> [data]
|
||||
/MiniGamesReward add parkour <name> <condition> <type> [data]
|
||||
/MiniGamesReward clear dropper <name> <condition>
|
||||
/MiniGamesReward clear parkour <name> <condition>
|
||||
|
||||
*/
|
||||
|
||||
Arena arena = null;
|
||||
if (arguments[1].equalsIgnoreCase("dropper")) {
|
||||
arena = MiniGames.getInstance().getDropperArenaHandler().getArena(arguments[2]);
|
||||
} else if (arguments[1].equalsIgnoreCase("parkour")) {
|
||||
arena = MiniGames.getInstance().getParkourArenaHandler().getArena(arguments[2]);
|
||||
}
|
||||
if (arena == null) {
|
||||
MiniGames.getInstance().getStringFormatter().displayErrorMessage(commandSender,
|
||||
MiniGameMessage.ERROR_ARENA_NOT_FOUND);
|
||||
return false;
|
||||
}
|
||||
|
||||
RewardCondition condition = RewardCondition.getFromString(arguments[3]);
|
||||
if (condition == null) {
|
||||
MiniGames.getInstance().getStringFormatter().displayErrorMessage(player,
|
||||
MiniGameMessage.ERROR_REWARD_CONDITION_INVALID);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (arguments[0].equalsIgnoreCase("clear")) {
|
||||
arena.clearRewards(condition);
|
||||
MiniGames.getInstance().getStringFormatter().displaySuccessMessage(player,
|
||||
MiniGameMessage.SUCCESS_REWARDS_CLEARED);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!arguments[0].equalsIgnoreCase("add") || arguments.length < 5) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String firstArgument = arguments.length > 5 ? arguments[5] : null;
|
||||
String secondArgument = arguments.length > 6 ? arguments[6] : null;
|
||||
|
||||
Reward reward = RewardHelper.parseRewardInput(player, arguments[4], firstArgument, secondArgument,
|
||||
Arrays.copyOfRange(arguments, 5, arguments.length));
|
||||
|
||||
if (reward != null) {
|
||||
arena.addReward(condition, reward);
|
||||
MiniGames.getInstance().getStringFormatter().displaySuccessMessage(player,
|
||||
MiniGameMessage.SUCCESS_REWARD_ADDED);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,168 @@
|
||||
package net.knarcraft.minigames.command;
|
||||
|
||||
import net.knarcraft.knarlib.util.MaterialHelper;
|
||||
import net.knarcraft.knarlib.util.TabCompletionHelper;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.Arena;
|
||||
import net.knarcraft.minigames.arena.reward.RewardCondition;
|
||||
import net.knarcraft.minigames.arena.reward.RewardType;
|
||||
import net.knarcraft.minigames.util.TabCompleteHelper;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabCompleter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static net.knarcraft.knarlib.util.TabCompletionHelper.filterMatchingContains;
|
||||
import static net.knarcraft.knarlib.util.TabCompletionHelper.filterMatchingStartsWith;
|
||||
|
||||
/**
|
||||
* The tab completer for the reward setting command
|
||||
*/
|
||||
public class SetArenaRewardTabCompleter implements TabCompleter {
|
||||
|
||||
private static final List<String> materials = getMaterials();
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public List<String> onTabComplete(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
|
||||
@NotNull String[] arguments) {
|
||||
if (arguments.length == 1) {
|
||||
// The first argument is either clear or add
|
||||
return TabCompletionHelper.filterMatchingStartsWith(Arrays.asList("add", "clear"), arguments[0]);
|
||||
}
|
||||
if (arguments.length >= 2) {
|
||||
// If the first argument is invalid, stop further tab completion
|
||||
if (!arguments[0].equalsIgnoreCase("add") && !arguments[0].equalsIgnoreCase("clear")) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
if (arguments.length == 2) {
|
||||
// The second argument is the type of arena to change rewards for
|
||||
return TabCompletionHelper.filterMatchingStartsWith(Arrays.asList("dropper", "parkour"), arguments[1]);
|
||||
} else if (arguments.length == 3) {
|
||||
// The third argument is the name of the arena to change rewards for
|
||||
if (arguments[1].equalsIgnoreCase("dropper")) {
|
||||
return filterMatchingContains(TabCompleteHelper.getDropperArenas(), arguments[2]);
|
||||
} else if (arguments[1].equalsIgnoreCase("parkour")) {
|
||||
return filterMatchingContains(TabCompleteHelper.getParkourArenas(), arguments[2]);
|
||||
}
|
||||
}
|
||||
if (arguments.length >= 4) {
|
||||
// Make sure a valid dropper or arena name has been given
|
||||
Arena arena = null;
|
||||
if (arguments[1].equalsIgnoreCase("dropper")) {
|
||||
arena = MiniGames.getInstance().getDropperArenaHandler().getArena(arguments[2]);
|
||||
} else if (arguments[1].equalsIgnoreCase("parkour")) {
|
||||
arena = MiniGames.getInstance().getParkourArenaHandler().getArena(arguments[2]);
|
||||
}
|
||||
if (arena == null) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
if (arguments.length == 4) {
|
||||
// The fourth argument is the condition to change the reward for
|
||||
return filterMatchingContains(getRewardConditions(), arguments[3]);
|
||||
}
|
||||
if (arguments.length >= 5) {
|
||||
// If the condition is invalid, or it's the clear action, stop tab-completion
|
||||
if (RewardCondition.getFromString(arguments[3]) == null ||
|
||||
arguments[0].equalsIgnoreCase("clear")) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
if (arguments.length == 5) {
|
||||
// The fifth argument is the type of reward to grant
|
||||
return filterMatchingContains(getRewardTypes(), arguments[4]);
|
||||
}
|
||||
if (arguments.length >= 6) {
|
||||
// Make sure a valid reward type has been given
|
||||
RewardType rewardType = RewardType.getFromString(arguments[4]);
|
||||
if (rewardType == null) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
if (arguments.length == 6) {
|
||||
return switch (rewardType) {
|
||||
case ITEM -> filterMatchingContains(materials, arguments[5]);
|
||||
case PERMISSION -> TabCompleteHelper.tabCompletePermission(arguments[5]);
|
||||
case ECONOMY -> filterMatchingStartsWith(Arrays.asList("1", "5", "10", "25", "50"), arguments[5]);
|
||||
case COMMAND -> filterMatchingStartsWith(getCommands(), arguments[5]);
|
||||
};
|
||||
}
|
||||
|
||||
if (rewardType == RewardType.ITEM && arguments.length == 7) {
|
||||
// If a valid item material has been given, give potential amounts
|
||||
if (MaterialHelper.loadMaterialString(arguments[5], MiniGames.getInstance().getLogger()) == null) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
return Arrays.asList("1", "5", "10", "16", "32", "48", "64");
|
||||
}
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets example command rewards
|
||||
*
|
||||
* @return <p>Example command rewards</p>
|
||||
*/
|
||||
private static List<String> getCommands() {
|
||||
List<String> commands = new ArrayList<>();
|
||||
commands.add("f powerboost player add %player% 1");
|
||||
commands.add("minecraft:xp give (player_name) 1000");
|
||||
return commands;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all materials grant-able as item rewards
|
||||
*
|
||||
* @return <p>All grant-able materials</p>
|
||||
*/
|
||||
private static List<String> getMaterials() {
|
||||
List<String> materials = new ArrayList<>();
|
||||
Set<Material> invalid = EnumSet.of(Material.WATER, Material.LAVA, Material.POWDER_SNOW);
|
||||
for (Material material : Material.values()) {
|
||||
if (material.isAir() || invalid.contains(material) || (material.isBlock() &&
|
||||
(material.getHardness() == -1 || material.getHardness() == Double.MAX_VALUE))) {
|
||||
continue;
|
||||
}
|
||||
materials.add(material.name());
|
||||
}
|
||||
return materials;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of all reward types
|
||||
*
|
||||
* @return <p>All reward types</p>
|
||||
*/
|
||||
private List<String> getRewardTypes() {
|
||||
List<String> types = new ArrayList<>();
|
||||
for (RewardType rewardType : RewardType.values()) {
|
||||
types.add(rewardType.name());
|
||||
}
|
||||
return types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of all reward conditions
|
||||
*
|
||||
* @return <p>All reward conditions</p>
|
||||
*/
|
||||
private List<String> getRewardConditions() {
|
||||
List<String> conditions = new ArrayList<>();
|
||||
for (RewardCondition rewardCondition : RewardCondition.values()) {
|
||||
conditions.add(rewardCondition.name());
|
||||
}
|
||||
return conditions;
|
||||
}
|
||||
|
||||
}
|
@ -3,7 +3,7 @@ package net.knarcraft.minigames.command.dropper;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArena;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaHandler;
|
||||
import net.knarcraft.minigames.config.Message;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import net.knarcraft.minigames.util.StringSanitizer;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
@ -20,7 +20,8 @@ public class CreateDropperArenaCommand implements CommandExecutor {
|
||||
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
|
||||
@NotNull String[] arguments) {
|
||||
if (!(commandSender instanceof Player player)) {
|
||||
commandSender.sendMessage(Message.ERROR_PLAYER_ONLY.getMessage());
|
||||
MiniGames.getInstance().getStringFormatter().displayErrorMessage(commandSender,
|
||||
MiniGameMessage.ERROR_PLAYER_ONLY);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -38,16 +39,17 @@ public class CreateDropperArenaCommand implements CommandExecutor {
|
||||
}
|
||||
|
||||
DropperArenaHandler arenaHandler = MiniGames.getInstance().getDropperArenaHandler();
|
||||
|
||||
DropperArena existingArena = arenaHandler.getArena(arenaName);
|
||||
if (existingArena != null) {
|
||||
commandSender.sendMessage(Message.ERROR_ARENA_NAME_COLLISION.getMessage());
|
||||
MiniGames.getInstance().getStringFormatter().displayErrorMessage(commandSender,
|
||||
MiniGameMessage.ERROR_ARENA_NAME_COLLISION);
|
||||
return false;
|
||||
}
|
||||
|
||||
DropperArena arena = new DropperArena(arenaName, player.getLocation(), arenaHandler);
|
||||
arenaHandler.addArena(arena);
|
||||
commandSender.sendMessage(Message.SUCCESS_ARENA_CREATED.getMessage());
|
||||
MiniGames.getInstance().getStringFormatter().displaySuccessMessage(commandSender,
|
||||
MiniGameMessage.SUCCESS_ARENA_CREATED);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
package net.knarcraft.minigames.command.dropper;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArena;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaGroup;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaHandler;
|
||||
import net.knarcraft.minigames.config.Message;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
@ -15,7 +16,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains;
|
||||
import static net.knarcraft.knarlib.util.TabCompletionHelper.filterMatchingContains;
|
||||
|
||||
/**
|
||||
* The command for listing groups and the stages within
|
||||
@ -60,13 +61,15 @@ public class DropperGroupListCommand implements TabExecutor {
|
||||
private boolean displayOrderedArenaNames(@NotNull DropperArenaHandler arenaHandler, @NotNull CommandSender sender,
|
||||
@NotNull String groupName) {
|
||||
DropperArenaGroup arenaGroup = arenaHandler.getGroup(groupName);
|
||||
StringFormatter stringFormatter = MiniGames.getInstance().getStringFormatter();
|
||||
if (arenaGroup == null) {
|
||||
sender.sendMessage(Message.ERROR_GROUP_NOT_FOUND.getMessage());
|
||||
stringFormatter.displayErrorMessage(sender, MiniGameMessage.ERROR_GROUP_NOT_FOUND);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send a list of all stages (arenas in the group)
|
||||
StringBuilder builder = new StringBuilder(Message.SUCCESS_GROUP_STAGES.getMessage("{group}", groupName));
|
||||
StringBuilder builder = new StringBuilder(stringFormatter.replacePlaceholder(
|
||||
MiniGameMessage.SUCCESS_GROUP_STAGES, "{group}", groupName));
|
||||
int counter = 1;
|
||||
for (UUID arenaId : arenaGroup.getArenas()) {
|
||||
DropperArena arena = arenaHandler.getArena(arenaId);
|
||||
@ -74,7 +77,7 @@ public class DropperGroupListCommand implements TabExecutor {
|
||||
builder.append(counter++).append(". ").append(arena.getArenaName()).append("\n");
|
||||
}
|
||||
}
|
||||
sender.sendMessage(builder.toString());
|
||||
stringFormatter.displaySuccessMessage(sender, builder.toString());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@ import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArena;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaGroup;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaHandler;
|
||||
import net.knarcraft.minigames.config.Message;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import net.knarcraft.minigames.util.StringSanitizer;
|
||||
import net.knarcraft.minigames.util.TabCompleteHelper;
|
||||
import org.bukkit.command.Command;
|
||||
@ -16,7 +16,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains;
|
||||
import static net.knarcraft.knarlib.util.TabCompletionHelper.filterMatchingContains;
|
||||
|
||||
/**
|
||||
* The command for setting the group of an arena
|
||||
@ -34,7 +34,8 @@ public class DropperGroupSetCommand implements TabExecutor {
|
||||
|
||||
DropperArena specifiedArena = arenaHandler.getArena(arguments[0]);
|
||||
if (specifiedArena == null) {
|
||||
commandSender.sendMessage(Message.ERROR_ARENA_NOT_FOUND.getMessage());
|
||||
MiniGames.getInstance().getStringFormatter().displayErrorMessage(commandSender,
|
||||
MiniGameMessage.ERROR_ARENA_NOT_FOUND);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -56,7 +57,8 @@ public class DropperGroupSetCommand implements TabExecutor {
|
||||
|
||||
arenaHandler.setGroup(specifiedArena.getArenaId(), arenaGroup);
|
||||
|
||||
commandSender.sendMessage(Message.SUCCESS_ARENA_GROUP_UPDATED.getMessage());
|
||||
MiniGames.getInstance().getStringFormatter().displaySuccessMessage(commandSender,
|
||||
MiniGameMessage.SUCCESS_ARENA_GROUP_UPDATED);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
package net.knarcraft.minigames.command.dropper;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArena;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaGroup;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaHandler;
|
||||
import net.knarcraft.minigames.config.Message;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
@ -15,7 +16,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains;
|
||||
import static net.knarcraft.knarlib.util.TabCompletionHelper.filterMatchingContains;
|
||||
|
||||
/**
|
||||
* The command for swapping the order of two arenas in a group
|
||||
@ -29,30 +30,31 @@ public class DropperGroupSwapCommand implements TabExecutor {
|
||||
return false;
|
||||
}
|
||||
|
||||
StringFormatter stringFormatter = MiniGames.getInstance().getStringFormatter();
|
||||
DropperArenaHandler arenaHandler = MiniGames.getInstance().getDropperArenaHandler();
|
||||
|
||||
DropperArena arena1 = arenaHandler.getArena(arguments[0]);
|
||||
if (arena1 == null) {
|
||||
commandSender.sendMessage(Message.ERROR_ARENA_1_NOT_FOUND.getMessage());
|
||||
stringFormatter.displayErrorMessage(commandSender, MiniGameMessage.ERROR_ARENA_1_NOT_FOUND);
|
||||
return false;
|
||||
}
|
||||
|
||||
DropperArena arena2 = arenaHandler.getArena(arguments[1]);
|
||||
if (arena2 == null) {
|
||||
commandSender.sendMessage(Message.ERROR_ARENA_2_NOT_FOUND.getMessage());
|
||||
stringFormatter.displayErrorMessage(commandSender, MiniGameMessage.ERROR_ARENA_2_NOT_FOUND);
|
||||
return false;
|
||||
}
|
||||
|
||||
DropperArenaGroup arena1Group = arenaHandler.getGroup(arena1.getArenaId());
|
||||
DropperArenaGroup arena2Group = arenaHandler.getGroup(arena2.getArenaId());
|
||||
if (arena1Group == null || !arena1Group.equals(arena2Group)) {
|
||||
commandSender.sendMessage(Message.ERROR_SWAP_DIFFERENT_GROUPS.getMessage());
|
||||
stringFormatter.displayErrorMessage(commandSender, MiniGameMessage.ERROR_SWAP_DIFFERENT_GROUPS);
|
||||
return false;
|
||||
}
|
||||
|
||||
arena1Group.swapArenas(arena1Group.getArenas().indexOf(arena1.getArenaId()),
|
||||
arena1Group.getArenas().indexOf(arena2.getArenaId()));
|
||||
commandSender.sendMessage(Message.SUCCESS_ARENAS_SWAPPED.getMessage());
|
||||
stringFormatter.displaySuccessMessage(commandSender, MiniGameMessage.SUCCESS_ARENAS_SWAPPED);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
package net.knarcraft.minigames.command.dropper;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArena;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaEditableProperty;
|
||||
import net.knarcraft.minigames.config.DropperConfiguration;
|
||||
import net.knarcraft.minigames.config.Message;
|
||||
import net.knarcraft.minigames.container.PlaceholderContainer;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.Command;
|
||||
@ -33,8 +33,9 @@ public class EditDropperArenaCommand implements CommandExecutor {
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
|
||||
@NotNull String[] arguments) {
|
||||
StringFormatter stringFormatter = MiniGames.getInstance().getStringFormatter();
|
||||
if (!(commandSender instanceof Player player)) {
|
||||
commandSender.sendMessage(Message.ERROR_PLAYER_ONLY.getMessage());
|
||||
stringFormatter.displayErrorMessage(commandSender, MiniGameMessage.ERROR_PLAYER_ONLY);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -44,29 +45,31 @@ public class EditDropperArenaCommand implements CommandExecutor {
|
||||
|
||||
DropperArena specifiedArena = MiniGames.getInstance().getDropperArenaHandler().getArena(arguments[0]);
|
||||
if (specifiedArena == null) {
|
||||
commandSender.sendMessage(Message.ERROR_ARENA_NOT_FOUND.getMessage());
|
||||
stringFormatter.displayErrorMessage(commandSender, MiniGameMessage.ERROR_ARENA_NOT_FOUND);
|
||||
return false;
|
||||
}
|
||||
|
||||
DropperArenaEditableProperty editableProperty = DropperArenaEditableProperty.getFromArgumentString(arguments[1]);
|
||||
if (editableProperty == null) {
|
||||
commandSender.sendMessage(Message.ERROR_UNKNOWN_PROPERTY.getMessage());
|
||||
stringFormatter.displayErrorMessage(commandSender, MiniGameMessage.ERROR_UNKNOWN_PROPERTY);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (arguments.length < 3) {
|
||||
// Print the current value of the property
|
||||
String value = editableProperty.getCurrentValueAsString(specifiedArena);
|
||||
commandSender.sendMessage(Message.SUCCESS_CURRENT_VALUE.getMessage(new PlaceholderContainer().add(
|
||||
"{property}", editableProperty.getArgumentString()).add("{value}", value)));
|
||||
stringFormatter.displaySuccessMessage(commandSender, stringFormatter.replacePlaceholders(
|
||||
MiniGameMessage.SUCCESS_CURRENT_VALUE, new String[]{"{property}", "{value}"},
|
||||
new String[]{editableProperty.getArgumentString(), value}));
|
||||
return true;
|
||||
} else {
|
||||
boolean successful = changeValue(specifiedArena, editableProperty, arguments[2], player);
|
||||
if (successful) {
|
||||
player.sendMessage(Message.SUCCESS_PROPERTY_CHANGED.getMessage("{property}",
|
||||
stringFormatter.displaySuccessMessage(player, stringFormatter.replacePlaceholder(
|
||||
MiniGameMessage.SUCCESS_PROPERTY_CHANGED, "{property}",
|
||||
editableProperty.getArgumentString()));
|
||||
} else {
|
||||
player.sendMessage(Message.ERROR_PROPERTY_INPUT_INVALID.getMessage());
|
||||
stringFormatter.displayErrorMessage(player, MiniGameMessage.ERROR_PROPERTY_INPUT_INVALID);
|
||||
}
|
||||
return successful;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains;
|
||||
import static net.knarcraft.knarlib.util.TabCompletionHelper.filterMatchingContains;
|
||||
|
||||
/**
|
||||
* The tab-completer for the edit arena command
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.knarcraft.minigames.command.dropper;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.ArenaPlayerRegistry;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArena;
|
||||
@ -7,7 +8,8 @@ import net.knarcraft.minigames.arena.dropper.DropperArenaGameMode;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaGroup;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaSession;
|
||||
import net.knarcraft.minigames.config.DropperConfiguration;
|
||||
import net.knarcraft.minigames.config.Message;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import net.knarcraft.minigames.util.GUIHelper;
|
||||
import net.knarcraft.minigames.util.PlayerTeleporter;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
@ -23,8 +25,9 @@ public class JoinDropperArenaCommand implements CommandExecutor {
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
|
||||
@NotNull String[] arguments) {
|
||||
StringFormatter stringFormatter = MiniGames.getInstance().getStringFormatter();
|
||||
if (!(commandSender instanceof Player player)) {
|
||||
commandSender.sendMessage(Message.ERROR_PLAYER_ONLY.getMessage());
|
||||
stringFormatter.displayErrorMessage(commandSender, MiniGameMessage.ERROR_PLAYER_ONLY);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -34,24 +37,25 @@ public class JoinDropperArenaCommand implements CommandExecutor {
|
||||
|
||||
// Disallow joining if the player is already in a mini-game arena
|
||||
if (MiniGames.getInstance().getSession(player.getUniqueId()) != null) {
|
||||
commandSender.sendMessage(Message.ERROR_ALREADY_PLAYING.getMessage());
|
||||
return false;
|
||||
stringFormatter.displayErrorMessage(commandSender, MiniGameMessage.ERROR_ALREADY_PLAYING);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make sure the arena exists
|
||||
DropperArena specifiedArena = MiniGames.getInstance().getDropperArenaHandler().getArena(arguments[0]);
|
||||
if (specifiedArena == null) {
|
||||
commandSender.sendMessage(Message.ERROR_ARENA_NOT_FOUND.getMessage());
|
||||
stringFormatter.displayErrorMessage(commandSender, MiniGameMessage.ERROR_ARENA_NOT_FOUND);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Deny vehicles as allowing this is tricky, and will cause problems in some cases
|
||||
if (player.isInsideVehicle() || !player.getPassengers().isEmpty()) {
|
||||
commandSender.sendMessage(Message.ERROR_JOIN_IN_VEHICLE_OR_PASSENGER.getMessage());
|
||||
return false;
|
||||
stringFormatter.displayErrorMessage(commandSender, MiniGameMessage.ERROR_JOIN_IN_VEHICLE_OR_PASSENGER);
|
||||
return true;
|
||||
}
|
||||
|
||||
return joinArena(specifiedArena, player, arguments);
|
||||
joinArena(specifiedArena, player, arguments);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -60,13 +64,12 @@ public class JoinDropperArenaCommand implements CommandExecutor {
|
||||
* @param specifiedArena <p>The arena the player wants to join</p>
|
||||
* @param player <p>The player joining the arena</p>
|
||||
* @param arguments <p>The arguments given</p>
|
||||
* @return <p>Whether the arena was joined successfully</p>
|
||||
*/
|
||||
private boolean joinArena(DropperArena specifiedArena, Player player, String[] arguments) {
|
||||
private void joinArena(DropperArena specifiedArena, Player player, String[] arguments) {
|
||||
// Find the specified game-mode
|
||||
DropperArenaGameMode gameMode;
|
||||
if (arguments.length > 1) {
|
||||
gameMode = DropperArenaGameMode.matchGamemode(arguments[1]);
|
||||
gameMode = DropperArenaGameMode.matchGameMode(arguments[1]);
|
||||
} else {
|
||||
gameMode = DropperArenaGameMode.DEFAULT;
|
||||
}
|
||||
@ -74,15 +77,17 @@ public class JoinDropperArenaCommand implements CommandExecutor {
|
||||
// Make sure the player has beaten the necessary levels
|
||||
DropperArenaGroup arenaGroup = MiniGames.getInstance().getDropperArenaHandler().getGroup(specifiedArena.getArenaId());
|
||||
if (arenaGroup != null && !doGroupChecks(specifiedArena, arenaGroup, gameMode, player)) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
StringFormatter stringFormatter = MiniGames.getInstance().getStringFormatter();
|
||||
|
||||
// Make sure the player has beaten the arena once in normal mode before playing another mode
|
||||
if (MiniGames.getInstance().getDropperConfiguration().mustDoNormalModeFirst() &&
|
||||
gameMode != DropperArenaGameMode.DEFAULT &&
|
||||
specifiedArena.getData().hasNotCompleted(DropperArenaGameMode.DEFAULT, player)) {
|
||||
player.sendMessage(Message.ERROR_NORMAL_MODE_REQUIRED.getMessage());
|
||||
return false;
|
||||
stringFormatter.displayErrorMessage(player, MiniGameMessage.ERROR_NORMAL_MODE_REQUIRED);
|
||||
return;
|
||||
}
|
||||
|
||||
// Register the player's session
|
||||
@ -90,17 +95,20 @@ public class JoinDropperArenaCommand implements CommandExecutor {
|
||||
ArenaPlayerRegistry<DropperArena> playerRegistry = MiniGames.getInstance().getDropperArenaPlayerRegistry();
|
||||
playerRegistry.registerPlayer(player.getUniqueId(), newSession);
|
||||
|
||||
// Update visibility and hit-box for the player
|
||||
MiniGames.getInstance().getPlayerVisibilityManager().updateHiddenPlayers(playerRegistry, player);
|
||||
|
||||
// Try to teleport the player to the arena
|
||||
boolean teleported = PlayerTeleporter.teleportPlayer(player, specifiedArena.getSpawnLocation(), false, false);
|
||||
if (!teleported) {
|
||||
player.sendMessage(Message.ERROR_ARENA_TELEPORT_FAILED.getMessage());
|
||||
newSession.triggerQuit(false);
|
||||
return false;
|
||||
stringFormatter.displayErrorMessage(player, MiniGameMessage.ERROR_ARENA_TELEPORT_FAILED);
|
||||
newSession.triggerQuit(false, true);
|
||||
} else {
|
||||
// Make sure to update the state again in the air to remove a potential swimming state
|
||||
// Update the player's state to follow the arena's rules
|
||||
newSession.getEntryState().setArenaState();
|
||||
player.sendMessage(Message.SUCCESS_ARENA_JOINED.getMessage());
|
||||
return true;
|
||||
|
||||
player.getInventory().addItem(GUIHelper.getGUIOpenItem());
|
||||
stringFormatter.displaySuccessMessage(player, MiniGameMessage.SUCCESS_ARENA_JOINED);
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,18 +123,19 @@ public class JoinDropperArenaCommand implements CommandExecutor {
|
||||
*/
|
||||
private boolean doGroupChecks(@NotNull DropperArena dropperArena, @NotNull DropperArenaGroup arenaGroup,
|
||||
@NotNull DropperArenaGameMode arenaGameMode, @NotNull Player player) {
|
||||
StringFormatter stringFormatter = MiniGames.getInstance().getStringFormatter();
|
||||
DropperConfiguration configuration = MiniGames.getInstance().getDropperConfiguration();
|
||||
// Require that players beat all arenas in the group in the normal game-mode before trying challenge modes
|
||||
if (configuration.mustDoNormalModeFirst() && arenaGameMode != DropperArenaGameMode.DEFAULT &&
|
||||
!arenaGroup.hasBeatenAll(DropperArenaGameMode.DEFAULT, player)) {
|
||||
player.sendMessage(Message.ERROR_GROUP_NORMAL_MODE_REQUIRED.getMessage());
|
||||
stringFormatter.displayErrorMessage(player, MiniGameMessage.ERROR_GROUP_NORMAL_MODE_REQUIRED);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Require that the player has beaten the previous arena on the same game-mode before trying this one
|
||||
if (configuration.mustDoGroupedInSequence() &&
|
||||
arenaGroup.cannotPlay(arenaGameMode, player, dropperArena.getArenaId())) {
|
||||
player.sendMessage(Message.ERROR_PREVIOUS_ARENA_REQUIRED.getMessage());
|
||||
stringFormatter.displayErrorMessage(player, MiniGameMessage.ERROR_PREVIOUS_ARENA_REQUIRED);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.knarcraft.minigames.command.dropper;
|
||||
|
||||
import net.knarcraft.minigames.config.Message;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import net.knarcraft.minigames.util.TabCompleteHelper;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@ -19,11 +20,12 @@ public class ListDropperArenaCommand implements TabExecutor {
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
|
||||
@NotNull String[] arguments) {
|
||||
StringBuilder builder = new StringBuilder(Message.SUCCESS_DROPPER_ARENAS_LIST.getMessage());
|
||||
StringBuilder builder = new StringBuilder(MiniGames.getInstance().getTranslator().getTranslatedMessage(
|
||||
MiniGameMessage.SUCCESS_DROPPER_ARENAS_LIST));
|
||||
for (String arenaName : TabCompleteHelper.getDropperArenas()) {
|
||||
builder.append("\n").append(arenaName);
|
||||
}
|
||||
sender.sendMessage(builder.toString());
|
||||
MiniGames.getInstance().getStringFormatter().displaySuccessMessage(sender, builder.toString());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
package net.knarcraft.minigames.command.dropper;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArena;
|
||||
import net.knarcraft.minigames.config.Message;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@ -21,16 +22,18 @@ public class RemoveDropperArenaCommand implements CommandExecutor {
|
||||
return false;
|
||||
}
|
||||
|
||||
StringFormatter stringFormatter = MiniGames.getInstance().getStringFormatter();
|
||||
|
||||
// Get the specified arena
|
||||
DropperArena targetArena = MiniGames.getInstance().getDropperArenaHandler().getArena(arguments[0]);
|
||||
if (targetArena == null) {
|
||||
commandSender.sendMessage(Message.ERROR_ARENA_NOT_FOUND.getMessage());
|
||||
stringFormatter.displayErrorMessage(commandSender, MiniGameMessage.ERROR_ARENA_NOT_FOUND);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove the arena
|
||||
MiniGames.getInstance().getDropperArenaHandler().removeArena(targetArena);
|
||||
commandSender.sendMessage(Message.SUCCESS_ARENA_REMOVED.getMessage());
|
||||
stringFormatter.displaySuccessMessage(commandSender, MiniGameMessage.SUCCESS_ARENA_REMOVED);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains;
|
||||
import static net.knarcraft.knarlib.util.TabCompletionHelper.filterMatchingContains;
|
||||
|
||||
/**
|
||||
* The tab-completer for the remove arena command
|
||||
|
@ -1,9 +1,10 @@
|
||||
package net.knarcraft.minigames.command.parkour;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArena;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArenaHandler;
|
||||
import net.knarcraft.minigames.config.Message;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import net.knarcraft.minigames.util.StringSanitizer;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
@ -19,8 +20,9 @@ public class CreateParkourArenaCommand implements CommandExecutor {
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
|
||||
@NotNull String[] arguments) {
|
||||
StringFormatter stringFormatter = MiniGames.getInstance().getStringFormatter();
|
||||
if (!(commandSender instanceof Player player)) {
|
||||
commandSender.sendMessage(Message.ERROR_PLAYER_ONLY.getMessage());
|
||||
stringFormatter.displayErrorMessage(commandSender, MiniGameMessage.ERROR_PLAYER_ONLY);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -38,16 +40,15 @@ public class CreateParkourArenaCommand implements CommandExecutor {
|
||||
}
|
||||
|
||||
ParkourArenaHandler arenaHandler = MiniGames.getInstance().getParkourArenaHandler();
|
||||
|
||||
ParkourArena existingArena = arenaHandler.getArena(arenaName);
|
||||
if (existingArena != null) {
|
||||
commandSender.sendMessage(Message.ERROR_ARENA_NAME_COLLISION.getMessage());
|
||||
stringFormatter.displayErrorMessage(commandSender, MiniGameMessage.ERROR_ARENA_NAME_COLLISION);
|
||||
return false;
|
||||
}
|
||||
|
||||
ParkourArena arena = new ParkourArena(arenaName, player.getLocation(), arenaHandler);
|
||||
arenaHandler.addArena(arena);
|
||||
commandSender.sendMessage(Message.SUCCESS_ARENA_CREATED.getMessage());
|
||||
stringFormatter.displaySuccessMessage(commandSender, MiniGameMessage.SUCCESS_ARENA_CREATED);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
package net.knarcraft.minigames.command.parkour;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArena;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArenaEditableProperty;
|
||||
import net.knarcraft.minigames.config.Message;
|
||||
import net.knarcraft.minigames.container.PlaceholderContainer;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.command.Command;
|
||||
@ -30,8 +30,9 @@ public class EditParkourArenaCommand implements CommandExecutor {
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
|
||||
@NotNull String[] arguments) {
|
||||
StringFormatter stringFormatter = MiniGames.getInstance().getStringFormatter();
|
||||
if (!(commandSender instanceof Player player)) {
|
||||
commandSender.sendMessage(Message.ERROR_PLAYER_ONLY.getMessage());
|
||||
stringFormatter.displayErrorMessage(commandSender, MiniGameMessage.ERROR_PLAYER_ONLY);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -41,29 +42,36 @@ public class EditParkourArenaCommand implements CommandExecutor {
|
||||
|
||||
ParkourArena specifiedArena = MiniGames.getInstance().getParkourArenaHandler().getArena(arguments[0]);
|
||||
if (specifiedArena == null) {
|
||||
commandSender.sendMessage(Message.ERROR_ARENA_NOT_FOUND.getMessage());
|
||||
stringFormatter.displayErrorMessage(commandSender, MiniGameMessage.ERROR_ARENA_NOT_FOUND);
|
||||
return false;
|
||||
}
|
||||
|
||||
ParkourArenaEditableProperty editableProperty = ParkourArenaEditableProperty.getFromArgumentString(arguments[1]);
|
||||
if (editableProperty == null) {
|
||||
commandSender.sendMessage(Message.ERROR_UNKNOWN_PROPERTY.getMessage());
|
||||
stringFormatter.displayErrorMessage(commandSender, MiniGameMessage.ERROR_UNKNOWN_PROPERTY);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (arguments.length < 3) {
|
||||
// Print the current value of the property
|
||||
String value = editableProperty.getCurrentValueAsString(specifiedArena);
|
||||
commandSender.sendMessage(Message.SUCCESS_CURRENT_VALUE.getMessage(new PlaceholderContainer().add(
|
||||
"{property}", editableProperty.getArgumentString()).add("{value}", value)));
|
||||
stringFormatter.displaySuccessMessage(commandSender, stringFormatter.replacePlaceholders(
|
||||
MiniGameMessage.SUCCESS_CURRENT_VALUE, new String[]{"{property}", "{value}"},
|
||||
new String[]{editableProperty.getArgumentString(), value}));
|
||||
return true;
|
||||
} else {
|
||||
boolean successful = changeValue(specifiedArena, editableProperty, arguments[2], player);
|
||||
boolean successful;
|
||||
try {
|
||||
successful = changeValue(specifiedArena, editableProperty, arguments[2], player);
|
||||
} catch (NumberFormatException exception) {
|
||||
successful = false;
|
||||
}
|
||||
if (successful) {
|
||||
player.sendMessage(Message.SUCCESS_PROPERTY_CHANGED.getMessage("{property}",
|
||||
stringFormatter.displaySuccessMessage(player, stringFormatter.replacePlaceholder(
|
||||
MiniGameMessage.SUCCESS_PROPERTY_CHANGED, "{property}",
|
||||
editableProperty.getArgumentString()));
|
||||
} else {
|
||||
player.sendMessage(Message.ERROR_PROPERTY_INPUT_INVALID.getMessage());
|
||||
stringFormatter.displayErrorMessage(player, MiniGameMessage.ERROR_PROPERTY_INPUT_INVALID);
|
||||
}
|
||||
return successful;
|
||||
}
|
||||
@ -77,9 +85,10 @@ public class EditParkourArenaCommand implements CommandExecutor {
|
||||
* @param value <p>The new value of the property</p>
|
||||
* @param player <p>The player trying to change the value</p>
|
||||
* @return <p>True if the value was successfully changed</p>
|
||||
* @throws NumberFormatException <p>If unable to parse a given numeric value</p>
|
||||
*/
|
||||
private boolean changeValue(@NotNull ParkourArena arena, @NotNull ParkourArenaEditableProperty property,
|
||||
@NotNull String value, @NotNull Player player) {
|
||||
@NotNull String value, @NotNull Player player) throws NumberFormatException {
|
||||
return switch (property) {
|
||||
case WIN_BLOCK_TYPE -> arena.setWinBlockType(parseMaterial(value));
|
||||
case SPAWN_LOCATION -> arena.setSpawnLocation(parseLocation(player, value));
|
||||
@ -89,6 +98,7 @@ public class EditParkourArenaCommand implements CommandExecutor {
|
||||
case CHECKPOINT_ADD -> arena.addCheckpoint(parseLocation(player, value));
|
||||
case CHECKPOINT_CLEAR -> arena.clearCheckpoints();
|
||||
case KILL_PLANE_BLOCKS -> arena.setKillPlaneBlocks(new HashSet<>(List.of(value.split(","))));
|
||||
case OBSTACLE_BLOCKS -> arena.setObstacleBlocks(new HashSet<>(List.of(value.split(","))));
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains;
|
||||
import static net.knarcraft.knarlib.util.TabCompletionHelper.filterMatchingContains;
|
||||
|
||||
/**
|
||||
* The tab-completer for the edit arena command
|
||||
|
@ -1,13 +1,15 @@
|
||||
package net.knarcraft.minigames.command.parkour;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.ArenaPlayerRegistry;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArena;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArenaGameMode;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArenaGroup;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArenaSession;
|
||||
import net.knarcraft.minigames.config.Message;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import net.knarcraft.minigames.config.ParkourConfiguration;
|
||||
import net.knarcraft.minigames.util.GUIHelper;
|
||||
import net.knarcraft.minigames.util.PlayerTeleporter;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
@ -23,8 +25,9 @@ public class JoinParkourArenaCommand implements CommandExecutor {
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender commandSender, @NotNull Command command, @NotNull String s,
|
||||
@NotNull String[] arguments) {
|
||||
StringFormatter stringFormatter = MiniGames.getInstance().getStringFormatter();
|
||||
if (!(commandSender instanceof Player player)) {
|
||||
commandSender.sendMessage(Message.ERROR_PLAYER_ONLY.getMessage());
|
||||
stringFormatter.displayErrorMessage(commandSender, MiniGameMessage.ERROR_PLAYER_ONLY);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -34,24 +37,25 @@ public class JoinParkourArenaCommand implements CommandExecutor {
|
||||
|
||||
// Disallow joining if the player is already in a mini-game arena
|
||||
if (MiniGames.getInstance().getSession(player.getUniqueId()) != null) {
|
||||
commandSender.sendMessage(Message.ERROR_ALREADY_PLAYING.getMessage());
|
||||
return false;
|
||||
stringFormatter.displayErrorMessage(commandSender, MiniGameMessage.ERROR_ALREADY_PLAYING);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make sure the arena exists
|
||||
ParkourArena specifiedArena = MiniGames.getInstance().getParkourArenaHandler().getArena(arguments[0]);
|
||||
if (specifiedArena == null) {
|
||||
commandSender.sendMessage(Message.ERROR_ARENA_NOT_FOUND.getMessage());
|
||||
stringFormatter.displayErrorMessage(commandSender, MiniGameMessage.ERROR_ARENA_NOT_FOUND);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Deny vehicles as allowing this is tricky, and will cause problems in some cases
|
||||
if (player.isInsideVehicle() || !player.getPassengers().isEmpty()) {
|
||||
commandSender.sendMessage(Message.ERROR_JOIN_IN_VEHICLE_OR_PASSENGER.getMessage());
|
||||
return false;
|
||||
stringFormatter.displayErrorMessage(commandSender, MiniGameMessage.ERROR_JOIN_IN_VEHICLE_OR_PASSENGER);
|
||||
return true;
|
||||
}
|
||||
|
||||
return joinArena(specifiedArena, player, arguments);
|
||||
joinArena(specifiedArena, player, arguments);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -60,9 +64,8 @@ public class JoinParkourArenaCommand implements CommandExecutor {
|
||||
* @param specifiedArena <p>The arena the player wants to join</p>
|
||||
* @param player <p>The player joining the arena</p>
|
||||
* @param arguments <p>The arguments given</p>
|
||||
* @return <p>Whether the arena was joined successfully</p>
|
||||
*/
|
||||
private boolean joinArena(ParkourArena specifiedArena, Player player, String[] arguments) {
|
||||
private void joinArena(ParkourArena specifiedArena, Player player, String[] arguments) {
|
||||
// Find the specified game-mode
|
||||
ParkourArenaGameMode gameMode;
|
||||
if (arguments.length > 1) {
|
||||
@ -71,10 +74,17 @@ public class JoinParkourArenaCommand implements CommandExecutor {
|
||||
gameMode = ParkourArenaGameMode.DEFAULT;
|
||||
}
|
||||
|
||||
// Don't allow joining the hardcore game-mode if there are no checkpoints to skip
|
||||
if (specifiedArena.hasNoCheckpoints() && gameMode == ParkourArenaGameMode.HARDCORE) {
|
||||
MiniGames.getInstance().getStringFormatter().displayErrorMessage(player,
|
||||
MiniGameMessage.ERROR_HARDCORE_NO_CHECKPOINTS);
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure the player has beaten the necessary levels
|
||||
ParkourArenaGroup arenaGroup = MiniGames.getInstance().getParkourArenaHandler().getGroup(specifiedArena.getArenaId());
|
||||
if (arenaGroup != null && !doGroupChecks(specifiedArena, arenaGroup, gameMode, player)) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Register the player's session
|
||||
@ -82,17 +92,22 @@ public class JoinParkourArenaCommand implements CommandExecutor {
|
||||
ArenaPlayerRegistry<ParkourArena> playerRegistry = MiniGames.getInstance().getParkourArenaPlayerRegistry();
|
||||
playerRegistry.registerPlayer(player.getUniqueId(), newSession);
|
||||
|
||||
// Update visibility and hit-box for the player
|
||||
MiniGames.getInstance().getPlayerVisibilityManager().updateHiddenPlayers(playerRegistry, player);
|
||||
|
||||
// Try to teleport the player to the arena
|
||||
boolean teleported = PlayerTeleporter.teleportPlayer(player, specifiedArena.getSpawnLocation(), false, false);
|
||||
if (!teleported) {
|
||||
player.sendMessage(Message.ERROR_ARENA_TELEPORT_FAILED.getMessage());
|
||||
newSession.triggerQuit(false);
|
||||
return false;
|
||||
MiniGames.getInstance().getStringFormatter().displayErrorMessage(player,
|
||||
MiniGameMessage.ERROR_ARENA_TELEPORT_FAILED);
|
||||
newSession.triggerQuit(false, true);
|
||||
} else {
|
||||
// Make sure to update the state again in the air to remove a potential swimming state
|
||||
// Update the player's state to follow the arena's rules
|
||||
newSession.getEntryState().setArenaState();
|
||||
player.sendMessage(Message.SUCCESS_ARENA_JOINED.getMessage());
|
||||
return true;
|
||||
|
||||
player.getInventory().addItem(GUIHelper.getGUIOpenItem());
|
||||
MiniGames.getInstance().getStringFormatter().displaySuccessMessage(player,
|
||||
MiniGameMessage.SUCCESS_ARENA_JOINED);
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,7 +127,8 @@ public class JoinParkourArenaCommand implements CommandExecutor {
|
||||
// Require that the player has beaten the previous arena on the same game-mode before trying this one
|
||||
if (configuration.mustDoGroupedInSequence() &&
|
||||
arenaGroup.cannotPlay(arenaGameMode, player, parkourArena.getArenaId())) {
|
||||
player.sendMessage(Message.ERROR_PREVIOUS_ARENA_REQUIRED.getMessage());
|
||||
MiniGames.getInstance().getStringFormatter().displayErrorMessage(player,
|
||||
MiniGameMessage.ERROR_PREVIOUS_ARENA_REQUIRED);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.knarcraft.minigames.command.parkour;
|
||||
|
||||
import net.knarcraft.minigames.config.Message;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import net.knarcraft.minigames.util.TabCompleteHelper;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@ -19,11 +20,12 @@ public class ListParkourArenaCommand implements TabExecutor {
|
||||
@Override
|
||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label,
|
||||
@NotNull String[] arguments) {
|
||||
StringBuilder builder = new StringBuilder(Message.SUCCESS_PARKOUR_ARENAS_LIST.getMessage());
|
||||
StringBuilder builder = new StringBuilder(MiniGames.getInstance().getTranslator().getTranslatedMessage(
|
||||
MiniGameMessage.SUCCESS_PARKOUR_ARENAS_LIST));
|
||||
for (String arenaName : TabCompleteHelper.getParkourArenas()) {
|
||||
builder.append("\n").append(arenaName);
|
||||
}
|
||||
sender.sendMessage(builder.toString());
|
||||
MiniGames.getInstance().getStringFormatter().displaySuccessMessage(sender, builder.toString());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
package net.knarcraft.minigames.command.parkour;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArena;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArenaGroup;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArenaHandler;
|
||||
import net.knarcraft.minigames.config.Message;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
@ -16,7 +17,7 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains;
|
||||
import static net.knarcraft.knarlib.util.TabCompletionHelper.filterMatchingContains;
|
||||
|
||||
/**
|
||||
* The command for listing groups and the stages within
|
||||
@ -60,14 +61,16 @@ public class ParkourGroupListCommand implements TabExecutor {
|
||||
*/
|
||||
private boolean displayOrderedArenaNames(@NotNull ParkourArenaHandler arenaHandler, @NotNull CommandSender sender,
|
||||
@NotNull String groupName) {
|
||||
StringFormatter stringFormatter = MiniGames.getInstance().getStringFormatter();
|
||||
ParkourArenaGroup arenaGroup = arenaHandler.getGroup(groupName);
|
||||
if (arenaGroup == null) {
|
||||
sender.sendMessage(Message.ERROR_GROUP_NOT_FOUND.getMessage());
|
||||
stringFormatter.displayErrorMessage(sender, MiniGameMessage.ERROR_GROUP_NOT_FOUND);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send a list of all stages (arenas in the group)
|
||||
StringBuilder builder = new StringBuilder(Message.SUCCESS_GROUP_STAGES.getMessage("{group}", groupName));
|
||||
StringBuilder builder = new StringBuilder(stringFormatter.replacePlaceholder(
|
||||
MiniGameMessage.SUCCESS_GROUP_STAGES, "{group}", groupName));
|
||||
int counter = 1;
|
||||
for (UUID arenaId : arenaGroup.getArenas()) {
|
||||
ParkourArena arena = arenaHandler.getArena(arenaId);
|
||||
@ -75,7 +78,7 @@ public class ParkourGroupListCommand implements TabExecutor {
|
||||
builder.append("\n").append(counter++).append(". ").append(arena.getArenaName());
|
||||
}
|
||||
}
|
||||
sender.sendMessage(builder.toString());
|
||||
stringFormatter.displaySuccessMessage(sender, builder.toString());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
package net.knarcraft.minigames.command.parkour;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArena;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArenaGroup;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArenaHandler;
|
||||
import net.knarcraft.minigames.config.Message;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import net.knarcraft.minigames.util.StringSanitizer;
|
||||
import net.knarcraft.minigames.util.TabCompleteHelper;
|
||||
import org.bukkit.command.Command;
|
||||
@ -16,7 +17,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains;
|
||||
import static net.knarcraft.knarlib.util.TabCompletionHelper.filterMatchingContains;
|
||||
|
||||
/**
|
||||
* The command for setting the group of an arena
|
||||
@ -30,11 +31,12 @@ public class ParkourGroupSetCommand implements TabExecutor {
|
||||
return false;
|
||||
}
|
||||
|
||||
StringFormatter stringFormatter = MiniGames.getInstance().getStringFormatter();
|
||||
ParkourArenaHandler arenaHandler = MiniGames.getInstance().getParkourArenaHandler();
|
||||
|
||||
ParkourArena specifiedArena = arenaHandler.getArena(arguments[0]);
|
||||
if (specifiedArena == null) {
|
||||
commandSender.sendMessage(Message.ERROR_ARENA_NOT_FOUND.getMessage());
|
||||
stringFormatter.displayErrorMessage(commandSender, MiniGameMessage.ERROR_ARENA_NOT_FOUND);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -56,7 +58,7 @@ public class ParkourGroupSetCommand implements TabExecutor {
|
||||
|
||||
arenaHandler.setGroup(specifiedArena.getArenaId(), arenaGroup);
|
||||
|
||||
commandSender.sendMessage(Message.SUCCESS_ARENA_GROUP_UPDATED.getMessage());
|
||||
stringFormatter.displaySuccessMessage(commandSender, MiniGameMessage.SUCCESS_ARENA_GROUP_UPDATED);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
package net.knarcraft.minigames.command.parkour;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArena;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArenaGroup;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArenaHandler;
|
||||
import net.knarcraft.minigames.config.Message;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.command.TabExecutor;
|
||||
@ -15,7 +16,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains;
|
||||
import static net.knarcraft.knarlib.util.TabCompletionHelper.filterMatchingContains;
|
||||
|
||||
/**
|
||||
* The command for swapping the order of two arenas in a group
|
||||
@ -30,29 +31,30 @@ public class ParkourGroupSwapCommand implements TabExecutor {
|
||||
}
|
||||
|
||||
ParkourArenaHandler arenaHandler = MiniGames.getInstance().getParkourArenaHandler();
|
||||
StringFormatter stringFormatter = MiniGames.getInstance().getStringFormatter();
|
||||
|
||||
ParkourArena arena1 = arenaHandler.getArena(arguments[0]);
|
||||
if (arena1 == null) {
|
||||
commandSender.sendMessage(Message.ERROR_ARENA_1_NOT_FOUND.getMessage());
|
||||
stringFormatter.displayErrorMessage(commandSender, MiniGameMessage.ERROR_ARENA_1_NOT_FOUND);
|
||||
return false;
|
||||
}
|
||||
|
||||
ParkourArena arena2 = arenaHandler.getArena(arguments[1]);
|
||||
if (arena2 == null) {
|
||||
commandSender.sendMessage(Message.ERROR_ARENA_2_NOT_FOUND.getMessage());
|
||||
stringFormatter.displayErrorMessage(commandSender, MiniGameMessage.ERROR_ARENA_2_NOT_FOUND);
|
||||
return false;
|
||||
}
|
||||
|
||||
ParkourArenaGroup arena1Group = arenaHandler.getGroup(arena1.getArenaId());
|
||||
ParkourArenaGroup arena2Group = arenaHandler.getGroup(arena2.getArenaId());
|
||||
if (arena1Group == null || !arena1Group.equals(arena2Group)) {
|
||||
commandSender.sendMessage(Message.ERROR_SWAP_DIFFERENT_GROUPS.getMessage());
|
||||
stringFormatter.displayErrorMessage(commandSender, MiniGameMessage.ERROR_SWAP_DIFFERENT_GROUPS);
|
||||
return false;
|
||||
}
|
||||
|
||||
arena1Group.swapArenas(arena1Group.getArenas().indexOf(arena1.getArenaId()),
|
||||
arena1Group.getArenas().indexOf(arena2.getArenaId()));
|
||||
commandSender.sendMessage(Message.SUCCESS_ARENAS_SWAPPED.getMessage());
|
||||
stringFormatter.displaySuccessMessage(commandSender, MiniGameMessage.SUCCESS_ARENAS_SWAPPED);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,9 @@
|
||||
package net.knarcraft.minigames.command.parkour;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArena;
|
||||
import net.knarcraft.minigames.config.Message;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import org.bukkit.command.Command;
|
||||
import org.bukkit.command.CommandExecutor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@ -21,16 +22,18 @@ public class RemoveParkourArenaCommand implements CommandExecutor {
|
||||
return false;
|
||||
}
|
||||
|
||||
StringFormatter stringFormatter = MiniGames.getInstance().getStringFormatter();
|
||||
|
||||
// Get the specified arena
|
||||
ParkourArena targetArena = MiniGames.getInstance().getParkourArenaHandler().getArena(arguments[0]);
|
||||
if (targetArena == null) {
|
||||
commandSender.sendMessage(Message.ERROR_ARENA_NOT_FOUND.getMessage());
|
||||
stringFormatter.displayErrorMessage(commandSender, MiniGameMessage.ERROR_ARENA_NOT_FOUND);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove the arena
|
||||
MiniGames.getInstance().getParkourArenaHandler().removeArena(targetArena);
|
||||
commandSender.sendMessage(Message.SUCCESS_ARENA_REMOVED.getMessage());
|
||||
stringFormatter.displaySuccessMessage(commandSender, MiniGameMessage.SUCCESS_ARENA_REMOVED);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static net.knarcraft.minigames.util.TabCompleteHelper.filterMatchingContains;
|
||||
import static net.knarcraft.knarlib.util.TabCompletionHelper.filterMatchingContains;
|
||||
|
||||
/**
|
||||
* The tab-completer for the remove arena command
|
||||
|
@ -19,8 +19,6 @@ public class DropperConfiguration extends MiniGameConfiguration {
|
||||
private boolean mustDoGroupedInSequence;
|
||||
private boolean ignoreRecordsUntilGroupBeatenOnce;
|
||||
private boolean mustDoNormalModeFirst;
|
||||
private boolean makePlayersInvisible;
|
||||
private boolean disableHitCollision;
|
||||
private boolean blockSneaking;
|
||||
private boolean blockSprinting;
|
||||
private Set<Material> blockWhitelist;
|
||||
@ -97,24 +95,6 @@ public class DropperConfiguration extends MiniGameConfiguration {
|
||||
return this.ignoreRecordsUntilGroupBeatenOnce;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether players should be made invisible while in an arena
|
||||
*
|
||||
* @return <p>Whether players should be made invisible</p>
|
||||
*/
|
||||
public boolean makePlayersInvisible() {
|
||||
return this.makePlayersInvisible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether entity hit-collision of players in an arena should be disabled
|
||||
*
|
||||
* @return <p>Whether to disable hit collision</p>
|
||||
*/
|
||||
public boolean disableHitCollision() {
|
||||
return this.disableHitCollision;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether players trying to sneak while in a dropper arena to increase their downwards speed should be blocked
|
||||
*
|
||||
@ -141,8 +121,6 @@ public class DropperConfiguration extends MiniGameConfiguration {
|
||||
this.mustDoGroupedInSequence = configuration.getBoolean(rootNode + "mustDoGroupedInSequence", true);
|
||||
this.ignoreRecordsUntilGroupBeatenOnce = configuration.getBoolean(rootNode + "ignoreRecordsUntilGroupBeatenOnce", false);
|
||||
this.mustDoNormalModeFirst = configuration.getBoolean(rootNode + "mustDoNormalModeFirst", true);
|
||||
this.makePlayersInvisible = configuration.getBoolean(rootNode + "makePlayersInvisible", false);
|
||||
this.disableHitCollision = configuration.getBoolean(rootNode + "disableHitCollision", true);
|
||||
this.blockSprinting = configuration.getBoolean(rootNode + "blockSprinting", true);
|
||||
this.blockSneaking = configuration.getBoolean(rootNode + "blockSneaking", true);
|
||||
this.blockWhitelist = loadMaterialList(rootNode + "blockWhitelist");
|
||||
@ -176,8 +154,6 @@ public class DropperConfiguration extends MiniGameConfiguration {
|
||||
"\n" + "Must do groups in sequence: " + mustDoGroupedInSequence +
|
||||
"\n" + "Ignore records until group beaten once: " + ignoreRecordsUntilGroupBeatenOnce +
|
||||
"\n" + "Must do normal mode first: " + mustDoNormalModeFirst +
|
||||
"\n" + "Make players invisible: " + makePlayersInvisible +
|
||||
"\n" + "Disable hit collision: " + disableHitCollision +
|
||||
"\n" + "Block whitelist: ");
|
||||
for (Material material : blockWhitelist) {
|
||||
builder.append("\n - ").append(material.name());
|
||||
|
@ -1,300 +0,0 @@
|
||||
package net.knarcraft.minigames.config;
|
||||
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.container.PlaceholderContainer;
|
||||
import net.knarcraft.minigames.util.ColorHelper;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A message which ca be displayed to the user
|
||||
*/
|
||||
public enum Message {
|
||||
|
||||
/* ************** *
|
||||
* Error messages *
|
||||
* ************** */
|
||||
|
||||
/**
|
||||
* The message displayed if saving arena groups fails
|
||||
*/
|
||||
ERROR_CANNOT_SAVE_ARENA_GROUPS("&cUnable to save current arena groups! Data loss can occur!"),
|
||||
|
||||
/**
|
||||
* The message displayed if an un-parse-able message is given by a user
|
||||
*/
|
||||
ERROR_MATERIAL_NOT_PARSE_ABLE("&cUnable to parse material: {material}"),
|
||||
|
||||
/**
|
||||
* The message displayed if a player tries to be teleported to/from an arena with a passenger
|
||||
*/
|
||||
ERROR_TELEPORT_WITH_PASSENGER("&cYou cannot be teleported with a passenger!"),
|
||||
|
||||
/**
|
||||
* The message displayed if a player tries to be teleported to/from an arena with a vehicle
|
||||
*/
|
||||
ERROR_TELEPORT_IN_VEHICLE("&cYou cannot be teleported while in a vehicle"),
|
||||
|
||||
/**
|
||||
* The message displayed if an arena cannot be loaded
|
||||
*/
|
||||
ERROR_ARENA_NOT_LOADED("&cCould not load the arena at configuration section {section}. Please check " +
|
||||
"the {file} storage file for issues."),
|
||||
|
||||
/**
|
||||
* The message displayed if an arena's data cannot be loaded
|
||||
*/
|
||||
ERROR_ARENA_DATA_NOT_LOADED("&cUnable to load arena data for dropper arena: {arena}"),
|
||||
|
||||
/**
|
||||
* The message displayed if the user specifies an unrecognized arena
|
||||
*/
|
||||
ERROR_ARENA_NOT_FOUND("&cUnable to find the specified arena."),
|
||||
|
||||
/**
|
||||
* The message displayed if the user specifies an unrecognized group
|
||||
*/
|
||||
ERROR_GROUP_NOT_FOUND("&cUnable to find the specified group!"),
|
||||
|
||||
/**
|
||||
* The message displayed if the console tries to execute a player-only command
|
||||
*/
|
||||
ERROR_PLAYER_ONLY("&cThis command must be used by a player"),
|
||||
|
||||
/**
|
||||
* The message displayed if the name of an arena is duplicated
|
||||
*/
|
||||
ERROR_ARENA_NAME_COLLISION("&cThere already exists an arena with that name!"),
|
||||
|
||||
/**
|
||||
* The message displayed if the player is required to win on the default difficulty first
|
||||
*/
|
||||
ERROR_NORMAL_MODE_REQUIRED("&cYou must complete this arena in normal mode first!"),
|
||||
|
||||
/**
|
||||
* The message displayed if the player is required to win on the default difficulty for all arenas in the group first
|
||||
*/
|
||||
ERROR_GROUP_NORMAL_MODE_REQUIRED("&cYou have not yet beaten the default game-mode for all arenas in this group!"),
|
||||
|
||||
/**
|
||||
* The message displayed if the player is required to beat the previous arena in the group
|
||||
*/
|
||||
ERROR_PREVIOUS_ARENA_REQUIRED("&cYou have not yet beaten the previous arena!"),
|
||||
|
||||
/**
|
||||
* The message displayed if player teleportation failed for some reason
|
||||
*/
|
||||
ERROR_ARENA_TELEPORT_FAILED("&cUnable to teleport you to the arena."),
|
||||
|
||||
/**
|
||||
* The message displayed if the player tries to quit the arena while not in an arena
|
||||
*/
|
||||
ERROR_NOT_IN_ARENA("&cYou are not in a mini-games arena!"),
|
||||
|
||||
/**
|
||||
* The message displayed if the player tries to join an arena while already playing
|
||||
*
|
||||
* <p>This should in theory be impossible, as players cannot use any commands except /miniGamesLeave while playing
|
||||
* in an arena.</p>
|
||||
*/
|
||||
ERROR_ALREADY_PLAYING("&cYou are already playing a mini-game!"),
|
||||
|
||||
/**
|
||||
* The message displayed if a player tries to join an arena with a passenger or riding a vehicle
|
||||
*/
|
||||
ERROR_JOIN_IN_VEHICLE_OR_PASSENGER("&cYou cannot join an arena while inside a vehicle or carrying a passenger."),
|
||||
|
||||
/**
|
||||
* The message displayed if the player tries to change an unrecognized arena property
|
||||
*/
|
||||
ERROR_UNKNOWN_PROPERTY("&cUnknown property specified."),
|
||||
|
||||
/**
|
||||
* The message displayed if the given input to /dEdit or /pEdit's value is invalid
|
||||
*/
|
||||
ERROR_PROPERTY_INPUT_INVALID("&cUnable to change the property. Make sure your input is valid!"),
|
||||
|
||||
/**
|
||||
* The message displayed if the first arena specified in /dgSwap or /pgSwap is invalid
|
||||
*/
|
||||
ERROR_ARENA_1_NOT_FOUND("&cUnable to find the first specified arena."),
|
||||
|
||||
/**
|
||||
* The message displayed if the second arena specified in /dgSwap or /pgSwap is invalid
|
||||
*/
|
||||
ERROR_ARENA_2_NOT_FOUND("&cUnable to find the second specified dropper arena."),
|
||||
|
||||
/**
|
||||
* The message displayed if the two groups specified for /dgSwap or /pgSwap are in different arenas
|
||||
*/
|
||||
ERROR_SWAP_DIFFERENT_GROUPS("&cYou cannot swap arenas in different groups!"),
|
||||
|
||||
/**
|
||||
* The message displayed if a player tries to use any command other than /mLeave while in an arena
|
||||
*/
|
||||
ERROR_ILLEGAL_COMMAND("&cYou cannot use that command while in an arena!"),
|
||||
|
||||
/* **************** *
|
||||
* Success messages *
|
||||
* **************** */
|
||||
|
||||
/**
|
||||
* The message displayed if an arena's group has been changed
|
||||
*/
|
||||
SUCCESS_ARENA_GROUP_UPDATED("&aThe arena's group has been updated"),
|
||||
|
||||
/**
|
||||
* The message displayed if the MiniGames plugin is reloaded
|
||||
*/
|
||||
SUCCESS_PLUGIN_RELOADED("&aPlugin reloaded!"),
|
||||
|
||||
/**
|
||||
* The message displayed if a new arena has been created
|
||||
*/
|
||||
SUCCESS_ARENA_CREATED("&aThe arena was successfully created!"),
|
||||
|
||||
/**
|
||||
* The message displayed if a player clears/wins an arena for the first time
|
||||
*/
|
||||
SUCCESS_ARENA_FIRST_CLEAR("&aYou cleared the arena!"),
|
||||
|
||||
/**
|
||||
* The message displayed when a player wins an arena
|
||||
*/
|
||||
SUCCESS_ARENA_WIN("&aYou won!"),
|
||||
|
||||
/**
|
||||
* The message displayed when a player quits an arena
|
||||
*/
|
||||
SUCCESS_ARENA_QUIT("&aYou quit the arena!"),
|
||||
|
||||
/**
|
||||
* The message used to display the current value of an arena property
|
||||
*/
|
||||
SUCCESS_CURRENT_VALUE("&aCurrent value of {property} is: {value}"),
|
||||
|
||||
/**
|
||||
* The message used to announce that an arena property has been changed
|
||||
*/
|
||||
SUCCESS_PROPERTY_CHANGED("&aProperty {property} successfully changed"),
|
||||
|
||||
/**
|
||||
* The message displayed when two arenas' order in a group have been swapped
|
||||
*/
|
||||
SUCCESS_ARENAS_SWAPPED("&aThe arenas have been swapped!"),
|
||||
|
||||
/**
|
||||
* The message displayed when an arena has been removed
|
||||
*/
|
||||
SUCCESS_ARENA_REMOVED("&aThe specified arena has been successfully removed"),
|
||||
|
||||
/**
|
||||
* The header displayed before listing all dropper arenas
|
||||
*/
|
||||
SUCCESS_DROPPER_ARENAS_LIST("&aDropper arenas:&r"),
|
||||
|
||||
/**
|
||||
* The header displayed before listing all parkour arenas
|
||||
*/
|
||||
SUCCESS_PARKOUR_ARENAS_LIST("&aParkour arenas:&r"),
|
||||
|
||||
/**
|
||||
* The message displayed when a player reaches a new checkpoint in a parkour arena
|
||||
*/
|
||||
SUCCESS_CHECKPOINT_REACHED("&aCheckpoint reached!"),
|
||||
|
||||
/**
|
||||
* The header displayed before listing all arenas (stages) in a group
|
||||
*/
|
||||
SUCCESS_GROUP_STAGES("&a{group}'s stages:&r"),
|
||||
|
||||
/**
|
||||
* The message displayed when a new record has been achieved
|
||||
*/
|
||||
SUCCESS_RECORD_ACHIEVED("&aYou just set a {recordInfo} on the {gameMode} game-mode!"),
|
||||
|
||||
/**
|
||||
* The partial message used to describe that the player achieved a world record
|
||||
*/
|
||||
RECORD_ACHIEVED_GLOBAL("new {recordType} record"),
|
||||
|
||||
/**
|
||||
* The partial message used to describe that the player achieved a personal best record
|
||||
*/
|
||||
RECORD_ACHIEVED_PERSONAL("personal {recordType} record"),
|
||||
|
||||
/**
|
||||
* The message displayed when a player joins an arena
|
||||
*/
|
||||
SUCCESS_ARENA_JOINED("&aYou joined the arena."),
|
||||
;
|
||||
|
||||
private final @NotNull String defaultMessage;
|
||||
|
||||
/**
|
||||
* Instantiates a new message
|
||||
*
|
||||
* @param defaultMessage <p>The default value of the message</p>
|
||||
*/
|
||||
Message(@NotNull String defaultMessage) {
|
||||
this.defaultMessage = defaultMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message this enum represents
|
||||
*
|
||||
* @return <p>The formatted message</p>
|
||||
*/
|
||||
public @NotNull String getMessage() {
|
||||
return formatMessage(this.defaultMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message this enum represents
|
||||
*
|
||||
* @param placeholder <p>The placeholder to replace</p>
|
||||
* @param replacement <p>The replacement to use</p>
|
||||
* @return <p>The formatted message</p>
|
||||
*/
|
||||
public @NotNull String getMessage(@NotNull String placeholder, @NotNull String replacement) {
|
||||
return formatMessage(this.defaultMessage.replace(placeholder, replacement));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message this enum represents, intended for display within another message
|
||||
*
|
||||
* @param placeholder <p>The placeholder to replace</p>
|
||||
* @param replacement <p>The replacement to use</p>
|
||||
* @return <p>The formatted message</p>
|
||||
*/
|
||||
public @NotNull String getPartialMessage(@NotNull String placeholder, @NotNull String replacement) {
|
||||
return ColorHelper.translateAllColorCodes(this.defaultMessage.replace(placeholder, replacement));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message this enum represents
|
||||
*
|
||||
* @param placeholders <p>The placeholder -> replacement map specifying necessary replacements</p>
|
||||
* @return <p>The formatted message</p>
|
||||
*/
|
||||
public @NotNull String getMessage(@NotNull PlaceholderContainer placeholders) {
|
||||
String replaced = this.defaultMessage;
|
||||
for (Map.Entry<String, String> entry : placeholders.getPlaceholders().entrySet()) {
|
||||
replaced = replaced.replace(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return formatMessage(replaced);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the formatted version of the given message
|
||||
*
|
||||
* @param message <p>The message to format</p>
|
||||
* @return <p>The formatted message</p>
|
||||
*/
|
||||
private @NotNull String formatMessage(@NotNull String message) {
|
||||
String prefix = MiniGames.getInstance().getDescription().getPrefix();
|
||||
return ColorHelper.translateAllColorCodes("#546EED[&r&l" + prefix + "#546EED]&r " + message);
|
||||
}
|
||||
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package net.knarcraft.minigames.config;
|
||||
|
||||
import net.knarcraft.minigames.util.MaterialHelper;
|
||||
import net.knarcraft.knarlib.util.MaterialHelper;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -46,7 +47,7 @@ public abstract class MiniGameConfiguration {
|
||||
*/
|
||||
public @NotNull Set<Material> loadMaterialList(@NotNull String path) {
|
||||
List<?> blockWhitelist = configuration.getList(path, new ArrayList<>());
|
||||
return MaterialHelper.loadMaterialList(blockWhitelist);
|
||||
return MaterialHelper.loadMaterialList(blockWhitelist, "+", MiniGames.getInstance().getLogger());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,303 @@
|
||||
package net.knarcraft.minigames.config;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.TranslatableMessage;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A message which ca be displayed to the user
|
||||
*/
|
||||
public enum MiniGameMessage implements TranslatableMessage {
|
||||
|
||||
/* ************** *
|
||||
* Error messages *
|
||||
* ************** */
|
||||
|
||||
/**
|
||||
* The message displayed if saving arena groups fails
|
||||
*/
|
||||
ERROR_CANNOT_SAVE_ARENA_GROUPS,
|
||||
|
||||
/**
|
||||
* The message displayed if an un-parse-able message is given by a user
|
||||
*/
|
||||
ERROR_MATERIAL_NOT_PARSE_ABLE,
|
||||
|
||||
/**
|
||||
* The message displayed if a player tries to be teleported to/from an arena with a passenger
|
||||
*/
|
||||
ERROR_TELEPORT_WITH_PASSENGER,
|
||||
|
||||
/**
|
||||
* The message displayed if a player tries to be teleported to/from an arena with a vehicle
|
||||
*/
|
||||
ERROR_TELEPORT_IN_VEHICLE,
|
||||
|
||||
/**
|
||||
* The message displayed if an arena cannot be loaded
|
||||
*/
|
||||
ERROR_ARENA_NOT_LOADED,
|
||||
|
||||
/**
|
||||
* The message displayed if an arena's data cannot be loaded
|
||||
*/
|
||||
ERROR_ARENA_DATA_NOT_LOADED,
|
||||
|
||||
/**
|
||||
* The message displayed if the user specifies an unrecognized arena
|
||||
*/
|
||||
ERROR_ARENA_NOT_FOUND,
|
||||
|
||||
/**
|
||||
* The message displayed if the user specifies an unrecognized group
|
||||
*/
|
||||
ERROR_GROUP_NOT_FOUND,
|
||||
|
||||
/**
|
||||
* The message displayed if the console tries to execute a player-only command
|
||||
*/
|
||||
ERROR_PLAYER_ONLY,
|
||||
|
||||
/**
|
||||
* The message displayed if the name of an arena is duplicated
|
||||
*/
|
||||
ERROR_ARENA_NAME_COLLISION,
|
||||
|
||||
/**
|
||||
* The message displayed if the player is required to win on the default difficulty first
|
||||
*/
|
||||
ERROR_NORMAL_MODE_REQUIRED,
|
||||
|
||||
/**
|
||||
* The message displayed if the player is required to win on the default difficulty for all arenas in the group first
|
||||
*/
|
||||
ERROR_GROUP_NORMAL_MODE_REQUIRED,
|
||||
|
||||
/**
|
||||
* The message displayed if the player is required to beat the previous arena in the group
|
||||
*/
|
||||
ERROR_PREVIOUS_ARENA_REQUIRED,
|
||||
|
||||
/**
|
||||
* The message displayed if player teleportation failed for some reason
|
||||
*/
|
||||
ERROR_ARENA_TELEPORT_FAILED,
|
||||
|
||||
/**
|
||||
* The message displayed if the player tries to quit the arena while not in an arena
|
||||
*/
|
||||
ERROR_NOT_IN_ARENA,
|
||||
|
||||
/**
|
||||
* The message displayed if the player tries to join an arena while already playing
|
||||
*
|
||||
* <p>This should in theory be impossible, as players cannot use any commands except /miniGamesLeave while playing
|
||||
* in an arena.</p>
|
||||
*/
|
||||
ERROR_ALREADY_PLAYING,
|
||||
|
||||
/**
|
||||
* The message displayed if a player tries to join an arena with a passenger or riding a vehicle
|
||||
*/
|
||||
ERROR_JOIN_IN_VEHICLE_OR_PASSENGER,
|
||||
|
||||
/**
|
||||
* The message displayed if the player tries to change an unrecognized arena property
|
||||
*/
|
||||
ERROR_UNKNOWN_PROPERTY,
|
||||
|
||||
/**
|
||||
* The message displayed if the given input to /dEdit or /pEdit's value is invalid
|
||||
*/
|
||||
ERROR_PROPERTY_INPUT_INVALID,
|
||||
|
||||
/**
|
||||
* The message displayed if the first arena specified in /dgSwap or /pgSwap is invalid
|
||||
*/
|
||||
ERROR_ARENA_1_NOT_FOUND,
|
||||
|
||||
/**
|
||||
* The message displayed if the second arena specified in /dgSwap or /pgSwap is invalid
|
||||
*/
|
||||
ERROR_ARENA_2_NOT_FOUND,
|
||||
|
||||
/**
|
||||
* The message displayed if the two groups specified for /dgSwap or /pgSwap are in different arenas
|
||||
*/
|
||||
ERROR_SWAP_DIFFERENT_GROUPS,
|
||||
|
||||
/**
|
||||
* The message displayed if a player tries to use any command other than /mLeave while in an arena
|
||||
*/
|
||||
ERROR_ILLEGAL_COMMAND,
|
||||
|
||||
/**
|
||||
* The message displayed if the player is trying to join a parkour arena on hardcore which has no checkpoints
|
||||
*/
|
||||
ERROR_HARDCORE_NO_CHECKPOINTS,
|
||||
|
||||
/**
|
||||
* The message displayed if a user specifies an invalid material
|
||||
*/
|
||||
ERROR_INVALID_MATERIAL,
|
||||
|
||||
/**
|
||||
* The message displayed if a user specifies an invalid world
|
||||
*/
|
||||
ERROR_INVALID_WORLD,
|
||||
|
||||
/**
|
||||
* The message displayed if a user specifies an invalid number
|
||||
*/
|
||||
ERROR_INVALID_NUMBER,
|
||||
|
||||
/**
|
||||
* The message displayed if a user specifies an invalid command (for a command reward)
|
||||
*/
|
||||
ERROR_INVALID_COMMAND_STRING,
|
||||
|
||||
/**
|
||||
* The message displayed if a user specified an invalid reward type
|
||||
*/
|
||||
ERROR_REWARD_TYPE_INVALID,
|
||||
|
||||
/**
|
||||
* The message displayed if a user specified an invalid reward condition
|
||||
*/
|
||||
ERROR_REWARD_CONDITION_INVALID,
|
||||
|
||||
/* **************** *
|
||||
* Success messages *
|
||||
* **************** */
|
||||
|
||||
/**
|
||||
* The message displayed if an arena's group has been changed
|
||||
*/
|
||||
SUCCESS_ARENA_GROUP_UPDATED,
|
||||
|
||||
/**
|
||||
* The message displayed if the MiniGames plugin is reloaded
|
||||
*/
|
||||
SUCCESS_PLUGIN_RELOADED,
|
||||
|
||||
/**
|
||||
* The message displayed if a new arena has been created
|
||||
*/
|
||||
SUCCESS_ARENA_CREATED,
|
||||
|
||||
/**
|
||||
* The message displayed if a player clears/wins an arena for the first time
|
||||
*/
|
||||
SUCCESS_ARENA_FIRST_CLEAR,
|
||||
|
||||
/**
|
||||
* The message displayed when a player wins an arena
|
||||
*/
|
||||
SUCCESS_ARENA_WIN,
|
||||
|
||||
/**
|
||||
* The message displayed when a player quits an arena
|
||||
*/
|
||||
SUCCESS_ARENA_QUIT,
|
||||
|
||||
/**
|
||||
* The message used to display the current value of an arena property
|
||||
*/
|
||||
SUCCESS_CURRENT_VALUE,
|
||||
|
||||
/**
|
||||
* The message used to announce that an arena property has been changed
|
||||
*/
|
||||
SUCCESS_PROPERTY_CHANGED,
|
||||
|
||||
/**
|
||||
* The message displayed when two arenas' order in a group have been swapped
|
||||
*/
|
||||
SUCCESS_ARENAS_SWAPPED,
|
||||
|
||||
/**
|
||||
* The message displayed when an arena has been removed
|
||||
*/
|
||||
SUCCESS_ARENA_REMOVED,
|
||||
|
||||
/**
|
||||
* The header displayed before listing all dropper arenas
|
||||
*/
|
||||
SUCCESS_DROPPER_ARENAS_LIST,
|
||||
|
||||
/**
|
||||
* The header displayed before listing all parkour arenas
|
||||
*/
|
||||
SUCCESS_PARKOUR_ARENAS_LIST,
|
||||
|
||||
/**
|
||||
* The message displayed when a player reaches a new checkpoint in a parkour arena
|
||||
*/
|
||||
SUCCESS_CHECKPOINT_REACHED,
|
||||
|
||||
/**
|
||||
* The header displayed before listing all arenas (stages) in a group
|
||||
*/
|
||||
SUCCESS_GROUP_STAGES,
|
||||
|
||||
/**
|
||||
* The message displayed when a new record has been achieved
|
||||
*/
|
||||
SUCCESS_RECORD_ACHIEVED,
|
||||
|
||||
/**
|
||||
* The partial message used to describe that the player achieved a world record
|
||||
*/
|
||||
RECORD_ACHIEVED_GLOBAL,
|
||||
|
||||
/**
|
||||
* The partial message used to describe that the player achieved a personal best record
|
||||
*/
|
||||
RECORD_ACHIEVED_PERSONAL,
|
||||
|
||||
/**
|
||||
* The message displayed when a player joins an arena
|
||||
*/
|
||||
SUCCESS_ARENA_JOINED,
|
||||
|
||||
/**
|
||||
* The message displayed when a player is rewarded with an item
|
||||
*/
|
||||
SUCCESS_ITEM_REWARDED,
|
||||
|
||||
/**
|
||||
* The message displayed when a player is rewarded with a permission
|
||||
*/
|
||||
SUCCESS_PERMISSION_REWARDED,
|
||||
|
||||
/**
|
||||
* The message displayed when a player is rewarded with a permission, for a specific world
|
||||
*/
|
||||
SUCCESS_PERMISSION_REWARDED_WORLD,
|
||||
|
||||
/**
|
||||
* The message displayed when a player is rewarded by a command being run
|
||||
*/
|
||||
SUCCESS_COMMAND_REWARDED,
|
||||
|
||||
/**
|
||||
* The message displayed when a player is rewarded with an amount of currency
|
||||
*/
|
||||
SUCCESS_ECONOMY_REWARDED,
|
||||
|
||||
/**
|
||||
* The message displayed when an arena reward has been successfully added
|
||||
*/
|
||||
SUCCESS_REWARD_ADDED,
|
||||
|
||||
/**
|
||||
* The message displayed when arena rewards have been cleared
|
||||
*/
|
||||
SUCCESS_REWARDS_CLEARED,
|
||||
;
|
||||
|
||||
@Override
|
||||
public @NotNull TranslatableMessage[] getAllMessages() {
|
||||
return MiniGameMessage.values();
|
||||
}
|
||||
|
||||
}
|
@ -16,8 +16,8 @@ public class ParkourConfiguration extends MiniGameConfiguration {
|
||||
private boolean enforceCheckpointOrder;
|
||||
private boolean mustDoGroupedInSequence;
|
||||
private boolean ignoreRecordsUntilGroupBeatenOnce;
|
||||
private boolean makePlayersInvisible;
|
||||
private Set<Material> killPlaneBlocks;
|
||||
private Set<Material> obstacleBlocks;
|
||||
|
||||
/**
|
||||
* Instantiates a new dropper configuration
|
||||
@ -55,15 +55,6 @@ public class ParkourConfiguration extends MiniGameConfiguration {
|
||||
return this.ignoreRecordsUntilGroupBeatenOnce;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether players should be made invisible while in an arena
|
||||
*
|
||||
* @return <p>Whether players should be made invisible</p>
|
||||
*/
|
||||
public boolean makePlayersInvisible() {
|
||||
return this.makePlayersInvisible;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all types of blocks constituting parkour arenas' kill planes
|
||||
*
|
||||
@ -73,13 +64,22 @@ public class ParkourConfiguration extends MiniGameConfiguration {
|
||||
return new HashSet<>(this.killPlaneBlocks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all types of blocks constituting parkour arena's obstacle blocks
|
||||
*
|
||||
* @return <p>The types of blocks constituting parkour arena's obstacle blocks</p>
|
||||
*/
|
||||
public Set<Material> getObstacleBlocks() {
|
||||
return new HashSet<>(this.obstacleBlocks);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void load() {
|
||||
this.enforceCheckpointOrder = configuration.getBoolean(rootNode + "enforceCheckpointOrder", false);
|
||||
this.mustDoGroupedInSequence = configuration.getBoolean(rootNode + "mustDoGroupedInSequence", true);
|
||||
this.ignoreRecordsUntilGroupBeatenOnce = configuration.getBoolean(rootNode + "ignoreRecordsUntilGroupBeatenOnce", false);
|
||||
this.makePlayersInvisible = configuration.getBoolean(rootNode + "makePlayersInvisible", false);
|
||||
this.killPlaneBlocks = loadMaterialList(rootNode + "killPlaneBlocks");
|
||||
this.obstacleBlocks = loadMaterialList(rootNode + "obstacleBlocks");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -89,11 +89,14 @@ public class ParkourConfiguration extends MiniGameConfiguration {
|
||||
"Current configuration:" +
|
||||
"\n" + "Must do groups in sequence: " + mustDoGroupedInSequence +
|
||||
"\n" + "Ignore records until group beaten once: " + ignoreRecordsUntilGroupBeatenOnce +
|
||||
"\n" + "Make players invisible: " + makePlayersInvisible +
|
||||
"\n" + "Kill plane blocks: ");
|
||||
for (Material material : killPlaneBlocks) {
|
||||
builder.append("\n - ").append(material.name());
|
||||
}
|
||||
builder.append("\n" + "Obstacle blocks: ");
|
||||
for (Material material : obstacleBlocks) {
|
||||
builder.append("\n - ").append(material.name());
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
|
@ -1,41 +0,0 @@
|
||||
package net.knarcraft.minigames.container;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A container for keeping track of several placeholder to value mappings
|
||||
*/
|
||||
public class PlaceholderContainer {
|
||||
|
||||
private final Map<String, String> placeholders;
|
||||
|
||||
/**
|
||||
* Instantiates a new placeholder container
|
||||
*/
|
||||
public PlaceholderContainer() {
|
||||
this.placeholders = new HashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all placeholders
|
||||
*
|
||||
* @return <p>All placeholders</p>
|
||||
*/
|
||||
public Map<String, String> getPlaceholders() {
|
||||
return new HashMap<>(this.placeholders);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new placeholder
|
||||
*
|
||||
* @param placeholder <p>The placeholder to register</p>
|
||||
* @param value <p>The value of the placeholder</p>
|
||||
* @return <p>This object</p>
|
||||
*/
|
||||
public PlaceholderContainer add(String placeholder, String value) {
|
||||
this.placeholders.put(placeholder, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
163
src/main/java/net/knarcraft/minigames/gui/ArenaGUI.java
Normal file
163
src/main/java/net/knarcraft/minigames/gui/ArenaGUI.java
Normal file
@ -0,0 +1,163 @@
|
||||
package net.knarcraft.minigames.gui;
|
||||
|
||||
import net.knarcraft.knargui.AbstractGUI;
|
||||
import net.knarcraft.knargui.GUIAction;
|
||||
import net.knarcraft.knargui.item.GUIItemFactory;
|
||||
import net.knarcraft.knargui.item.PlayerHeadGUIItemFactory;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.ArenaPlayerRegistry;
|
||||
import net.knarcraft.minigames.arena.ArenaSession;
|
||||
import net.knarcraft.minigames.arena.PlayerVisibilityManager;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A generic GUI for all arenas
|
||||
*/
|
||||
public abstract class ArenaGUI extends AbstractGUI {
|
||||
|
||||
/**
|
||||
* Instantiates a new arena gui
|
||||
*
|
||||
* @param inventorySize <p>The size of the GUI's inventory</p>
|
||||
* @param inventoryName <p>The name of the inventory</p>
|
||||
*/
|
||||
public ArenaGUI(int inventorySize, String inventoryName) {
|
||||
super(inventorySize, inventoryName, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an item describing a retry arena action
|
||||
*
|
||||
* @return <p>An arena restart item</p>
|
||||
*/
|
||||
protected ItemStack getRestartItem() {
|
||||
PlayerHeadGUIItemFactory restartItemFactory = new PlayerHeadGUIItemFactory();
|
||||
restartItemFactory.useSkin("e23b225ed0443c4eec7cf30a034490485904e6eb3d53ef2ab9e39c73bdf22c30");
|
||||
List<String> loreLines = getLoreLines();
|
||||
loreLines.add(ChatColor.GRAY + "Use this item to retry the arena");
|
||||
restartItemFactory.setName(ChatColor.BLUE + "Retry arena");
|
||||
restartItemFactory.setLore(loreLines);
|
||||
return restartItemFactory.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an item describing player visibility toggling
|
||||
*
|
||||
* @return <p>A player toggle item</p>
|
||||
*/
|
||||
protected ItemStack getTogglePlayersItemDisabled() {
|
||||
GUIItemFactory togglePlayersItemFactory = new GUIItemFactory(Material.PLAYER_HEAD);
|
||||
List<String> loreLines = getLoreLines();
|
||||
loreLines.add(ChatColor.GRAY + "Use this item to disable the visibility");
|
||||
loreLines.add(ChatColor.GRAY + "of other players");
|
||||
togglePlayersItemFactory.setName(ChatColor.BLUE + "Disable Players");
|
||||
togglePlayersItemFactory.setLore(loreLines);
|
||||
return togglePlayersItemFactory.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an item describing player visibility toggling
|
||||
*
|
||||
* @return <p>A player toggle item</p>
|
||||
*/
|
||||
protected ItemStack getTogglePlayersItemEnabled() {
|
||||
PlayerHeadGUIItemFactory togglePlayersItemFactory = new PlayerHeadGUIItemFactory();
|
||||
togglePlayersItemFactory.useSkin("c10591e6909e6a281b371836e462d67a2c78fa0952e910f32b41a26c48c1757c");
|
||||
List<String> loreLines = getLoreLines();
|
||||
loreLines.add(ChatColor.GRAY + "Use this item to enable the visibility");
|
||||
loreLines.add(ChatColor.GRAY + "of other players");
|
||||
togglePlayersItemFactory.setName(ChatColor.BLUE + "Enable Players");
|
||||
togglePlayersItemFactory.setLore(loreLines);
|
||||
return togglePlayersItemFactory.build();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets an item describing a leave arena action
|
||||
*
|
||||
* @return <p>A leave item</p>
|
||||
*/
|
||||
protected ItemStack getLeaveItem() {
|
||||
GUIItemFactory leaveItemFactory = new GUIItemFactory(Material.BARRIER);
|
||||
List<String> loreLines = getLoreLines();
|
||||
loreLines.add(ChatColor.GRAY + "Use this item to leave the arena");
|
||||
leaveItemFactory.setName(ChatColor.DARK_RED + "Leave");
|
||||
leaveItemFactory.setLore(loreLines);
|
||||
return leaveItemFactory.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an arraylist with one blank line lore-lines can be added to
|
||||
*
|
||||
* @return <p>An arraylist with one blank line</p>
|
||||
*/
|
||||
protected List<String> getLoreLines() {
|
||||
List<String> loreLines = new ArrayList<>();
|
||||
loreLines.add("");
|
||||
return loreLines;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a click action for both right-click and left-click
|
||||
*
|
||||
* @param inventorySlot <p>The inventory slot the action should be added to</p>
|
||||
* @param action <p>The action to register</p>
|
||||
*/
|
||||
protected void setAnyClickAction(int inventorySlot, GUIAction action) {
|
||||
setClickAction(inventorySlot, ClickType.LEFT, action);
|
||||
setClickAction(inventorySlot, ClickType.RIGHT, action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the action to run when triggering the leave item
|
||||
*
|
||||
* @return <p>The leave action</p>
|
||||
*/
|
||||
public static GUIAction getLeaveAction() {
|
||||
return (player) -> {
|
||||
ArenaSession session = MiniGames.getInstance().getSession(player.getUniqueId());
|
||||
if (session != null) {
|
||||
session.triggerQuit(false, true);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the action to run when triggering the restart action
|
||||
*
|
||||
* @return <p>The action for triggering a session restart</p>
|
||||
*/
|
||||
public static GUIAction getRestartAction() {
|
||||
return (player -> {
|
||||
ArenaSession session = MiniGames.getInstance().getSession(player.getUniqueId());
|
||||
if (session != null) {
|
||||
session.reset();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the action to run when triggering the toggle players action
|
||||
*
|
||||
* @param playerRegistry <p>The registry containing relevant players</p>
|
||||
* @return <p>The action for triggering player visibility</p>
|
||||
*/
|
||||
public GUIAction getTogglePlayersAction(ArenaPlayerRegistry<?> playerRegistry) {
|
||||
return (player) -> {
|
||||
PlayerVisibilityManager visibilityManager = MiniGames.getInstance().getPlayerVisibilityManager();
|
||||
visibilityManager.toggleHidePlayers(playerRegistry, player);
|
||||
if (MiniGames.getInstance().getPlayerVisibilityManager().isHidingPlayers(player)) {
|
||||
setItem(0, getTogglePlayersItemEnabled());
|
||||
} else {
|
||||
setItem(0, getTogglePlayersItemDisabled());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
31
src/main/java/net/knarcraft/minigames/gui/DropperGUI.java
Normal file
31
src/main/java/net/knarcraft/minigames/gui/DropperGUI.java
Normal file
@ -0,0 +1,31 @@
|
||||
package net.knarcraft.minigames.gui;
|
||||
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* A GUI used in the dropper arena
|
||||
*/
|
||||
public class DropperGUI extends ArenaGUI {
|
||||
|
||||
/**
|
||||
* Instantiates a new dropper gui
|
||||
*
|
||||
* @param player <p>The player the GUI is created for</p>
|
||||
*/
|
||||
public DropperGUI(Player player) {
|
||||
super(9, "Dropper");
|
||||
if (MiniGames.getInstance().getPlayerVisibilityManager().isHidingPlayers(player)) {
|
||||
setItem(0, getTogglePlayersItemEnabled());
|
||||
} else {
|
||||
setItem(0, getTogglePlayersItemDisabled());
|
||||
}
|
||||
setItem(2, getLeaveItem());
|
||||
setItem(4, getRestartItem());
|
||||
|
||||
setAnyClickAction(0, getTogglePlayersAction(MiniGames.getInstance().getDropperArenaPlayerRegistry()));
|
||||
setAnyClickAction(2, getLeaveAction());
|
||||
setAnyClickAction(4, getRestartAction());
|
||||
}
|
||||
|
||||
}
|
27
src/main/java/net/knarcraft/minigames/gui/MiniGamesGUI.java
Normal file
27
src/main/java/net/knarcraft/minigames/gui/MiniGamesGUI.java
Normal file
@ -0,0 +1,27 @@
|
||||
package net.knarcraft.minigames.gui;
|
||||
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
* A GUI used outside arenas
|
||||
*/
|
||||
public class MiniGamesGUI extends ArenaGUI {
|
||||
|
||||
/**
|
||||
* Instantiates a new mini games gui
|
||||
*
|
||||
* @param player <p>The player the GUI is created for</p>
|
||||
*/
|
||||
public MiniGamesGUI(Player player) {
|
||||
super(9, "MiniGames");
|
||||
if (MiniGames.getInstance().getPlayerVisibilityManager().isHidingPlayers(player)) {
|
||||
setItem(0, getTogglePlayersItemEnabled());
|
||||
} else {
|
||||
setItem(0, getTogglePlayersItemDisabled());
|
||||
}
|
||||
|
||||
setAnyClickAction(0, getTogglePlayersAction(null));
|
||||
}
|
||||
|
||||
}
|
71
src/main/java/net/knarcraft/minigames/gui/ParkourGUI.java
Normal file
71
src/main/java/net/knarcraft/minigames/gui/ParkourGUI.java
Normal file
@ -0,0 +1,71 @@
|
||||
package net.knarcraft.minigames.gui;
|
||||
|
||||
import net.knarcraft.knargui.GUIAction;
|
||||
import net.knarcraft.knargui.item.GUIItemFactory;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.ArenaSession;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArenaSession;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A GUI used in the parkour arena
|
||||
*/
|
||||
public class ParkourGUI extends ArenaGUI {
|
||||
|
||||
/**
|
||||
* Instantiates a new parkour gui
|
||||
*
|
||||
* @param player <p>The player the GUI is created for</p>
|
||||
*/
|
||||
public ParkourGUI(Player player) {
|
||||
super(9, "Parkour");
|
||||
if (MiniGames.getInstance().getPlayerVisibilityManager().isHidingPlayers(player)) {
|
||||
setItem(0, getTogglePlayersItemEnabled());
|
||||
} else {
|
||||
setItem(0, getTogglePlayersItemDisabled());
|
||||
}
|
||||
setItem(2, getGiveUpItem());
|
||||
setItem(4, getLeaveItem());
|
||||
setItem(6, getRestartItem());
|
||||
|
||||
setAnyClickAction(0, getTogglePlayersAction(MiniGames.getInstance().getParkourArenaPlayerRegistry()));
|
||||
setAnyClickAction(2, getGiveUpAction());
|
||||
setAnyClickAction(4, getLeaveAction());
|
||||
setAnyClickAction(6, getRestartAction());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an item describing a give up action
|
||||
*
|
||||
* @return <p>A give up item</p>
|
||||
*/
|
||||
private ItemStack getGiveUpItem() {
|
||||
GUIItemFactory giveUpItemFactory = new GUIItemFactory(Material.RESPAWN_ANCHOR);
|
||||
List<String> loreLines = getLoreLines();
|
||||
loreLines.add(ChatColor.GRAY + "Use this item to give up");
|
||||
loreLines.add(ChatColor.GRAY + "and go to the last checkpoint");
|
||||
giveUpItemFactory.setName(ChatColor.RED + "Give up");
|
||||
giveUpItemFactory.setLore(loreLines);
|
||||
return giveUpItemFactory.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the action to run when triggering the give up item
|
||||
*
|
||||
* @return <p>The give up action</p>
|
||||
*/
|
||||
public static GUIAction getGiveUpAction() {
|
||||
return (player) -> {
|
||||
ArenaSession session = MiniGames.getInstance().getSession(player.getUniqueId());
|
||||
if (session instanceof ParkourArenaSession) {
|
||||
session.triggerLoss();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
@ -2,7 +2,7 @@ package net.knarcraft.minigames.listener;
|
||||
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.ArenaSession;
|
||||
import net.knarcraft.minigames.config.Message;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
@ -29,6 +29,8 @@ public class CommandListener implements Listener {
|
||||
allowedCommands.add("/mLeave");
|
||||
allowedCommands.add("/dLeave");
|
||||
allowedCommands.add("/pLeave");
|
||||
allowedCommands.add("/miniGamesMenu");
|
||||
allowedCommands.add("/mMenu");
|
||||
|
||||
String message = event.getMessage();
|
||||
if (!message.startsWith("/")) {
|
||||
@ -41,7 +43,7 @@ public class CommandListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
player.sendMessage(Message.ERROR_ILLEGAL_COMMAND.getMessage());
|
||||
MiniGames.getInstance().getStringFormatter().displayErrorMessage(player, MiniGameMessage.ERROR_ILLEGAL_COMMAND);
|
||||
event.setCancelled(true);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,53 @@
|
||||
package net.knarcraft.minigames.listener;
|
||||
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.gui.ArenaGUI;
|
||||
import net.knarcraft.minigames.gui.ParkourGUI;
|
||||
import net.knarcraft.minigames.property.PersistentDataKey;
|
||||
import net.knarcraft.minigames.util.GUIHelper;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerInteractEvent;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
/**
|
||||
* A listener that listens for player interactions
|
||||
*/
|
||||
public class InteractListener implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void menuInteractListener(PlayerInteractEvent event) {
|
||||
ItemStack item = event.getItem();
|
||||
if (item == null || !item.hasItemMeta()) {
|
||||
return;
|
||||
}
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
if (meta == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
Integer persistentData = meta.getPersistentDataContainer().get(new NamespacedKey(MiniGames.getInstance(),
|
||||
PersistentDataKey.MENU_ITEM.getKeyName()), PersistentDataType.INTEGER);
|
||||
|
||||
if (persistentData != null && persistentData == PersistentDataKey.MENU_ITEM.getDataValue()) {
|
||||
event.setCancelled(true);
|
||||
GUIHelper.openGUI(event.getPlayer());
|
||||
return;
|
||||
}
|
||||
|
||||
persistentData = meta.getPersistentDataContainer().get(new NamespacedKey(MiniGames.getInstance(),
|
||||
PersistentDataKey.LEAVE_ITEM.getKeyName()), PersistentDataType.INTEGER);
|
||||
if (persistentData != null) {
|
||||
event.setCancelled(true);
|
||||
if (persistentData == PersistentDataKey.LEAVE_ITEM.getDataValue()) {
|
||||
ArenaGUI.getLeaveAction().run(event.getPlayer());
|
||||
} else if (persistentData == PersistentDataKey.GIVE_UP_ITEM.getDataValue()) {
|
||||
ParkourGUI.getGiveUpAction().run(event.getPlayer());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -3,20 +3,25 @@ package net.knarcraft.minigames.listener;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.Arena;
|
||||
import net.knarcraft.minigames.arena.ArenaSession;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArena;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaGameMode;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaSession;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArena;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArenaGameMode;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArenaSession;
|
||||
import net.knarcraft.minigames.config.DropperConfiguration;
|
||||
import net.knarcraft.minigames.config.Message;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import net.knarcraft.minigames.config.ParkourConfiguration;
|
||||
import net.knarcraft.minigames.config.SharedConfiguration;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerMoveEvent;
|
||||
import org.bukkit.util.BoundingBox;
|
||||
import org.bukkit.util.Vector;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@ -30,6 +35,8 @@ import java.util.Set;
|
||||
*/
|
||||
public class MoveListener implements Listener {
|
||||
|
||||
private static final BoundingBox fullBlockBox = new BoundingBox(0, 0, 0, 1, 1, 1);
|
||||
|
||||
private final DropperConfiguration dropperConfiguration;
|
||||
private final ParkourConfiguration parkourConfiguration;
|
||||
|
||||
@ -47,12 +54,15 @@ public class MoveListener implements Listener {
|
||||
@EventHandler
|
||||
public void onPlayerMove(PlayerMoveEvent event) {
|
||||
// Ignore if no actual movement is happening
|
||||
if (event.getFrom().equals(event.getTo()) || event.getTo() == null) {
|
||||
if (event.getTo() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ArenaSession session = MiniGames.getInstance().getSession(event.getPlayer().getUniqueId());
|
||||
if (session instanceof DropperArenaSession dropperSession) {
|
||||
if (event.getFrom().equals(event.getTo())) {
|
||||
return;
|
||||
}
|
||||
doDropperArenaChecks(event, dropperSession);
|
||||
} else if (session instanceof ParkourArenaSession parkourSession) {
|
||||
doParkourArenaChecks(event, parkourSession);
|
||||
@ -66,8 +76,7 @@ public class MoveListener implements Listener {
|
||||
* @param arenaSession <p>The dropper session of the player triggering the event</p>
|
||||
*/
|
||||
private void doParkourArenaChecks(@NotNull PlayerMoveEvent event, ParkourArenaSession arenaSession) {
|
||||
// Ignore movement which won't cause the player's block to change
|
||||
if (event.getTo() == null || event.getFrom().getBlock() == event.getTo().getBlock()) {
|
||||
if (event.getTo() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -76,14 +85,30 @@ public class MoveListener implements Listener {
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip checkpoint registration if playing on hardcore
|
||||
if (arenaSession.getGameMode() == ParkourArenaGameMode.HARDCORE) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the player reached one of the checkpoints for the arena
|
||||
updateCheckpoint(arenaSession, event.getTo().getBlock(), event.getPlayer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the checkpoint of a player if reached
|
||||
*
|
||||
* @param arenaSession <p>The session of the player</p>
|
||||
* @param targetBlock <p>The block the player is moving to</p>
|
||||
* @param player <p>The player moving</p>
|
||||
*/
|
||||
private void updateCheckpoint(ParkourArenaSession arenaSession, Block targetBlock, Player player) {
|
||||
ParkourArena arena = arenaSession.getArena();
|
||||
List<Location> checkpoints = arena.getCheckpoints();
|
||||
for (Location checkpoint : checkpoints) {
|
||||
Location previousCheckpoint = arenaSession.getRegisteredCheckpoint();
|
||||
|
||||
// Skip if checkpoint has not been reached
|
||||
if (!checkpoint.getBlock().equals(event.getTo().getBlock())) {
|
||||
if (!checkpoint.getBlock().equals(targetBlock)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -103,7 +128,8 @@ public class MoveListener implements Listener {
|
||||
|
||||
// Register the checkpoint
|
||||
arenaSession.registerCheckpoint(checkpoint.clone());
|
||||
event.getPlayer().sendMessage(Message.SUCCESS_CHECKPOINT_REACHED.getMessage());
|
||||
MiniGames.getInstance().getStringFormatter().displaySuccessMessage(player,
|
||||
MiniGameMessage.SUCCESS_CHECKPOINT_REACHED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -115,14 +141,26 @@ public class MoveListener implements Listener {
|
||||
* @param arenaSession <p>The dropper session of the player triggering the event</p>
|
||||
*/
|
||||
private void doDropperArenaChecks(@NotNull PlayerMoveEvent event, @NotNull DropperArenaSession arenaSession) {
|
||||
if (event.getTo() == null) {
|
||||
// If the player has yet to move in the arena, allow them to look around
|
||||
boolean startedMoving = arenaSession.getStartedMoving();
|
||||
if (event.getTo() == null ||
|
||||
(!startedMoving && isSameLocation(event.getFrom(), event.getTo()))) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Marks the player as started moving if necessary, so they can no longer hang in the air
|
||||
if (!startedMoving) {
|
||||
arenaSession.setStartedMoving();
|
||||
}
|
||||
|
||||
// Prevent the player from flying upwards while in flight mode
|
||||
if (event.getFrom().getY() < event.getTo().getY() ||
|
||||
(dropperConfiguration.blockSneaking() && event.getPlayer().isSneaking()) ||
|
||||
(dropperConfiguration.blockSprinting() && event.getPlayer().isSprinting())) {
|
||||
event.setCancelled(true);
|
||||
// Force movement downwards once the player lets go
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(MiniGames.getInstance(),
|
||||
() -> updatePlayerVelocity(arenaSession), 1);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -137,6 +175,18 @@ public class MoveListener implements Listener {
|
||||
updatePlayerVelocity(arenaSession);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if two locations are the same, excluding rotation
|
||||
*
|
||||
* @param location1 <p>The first location to check</p>
|
||||
* @param location2 <p>The second location to check</p>
|
||||
* @return <p>True if the locations are the same, excluding rotation</p>
|
||||
*/
|
||||
private boolean isSameLocation(Location location1, Location location2) {
|
||||
return location1.getX() == location2.getX() && location1.getY() == location2.getY() &&
|
||||
location1.getZ() == location2.getZ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the player in the session is triggering a block with a special significance
|
||||
*
|
||||
@ -146,30 +196,140 @@ public class MoveListener implements Listener {
|
||||
* @param toLocation <p>The location the player's session is about to hit</p>
|
||||
* @return <p>True if a special block has been hit</p>
|
||||
*/
|
||||
private boolean checkForSpecialBlock(ArenaSession arenaSession, Location toLocation) {
|
||||
private boolean checkForSpecialBlock(@NotNull ArenaSession arenaSession, @NotNull Location toLocation) {
|
||||
SharedConfiguration sharedConfiguration = MiniGames.getInstance().getSharedConfiguration();
|
||||
double liquidDepth = sharedConfiguration.getLiquidHitBoxDepth();
|
||||
double solidDepth = sharedConfiguration.getSolidHitBoxDistance();
|
||||
|
||||
double liquidDepth = sharedConfiguration.getLiquidHitBoxDepth();
|
||||
Arena arena = arenaSession.getArena();
|
||||
|
||||
// For water, only trigger when the player enters the water, but trigger earlier for everything else
|
||||
double depth = arena.winLocationIsSolid() ? solidDepth : liquidDepth;
|
||||
for (Block block : getBlocksBeneathLocation(toLocation, depth)) {
|
||||
Set<Block> potentialWinTriggerBlocks;
|
||||
if (arena.winLocationIsSolid()) {
|
||||
potentialWinTriggerBlocks = getBlocksBeneathLocation(toLocation, solidDepth);
|
||||
} else {
|
||||
potentialWinTriggerBlocks = getBlocksBeneathLocation(toLocation, liquidDepth);
|
||||
}
|
||||
for (Block block : potentialWinTriggerBlocks) {
|
||||
if (arena.willCauseWin(block)) {
|
||||
arenaSession.triggerWin();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the player is about to hit a non-air and non-liquid block
|
||||
for (Block block : getBlocksBeneathLocation(toLocation, solidDepth)) {
|
||||
if (!block.getType().isAir() && arena.willCauseLoss(block)) {
|
||||
if (arena instanceof DropperArena) {
|
||||
// Check if the player is about to hit a non-air and non-liquid block
|
||||
for (Block block : getBlocksBeneathLocation(toLocation, solidDepth)) {
|
||||
if (!block.getType().isAir() && !block.isLiquid() && arena.willCauseLoss(block)) {
|
||||
arenaSession.triggerLoss();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the player has entered a liquid that causes a loss
|
||||
for (Block block : getBlocksBeneathLocation(toLocation, liquidDepth)) {
|
||||
if (block.isLiquid() && arena.willCauseLoss(block)) {
|
||||
arenaSession.triggerLoss();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (arena instanceof ParkourArena) {
|
||||
return checkParkourDeathBlock((ParkourArenaSession) arenaSession, toLocation);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a player is moving onto a block part of the parkour death plane
|
||||
*
|
||||
* @param arenaSession <p>The player's arena session</p>
|
||||
* @param toLocation <p>The location the player is moving to</p>
|
||||
* @return <p>True if the player hit a death block</p>
|
||||
*/
|
||||
private boolean checkParkourDeathBlock(@NotNull ParkourArenaSession arenaSession,
|
||||
@NotNull Location toLocation) {
|
||||
// A simple check, only for kill blocks
|
||||
if (isOnKillBlock(arenaSession, toLocation)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// As the check for obstacle blocks is extensive, it's skipped if possible
|
||||
Set<Material> obstacleBlocks = arenaSession.getArena().getObstacleBlocks();
|
||||
if (obstacleBlocks.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create a hit-box approximate to the player's real hit-box
|
||||
double playerHeight = 1.8;
|
||||
Player player = Bukkit.getPlayer(arenaSession.getEntryState().getPlayerId());
|
||||
if (player != null && player.isSneaking()) {
|
||||
playerHeight = 1.5;
|
||||
}
|
||||
BoundingBox playerBox = new BoundingBox(-0.05, -0.05, -0.05,
|
||||
0.6 + 0.05, playerHeight + 0.05, 0.6 + 0.05).shift(
|
||||
toLocation).shift(-0.3, -0.05, -0.3);
|
||||
BoundingBox playerPassableBox = new BoundingBox(0.2, 0.5, 0.2,
|
||||
0.4, playerHeight - 0.5, 0.4).shift(
|
||||
toLocation).shift(-0.3, 0, -0.3);
|
||||
Set<Block> possiblyHitBlocks = new HashSet<>();
|
||||
possiblyHitBlocks.addAll(getBlocksBeneathLocation(toLocation, 0, 0.01));
|
||||
possiblyHitBlocks.addAll(getBlocksBeneathLocation(toLocation, 1, 0.01));
|
||||
possiblyHitBlocks.addAll(getBlocksBeneathLocation(toLocation, -1, 0.01));
|
||||
possiblyHitBlocks.addAll(getBlocksBeneathLocation(toLocation, -2, 0.01));
|
||||
|
||||
for (Block block : possiblyHitBlocks) {
|
||||
if (!obstacleBlocks.contains(block.getType())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// For liquids, or anything without a proper collision shape, trigger collision if the player is partly
|
||||
// inside when treated as a full block
|
||||
if (block.isLiquid() || block.getCollisionShape().getBoundingBoxes().isEmpty()) {
|
||||
if (playerPassableBox.overlaps(fullBlockBox.clone().shift(block.getLocation()))) {
|
||||
arenaSession.triggerLoss();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Check whether the player's actual hit-box is intersecting with a block
|
||||
for (BoundingBox boundingBox : block.getCollisionShape().getBoundingBoxes()) {
|
||||
// A collision shape's bounding box is relative to 0,0 and therefore must be adjusted to the block's
|
||||
// location. Then overlap is checked by the player's collision box and the shifted bounding box.
|
||||
if (playerBox.overlaps(boundingBox.clone().shift(block.getLocation()))) {
|
||||
arenaSession.triggerLoss();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* As simple check for whether a player is moving on top of a kill block
|
||||
*
|
||||
* @param arenaSession <p>The arena session the player is in</p>
|
||||
* @param toLocation <p>The location the player is moving to</p>
|
||||
* @return <p>True if the player is on a kill block, and a loss has been triggered</p>
|
||||
*/
|
||||
private boolean isOnKillBlock(ParkourArenaSession arenaSession, Location toLocation) {
|
||||
// If the player is standing on a non-full block, event.getTo will give the correct block, but if not, the
|
||||
// block below has to be checked instead.
|
||||
Set<Block> blocksBelow = getBlocksBeneathLocation(toLocation, 0);
|
||||
Set<Material> killPlaneBlocks = arenaSession.getArena().getKillPlaneBlocks();
|
||||
for (Block block : blocksBelow) {
|
||||
if (block.getType().isAir()) {
|
||||
block = block.getLocation().clone().subtract(0, 0.2, 0).getBlock();
|
||||
// Only trigger hit detection for passable blocks if the player is in the block
|
||||
if (block.isPassable()) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (killPlaneBlocks.contains(block.getType())) {
|
||||
arenaSession.triggerLoss();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -180,12 +340,31 @@ public class MoveListener implements Listener {
|
||||
* @return <p>The blocks beneath the player</p>
|
||||
*/
|
||||
private Set<Block> getBlocksBeneathLocation(Location location, double depth) {
|
||||
return getBlocksBeneathLocation(location, depth, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the blocks at the given location that will be affected by the player's hit-box
|
||||
*
|
||||
* @param location <p>The location to check</p>
|
||||
* @param extraRange <p>Extra range of the square used for finding blocks</p>
|
||||
* @return <p>The blocks beneath the player</p>
|
||||
*/
|
||||
private Set<Block> getBlocksBeneathLocation(Location location, double depth, double extraRange) {
|
||||
Set<Block> blocksBeneath = new HashSet<>();
|
||||
double halfPlayerWidth = 0.3;
|
||||
double halfPlayerWidth = 0.3 + extraRange;
|
||||
blocksBeneath.add(location.clone().subtract(halfPlayerWidth, depth, halfPlayerWidth).getBlock());
|
||||
blocksBeneath.add(location.clone().subtract(-halfPlayerWidth, depth, halfPlayerWidth).getBlock());
|
||||
blocksBeneath.add(location.clone().subtract(halfPlayerWidth, depth, -halfPlayerWidth).getBlock());
|
||||
blocksBeneath.add(location.clone().subtract(-halfPlayerWidth, depth, -halfPlayerWidth).getBlock());
|
||||
// Once a certain size is reached, if the player is in the centre of a block, 9 must be accounted for
|
||||
if (halfPlayerWidth > 0.5) {
|
||||
blocksBeneath.add(location.getBlock());
|
||||
blocksBeneath.add(location.clone().subtract(halfPlayerWidth, depth, 0).getBlock());
|
||||
blocksBeneath.add(location.clone().subtract(-halfPlayerWidth, depth, 0).getBlock());
|
||||
blocksBeneath.add(location.clone().subtract(0, depth, -halfPlayerWidth).getBlock());
|
||||
blocksBeneath.add(location.clone().subtract(0, depth, halfPlayerWidth).getBlock());
|
||||
}
|
||||
return blocksBeneath;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,55 @@
|
||||
package net.knarcraft.minigames.manager;
|
||||
|
||||
import net.milkbowl.vault.economy.Economy;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
/**
|
||||
* A manager that performs all Economy tasks
|
||||
*/
|
||||
public final class EconomyManager {
|
||||
|
||||
private static Economy economy;
|
||||
|
||||
private EconomyManager() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the economy manager
|
||||
*
|
||||
* @param economy <p>The economy object to use for everything economy-related</p>
|
||||
*/
|
||||
public static void initialize(Economy economy) {
|
||||
EconomyManager.economy = economy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the economy manager has been initialized
|
||||
*
|
||||
* @return <p>True if the economy manager has been initialized</p>
|
||||
*/
|
||||
public static boolean isInitialized() {
|
||||
return EconomyManager.economy != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the given amount of currency according to the economy plugin's format
|
||||
*
|
||||
* @param amount <p>The amount of currency to format</p>
|
||||
* @return <p>The formatted string</p>
|
||||
*/
|
||||
public static String format(double amount) {
|
||||
return economy.format(amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deposits a given sum into the given player's account
|
||||
*
|
||||
* @param player <p>The player to deposit money to</p>
|
||||
* @param sum <p>The amount of money to deposit</p>
|
||||
*/
|
||||
public static void deposit(OfflinePlayer player, double sum) {
|
||||
economy.depositPlayer(player, sum);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package net.knarcraft.minigames.manager;
|
||||
|
||||
import net.milkbowl.vault.permission.Permission;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* A manager that performs all Permission tasks
|
||||
*/
|
||||
public final class PermissionManager {
|
||||
|
||||
private static Permission permission;
|
||||
|
||||
private PermissionManager() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the permission manager
|
||||
*
|
||||
* @param permission <p>The permission object to use for everything permission-related</p>
|
||||
*/
|
||||
public static void initialize(Permission permission) {
|
||||
PermissionManager.permission = permission;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the permission manager has been initialized
|
||||
*
|
||||
* @return <p>True if the permission manager has been initialized</p>
|
||||
*/
|
||||
public static boolean isInitialized() {
|
||||
return PermissionManager.permission != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grants a permanent permission to a player
|
||||
*
|
||||
* @param player <p>The player to grant the permission to</p>
|
||||
* @param permissionNode <p>The permission node to grant to the player</p>
|
||||
*/
|
||||
public static void addPermission(@NotNull Player player, @NotNull String permissionNode, @Nullable World world) {
|
||||
if (world != null) {
|
||||
permission.playerAdd(world.getName(), player, permissionNode);
|
||||
} else {
|
||||
permission.playerAdd(player, permissionNode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the given player has the given permission
|
||||
*
|
||||
* @param player <p>The player to check</p>
|
||||
* @param permissionNode <p>The permission node to check for</p>
|
||||
* @param world <p>The world to check for the permission</p>
|
||||
* @return <p>True if the player has the permission</p>
|
||||
*/
|
||||
public static boolean hasPermission(@NotNull Player player, @NotNull String permissionNode, @Nullable String world) {
|
||||
return permission.playerHas(world, player, permissionNode);
|
||||
}
|
||||
|
||||
}
|
@ -26,7 +26,7 @@ public class DropperRecordExpansion extends RecordExpansion {
|
||||
|
||||
@Override
|
||||
protected @NotNull ArenaGameMode parseGameMode(@NotNull String gameMode) {
|
||||
return DropperArenaGameMode.matchGamemode(gameMode);
|
||||
return DropperArenaGameMode.matchGameMode(gameMode);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.knarcraft.minigames.placeholder;
|
||||
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.Arena;
|
||||
import net.knarcraft.minigames.arena.ArenaGameMode;
|
||||
import net.knarcraft.minigames.arena.ArenaGroup;
|
||||
@ -26,6 +27,7 @@ import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* A placeholder expansion for parkour record placeholders
|
||||
@ -71,7 +73,14 @@ public abstract class RecordExpansion extends PlaceholderExpansion {
|
||||
ArenaGameMode gameMode = parseGameMode(parts[2]);
|
||||
SelectionType selectionType = SelectionType.getFromString(parts[3]);
|
||||
String identifier = parts[4];
|
||||
int recordNumber = Integer.parseInt(parts[5]) - 1;
|
||||
int recordNumber;
|
||||
try {
|
||||
recordNumber = Integer.parseInt(parts[5]) - 1;
|
||||
} catch (NumberFormatException exception) {
|
||||
MiniGames.log(Level.WARNING, "Invalid placeholder given. " + parts[5] +
|
||||
" supplied instead of record placement.");
|
||||
return parameters;
|
||||
}
|
||||
InfoType infoType = InfoType.getFromString(parts[6]);
|
||||
|
||||
if (recordType == null || infoType == null) {
|
||||
@ -304,8 +313,8 @@ public abstract class RecordExpansion extends PlaceholderExpansion {
|
||||
private String getRecordData(@NotNull InfoType infoType, @NotNull ArenaRecord<?> arenaRecord) {
|
||||
return switch (infoType) {
|
||||
case PLAYER -> getPlayerName(arenaRecord.getUserId());
|
||||
case VALUE -> arenaRecord.getRecord().toString();
|
||||
case COMBINED -> getPlayerName(arenaRecord.getUserId()) + ": " + arenaRecord.getRecord().toString();
|
||||
case VALUE -> arenaRecord.getAsString();
|
||||
case COMBINED -> getPlayerName(arenaRecord.getUserId()) + ": " + arenaRecord.getAsString();
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,45 @@
|
||||
package net.knarcraft.minigames.property;
|
||||
|
||||
/**
|
||||
* An enum for all persistent data keys used by this plugin
|
||||
*/
|
||||
public enum PersistentDataKey {
|
||||
|
||||
MENU_ITEM("MiniGamesMenu", 1799804),
|
||||
LEAVE_ITEM("MiniGamesAction", 1799871),
|
||||
GIVE_UP_ITEM("MiniGamesAction", 1799872),
|
||||
;
|
||||
|
||||
private final String keyName;
|
||||
private final int dataValue;
|
||||
|
||||
/**
|
||||
* Instantiates a new persistent data key
|
||||
*
|
||||
* @param keyName <p>The name of this key</p>
|
||||
* @param dataValue <p>The integer data value of this key</p>
|
||||
*/
|
||||
PersistentDataKey(String keyName, int dataValue) {
|
||||
this.keyName = keyName;
|
||||
this.dataValue = dataValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of this persistent data key
|
||||
*
|
||||
* @return <p>The name of this key</p>
|
||||
*/
|
||||
public String getKeyName() {
|
||||
return this.keyName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the integer data value of this persistent data key
|
||||
*
|
||||
* @return <p>The integer data value</p>
|
||||
*/
|
||||
public int getDataValue() {
|
||||
return this.dataValue;
|
||||
}
|
||||
|
||||
}
|
@ -35,7 +35,7 @@ public final class ArenaStorageHelper {
|
||||
|
||||
try {
|
||||
configuration.save(new File(MiniGames.getInstance().getDataFolder(), key + "EntryStates.yml"));
|
||||
} catch (IOException e) {
|
||||
} catch (IOException exception) {
|
||||
MiniGames.log(Level.SEVERE, "Unable to save entry states to disk");
|
||||
}
|
||||
}
|
||||
|
@ -1,29 +0,0 @@
|
||||
package net.knarcraft.minigames.util;
|
||||
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* A helper class for converting colors
|
||||
*/
|
||||
public class ColorHelper {
|
||||
|
||||
/**
|
||||
* Translates all found color codes to formatting in a string
|
||||
*
|
||||
* @param message <p>The string to search for color codes</p>
|
||||
* @return <p>The message with color codes translated</p>
|
||||
*/
|
||||
public static String translateAllColorCodes(String message) {
|
||||
message = ChatColor.translateAlternateColorCodes('&', message);
|
||||
Pattern pattern = Pattern.compile("&?(#[a-fA-F0-9]{6})");
|
||||
Matcher matcher = pattern.matcher(message);
|
||||
while (matcher.find()) {
|
||||
message = message.replace(matcher.group(), "" + ChatColor.of(matcher.group(1)));
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
@ -9,8 +9,9 @@ import net.knarcraft.minigames.arena.dropper.DropperArenaGameMode;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaGroup;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaRecordsRegistry;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaStorageKey;
|
||||
import net.knarcraft.minigames.config.Message;
|
||||
import net.knarcraft.minigames.container.PlaceholderContainer;
|
||||
import net.knarcraft.minigames.arena.reward.Reward;
|
||||
import net.knarcraft.minigames.arena.reward.RewardCondition;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import net.knarcraft.minigames.container.SerializableMaterial;
|
||||
import net.knarcraft.minigames.container.SerializableUUID;
|
||||
import org.bukkit.Location;
|
||||
@ -19,6 +20,7 @@ import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.yaml.snakeyaml.error.YAMLException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@ -96,21 +98,49 @@ public final class DropperArenaStorageHelper {
|
||||
YamlConfiguration configuration = new YamlConfiguration();
|
||||
ConfigurationSection arenaSection = configuration.createSection(dropperArenasConfigurationSection);
|
||||
for (DropperArena arena : arenas.values()) {
|
||||
//Note: While the arena name is used as the key, as the key has to be sanitized, the un-sanitized arena name
|
||||
// must be stored as well
|
||||
@NotNull ConfigurationSection configSection = arenaSection.createSection(arena.getArenaId().toString());
|
||||
configSection.set(DropperArenaStorageKey.ID.getKey(), new SerializableUUID(arena.getArenaId()));
|
||||
configSection.set(DropperArenaStorageKey.NAME.getKey(), arena.getArenaName());
|
||||
configSection.set(DropperArenaStorageKey.SPAWN_LOCATION.getKey(), arena.getSpawnLocation());
|
||||
configSection.set(DropperArenaStorageKey.EXIT_LOCATION.getKey(), arena.getExitLocation());
|
||||
configSection.set(DropperArenaStorageKey.PLAYER_VERTICAL_VELOCITY.getKey(), arena.getPlayerVerticalVelocity());
|
||||
configSection.set(DropperArenaStorageKey.PLAYER_HORIZONTAL_VELOCITY.getKey(), arena.getPlayerHorizontalVelocity());
|
||||
configSection.set(DropperArenaStorageKey.WIN_BLOCK_TYPE.getKey(), new SerializableMaterial(arena.getWinBlockType()));
|
||||
saveDropperArenaData(arena.getData());
|
||||
saveDropperArena(arenaSection, arena);
|
||||
}
|
||||
configuration.save(dropperArenaFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a single arena
|
||||
*
|
||||
* @param arena <p>The arena to save</p>
|
||||
* @throws IOException <p>If unable to write to the file</p>
|
||||
*/
|
||||
public static void saveSingleDropperArena(DropperArena arena) throws IOException {
|
||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(dropperArenaFile);
|
||||
ConfigurationSection arenaSection = configuration.getConfigurationSection(dropperArenasConfigurationSection);
|
||||
if (arenaSection == null) {
|
||||
arenaSection = configuration.createSection(dropperArenasConfigurationSection);
|
||||
}
|
||||
saveDropperArena(arenaSection, arena);
|
||||
configuration.save(dropperArenaFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the given configuration section with the arena's data, and stores arena data for the arena
|
||||
*
|
||||
* @param arenaSection <p>The configuration section to update</p>
|
||||
* @param arena <p>The arena to save</p>
|
||||
* @throws IOException <p>If unable to save the arena data</p>
|
||||
*/
|
||||
private static void saveDropperArena(ConfigurationSection arenaSection, DropperArena arena) throws IOException {
|
||||
//Note: While the arena name is used as the key, as the key has to be sanitized, the un-sanitized arena name
|
||||
// must be stored as well
|
||||
@NotNull ConfigurationSection configSection = arenaSection.createSection(arena.getArenaId().toString());
|
||||
configSection.set(DropperArenaStorageKey.ID.getKey(), new SerializableUUID(arena.getArenaId()));
|
||||
configSection.set(DropperArenaStorageKey.NAME.getKey(), arena.getArenaName());
|
||||
configSection.set(DropperArenaStorageKey.SPAWN_LOCATION.getKey(), arena.getSpawnLocation());
|
||||
configSection.set(DropperArenaStorageKey.EXIT_LOCATION.getKey(), arena.getExitLocation());
|
||||
configSection.set(DropperArenaStorageKey.PLAYER_VERTICAL_VELOCITY.getKey(), arena.getPlayerVerticalVelocity());
|
||||
configSection.set(DropperArenaStorageKey.PLAYER_HORIZONTAL_VELOCITY.getKey(), arena.getPlayerHorizontalVelocity());
|
||||
configSection.set(DropperArenaStorageKey.WIN_BLOCK_TYPE.getKey(), new SerializableMaterial(arena.getWinBlockType()));
|
||||
RewardStorageHelper.saveRewards(arena, configSection, DropperArenaStorageKey.REWARDS.getKey());
|
||||
saveDropperArenaData(arena.getData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all arenas
|
||||
*
|
||||
@ -161,24 +191,28 @@ public final class DropperArenaStorageHelper {
|
||||
DropperArenaStorageKey.WIN_BLOCK_TYPE.getKey());
|
||||
|
||||
if (arenaName == null || spawnLocation == null) {
|
||||
MiniGames.log(Level.SEVERE, Message.ERROR_ARENA_NOT_LOADED.getMessage(new PlaceholderContainer().add(
|
||||
"{section}", configurationSection.getName()).add("{file}", "dropper_arenas")));
|
||||
MiniGames.log(Level.SEVERE, MiniGames.getInstance().getStringFormatter().replacePlaceholders(
|
||||
MiniGameMessage.ERROR_ARENA_NOT_LOADED, new String[]{"{section}", "{file}"},
|
||||
new String[]{configurationSection.getName(), "dropper_arenas"}));
|
||||
return null;
|
||||
}
|
||||
if (winBlockType == null) {
|
||||
winBlockType = new SerializableMaterial(Material.WATER);
|
||||
}
|
||||
|
||||
Map<RewardCondition, Set<Reward>> rewards = RewardStorageHelper.loadRewards(configurationSection,
|
||||
DropperArenaStorageKey.REWARDS.getKey());
|
||||
|
||||
// Generate new, empty arena data if not available
|
||||
DropperArenaData arenaData = loadDropperArenaData(arenaId);
|
||||
if (arenaData == null) {
|
||||
MiniGames.log(Level.SEVERE, Message.ERROR_ARENA_DATA_NOT_LOADED.getMessage("{arena}",
|
||||
arenaId.toString()));
|
||||
MiniGames.log(Level.SEVERE, MiniGames.getInstance().getStringFormatter().replacePlaceholder(
|
||||
MiniGameMessage.ERROR_ARENA_DATA_NOT_LOADED, "{arena}", arenaId.toString()));
|
||||
arenaData = getEmptyDropperData(arenaId);
|
||||
}
|
||||
|
||||
return new DropperArena(arenaId, arenaName, spawnLocation, exitLocation, verticalVelocity, horizontalVelocity,
|
||||
winBlockType.getRawValue(), arenaData, MiniGames.getInstance().getDropperArenaHandler());
|
||||
winBlockType.getRawValue(), rewards, arenaData, MiniGames.getInstance().getDropperArenaHandler());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -216,9 +250,14 @@ public final class DropperArenaStorageHelper {
|
||||
* @return <p>The loaded arena data</p>
|
||||
*/
|
||||
private static @Nullable DropperArenaData loadDropperArenaData(@NotNull UUID arenaId) {
|
||||
File arenaDataFile = getDropperArenaDataFile(arenaId);
|
||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(arenaDataFile);
|
||||
return (DropperArenaData) configuration.get(DropperArenaStorageKey.DATA.getKey());
|
||||
try {
|
||||
File arenaDataFile = getDropperArenaDataFile(arenaId);
|
||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(arenaDataFile);
|
||||
return (DropperArenaData) configuration.get(DropperArenaStorageKey.DATA.getKey());
|
||||
} catch (YAMLException exception) {
|
||||
MiniGames.log(Level.SEVERE, "Unable to load arena data from arena " + arenaId);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
58
src/main/java/net/knarcraft/minigames/util/GUIHelper.java
Normal file
58
src/main/java/net/knarcraft/minigames/util/GUIHelper.java
Normal file
@ -0,0 +1,58 @@
|
||||
package net.knarcraft.minigames.util;
|
||||
|
||||
import net.knarcraft.knargui.item.PlayerHeadGUIItemFactory;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.ArenaSession;
|
||||
import net.knarcraft.minigames.gui.MiniGamesGUI;
|
||||
import net.knarcraft.minigames.property.PersistentDataKey;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
/**
|
||||
* A helper class for the in-arena GUI
|
||||
*/
|
||||
public final class GUIHelper {
|
||||
|
||||
private GUIHelper() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the item used for opening the mini-games menu
|
||||
*
|
||||
* @return <p>The item used for opening the GUI</p>
|
||||
*/
|
||||
public static ItemStack getGUIOpenItem() {
|
||||
PlayerHeadGUIItemFactory factory = new PlayerHeadGUIItemFactory();
|
||||
factory.useSkin("3fdab40434ed5d01f58c45ca0c9fada4662e1772ff43e2974979440a5cfe15c9");
|
||||
factory.setName(ChatColor.AQUA + "§ MiniGames Menu §");
|
||||
ItemStack item = factory.build();
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
if (meta != null) {
|
||||
meta.getPersistentDataContainer().set(new NamespacedKey(MiniGames.getInstance(),
|
||||
PersistentDataKey.MENU_ITEM.getKeyName()),
|
||||
PersistentDataType.INTEGER, PersistentDataKey.MENU_ITEM.getDataValue());
|
||||
}
|
||||
item.setItemMeta(meta);
|
||||
return item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the correct GUI for the given player
|
||||
*
|
||||
* @param player <p>The player to show a GUI for</p>
|
||||
*/
|
||||
public static void openGUI(Player player) {
|
||||
ArenaSession existingSession = MiniGames.getInstance().getSession(player.getUniqueId());
|
||||
if (existingSession == null) {
|
||||
new MiniGamesGUI(player).openFor(player);
|
||||
} else {
|
||||
existingSession.getGUI().openFor(player);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
package net.knarcraft.minigames.util;
|
||||
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.config.Message;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.Tag;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* A helper class for dealing with and parsing materials
|
||||
*/
|
||||
public final class MaterialHelper {
|
||||
|
||||
private MaterialHelper() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the materials specified in the block whitelist
|
||||
*/
|
||||
public static @NotNull Set<Material> loadMaterialList(@NotNull List<?> materials) {
|
||||
Set<Material> parsedMaterials = new HashSet<>();
|
||||
for (Object value : materials) {
|
||||
if (!(value instanceof String string)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Try to parse a material tag first
|
||||
if (parseMaterialTag(parsedMaterials, string)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Try to parse a material name
|
||||
Material matched = Material.matchMaterial(string);
|
||||
if (matched != null) {
|
||||
parsedMaterials.add(matched);
|
||||
} else {
|
||||
MiniGames.log(Level.WARNING, Message.ERROR_MATERIAL_NOT_PARSE_ABLE.getMessage("{material}", string));
|
||||
}
|
||||
}
|
||||
return parsedMaterials;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to parse the material tag in the specified material name
|
||||
*
|
||||
* @param targetSet <p>The set all parsed materials should be added to</p>
|
||||
* @param materialName <p>The material name that might be a material tag</p>
|
||||
* @return <p>True if a tag was found</p>
|
||||
*/
|
||||
private static boolean parseMaterialTag(@NotNull Set<Material> targetSet, @NotNull String materialName) {
|
||||
Pattern pattern = Pattern.compile("^\\+([a-zA-Z_]+)");
|
||||
Matcher matcher = pattern.matcher(materialName);
|
||||
if (matcher.find()) {
|
||||
// The material is a material tag
|
||||
Tag<Material> tag = Bukkit.getTag(Tag.REGISTRY_BLOCKS, NamespacedKey.minecraft(
|
||||
matcher.group(1).toLowerCase()), Material.class);
|
||||
if (tag != null) {
|
||||
targetSet.addAll(tag.getValues());
|
||||
} else {
|
||||
MiniGames.log(Level.WARNING, "Unable to parse: " + materialName);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -9,8 +9,9 @@ import net.knarcraft.minigames.arena.parkour.ParkourArenaGameMode;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArenaGroup;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArenaRecordsRegistry;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArenaStorageKey;
|
||||
import net.knarcraft.minigames.config.Message;
|
||||
import net.knarcraft.minigames.container.PlaceholderContainer;
|
||||
import net.knarcraft.minigames.arena.reward.Reward;
|
||||
import net.knarcraft.minigames.arena.reward.RewardCondition;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import net.knarcraft.minigames.container.SerializableMaterial;
|
||||
import net.knarcraft.minigames.container.SerializableUUID;
|
||||
import org.bukkit.Location;
|
||||
@ -98,22 +99,79 @@ public final class ParkourArenaStorageHelper {
|
||||
YamlConfiguration configuration = new YamlConfiguration();
|
||||
ConfigurationSection arenaSection = configuration.createSection(parkourArenasConfigurationSection);
|
||||
for (ParkourArena arena : arenas.values()) {
|
||||
//Note: While the arena name is used as the key, as the key has to be sanitized, the un-sanitized arena name
|
||||
// must be stored as well
|
||||
@NotNull ConfigurationSection configSection = arenaSection.createSection(arena.getArenaId().toString());
|
||||
configSection.set(ParkourArenaStorageKey.ID.getKey(), new SerializableUUID(arena.getArenaId()));
|
||||
configSection.set(ParkourArenaStorageKey.NAME.getKey(), arena.getArenaName());
|
||||
configSection.set(ParkourArenaStorageKey.SPAWN_LOCATION.getKey(), arena.getSpawnLocation());
|
||||
configSection.set(ParkourArenaStorageKey.EXIT_LOCATION.getKey(), arena.getExitLocation());
|
||||
configSection.set(ParkourArenaStorageKey.WIN_BLOCK_TYPE.getKey(), new SerializableMaterial(arena.getWinBlockType()));
|
||||
configSection.set(ParkourArenaStorageKey.WIN_LOCATION.getKey(), arena.getWinLocation());
|
||||
configSection.set(ParkourArenaStorageKey.KILL_PLANE_BLOCKS.getKey(), arena.getKillPlaneBlockNames());
|
||||
configSection.set(ParkourArenaStorageKey.CHECKPOINTS.getKey(), arena.getCheckpoints());
|
||||
saveParkourArenaData(arena.getData());
|
||||
saveParkourArena(arenaSection, arena);
|
||||
}
|
||||
configuration.save(parkourArenaFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves a single arena
|
||||
*
|
||||
* @param arena <p>The arena to save</p>
|
||||
* @throws IOException <p>If unable to write to the file</p>
|
||||
*/
|
||||
public static void saveSingleParkourArena(ParkourArena arena) throws IOException {
|
||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(parkourArenaFile);
|
||||
ConfigurationSection arenaSection = configuration.getConfigurationSection(parkourArenasConfigurationSection);
|
||||
if (arenaSection == null) {
|
||||
arenaSection = configuration.createSection(parkourArenasConfigurationSection);
|
||||
}
|
||||
saveParkourArena(arenaSection, arena);
|
||||
configuration.save(parkourArenaFile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the given configuration section with the arena's data, and stores arena data for the arena
|
||||
*
|
||||
* @param arenaSection <p>The configuration section to update</p>
|
||||
* @param arena <p>The arena to save</p>
|
||||
* @throws IOException <p>If unable to save the arena data</p>
|
||||
*/
|
||||
private static void saveParkourArena(ConfigurationSection arenaSection, ParkourArena arena) throws IOException {
|
||||
//Note: While the arena name is used as the key, as the key has to be sanitized, the un-sanitized arena name
|
||||
// must be stored as well
|
||||
@NotNull ConfigurationSection configSection = arenaSection.createSection(arena.getArenaId().toString());
|
||||
configSection.set(ParkourArenaStorageKey.ID.getKey(), new SerializableUUID(arena.getArenaId()));
|
||||
configSection.set(ParkourArenaStorageKey.NAME.getKey(), arena.getArenaName());
|
||||
configSection.set(ParkourArenaStorageKey.SPAWN_LOCATION.getKey(), arena.getSpawnLocation());
|
||||
configSection.set(ParkourArenaStorageKey.EXIT_LOCATION.getKey(), arena.getExitLocation());
|
||||
configSection.set(ParkourArenaStorageKey.WIN_BLOCK_TYPE.getKey(), new SerializableMaterial(arena.getWinBlockType()));
|
||||
configSection.set(ParkourArenaStorageKey.WIN_LOCATION.getKey(), arena.getWinLocation());
|
||||
configSection.set(ParkourArenaStorageKey.KILL_PLANE_BLOCKS.getKey(), getKillPlaneBlocks(arena));
|
||||
configSection.set(ParkourArenaStorageKey.OBSTACLE_BLOCKS.getKey(), getObstacleBlocks(arena));
|
||||
configSection.set(ParkourArenaStorageKey.CHECKPOINTS.getKey(), arena.getCheckpoints());
|
||||
RewardStorageHelper.saveRewards(arena, configSection, ParkourArenaStorageKey.REWARDS.getKey());
|
||||
saveParkourArenaData(arena.getData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of the kill plane blocks for the given arena
|
||||
*
|
||||
* @param arena <p>The arena to get kill plane blocks for</p>
|
||||
* @return <p>The kill plane blocks</p>
|
||||
*/
|
||||
private static List<String> getKillPlaneBlocks(ParkourArena arena) {
|
||||
if (arena.getKillPlaneBlockNames() == null) {
|
||||
return new ArrayList<>();
|
||||
} else {
|
||||
return new ArrayList<>(arena.getKillPlaneBlockNames());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of the obstacle blocks for the given arena
|
||||
*
|
||||
* @param arena <p>The arena to get obstacle blocks for</p>
|
||||
* @return <p>The obstacle blocks</p>
|
||||
*/
|
||||
private static List<String> getObstacleBlocks(ParkourArena arena) {
|
||||
if (arena.getObstacleBlockNames() == null) {
|
||||
return new ArrayList<>();
|
||||
} else {
|
||||
return new ArrayList<>(arena.getObstacleBlockNames());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all arenas
|
||||
*
|
||||
@ -161,13 +219,30 @@ public final class ParkourArenaStorageHelper {
|
||||
Location winLocation = (Location) configurationSection.get(ParkourArenaStorageKey.WIN_LOCATION.getKey());
|
||||
SerializableMaterial winBlockType = (SerializableMaterial) configurationSection.get(
|
||||
ParkourArenaStorageKey.WIN_BLOCK_TYPE.getKey());
|
||||
List<?> killPlaneBlockNames = configurationSection.getList(ParkourArenaStorageKey.KILL_PLANE_BLOCKS.getKey());
|
||||
List<?> killPlaneBlockNamesList = configurationSection.getList(ParkourArenaStorageKey.KILL_PLANE_BLOCKS.getKey());
|
||||
Set<String> killPlaneBlockNames;
|
||||
if (killPlaneBlockNamesList == null) {
|
||||
killPlaneBlockNames = null;
|
||||
} else {
|
||||
killPlaneBlockNames = new HashSet<>((List<String>) killPlaneBlockNamesList);
|
||||
}
|
||||
List<?> obstacleBlockNamesList = configurationSection.getList(ParkourArenaStorageKey.OBSTACLE_BLOCKS.getKey());
|
||||
Set<String> obstacleBlockNames;
|
||||
if (obstacleBlockNamesList == null) {
|
||||
obstacleBlockNames = null;
|
||||
} else {
|
||||
obstacleBlockNames = new HashSet<>((List<String>) obstacleBlockNamesList);
|
||||
}
|
||||
List<Location> checkpoints = (List<Location>) configurationSection.get(ParkourArenaStorageKey.CHECKPOINTS.getKey());
|
||||
|
||||
Map<RewardCondition, Set<Reward>> rewards = RewardStorageHelper.loadRewards(configurationSection,
|
||||
ParkourArenaStorageKey.REWARDS.getKey());
|
||||
|
||||
// The arena name and spawn location must be present
|
||||
if (arenaName == null || spawnLocation == null) {
|
||||
MiniGames.log(Level.SEVERE, Message.ERROR_ARENA_NOT_LOADED.getMessage(new PlaceholderContainer().add(
|
||||
"{section}", configurationSection.getName()).add("{file}", "parkour_arena")));
|
||||
MiniGames.log(Level.SEVERE, MiniGames.getInstance().getStringFormatter().replacePlaceholders(
|
||||
MiniGameMessage.ERROR_ARENA_NOT_LOADED, new String[]{"{section}", "{file}"},
|
||||
new String[]{configurationSection.getName(), "parkour_arena"}));
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -179,8 +254,8 @@ public final class ParkourArenaStorageHelper {
|
||||
// Generate new, empty arena data if not available
|
||||
ParkourArenaData arenaData = loadParkourArenaData(arenaId);
|
||||
if (arenaData == null) {
|
||||
MiniGames.log(Level.SEVERE, Message.ERROR_ARENA_DATA_NOT_LOADED.getMessage("{arena}",
|
||||
arenaId.toString()));
|
||||
MiniGames.log(Level.SEVERE, MiniGames.getInstance().getStringFormatter().replacePlaceholder(
|
||||
MiniGameMessage.ERROR_ARENA_DATA_NOT_LOADED, "{arena}", arenaId.toString()));
|
||||
arenaData = getEmptyParkourData(arenaId);
|
||||
}
|
||||
|
||||
@ -189,7 +264,8 @@ public final class ParkourArenaStorageHelper {
|
||||
}
|
||||
|
||||
return new ParkourArena(arenaId, arenaName, spawnLocation, exitLocation, winBlockType.getRawValue(), winLocation,
|
||||
(Set<String>) killPlaneBlockNames, checkpoints, arenaData, MiniGames.getInstance().getParkourArenaHandler());
|
||||
killPlaneBlockNames, obstacleBlockNames, checkpoints, rewards, arenaData,
|
||||
MiniGames.getInstance().getParkourArenaHandler());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,7 +1,7 @@
|
||||
package net.knarcraft.minigames.util;
|
||||
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.config.Message;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Entity;
|
||||
@ -36,7 +36,8 @@ public final class PlayerTeleporter {
|
||||
passenger.teleport(location);
|
||||
}
|
||||
} else {
|
||||
player.sendMessage(Message.ERROR_TELEPORT_WITH_PASSENGER.getMessage());
|
||||
MiniGames.getInstance().getStringFormatter().displayErrorMessage(player,
|
||||
MiniGameMessage.ERROR_TELEPORT_WITH_PASSENGER);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -46,7 +47,8 @@ public final class PlayerTeleporter {
|
||||
player.eject();
|
||||
vehicle.teleport(location);
|
||||
} else {
|
||||
player.sendMessage(Message.ERROR_TELEPORT_IN_VEHICLE.getMessage());
|
||||
MiniGames.getInstance().getStringFormatter().displayErrorMessage(player,
|
||||
MiniGameMessage.ERROR_TELEPORT_IN_VEHICLE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
189
src/main/java/net/knarcraft/minigames/util/RewardHelper.java
Normal file
189
src/main/java/net/knarcraft/minigames/util/RewardHelper.java
Normal file
@ -0,0 +1,189 @@
|
||||
package net.knarcraft.minigames.util;
|
||||
|
||||
import net.knarcraft.knarlib.formatting.StringFormatter;
|
||||
import net.knarcraft.knarlib.util.MaterialHelper;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.reward.CommandReward;
|
||||
import net.knarcraft.minigames.arena.reward.EconomyReward;
|
||||
import net.knarcraft.minigames.arena.reward.ItemReward;
|
||||
import net.knarcraft.minigames.arena.reward.PermissionReward;
|
||||
import net.knarcraft.minigames.arena.reward.Reward;
|
||||
import net.knarcraft.minigames.arena.reward.RewardType;
|
||||
import net.knarcraft.minigames.config.MiniGameMessage;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* A helopr class for getting the reward specified in user input
|
||||
*/
|
||||
public final class RewardHelper {
|
||||
|
||||
private RewardHelper() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Grants the given rewards to the given player
|
||||
*
|
||||
* @param player <p>The player to reward</p>
|
||||
* @param rewards <p>The rewards to give</p>
|
||||
*/
|
||||
public static void grantRewards(@NotNull Player player, @NotNull Collection<Reward> rewards) {
|
||||
StringFormatter stringFormatter = MiniGames.getInstance().getStringFormatter();
|
||||
for (Reward reward : rewards) {
|
||||
boolean granted = reward.grant(player);
|
||||
if (granted) {
|
||||
stringFormatter.displaySuccessMessage(player, reward.getGrantMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses input describing a reward
|
||||
*
|
||||
* @param player <p>The player that specified the reward</p>
|
||||
* @param typeString <p>The string given to specify the reward type</p>
|
||||
* @param firstArgument <p>The first reward argument given by the player, or null</p>
|
||||
* @param secondArgument <p>The second reward argument given by the player, or null</p>
|
||||
* @param allArguments <p>A list of all the reward arguments, in case the reward is a command reward</p>
|
||||
* @return <p>The parsed reward, or null if some input was invalid</p>
|
||||
*/
|
||||
public static @Nullable Reward parseRewardInput(@NotNull Player player,
|
||||
@NotNull String typeString,
|
||||
@Nullable String firstArgument,
|
||||
@Nullable String secondArgument,
|
||||
@NotNull String[] allArguments) {
|
||||
RewardType rewardType = RewardType.getFromString(typeString);
|
||||
if (rewardType == null) {
|
||||
MiniGames.getInstance().getStringFormatter().displayErrorMessage(player,
|
||||
MiniGameMessage.ERROR_REWARD_TYPE_INVALID);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (rewardType != RewardType.ITEM && firstArgument == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return switch (rewardType) {
|
||||
case COMMAND -> new CommandReward(getArrayAsString(allArguments));
|
||||
case ECONOMY -> new EconomyReward(getDouble(firstArgument));
|
||||
case PERMISSION -> new PermissionReward(getWorld(secondArgument), firstArgument);
|
||||
case ITEM -> new ItemReward(getItem(player, firstArgument, secondArgument));
|
||||
};
|
||||
} catch (IllegalArgumentException exception) {
|
||||
MiniGames.getInstance().getStringFormatter().displayErrorMessage(player, exception.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a double from the given input
|
||||
*
|
||||
* @param input <p>The input representing a double</p>
|
||||
* @return <p>The double specified</p>
|
||||
* @throws IllegalArgumentException <p>If the input is not a number or is not positive</p>
|
||||
*/
|
||||
private static double getDouble(@NotNull String input) throws IllegalArgumentException {
|
||||
IllegalArgumentException invalidException = new IllegalArgumentException(
|
||||
MiniGames.getInstance().getTranslator().getTranslatedMessage(MiniGameMessage.ERROR_INVALID_NUMBER));
|
||||
try {
|
||||
double number = Double.parseDouble(input);
|
||||
if (number <= 0) {
|
||||
throw invalidException;
|
||||
}
|
||||
return number;
|
||||
} catch (NumberFormatException exception) {
|
||||
throw invalidException;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the world specified in the given identifier
|
||||
*
|
||||
* @param worldIdentifier <p>A world UUID or name</p>
|
||||
* @return <p>The world, or null if no such world exists</p>
|
||||
*/
|
||||
private static @Nullable World getWorld(@Nullable String worldIdentifier) {
|
||||
if (worldIdentifier == null || worldIdentifier.isBlank()) {
|
||||
return null;
|
||||
}
|
||||
World world;
|
||||
try {
|
||||
UUID worldId = UUID.fromString(worldIdentifier);
|
||||
world = Bukkit.getWorld(worldId);
|
||||
} catch (IllegalArgumentException exception) {
|
||||
world = Bukkit.getWorld(worldIdentifier);
|
||||
}
|
||||
if (world != null) {
|
||||
return world;
|
||||
} else {
|
||||
throw new IllegalArgumentException(MiniGames.getInstance().getTranslator().getTranslatedMessage(
|
||||
MiniGameMessage.ERROR_INVALID_WORLD));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an item stack according to the given input
|
||||
*
|
||||
* @param player <p>The player that caused this method to execute</p>
|
||||
* @param argument1 <p>The first argument given by the player, or null</p>
|
||||
* @param argument2 <p>The second argument given by the player, or null</p>
|
||||
* @return <p>An item stack as described, or the player's held item</p>
|
||||
* @throws IllegalArgumentException <p>If an invalid material was specified</p>
|
||||
*/
|
||||
private static @NotNull ItemStack getItem(@NotNull Player player, @Nullable String argument1,
|
||||
@Nullable String argument2) throws IllegalArgumentException {
|
||||
if (argument1 != null) {
|
||||
Material material = MaterialHelper.loadMaterialString(argument1, MiniGames.getInstance().getLogger());
|
||||
int amount;
|
||||
try {
|
||||
if (argument2 != null) {
|
||||
amount = Integer.parseInt(argument2);
|
||||
} else {
|
||||
amount = 1;
|
||||
}
|
||||
} catch (NumberFormatException exception) {
|
||||
amount = 1;
|
||||
}
|
||||
if (material == null || material.isAir()) {
|
||||
throw new IllegalArgumentException(MiniGames.getInstance().getTranslator().getTranslatedMessage(
|
||||
MiniGameMessage.ERROR_INVALID_MATERIAL));
|
||||
}
|
||||
return new ItemStack(material, amount);
|
||||
} else {
|
||||
ItemStack inHand = player.getInventory().getItemInMainHand();
|
||||
if (!inHand.getType().isAir()) {
|
||||
return inHand;
|
||||
} else {
|
||||
throw new IllegalArgumentException(MiniGames.getInstance().getTranslator().getTranslatedMessage(
|
||||
MiniGameMessage.ERROR_INVALID_MATERIAL));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the string array as a space separated string
|
||||
*
|
||||
* @param array <p>The array to get as a string</p>
|
||||
* @return <p>The array as a string</p>
|
||||
*/
|
||||
private static String getArrayAsString(@NotNull String[] array) {
|
||||
String output = String.join(" ", array);
|
||||
if (output.isBlank()) {
|
||||
throw new IllegalArgumentException(MiniGames.getInstance().getTranslator().getTranslatedMessage(
|
||||
MiniGameMessage.ERROR_INVALID_COMMAND_STRING));
|
||||
} else {
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package net.knarcraft.minigames.util;
|
||||
|
||||
import net.knarcraft.minigames.arena.Arena;
|
||||
import net.knarcraft.minigames.arena.reward.Reward;
|
||||
import net.knarcraft.minigames.arena.reward.RewardCondition;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A helper class for loading and storing rewards
|
||||
*/
|
||||
public class RewardStorageHelper {
|
||||
|
||||
/**
|
||||
* Loads the rewards contained at the given path
|
||||
*
|
||||
* @param configurationSection <p>The configuration section containing the reward</p>
|
||||
* @param key <p>The section key to search</p>
|
||||
* @return <p>The loaded rewards</p>
|
||||
*/
|
||||
public static Map<RewardCondition, Set<Reward>> loadRewards(@NotNull ConfigurationSection configurationSection,
|
||||
@NotNull String key) {
|
||||
Map<RewardCondition, Set<Reward>> rewards = new HashMap<>();
|
||||
if (!configurationSection.contains(key)) {
|
||||
return rewards;
|
||||
}
|
||||
for (RewardCondition condition : RewardCondition.values()) {
|
||||
String section = key + "." + condition.name();
|
||||
if (!configurationSection.contains(section)) {
|
||||
continue;
|
||||
}
|
||||
Set<Reward> rewardSet = new HashSet<>();
|
||||
List<?> rewardList = configurationSection.getList(section, new ArrayList<>());
|
||||
for (Object object : rewardList) {
|
||||
if (object instanceof Reward reward) {
|
||||
rewardSet.add(reward);
|
||||
}
|
||||
}
|
||||
rewards.put(condition, rewardSet);
|
||||
}
|
||||
|
||||
return rewards;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves rewards for the given arena
|
||||
*
|
||||
* @param arena <p>The arena to save rewards for</p>
|
||||
* @param configurationSection <p>The configuration section to save the rewards at</p>
|
||||
* @param key <p>The section key to save at</p>
|
||||
*/
|
||||
public static void saveRewards(@NotNull Arena arena, @NotNull ConfigurationSection configurationSection,
|
||||
@NotNull String key) {
|
||||
for (RewardCondition condition : RewardCondition.values()) {
|
||||
configurationSection.set(key + "." + condition.name(),
|
||||
new ArrayList<>(arena.getRewards(condition)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,18 +1,22 @@
|
||||
package net.knarcraft.minigames.util;
|
||||
|
||||
import net.knarcraft.knarlib.util.TabCompletionHelper;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.Arena;
|
||||
import net.knarcraft.minigames.arena.ArenaHandler;
|
||||
import net.knarcraft.minigames.arena.EditablePropertyType;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaEditableProperty;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArenaEditableProperty;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.permissions.Permission;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
/**
|
||||
* A helper-class for common tab-completions
|
||||
@ -20,6 +24,8 @@ import java.util.Map;
|
||||
public final class TabCompleteHelper {
|
||||
|
||||
private static Map<EditablePropertyType, List<String>> tabCompleteSuggestions;
|
||||
private static List<String> plugins;
|
||||
private static Map<String, List<String>> permissions;
|
||||
|
||||
private TabCompleteHelper() {
|
||||
|
||||
@ -82,23 +88,6 @@ public final class TabCompleteHelper {
|
||||
return arenaProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds tab complete values that contain the typed text
|
||||
*
|
||||
* @param values <p>The values to filter</p>
|
||||
* @param typedText <p>The text the player has started typing</p>
|
||||
* @return <p>The given string values that contain the player's typed text</p>
|
||||
*/
|
||||
public static List<String> filterMatchingContains(@NotNull List<String> values, @NotNull String typedText) {
|
||||
List<String> configValues = new ArrayList<>();
|
||||
for (String value : values) {
|
||||
if (value.toLowerCase().contains(typedText.toLowerCase())) {
|
||||
configValues.add(value);
|
||||
}
|
||||
}
|
||||
return configValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets tab-complete suggestions for the given property type
|
||||
*
|
||||
@ -115,11 +104,30 @@ public final class TabCompleteHelper {
|
||||
tabCompleteSuggestions.put(EditablePropertyType.BLOCK_TYPE, getBlockTypeSuggestions());
|
||||
tabCompleteSuggestions.put(EditablePropertyType.CHECKPOINT_CLEAR, getCheckpointClearSuggestions());
|
||||
tabCompleteSuggestions.put(EditablePropertyType.MATERIAL_LIST, getMaterialListSuggestions());
|
||||
tabCompleteSuggestions.put(EditablePropertyType.DOUBLE, getDoubleSuggestions());
|
||||
}
|
||||
|
||||
return tabCompleteSuggestions.get(propertyType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets suggestions for double values
|
||||
*
|
||||
* @return <p>A list of suggestions</p>
|
||||
*/
|
||||
private static List<String> getDoubleSuggestions() {
|
||||
List<String> suggestions = new ArrayList<>();
|
||||
suggestions.add("0");
|
||||
suggestions.add("0.01");
|
||||
suggestions.add("0.1");
|
||||
suggestions.add("0.2");
|
||||
suggestions.add("0.3");
|
||||
suggestions.add("0.4");
|
||||
suggestions.add("0.5");
|
||||
suggestions.add("1");
|
||||
return suggestions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets suggestions for a list of materials
|
||||
*
|
||||
@ -129,6 +137,7 @@ public final class TabCompleteHelper {
|
||||
List<String> suggestions = new ArrayList<>();
|
||||
suggestions.add("LAVA,MAGMA_BLOCK");
|
||||
suggestions.add("WATER,MAGMA_BLOCK,LAVA,+BUTTONS,+CORALS");
|
||||
suggestions.add("CHAIN,END_ROD,LIGHTNING_ROD");
|
||||
return suggestions;
|
||||
}
|
||||
|
||||
@ -215,4 +224,65 @@ public final class TabCompleteHelper {
|
||||
return locations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the tab complete value for the permission typed
|
||||
*
|
||||
* @param typedNode <p>The full permission node typed by the player</p>
|
||||
* @return <p>All known valid auto-complete options</p>
|
||||
*/
|
||||
public static List<String> tabCompletePermission(String typedNode) {
|
||||
if (plugins == null) {
|
||||
loadAvailablePermissions();
|
||||
}
|
||||
List<String> output;
|
||||
if (typedNode.contains(".")) {
|
||||
List<String> matchingPermissions = permissions.get(typedNode.substring(0, typedNode.lastIndexOf(".")));
|
||||
if (matchingPermissions == null) {
|
||||
output = new ArrayList<>();
|
||||
} else {
|
||||
//Filter by the typed text
|
||||
output = TabCompletionHelper.filterMatchingStartsWith(matchingPermissions, typedNode);
|
||||
}
|
||||
} else {
|
||||
output = plugins;
|
||||
}
|
||||
|
||||
//Add previous permissions in the comma-separated lists as a prefix
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads all permissions available from bukkit plugins
|
||||
*/
|
||||
private static void loadAvailablePermissions() {
|
||||
plugins = new ArrayList<>();
|
||||
permissions = new HashMap<>();
|
||||
|
||||
for (Permission permission : Bukkit.getPluginManager().getPermissions()) {
|
||||
loadPermission(permission.getName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a given permission into the proper lists and maps
|
||||
*
|
||||
* @param permissionName <p>The permission to load</p>
|
||||
*/
|
||||
private static void loadPermission(String permissionName) {
|
||||
String[] permissionParts = permissionName.split("\\.");
|
||||
if (permissionParts.length == 1 && !plugins.contains(permissionParts[0])) {
|
||||
plugins.add(permissionParts[0]);
|
||||
} else if (permissionParts.length > 1) {
|
||||
StringJoiner pathJoiner = new StringJoiner(".");
|
||||
for (int j = 0; j < permissionParts.length - 1; j++) {
|
||||
pathJoiner.add(permissionParts[j]);
|
||||
}
|
||||
String path = pathJoiner.toString();
|
||||
List<String> permissionList = permissions.computeIfAbsent(path, k -> new ArrayList<>());
|
||||
permissionList.add(permissionName);
|
||||
|
||||
loadPermission(path);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
# Configuration values for mini-games
|
||||
|
||||
# The chosen language for Launchpad. You can use "en" or any custom language specified in strings.yml
|
||||
language: en
|
||||
parkour:
|
||||
# Whether to enforce the order in which a player must reach checkpoints. Enabling this ensures that a player cannot
|
||||
# trigger a previous checkpoint by accident. It also ensures players cannot skip a checkpoint, even if the arena
|
||||
@ -12,14 +15,17 @@ parkour:
|
||||
# are required to do a second play-through to register a record for a grouped arena.
|
||||
ignoreRecordsUntilGroupBeatenOnce: false
|
||||
|
||||
# Whether players should be made invisible while playing in a dropper arena
|
||||
makePlayersInvisible: false
|
||||
|
||||
# The blocks compromising parkour arenas' kill planes. Add any materials you want to use for the "bottom" of your
|
||||
# parkour arenas.
|
||||
killPlaneBlocks:
|
||||
- LAVA
|
||||
- MAGMA_BLOCK
|
||||
|
||||
# The blocks treated as obstacles in a parkour arena, which will trigger a loss in any direction
|
||||
obstacleBlocks:
|
||||
- END_ROD
|
||||
- LIGHTNING_ROD
|
||||
- CHAIN
|
||||
dropper:
|
||||
# Whether to block using the shift key to drop faster than the intended drop speed
|
||||
blockSneaking: true
|
||||
@ -48,13 +54,6 @@ dropper:
|
||||
# Whether a player must do the normal/default game-mode before playing any other game-modes
|
||||
mustDoNormalModeFirst: true
|
||||
|
||||
# Whether players should be made invisible while playing in a dropper arena
|
||||
makePlayersInvisible: false
|
||||
|
||||
# Whether players should have their entity hit collision disabled while in an arena. This prevents players from
|
||||
# pushing each-other if in the same arena.
|
||||
disableHitCollision: true
|
||||
|
||||
# A whitelist for which blocks won't trigger a loss when hit/passed through. The win block check happens before the
|
||||
# loss check, so even blocks on the whitelist can be used as the win-block. "+" denotes a material tag.
|
||||
blockWhitelist:
|
||||
@ -70,6 +69,7 @@ dropper:
|
||||
- +BUTTONS
|
||||
- +CORALS
|
||||
- +WALL_CORALS
|
||||
- LIGHT
|
||||
shared:
|
||||
# This decides how far inside a non-solid block the player must go before detection triggers (-1, 0). The closer to -1
|
||||
# it is, the more accurate it will seem to the player, but the likelihood of not detecting the hit increases.
|
||||
|
@ -6,6 +6,7 @@ api-version: 1.19
|
||||
description: A plugin that adds various mini-games
|
||||
softdepend:
|
||||
- PlaceholderAPI
|
||||
- Vault
|
||||
|
||||
# Note to self: Aliases must be lowercase!
|
||||
commands:
|
||||
@ -20,13 +21,25 @@ commands:
|
||||
- mleave
|
||||
- dleave
|
||||
- pleave
|
||||
permission: minigames.join
|
||||
usage: /<command>
|
||||
description: Used to leave the current dropper arena
|
||||
miniGamesMenu:
|
||||
aliases:
|
||||
- mmenu
|
||||
usage: /<command>
|
||||
description: Used to display an actions menu while in an arena
|
||||
miniGamesReward:
|
||||
aliases:
|
||||
- mreward
|
||||
usage: |
|
||||
/<command> add dropper|parkour <name> <condition> <type> [value] [value] ...
|
||||
/<command> clear dropper|parkour <name> <condition>
|
||||
description: Used to set rewards for arenas
|
||||
permission: minigames.edit
|
||||
dropperGroupSet:
|
||||
aliases:
|
||||
- dgset
|
||||
permission: minigames.edit
|
||||
permission: minigames.edit.dropper
|
||||
usage: |
|
||||
/<command> <arena> <group>
|
||||
- The group will be created if it doesn't already exist
|
||||
@ -35,7 +48,7 @@ commands:
|
||||
dropperGroupSwap:
|
||||
aliases:
|
||||
- dgswap
|
||||
permission: minigames.edit
|
||||
permission: minigames.edit.dropper
|
||||
usage: |
|
||||
/<command> <arena1> <arena2>
|
||||
- The two arenas must be in the same group
|
||||
@ -43,7 +56,7 @@ commands:
|
||||
dropperGroupList:
|
||||
aliases:
|
||||
- dglist
|
||||
permission: minigames.edit
|
||||
permission: minigames.edit.dropper
|
||||
usage: |
|
||||
/<command> [group]
|
||||
- Existing groups will be listed if used without an argument
|
||||
@ -52,13 +65,13 @@ commands:
|
||||
dropperList:
|
||||
aliases:
|
||||
- dlist
|
||||
permission: minigames.join
|
||||
permission: minigames.join.dropper
|
||||
usage: /<command>
|
||||
description: Used to list all current dropper arenas
|
||||
dropperJoin:
|
||||
aliases:
|
||||
- djoin
|
||||
permission: minigames.join
|
||||
permission: minigames.join.dropper
|
||||
usage: |
|
||||
/<command> <arena> [mode]
|
||||
- Mode can be used to select challenge modes which can be played after beating the arena.
|
||||
@ -68,21 +81,21 @@ commands:
|
||||
dropperCreate:
|
||||
aliases:
|
||||
- dcreate
|
||||
permission: minigames.create
|
||||
usage: |
|
||||
/<command> <arena> <property> [new value]
|
||||
- Valid properties: name, spawnLocation, exitLocation, verticalVelocity, horizontalVelocity, winBlockType
|
||||
permission: minigames.create.dropper
|
||||
usage: /<command> <arena>
|
||||
description: Used to create a new dropper arena
|
||||
dropperEdit:
|
||||
aliases:
|
||||
- dedit
|
||||
permission: minigames.edit
|
||||
usage: /<command> (Details not finalized)
|
||||
permission: minigames.edit.dropper
|
||||
usage: |
|
||||
/<command> <arena> <property> [new value]
|
||||
- Valid properties: name, spawnLocation, exitLocation, verticalVelocity, horizontalVelocity, winBlockType
|
||||
description: Used to edit an existing dropper arena
|
||||
dropperRemove:
|
||||
aliases:
|
||||
- dremove
|
||||
permission: minigames.remove
|
||||
permission: minigames.remove.dropper
|
||||
usage: /<command> <arena>
|
||||
description: Used to remove an existing dropper arena
|
||||
parkourGroupSet:
|
||||
@ -97,7 +110,7 @@ commands:
|
||||
parkourGroupSwap:
|
||||
aliases:
|
||||
- pgswap
|
||||
permission: minigames.edit
|
||||
permission: minigames.edit.parkour
|
||||
usage: |
|
||||
/<command> <arena1> <arena2>
|
||||
- The two arenas must be in the same group
|
||||
@ -105,7 +118,7 @@ commands:
|
||||
parkourGroupList:
|
||||
aliases:
|
||||
- pglist
|
||||
permission: minigames.edit
|
||||
permission: minigames.edit.parkour
|
||||
usage: |
|
||||
/<command> [group]
|
||||
- Existing groups will be listed if used without an argument
|
||||
@ -114,34 +127,36 @@ commands:
|
||||
parkourList:
|
||||
aliases:
|
||||
- plist
|
||||
permission: minigames.join
|
||||
permission: minigames.join.parkour
|
||||
usage: /<command>
|
||||
description: Used to list all current parkour arenas
|
||||
parkourJoin:
|
||||
aliases:
|
||||
- pjoin
|
||||
permission: minigames.join
|
||||
permission: minigames.join.parkour
|
||||
usage: |
|
||||
/<command> <arena>
|
||||
/<command> <arena> [mode]
|
||||
- Mode can be used to select challenge modes which can be played after beating the arena.
|
||||
- hardcore = A game-mode where checkpoints cannot be triggered
|
||||
description: Used to join a parkour arena
|
||||
parkourCreate:
|
||||
aliases:
|
||||
- pcreate
|
||||
permission: minigames.create
|
||||
usage: |
|
||||
/<command> <arena> <property> [new value]
|
||||
- Valid properties: name, spawnLocation, exitLocation, winBlockType, winLocation, checkpointAdd, checkpointClear, killPlaneBlocks
|
||||
permission: minigames.create.parkour
|
||||
usage: /<command> <arena>
|
||||
description: Used to create a new parkour arena
|
||||
parkourEdit:
|
||||
aliases:
|
||||
- pedit
|
||||
permission: minigames.edit
|
||||
usage: /<command> (Details not finalized)
|
||||
permission: minigames.edit.parkour
|
||||
usage: |
|
||||
/<command> <arena> <property> [new value]
|
||||
- Valid properties: name, spawnLocation, exitLocation, winBlockType, winLocation, checkpointAdd, checkpointClear, killPlaneBlocks
|
||||
description: Used to edit an existing parkour arena
|
||||
parkourRemove:
|
||||
aliases:
|
||||
- dremove
|
||||
permission: minigames.remove
|
||||
- premove
|
||||
permission: minigames.remove.parkour
|
||||
usage: /<command> <arena>
|
||||
description: Used to remove an existing parkour arena
|
||||
permissions:
|
||||
|
56
src/main/resources/strings.yml
Normal file
56
src/main/resources/strings.yml
Normal file
@ -0,0 +1,56 @@
|
||||
en:
|
||||
ERROR_CANNOT_SAVE_ARENA_GROUPS: "Unable to save current arena groups! Data loss can occur!"
|
||||
ERROR_MATERIAL_NOT_PARSE_ABLE: "Unable to parse material: {material}"
|
||||
ERROR_TELEPORT_WITH_PASSENGER: "You cannot be teleported with a passenger!"
|
||||
ERROR_TELEPORT_IN_VEHICLE: "You cannot be teleported while in a vehicle"
|
||||
ERROR_ARENA_NOT_LOADED: "Could not load the arena at configuration section {section}. Please check the {file} storage file for issues."
|
||||
ERROR_ARENA_DATA_NOT_LOADED: "Unable to load arena data for dropper arena: {arena}"
|
||||
ERROR_ARENA_NOT_FOUND: "Unable to find the specified arena."
|
||||
ERROR_GROUP_NOT_FOUND: "Unable to find the specified group!"
|
||||
ERROR_PLAYER_ONLY: "This command must be used by a player"
|
||||
ERROR_ARENA_NAME_COLLISION: "There already exists an arena with that name!"
|
||||
ERROR_NORMAL_MODE_REQUIRED: "You must complete this arena in normal mode first!"
|
||||
ERROR_GROUP_NORMAL_MODE_REQUIRED: "You have not yet beaten the default game-mode for all arenas in this group!"
|
||||
ERROR_PREVIOUS_ARENA_REQUIRED: "You have not yet beaten the previous arena!"
|
||||
ERROR_ARENA_TELEPORT_FAILED: "Unable to teleport you to the arena."
|
||||
ERROR_NOT_IN_ARENA: "You are not in a mini-games arena!"
|
||||
ERROR_ALREADY_PLAYING: "You are already playing a mini-game!"
|
||||
ERROR_JOIN_IN_VEHICLE_OR_PASSENGER: "You cannot join an arena while inside a vehicle or carrying a passenger."
|
||||
ERROR_UNKNOWN_PROPERTY: "Unknown property specified."
|
||||
ERROR_PROPERTY_INPUT_INVALID: "Unable to change the property. Make sure your input is valid!"
|
||||
ERROR_ARENA_1_NOT_FOUND: "Unable to find the first specified arena."
|
||||
ERROR_ARENA_2_NOT_FOUND: "Unable to find the second specified dropper arena."
|
||||
ERROR_SWAP_DIFFERENT_GROUPS: "You cannot swap arenas in different groups!"
|
||||
ERROR_ILLEGAL_COMMAND: "You cannot use that command while in an arena!"
|
||||
ERROR_HARDCORE_NO_CHECKPOINTS: "This arena cannot be played in hardcore mode as it has no checkpoints!"
|
||||
ERROR_INVALID_MATERIAL: "You specified an invalid material"
|
||||
ERROR_INVALID_WORLD: "You specified an invalid world"
|
||||
ERROR_INVALID_NUMBER: "You specified an invalid number"
|
||||
ERROR_INVALID_COMMAND_STRING: "You specified an invalid command. Make sure you don't add a slash in front of the command definition."
|
||||
ERROR_REWARD_TYPE_INVALID: "You have specified an invalid reward type"
|
||||
ERROR_REWARD_CONDITION_INVALID: "You have specified an invalid reward condition"
|
||||
SUCCESS_ARENA_GROUP_UPDATED: "The arena's group has been updated"
|
||||
SUCCESS_PLUGIN_RELOADED: "Plugin reloaded!"
|
||||
SUCCESS_ARENA_CREATED: "The arena was successfully created!"
|
||||
SUCCESS_ARENA_FIRST_CLEAR: "You cleared the arena!"
|
||||
SUCCESS_ARENA_WIN: "You won!"
|
||||
SUCCESS_ARENA_QUIT: "You quit the arena!"
|
||||
SUCCESS_CURRENT_VALUE: "Current value of {property} is: {value}"
|
||||
SUCCESS_PROPERTY_CHANGED: "Property {property} successfully changed"
|
||||
SUCCESS_ARENAS_SWAPPED: "The arenas have been swapped!"
|
||||
SUCCESS_ARENA_REMOVED: "The specified arena has been successfully removed"
|
||||
SUCCESS_DROPPER_ARENAS_LIST: "Dropper arenas:&r"
|
||||
SUCCESS_PARKOUR_ARENAS_LIST: "Parkour arenas:&r"
|
||||
SUCCESS_CHECKPOINT_REACHED: "Checkpoint reached!"
|
||||
SUCCESS_GROUP_STAGES: "{group}'s stages:&r"
|
||||
SUCCESS_RECORD_ACHIEVED: "You just set a {recordInfo} on the {gameMode} game-mode!"
|
||||
RECORD_ACHIEVED_GLOBAL: "new {recordType} record"
|
||||
RECORD_ACHIEVED_PERSONAL: "personal {recordType} record"
|
||||
SUCCESS_ARENA_JOINED: "You joined the arena."
|
||||
SUCCESS_ITEM_REWARDED: "You have been rewarded {amount} {item}(s)"
|
||||
SUCCESS_PERMISSION_REWARDED: "You have been granted the permission: {permission}"
|
||||
SUCCESS_PERMISSION_REWARDED_WORLD: "You have been granted the permission: {permission} in world: {world}"
|
||||
SUCCESS_COMMAND_REWARDED: "The command `{command}` has been run as your reward."
|
||||
SUCCESS_ECONOMY_REWARDED: "You have been granted {currency}"
|
||||
SUCCESS_REWARD_ADDED: "The reward was added."
|
||||
SUCCESS_REWARDS_CLEARED: "Rewards cleared."
|
@ -1,51 +0,0 @@
|
||||
package net.knarcraft.minigames.arena;
|
||||
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaGroup;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Tests for arena dropper groups
|
||||
*/
|
||||
public class MiniGamesArenaGroupTest {
|
||||
|
||||
@Test
|
||||
public void swapTest() {
|
||||
/*
|
||||
This test makes sure the order of arenas is as expected when the arenas are added to a group. It also makes
|
||||
sure that swapping two items works as expected.
|
||||
*/
|
||||
|
||||
DropperArenaGroup arenaGroup = new DropperArenaGroup("test");
|
||||
UUID arena1Id = UUID.randomUUID();
|
||||
UUID arena2Id = UUID.randomUUID();
|
||||
UUID arena3Id = UUID.randomUUID();
|
||||
UUID arena4Id = UUID.randomUUID();
|
||||
|
||||
arenaGroup.addArena(arena1Id);
|
||||
arenaGroup.addArena(arena2Id);
|
||||
arenaGroup.addArena(arena3Id);
|
||||
arenaGroup.addArena(arena4Id);
|
||||
|
||||
List<UUID> initialOrder = new ArrayList<>();
|
||||
initialOrder.add(arena1Id);
|
||||
initialOrder.add(arena2Id);
|
||||
initialOrder.add(arena3Id);
|
||||
initialOrder.add(arena4Id);
|
||||
Assertions.assertEquals(initialOrder, arenaGroup.getArenas());
|
||||
|
||||
arenaGroup.swapArenas(1, 3);
|
||||
|
||||
List<UUID> swapped = new ArrayList<>();
|
||||
swapped.add(arena1Id);
|
||||
swapped.add(arena4Id);
|
||||
swapped.add(arena3Id);
|
||||
swapped.add(arena2Id);
|
||||
Assertions.assertEquals(swapped, arenaGroup.getArenas());
|
||||
}
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user