Commit Graph

775 Commits

Author SHA1 Message Date
Andreas Troelsen 8e5d2f0d23 Make InventoryThingParser package-private.
We don't need the parser exposed outside of the `things` package, and
none of the other thing parsers are public anyway. Coincidentally, this
fixes a warning about exposing InventoryThing outside of its visibility
scope, so yay.
2024-01-01 18:34:20 +01:00
Andreas Troelsen 3b7b638b00 Make LexeMatcher package-private.
We don't need it outside of the `formula` package.

This fixes warnings about exposing Lexeme outside of its visibility
scope, so yay.
2024-01-01 18:26:44 +01:00
Andreas Troelsen eb51a31720 Remove unused ThingManager constructor.
This fixes a warning about exposing ItemStackThingParser outside of its
visibility scope, but really it's just a good little cleanup step, since
the constructor in question is never used for anything. We might want to
eventually expose the ItemStackThingParser and use it in more places in
the code base, but in that case, and in that case it would probably make
sense to re-introduce the constructor, but I'm calling YAGNI on this in
order to nuke a warning.
2024-01-01 18:23:54 +01:00
Andreas Troelsen 82f00c5535 Fix "unary operator" warnings in FormulaManagerIT.
Okay, the reason the code included the unary plus was to more directly
represent the resulting expression, but I'm guessing the compiler isn't
going to respect that intent even if it could somehow understand it, so
it will probably remove the symbols and just parse it all the same.

Unlike with the unary plus, the unary minus can be "fixed" by wrapping
it in parentheses. The end result is of course the exact same, but the
intent is perhaps a bit clearer this way. We want to try to coerce the
compiler into creating an expression with "add a negative value", just
for the sake of "correctness" at the runtime evaluation level, but even
if that isn't what will actually happen, the explicit code is still a
bit easier to read. While unary plus is easy to disregard, "fixing" an
unnecessary unary minus would mean having to change the binary operator
before it, which muddies the intent of the expression.
2024-01-01 17:49:21 +01:00
Andreas Troelsen d8fdbb80c0 Simplify formula operation interfaces.
This commit releases the BinaryOperation and UnaryOperation interfaces
of the `formula` package from their `java.util.function` supertypes and
redeclares the previously inherited functions directly in the operation
interfaces, but also reifies them by explicitly using primitive doubles
instead of generics and wrapper classes. Doing so does not change the
functionality or any other code at all, but it makes the interfaces much
"stronger", since they no longer need to consider `null` values, which
they didn't actually take into account anyway. This fixes a warning in
Visual Studio Code (not sure how to get the same warning in IntelliJ)
about the operator registrations in the default formula environment
factory method being unsafe.
2024-01-01 19:39:59 +01:00
Andreas Troelsen 7942c33e67 Add `monster-teleporting` to resource file.
This should have been part of commit 511d16f, but apparently I forgot to
stage the file.

Whoops.
2023-12-17 21:20:25 +01:00
Andreas Troelsen 511d16f45a Add per-arena setting `monster-teleporting`.
This setting allows server owners to allow arena monsters to teleport
around _while inside the region_. They still can't teleport out of the
region.

Taken at face value, this should just be the default behavior. However,
due to arena regions being boxes, any non-box shaped arena will need a
region that covers more than the physical arena structure, which means
mobs like Endermen will be able to teleport into possibly unreachable
areas of the physical structure. So we have to make do with a setting.

