This changes the upgrade waves from the local Upgrade interface to the Thing interface. This means that all Things can now be used in upgrade waves, including commands, money, potion effects, and permissions.
Unfortunately, the weapons upgrade/replace functionality has been gutted as a result of the Things API not supporting it. We could add it back in later down the road, but for now let's just see if it causes anyone any inconvenience.
Closes#468
This replaces the Map<String, Boolean> approach in ArenaClass with a List<Thing> approach. This greatly simplifies how per-class permissions are handled.
This commit introduces the PermissionThing and associated parser. The parser determines the value (grant/revoke) of the permission by looking at the first character of the input string - if it is a minus (-) or caret (^), the value is false (revoke), otherwise it is true (grant). To distinguish permissions from other things, the parser requires a prefix of "perm:".
This removes the map of attachments in ArenaImpl and makes the permissions "replacement" happen via the Bukkit API's PermissionAttachmentInfo. Bukkit already keeps track of which attachments we've added to a player, so removing them is just a matter of looping through and finding those. This reduces the coupling between the Arena interface and UpgradeWave (which is the only interface that used the methods removed from the Arena interface).
The goal with these specific metrics is to figure out if some of the arena settings can be removed. If everyone uses the same values for these settings, there is no point in having the added complexity in the code.
Three different types of health bars are implemented behind a basic Strategy Pattern. A new per-arena setting, boss-health-bar, can be used to configure which one of the three types (if any) of health bar should be used for bosses in the given arena:
- `boss-bar` creates a boss bar at the top of the screen as if the players were fighting an ender dragon or a wither.
- `title` uses the Chapters/Titles API in Bukkit to display the health of the boss as a "subtitle" whenever it takes damage.
- `name` sets the entitiy's health along with an optional custom name above the entity's head.
The announcements file loading method is renamed to indicate that it's also meant for re-loading, and the access modifier is changed from private to package-private to allow ArenaMasterImpl to call it.
Closes#462
The existing issue template tries to cover everything, and as a result it is a bit overwhelming. Using multiple issue templates trims the noise when you know what kind of issue you're submitting.
It's just UTF-8, Maven. No need to throw warnings all over the place...
This commit fixes some of the source encoding warnings Maven would print during compilation.
This commit introduces the PotionEffectThing and associated parser. The parser simply delegates to the existing PotionEffectParser utility class the same way the ItemStackThing parser does it. To distinguish potion effects from other things, the parser requires a prefix of "effect:".
As with the initial Thing API commit, this commit also adds an overload to the existing parser class to avoid spamming the console with meaningless warnings.
Boss waves already support potion effects, but with this commit, the potions node moves up as a common node, so all waves that spawn monsters (all but upgrade waves) can now spawn those monsters with a list of potion effects applied to them. It's not possible to give certain potion effects to specific monster types. All monsters get all the effects listed in the node.
Because we aren't actually giving potions but potion effects, the node is renamed from "potions" to "effects". However, to preserve backwards compatibility, both names are supported in this commit.
Closes#453
The ability to execute commands by hitting signs is already implemented by other plugins, but by creating built-in support for such signs, it's possible to leverage information about the plugin and its current state. This implementation allows for displaying live information about player counts, waves, etc. on the signs in addition to tying actions to them.
Customizable templates defined in the new signs.yml config-file can be bound to signs during the in-game sign creation, and users can define state-specific templates that change based on whether an arena is completely idle, has players in the lobby, or is running and in full swing.
Sign data is stored in data/signs.data as a YAML-formatted file that shouldn't be modified directly, effectively separating configuration (templates in signs.yml) and data (coordinates and parameters in signs.data).
Closes#385
This commit makes it possible for mounted players to dismount. Upon dismounting, the horse AI is set to false to prevent it from moving around. Players attempting to mount an available horse will be thrown off unless they actually own the horse. The owners are free to remount when they want.
Metrics will greatly help the development process in terms of finding out which server versions people are running, as well as which features they are using. For now, we check to see how widespread Vault is, and how many arenas and classes people have.
Advanced bar charts are, at the time of this commit, not supported in the bStats dashboard. When they are supported again, we can look into usage statistics for specific settings and features.
Changes the "Vault was not found" message in Vault setup to INFO instead of WARNING, because this configuration isn't actually necessarily a warning sign. Parsing a money thing with no economy is, however. MoneyThingParser logs at ERROR level if Vault or an economy plugin isn't found, but a money thing is parsed.
This also swaps out the dependency on mockito-all with mockito-core, which is actually maintained. The purpose of updating is to allow for new Mockito features, such as mocking final methods, which happens due to the test resource org.mockito.plugins.MockMaker.
It turns out that the method reference on MobArena#getEconomy() in ThingManager is a tight enough dependency on Vault's Economy interface that it results in a NoClassDefFoundError if Vault isn't present.
By resorting to a more "naive" approach of resolving the Economy instance from the main plugin class on every parse call in MoneyThingParser, the NoClassDefFoundError is avoided along with the load/enable ordering issue that was fixed with the lazy-fetching in commit 2fcb20b2ae.
This reverts 2fcb20b2ae and partly 4c34a183c7.
Fixes#463
If the arena has already started, there is no reason why a leaver should have a refund. It's also a douchey move because your buddies in the arena will have a harder time after you leave them for dead.
This moves the refunding of the entry fee to after the join/leave process for the player has been rolled back, i.e. after the inventory is restored. Before this change, the refund would happen before restoring the player's inventory, which resulted in the refund getting overwritten.
This was mainly left in for debugging purposes, but it creates a bit too much spam that isn't really informative or helpful in any way, since the exception reveals the failed step anyway.
This commit swaps out the naive call to takeFee with a more robust approach that actually checks the result. If it fails, the player doesn't join.
It also refactors takeFee so that it will refund any already taken parts of the entry fee if one of the parts fails.
The eager loading results in nothing but nulls because ThingManager (and, by proxy, MoneyThingParser) is instantiated on load, while the Economy provider from Vault is fetched on enable.
The bug was introduced with 4c34a183c7.
This fixes#451
MobArena has been on version 0.9x for so long that it just never was an issue that the version string was unquoted until now. Because SnakeYAML parses the string as a number, 0.100 becomes 0.1, which means the version string gets parsed into a 0 and a 1, which is less than 0 and 99 (previous version).
This should fix that problem for good.
This commit adds two new announcements for use in boss waves:
- wave-boss-killed to announce who killed the boss
- wave-boss-reward-earned to notify the killer of the boss reward, if any
Fixes#428
Historically, we've seen plugins try to "auto-correct" the falling-through-the-world bug in Minecraft when chunks load too slowly. The plugins often solve this by force-warping until the player is stable, and blocking those teleport events are going to cause heavy "not allowed" spam.
Note that this commit makes breaking changes to the Arena interface and completely changes the responsibility of the InventoryManager.
The join/leave process is replaced with an implementation of the Command Pattern, where every step of the process (e.g. teleport to lobby, change gamemode to survival, reset health, etc.) is realized as an implementation of the new Step interface, which has "run" and "undo" operations. The "run" operation takes a snapshot of a specific part of the player's state and then resets it. The "undo" operation restores the snapshot.
Step groupings are arranged in two factory classes, PlayerJoinArena and PlayerSpecArena, which realize, respectively, the join and spectate processes. Each instance of ArenaImpl instantiates groupings for its own context, and a grouping is invoked as one unit when a player joins or spectates an arena, and rolled back when a player leaves.
As a result of a more stringent process, some things are now a little different than before:
- Setting spectate-on-death to true effectively results in /ma leave followed by /ma spec. This makes the player/arena state a little more predictable and well-defined.
- Using exit warps will result in the player leaving to their entry point and then being teleported to the exit warp. This means the exit warp doesn't have any effect on the rest of the restoration process, as it effectively happens "post leave".
This finally fixes#423.
The goal of the contributing guidelines is to give contributors some
concrete dos and don'ts to work by, effectively making it easier on
everybody involved.
This makes commands case insensitive, e.g. /ma join. Note that arenas with the same name but different casing are considered the same arena, and one of them will be ignored during config-file parsing.
It turns out that the Inventory#removeItem(ItemStack) method doesn't actually work for items held in the offhand. This commit changes the behavior so it simply decrements the ItemStack amount for the item held during the block place. Note that going from 1 to 0 will result in an air stack, which will just disappear from the inventory.
Fixes#429