Closes #762
2023-11-13 16:29:51 +01:00
Andreas Troelsen 457bf2ffff Clean up PvP activation logic.
The idea behind the previous implementation worked, but it was a tad bit
confusing. This commit refactors the activation logic by simply removing
it entirely. The "activation" part of the logic is now derived from the
wave number (if 0, it means we haven't _really_ started yet), instead of
relying on the spawn thread to toggle the flag on and off. This kind of
dependency inversion (spawn thread -> listener, listener -> "phase") is
a pretty decent (albeit super tiny) step towards cleaning up the whole
session system, so I call that a victory in and of itself!
2023-11-13 16:19:01 +01:00
Andreas Troelsen a662157cbf Reformat ArenaListener fields.
What a mess, sheesh...
2023-11-13 15:37:51 +01:00
Andreas Troelsen 9e083a91de Report Spigot health error to admins.
Using the new `mobarena.admin.errors` permission, this commit provides
server owners with a way to make the infamous Spigot health error much
more visible by sending the error message to any "admins" online when
the error occurs.

Closes #764
2023-11-13 14:39:05 +01:00
Andreas Troelsen 12314f476c Add `mobarena.admin.errors` permission.
Introduces a new permission for "admins" that can be used to increase
visibility of errors caught by the plugin. Server owners may not want
_all_ online players to see these types of messages, so the permission
gives error handlers a way to filter the list of online players before
sending the error message.
2023-11-13 14:37:34 +01:00
Andreas Troelsen feb257213c Add support for saved items.
Introduces the concept of a _saved item_; an in-game item that has been
captured in a YAML file via Bukkit's item serialization mechanism. These
items can be referenced in the config-file in all places that any other
normal item can be used, assuming the ThingManager is in charge of the
parsing. This should help bridge the gap between class chests and the
config-file by allowing any Bukkit serializable item stack to be stored
and referenced as if MobArena's item syntax directly supported it.

Three new setup commands are introduced to help manage the items, such
that they can be created, deleted, and loaded (for "editing" purposes).
The commands are somewhat rough around the edges and may need a little
bit of polish going forward.

Together with the new inventory referencing Things, this functionality
should help provide most of the flexibility people have been missing
from the item syntax for about a decade... Hell, it's about time.

Closes #212
2023-11-13 14:33:31 +01:00
Andreas Troelsen d7336526e1 Add InventoryThing collection.
Adds three new Thing types that can be used to reference items in chests
(or any block-based InventoryHolder):

- InventoryIndexThing looks up an item by index/slot in an inventory.
- InventoryGroupThing groups all non-null/non-air items in an inventory
  into a ThingGroup.
- InventoryRangeThing groups all non-null/non-air items in a given range
  of an inventory into a ThingGroup.

The new Thing types aim to bridge a gap between the class chests and the
rest of the Thing-based parts of the config-file. The goal is two-fold:
allow for more in-game configuration so access to the config-file isn't
_quite_ as crucial, and propagate the item-wise feature completeness of
class chests to other parts of the plugin.

While class chests are low configuration and a bit "all or nothing", the
inventory Thing types require manually punching in the coords for chests
and possibly indices/ranges for items. This means that the initial setup
could be a bit unwieldy, and highly volatile wave setups are definitely
not a good fit. If the wave setup is mostly pre-defined, it is fairly
easy to tweak upgrade waves and rewards in the same way class chests are
tweaked.

As for item-wise feature completeness, the inventory Thing types share
the same "if Bukkit can copy it, it will work" rule of thumb as class
chests do, which means items with metadata such as custom names, lore,
or even NBTs, should just work. This could remove the need to employ
other plugins.

By no means can this solution be considered "optimal", but it it _does_
enable some long-requested features.

Closes #456
2023-11-13 14:32:35 +01:00
Andreas Troelsen af513b03b0 Prevent unauthorized sign edits.
Since Minecraft 1.20, players can edit signs by right-clicking on them,
and that poses a problem for the sign-centric portions of the plugin,
such as class selection signs and the various types of arena signs.

This commit refactors the PlayerInteractEvent handler in ArenaListener
in order to break open the possibility of handling non-lobby players as
well. We're a little more strict with lobby players, and we still want
to handle class sign clicks and iron block clicks here. For players who
aren't in the lobby, we're really just blocking the event according to
the regular protection rules (block is inside region, protect is on, and
arena is not in edit mode).

It also blanket cancels events in the HandlesSignClicks event handler,
because there is no meaningful way to edit an arena sign, since their
contents come from the template file and not from what is written on
them by the sign renderer.

Ideally, we'd refactor some of this event handler logic, because it's a
lot easier to take care of the individual responsibilities in separate
event handlers.

Fixes #765
2023-11-04 00:20:39 +01:00
Andreas Troelsen 6579c4bf0e Call `update()` when reparing signs.
It boggles the mind that this tiny little class has worked as intended
since 2011 (!!), and all of a sudden, signs no longer retain their text
in the repair procedure...

By calling the somewhat arbitrary `update()` method on the sign after
setting the contents, the sign appears to correctly update again.

Fixes #772
2023-10-23 18:55:08 +02:00
Andreas Troelsen 61550161a7 Remove unused class.
I had no idea this class existed, but it seems like it's actually never
been used for anything, since the commit that introduced it didn't even
use it either.
2023-10-23 00:30:55 +02:00
Andreas Troelsen bbe7ed491d Bulk up the test suite for FormulaManager.
Introduces a couple of tests for the FormulaManager test suite in order
to cover all the methods the class exposes. This means it is no longer
necessary to suppress the "unused" warnings.
2023-10-23 00:30:55 +02:00
Tad Hunt a8b2cf90e9
Fix scanner resource leak.
Wraps the Scanner in try-with-resources to ensure resource cleanup after
reading the config-file from the plugin jar.
2023-10-22 01:24:53 +02:00
Andreas Troelsen 15a79bdd7e Remove discrepancy in auto-ready behavior.
It's not clear why this variation in the auto-ready logic exists, and
the commit history doesn't seem to have any clues either. Perhaps the
actual readying up logic was incompatible with auto-ready at some point,
but at this point in time it doesn't seem like this is necessary at all,
and it appears to be causing a bug with the MobArenaStats extension.

By simply calling the player ready procedure regardless of the status of
the auto start timer, MobArena fires the arena player ready event that
MobArenaStats depends on for some of its pre-session bookkeeping. It
could be argued that MobArenaStats should be more robust, but we would
much rather fix the root problem than slack on the otherwise fairly
sound strictness of the MobArenaStats data model.

Fixes #746
2023-05-07 11:52:31 +02:00
Andreas Troelsen 4f78936716 Use boss entity as source for obsidian bomb.
Makes the boss entity the source of the obsidian bomb explosion, which
then makes the damage event listener handle the explosion damage as if
the boss is the damager, which means the `monster-infight` flag should
be respected.

Fixes #759
2023-05-07 11:29:36 +02:00
Andreas Troelsen 2eb1761e76 Use exploding sheep as source for explosion.
Makes the sheep entity the source of the explosion that's created when
it triggers close to a player. This, in turn, makes the damage event
listener handle the explosion damage as if the sheep is the damager,
which means it will respect the `monster-infight` flag.

Fixes #758
2023-05-07 11:28:13 +02:00
Andreas Troelsen ec644df05b Adapt to the new `SPELL` spawn reason.
This new spawn reason was introduced somewhere between 1.18 and 1.18.1,
and unfortunately it is a breaking change, so we have to employ it for
MobArena to properly allow and register vexes (again...), but we also
have to maintain a variation of the old logic so we don't break support
for older server versions.

Fixes #719
2022-07-26 13:20:54 +02:00
Andreas Troelsen 36908cbe85 Remove class pets on player death.
When a player with pets dies in the arena, we want their pets to be
removed. One could probably argue that the pets _should_ be able to
stick around, but the original intent was for them to be removed
alongside their owner.

Fixes #721
2022-06-25 17:16:09 +02:00
Nesseley 3e2c614c18
Remove normal/undyed shulker boxes from My Items inventories.
Removes the first `_` in the `_SHULKER_BOX` matching to ensure that normal shulker boxes with ID `SHULKER_BOX` are removed from My Items as well.


Co-authored-by: Andreas Troelsen <garbagemule@gmail.com>
2022-03-07 17:45:16 +01:00
Andreas Troelsen c88f20c46f Add per-arena setting `auto-ignite-fuse`.
This new setting allows changing the fuse time for auto-ignited TNT,
which is normally a hardcoded 80 ticks in Minecraft. Note the somewhat
weak safeguarding without any sort of error message - with great power
comes great responsibility...

Closes #715
2022-02-13 00:33:18 +01:00
Andreas Troelsen b9b4d0d204 Replace metadata "planter" logic with TNT primed source.
Now that MobArena sets the TNTPrimed source on auto-ignited TNT, the
"planter" logic becomes _somewhat_ obsolete. This is due to the fact
that manually ignited TNT blocks produce a TNTPrimed entity with the
source property set to the player that ignited the block.

Because the "planter" logic in the BlockIgniteEvent handler didn't
actually work, this change shouldn't actually do anything in that
regard. That is, a TNT block ignited by a player would still have that
player as its source regardless of who the planter was, because the
procedure that would have otherwise set the planter of the TNTPrimed
entity never ran.
2022-02-12 23:53:04 +01:00
Andreas Troelsen 4470b60aaf Remove unused code block.
Turns out igniting TNT _doesn't_ fire a BlockIgniteEvent but rather an
ExplosionPrimeEvent, which means this code has never actually been of
any use. This code block was likely dead on arrival and has been dead
for almost 9 years. Wonderful...

The proper handling here would be to listen for the PlayerInteractEvent
and detect flint and steel interactions with TNT blocks. This is super
cumbersome, however, because the event handler would have to listen on
the MONITOR priority to ensure that nothing changes down the line. What
we are _actually_ need to do is remove the TNT block from the arena's
block set when it is ignited, but since this hasn't worked for almost a
decade, we're not really in a hurry to fix it now. It just makes for a
slightly slower (but negligible) cleanup procedure most of the time.
2022-02-12 23:30:21 +01:00
Andreas Troelsen d3e5d44cb2 Set source property on TNTPrimed entities.
This property makes TNT explosions look more "real" to other plugins who
may be consuming events from MobArena's sessions. It also gives way to a
potential rework of the "planter" logic that currently makes use of the
Bukkit Metadata API.

Closes #718
2022-02-12 22:42:39 +01:00
Andreas Troelsen d4dcc8dc90 Don't nag players with `mobarena.admin.teleport`.
Changes the behavior of the ArenaListener's teleport event handler such
that it _ignores_ teleport attempts instead of _rejecting_ them when the
player in question has the `mobarena.admin.teleport` permission. Because
the global listener's event handler only ever checks the permission if
at least one per-arena listener has _rejected_ the teleport attempt, and
none of them have explicitly _allowed_ it, the change means that it will
never check the permission, because its internal `allow` flag will never
change to `false`. Thus, the check can be safely removed from the global
listener's logic.

When the response is to ignore instead of reject, the message that would
have otherwise been sent to the player is skipped. This fixes #702.

It is perhaps tempting to move the permission check up into the section
of sanity checks in the global listener, but this is very specifically
avoided to allow MobArena to _uncancel_ teleport events that have been
cancelled by other plugins, but that MobArena might need to go through.
Please see afcc526a71 for more info.
2022-02-12 19:06:40 +01:00
Andreas Troelsen 77b2525707 Cancel damage to players by pets.
This is technically not necessary when pets are simple entities like
wolves and zombies, because these types of pets will never target and
thus attack other players in the arena. However, projectile entities
such as Blazes and Ghasts may hit players in the line of fire, and so
any such damage should be cancelled.

Fixes #712
2022-02-12 17:55:58 +01:00
Ghmmy d5ea15fa08
Add per-arena setting `clear-wave-leeway`.
Introduces a new arena setting that changes the "emptiness check" for 
`clear-wave-before-next`, `clear-wave-before-boss`, and the final wave 
check, allowing for a customizable _leeway_.

By default, the leeway is 0, which means the monster set has to be
completely empty for the checks to pass. With a value of 2, the set
may contain up to two monsters for the checks to pass, and so on.

The leeway should help alleviate some of the issues some people have
with their arena sessions when monsters "disappear" behind terrain or
end up in hard-to-reach areas. This is by no means a real "solution"
to the underlying problem, since the build-up of monsters in longer
sessions will just result in the issue being pushed to later waves.

We'll see if the setting leaves any additional customization to be
desired and perhaps defer any such requests to the Sessions Rework.

Closes #706
2022-02-12 16:57:47 +01:00
sepulzera be6be4bb98 Reset player velocity on select teleports.
Sets the player fall-distance to 0 before performing a player teleport
during "move player" steps. This should cancel out the any fall damage
that may have built up before the teleport was initiated.

Fixes #698

Co-authored-by: Andreas Troelsen <garbagemule@gmail.com>
2022-02-12 16:24:44 +01:00
Andreas Troelsen 9164b125bd Allow flaming arrows to ignite TNT.
It turns out that, according to the Spigot API, flaming arrows actually
_change_ TNT blocks to air before/instead of igniting them. While this
is a little counter-intuitive, the fix seems to revolve around allowing
the change to happen if the changed block is TNT and the "changer" is an
arrow.

Allowing the change event to happen means "foreign" primed TNT entities
will spawn, which makes it necessary to clean them up during the session
cleanup phase in ArenaImpl.

Fixes #696
2021-12-05 17:30:24 +01:00
Andreas Troelsen c80f0375ee Copy cancel state to fake EntityExplodeEvent.
It's not clear if this change actually solves the underlying issue,
because it has not been tested in a controlled environment. However,
considering the EntityExplodeEvent constructor, which doesn't take a
cancel state value, and the `HIGHEST` priority setting of MobArena's
event handler, the issue is realistic, and this change very likely
solves the issue.

Fixes #704
2021-12-05 16:18:54 +01:00
Andreas Troelsen 4348a0497e Use arena slugs in arena sign update handler.
The arena signs predate the use of arena slugs everywhere, so something
slipped through the cracks in this regard. Incidentally, the handler for
arena updates is one of the few classes in the signs package that has no
unit tests, probably due to it being "obvious implementation". Not so
obvious after all, it seems, so now we have a basic test for it.

Fixes #705
2021-10-13 23:25:13 +02:00
Maroon28 3693c039a6
Force adult entities; additional baby entities.
This commit (unfortunately) makes two somewhat unrelated changes:

- Forces certain ageable entities into adulthood to prevent the occasional baby spawns (fixes #687).
- Introduces support for baby versions of certain ageable entities (fixes #689).


Co-authored-by: Andreas Troelsen <garbagemule@gmail.com>
2021-10-13 23:24:56 +02:00
Griffin caee8be6ca
Add boss abilities with `all` modifiers.
Introduces four "new" boss abilities that work like their pre-existing counterparts, but affect all players in the arena. This makes the four _ability sets_ a bit more complete, as it were, in that it is now possible to choose between single targets, nearby, distant, or _all_ players for the given abilities.

Closes #434
2021-08-30 19:02:30 +02:00
Nesseley c9766dee97 Use spaces for "empty" titles.
Due to a breaking change in Spigot 1.17, sending a title with an empty string no longer works, even if a non-empty subtitle is provided. The TitleAnnouncer and TitleHealthBar components only use the subtitle portion of the title API to avoid obtrusive behavior.

With this commit, the two components send a single space character as the title. Effectively, there is no difference between showing the empty string or a single space on the client-side. It's a dirty hack to fix something that should be fixed in Spigot instead, but odds are that it won't be.

Fixes #683
2021-08-09 21:32:55 +02:00
Andreas Troelsen c143cc81c9 Add per-arena setting `auto-leave-on-end`.
Introduces a new arena setting to force spectators to leave the arena
when the current session ends. If set to `true`, it "overrides" the
behavior of `spectate-on-death: true` when players respawn, such that
they only become spectators if there is an active arena session.

The respawn behavior technically means that it is possible for a player
to begin spectating "the next session" if a new session begins between
them dying and clicking Respawn on the death screen. Ideally, we would
want the player to auto-leave, because the session _they_ participated
in ended, but we don't have a concept of "previous sessions", so this
quirky behavior will have to do.

Closes #682
2021-08-08 00:56:41 +02:00
Andreas Troelsen 52226fa1c9 Make Thing extend ThingPicker.
By turning things into their own thing pickers, we can avoid creating a
bunch of SingleThingPicker wrappers, which are now redundant. Because
the semantics of using things and thing pickers are quite different, it
does perhaps make it necessary to be a bit more careful about picking
the right type.
2021-08-07 16:08:23 +02:00
Maroon28 1c225d93f9
Make piglins and hoglins immune to zombification
When piglins, piglin brutes, and hoglins go through zombification, the current entity is removed, and a new one spawns. MobArena prevents the zombified entity from spawning, so it feels like the mobs just "vanish".

We don't actually want the mobs to zombify, however, so this commit makes them immune to the zombification process. Note that this shouldn't cause any problems on server versions prior to 1.16, because the piglin and hoglin keys never get registered on those versions, so there is no risk of hitting those branches in the `switch` statement.

Fixes #684

Co-authored-by: Andreas Troelsen <garbagemule@gmail.com>
2021-08-07 16:05:18 +02:00
Bobcat00 6be130daf1
Make pet names per-class configurable.
Adds a new optional `pet-name` property to arena class configurations that lets server owners set a custom pet name template instead of the hardcoded "<player>'s pet". This allows for translation and color coding. To accommodate setups where the player's "display name" isn't a good fit, e.g. because it is too long, the more generic "player name" is available for use instead.

Closes #595 

Co-authored-by: Bobcat00 <Bobcat00@users.noreply.github.com>
Co-authored-by: Andreas Troelsen <garbagemule@gmail.com>
2021-08-07 15:13:44 +02:00
Maroon28 a21f47e193 Don't remove monster weapons.
Changes the way monster equipment is handled from clearing _all_ items to clearing just the armor contents. This means that monsters that naturally spawn with weapons won't need their weapons added back in.

It also means that monsters that _occasionally_ spawn naturally with weapons now may do that in arenas. This is deemed acceptable, because:

- occasional weapons don't have as much of an impact as occasional armor,
- the forwards compatibility aspect is too valuable to pass up on, and
- should occasional weapons become too much of an issue, they can be conditionally removed, i.e. we can implement the _inverse_ behavior of what we had previously.

Fixes #641
Fixes #686

Co-authored-by: Andreas Troelsen <garbagemule@gmail.com>
2021-08-07 14:59:07 +02:00
Andreas Troelsen 7b9a9505b9 Reformat code in `things` package.
This is mostly just line breaks at the top and bottom of classes and
interfaces, but also marks some fields `final`.
2021-08-07 12:29:44 +02:00
Andreas Troelsen cad2eef8ba Optimize imports in `things` package.
We're good with on-demand imports for the static Hamcrest and Mockito
functions in test code, because the arrange and assert steps of unit
tests all make use of them, so it's known where they come from.
2021-08-07 12:20:45 +02:00
Andreas Troelsen 9fec49cc58 Make ThingGroupPicker aware of result set size.
This commit makes the ThingGroupPicker return different values depending
on the size of the picked result set. If the set is empty, the picker
returns null, emulating a NothingPicker. If the set is a singleton, the
element itself is returned, emulating the SingleThingPicker. Finally, if
the set contains more than one element, a ThingGroup containing those
elements is returned.
2021-08-07 01:36:37 +02:00
Andreas Troelsen 823be96b4e Guard against `nothing` in ThingGroupPicker.
This commit filters the result list of a ThingGroupPicker by a non-null
predicate to avoid null values in the resulting ThingGroup instance.

Since null values represent `nothing`, and we don't usually announce it
when players earn a `nothing` reward, it makes sense that they wouldn't
bubble up and somehow "manifest" in groups of things either.

Fixes #691
2021-08-07 01:36:35 +02:00
Andreas Troelsen 286071871f Add support for angry bees.
This commit introduces a new type variant, `angry-bee`, which is a bee
whose anger level is maximized upon spawning, much in the same vein as
its angry wolf cousin.

Note that bees are not available prior to Minecraft 1.15, so a sentinel
`null` name is used in the registration to prevent warnings from being
logged on server versions that don't have a concept of bees.

Closes #584
2021-07-30 18:21:41 +02:00
Andreas Troelsen 15698d3eee Use block data to check if blocks are signs.
Instead of relying on the evolving Material enum values, we can use the
new BlockData API as advised by some of the folks "in the know". It is
unclear how much of a performance impact the the "block data gathering"
and `instanceof` checks incur, but this is a pretty secluded place in
the code base, so probably nothing to worry about.

An alternative solution could have been to check if the _name_ of the
Material equals "SIGN" or "WALL_SIGN", or ends with "_SIGN". That should
cover all cases in a sorta kinda safe manner, but it isn't as resilient
as the BlockData/BlockState hierarchies.

We could also employ the new Materials utility class and enumerate all
sign types by name and just check for membership of the resulting set,
but this creates another brittle crash point.
2021-07-30 18:21:41 +02:00
Andreas Troelsen b4cd509eff Use "legacy-aware" utility class for Material types.
Introduces the Materials utility class, which works much like the static
MACreature registration process, but for certain material types. Instead
of storing everything in a stringly typed map, certain Material values
are stored as constants.

Right now it's just the `OAK_SIGN`/`SIGN` pair for the autogeneration in
MAUtils, and chances are we can throw it out at some point in the near
future, but at least now there's room for more materials, should the
need arise.
2021-07-30 18:21:41 +02:00