Commit Graph

999 Commits

Author SHA1 Message Date
Andreas Troelsen c500a17214 Add explicit cast from `Yaml#load(String)`.
The version of SnakeYAML used in 1.8 land doesn't use a generic type
parameter for the return value of `Yaml#load(String)`, so we have to do
it manually on these old builds.
2021-05-09 13:50:46 +02:00
Andreas Troelsen b2194480a9 Merge branch 'master' into 1.8 2021-05-09 13:46:37 +02:00
Andreas Troelsen f407e6eb4a Release 0.106. 2021-05-09 13:46:05 +02:00
Andreas Troelsen 30c059f51b Include bStats, Github Actions in changelog.
These should have been included in their respective commits, but they
didn't seem particularly interesting for end users at the time. Might as
well include them, though.
2021-05-09 13:43:55 +02:00
Andreas Troelsen b34dc0d5ac Merge branch 'master' into 1.8 2021-05-09 13:18:46 +02:00
Andreas Troelsen b08c74afbd Replace Travis CI with Github Actions.
This commit introduces a Github Actions workflow in the form of the file
`.github/workflows/build.yml`, replacing Travis CI and its `.travis.yml`
file.

The new workflow does a little bit more than Travis CI: it uploads an
artifact after a successful build. Due to a known issue with Github's
package UI, the MobArena.jar file is dynamically zipped on download, so
we get MobArena.jar.zip containing just MobArena.jar. It's redundant,
but there doesn't seem to be a simple way around it at the time of this
commit, so we'll leave it be.

For now, the workflow runs on every push to every branch. I'm probably
going to regret that, but we'll leave that as it is for now as well.
2021-04-15 17:24:56 +02:00
Andreas Troelsen c7e740040c Update bStats Metrics to 2.2.1.
The previously nested classes are now standalone, so imports and super
class definitions of the custom various charts are updated as well.
2021-04-11 13:11:47 +02:00
Andreas Troelsen 9081ec8055 Add support for custom formulas.
This commit re-frames the formula concept used by the wave growth, swarm
amount, and boss health wave configuration properties. It fundamentally
changes how these values are calculated, from a static, compile-time set
of enum values and hardcoded expressions, to a powerful math expression
feature that supports constants, variables, operators, and functions.

In part to remain backwards compatible with existing MobArena setups,
and in part for a better user experience, the old enum-based expressions
are relocated into a new file, `formulas.yml`, as _macros_. The file is
written to the plugin folder if missing, and it contains a formula for
each of the legacy values for each of the enums. Additionally, it has a
global section with some predefined macros for inspiration's sake. The
goal of this file is to allow people to define new formulas and reuse
them in their wave configurations instead of having to duplicate the
same formulas again and again.

Parts of the system are extensible. It is possible for other plugins to
register additional constants, variables, operators, and functions.

Closes #460
Closes #461
2021-04-07 22:13:03 +02:00
Andreas Troelsen 0da90f3963 Rework arena sign data store.
This commit constitutes a major rewrite of how arena signs are stored
and loaded. It fixes an issue where an unloaded or missing world would
cause MobArena to throw errors if there were any arena signs recorded in
said world.

The solution is to load signs of a given world when it is available,
rather than loading all signs at once indiscriminately. At startup,
signs for all _currently available_ worlds are loaded. This fixes the
errors. When a world loads and a WorldLoadEvent is fired, signs in that
world are loaded. This ensures that all valid signs in existing worlds
will _eventually_ load. To keep things tidy, a WorldUnloadEvent will
unload all signs for the unloaded world.

Bukkit's own YAML deserialization implementation doesn't re-throw all
deserialization errors, which means we can't actually catch the problem
of missing worlds without doing an awkward "scan" of the deserialized
objects. This prompted a rewrite of the serialization and data storage
into a custom CSV-like format which is both simpler and also provides a
lot more control over the process. Instead of relying on world _names_,
the new format uses world _UUIDs_. While the rest of the plugin won't
necessarily adapt well to a world being renamed, the signs data store
should be resilient enough to handle it.

Most of the actual sign rendering code and almost all of the template
code is intact, but quite a lot of other classes have been rewritten or
replaced. Some of the rewrites weren't strictly necessary, but because
the components were already fairly small, rewrites were much faster and
a lot less awkward than attempting to adapt existing code.

Fixes #645
2021-03-25 10:20:49 +01:00
Andreas Troelsen cf296704b0 Clean up .gitignore.
This file has an interesting history with content that goes all the way
back to MobArena's dark days of both Ant and Eclipse. This commit cleans
up the file a bit, removing a lot of unnecessary bits and pieces, and
making it a little more tightly bound to the current project setup.
2020-11-08 19:27:22 +01:00
Andreas Troelsen 9bc23c61a0 Bump version to 0.105.1. 2020-11-08 18:34:37 +01:00
Andreas Troelsen 3bef4948a6 Fix date of 0.105 release in changelog.md.
Time flies, oh my!
2020-11-08 18:33:18 +01:00
Andreas Troelsen cd7aa71f57 Merge branch 'master' into 1.8 2020-11-08 17:37:45 +01:00
Andreas Troelsen 5f62b8013b Release 0.105. 2020-11-08 17:35:31 +01:00
Andreas Troelsen 24bb925050 Merge branch 'master' into 1.8 2020-11-04 01:26:01 +01:00
Andreas Troelsen 532a2ce0da Add Maven Wrapper.
This should make it a lot easier to get started with the project and to
build a custom artifact from source.
2020-11-04 01:21:50 +01:00
Andreas Troelsen 07f0ce5d08 Add changelog entry for water bottle fix on 1.8.
This is a bit awkward to deal with, because the actual fix exists only
on the 1.8 branch, but we release from the main branch, so we want the
changelog entry to come from there.
2020-11-04 01:12:27 +01:00
Andreas Troelsen d960aebbb0 Reformat changelog for upcoming changes.
Rearranges and reformats the changelog entry for the upcoming version to
better fit with the Keep a Changelog guidelines. We're already grouping
stuff decently, but we can do better with section headers. In an entry
like this one with lots of changes, it just makes the reading experience
much better, and we do want people to read the changelog :)
2020-11-04 01:09:28 +01:00
Andreas Troelsen 3124703d96 Merge branch 'master' into 1.8 2020-11-04 01:07:37 +01:00
Andreas Troelsen 4ceb5b7bec Allow use of "config name" in `default-class`.
This is a very simple change that could potentially save a lot of
headaches when people look elsewhere in their config-file and see a
class name like "Big Gary" and wonder why putting that value in the
`default-class` property won't work.
2020-11-04 01:05:53 +01:00
Andreas Troelsen 81894b425b Don't try to make potions unbreakable.
The catch-all approach to unbreakability works in modern Minecraft
because it's just a flag. Historians speculate that back in ancient
times when Minecraft 1.8 was relevant and worth anyone's time, no such
flag existed, and as a result, primitive plugin developers of the ages
resorted to hacks where the durability was just set to something very
high (or low, rather), making stuff _effectively_ unbreakable. However,
because we didn't know better back then, we also used the durability to
configure potion metadata. As a result, making potions "unbreakable"
just means changing their type, and `Short.MIN_VALUE` is not a valid
potion type, so it just defaults to water bottle.

For the love of maintainability, please just let 1.8 die...

Fixes #633
2020-11-04 00:10:43 +01:00
Andreas Troelsen 59e1977d90 Merge branch 'master' into 1.8 2020-11-04 00:10:12 +01:00
Andreas Troelsen 6c693294bd Remove unused methods in MAUtils.
Slowly but surely, we're getting rid of this abomination...
2020-11-03 20:08:00 +01:00
Andreas Troelsen 70e51d24fb Return config name in Arena `arenaName()` method.
This is really just an internal change, since the `arenaName()` method
is likely not used anywhere. If it is, however, it shouldn't be depended
on as an identifier anyway, so I'm confident that removing it won't mess
up anything that doesn't need a rework anyway.
2020-11-03 20:04:16 +01:00
Andreas Troelsen 7288fc566b Return class name slugs in MobArenaHandler. 2020-11-03 19:58:30 +01:00
Andreas Troelsen 31282014b3 Use slugs internally in Upgrade Waves.
This just removes the internal use of "lowercase name" in Upgrade Waves
and _should_ have no effect on the actual config-file and the parsing
done there.
2020-11-03 19:58:30 +01:00
Andreas Troelsen 2a87aef9f3 Use class "config name" on leaderboard signs.
Same as with arena names, we can just use the class "config name" on
leaderboards for a prettier experience.
2020-11-03 19:58:30 +01:00
Andreas Troelsen 06cedde031 Allow multi-word names in `/ma addarena` and `/ma autogenerate`.
Introduces support for multi-word arena names in the two commands. The
approach is to simply join the arguments by spaces. Because of the new
slug-based lookups, multi-word names are fairly straightforward.
2020-11-03 19:58:30 +01:00
Andreas Troelsen 0f93d8ac05 Resolve arenas by name using slugs.
This commit is a minor refactor of how arenas are resolved by name,
similar to the previous arena class resolution refactoring.

The difference this time around is that there is an ArenaMaster method
that does most of the work for a lot of different areas of the plugin,
`getArenaWithName(String)`. This method is called from well over 30
different places in the code base, making it a cornerstone of all arena
resolution. Luckily, it is called primarily from places that shouldn't
care _how_ an arena is resolved.

Affected by this commit are all commands that resolve arenas by name,
including all those not listed in the diff, because of the change to
`getArenaWithName(String)` on ArenaMaster.

Commands that can tab complete arena name arguments now complete slugs
instead of config names.
2020-11-03 19:58:30 +01:00
Andreas Troelsen fdb84dfaf4 Use Arena "config name" on leaderboard headers.
Going forward, it should be possible to show "pretty" arena names by
simply using a pretty name in the config-file instead of slug-like names
now that slugs are on the horizon.
2020-11-03 19:58:30 +01:00
Andreas Troelsen f10c7e464c Deprecate Arena `arenaName()` method.
Conversely to how the "lowercase name" of ArenaClass was deprecated in
favor of the slug, the "arena name" method here is deprecated in favor
of the "config name" of arenas. Instead of trying to pretty up an arena
name (which is doomed to fail), we just use the "config name" for pretty
printing instead, and start using slugs elsewhere.

This should give way to a much better experience with multi-word arena
names as well.
2020-11-03 19:58:30 +01:00
Andreas Troelsen 037c2ffa43 Use arena class "config names" in `/ma autogenerate`.
Swaps the weird "camel casing" approach in the autogenerate command out
with simply using the "config name" of the arena classes when creating
class selection signs.

This fixes the breaking change to how classes are resolved in a previous
commit, but only in future arena generation procedures. Arena generated
before this change may still contain broken class signs.
2020-11-03 19:58:30 +01:00
Andreas Troelsen 5bcab8fa46 Use arena class slugs for class selection.
This commit is a minor refactoring of the class selection functionality
plugin-wide. Instead of selecting classes based on the "lowercase name"
of a class, commands and listeners are now "slug aware", as it were.

The ArenaClass class now uses its slug instead of its "lowercase name"
for equality and hash codes.

The `/ma class` command now tab completes slugs, but it still supports
class names as they appear in the config-file when executing the command
itself. The same applies to the `/ma classchest` command.

The sign handling in ArenaListener slugifies sign text instead of just
lowercasing and stripping spaces.
2020-11-03 19:58:30 +01:00
Andreas Troelsen 519886cf3e Use slugs in arena and class permission checks.
This commit changes the permission checks for arenas and classes to a
slug-based approach instead of the "config names", which are somewhat
arbitrary and may contain spaces, which are generally not supported by
permissions plugins.

This is a breaking change, which means it will be necessary for users
to change their permission setups. Backwards compatibility could have
been implemented, but it just leaves more room for ambiguity and will
make a necessary transition later down the road less obvious. Instead,
we burn the ships!

As a result of this change, access to the "My Items" class can now be
revoked as intended with the key `mobarena.classes.my-items`.

Fixes #647
2020-11-03 19:50:29 +01:00
Andreas Troelsen 1b46e17e38 Deprecate ArenaClass `getLowercaseName()` method.
This commit deprecates the "lowercase name" method on ArenaClass to push
the new slug concept throughout the code base in a "healthy" way.
2020-11-01 14:28:40 +01:00
Andreas Troelsen aed57f5cb6 Introduce slugs in arenas and classes.
Whitespace and punctuation in identifiers is a fairly big source of
issues in areas like permissions and commands where whitespace isn't
directly supported (or at least makes things needlessly difficult).

This commit introduces the concept of a "slug" in arenas and classes,
giving them a _consistent_ `kebab-case` name for use in such places, but
it does not implement their use anywhere. Slugs are expected to be the
solution to problems like the one posed in issue #647.

At the time of writing, we're only concerned with simple stuff like
removing periods, commas, parentheses and replacing underscores and
spaces with dashes. If it turns out that people have unanticipatedly
problematic arena and class names, we may have to expand the slug
definition rules or allow for custom slugs.
2020-11-01 14:28:33 +01:00
dependabot[bot] 5ebdf45f6a
Bump junit from 4.12 to 4.13.1
Bumps [junit](https://github.com/junit-team/junit4) from 4.12 to 4.13.1.
- [Release notes](https://github.com/junit-team/junit4/releases)
- [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.12.md)
- [Commits](https://github.com/junit-team/junit4/compare/r4.12...r4.13.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-13 04:37:10 +00:00
Andreas Troelsen efc66820c6 Add specific Msg value for `/ma addreward`.
This commit introduces a new announcement value for the `addreward`
command. This allows server owners to completely remove the message by
setting it to the empty string while retaining wave reward messages.

In general, we shouldn't reuse announcements unless the actions that
send them are identical, because it makes everything a lot more tangled
than it has to be.
2020-09-19 10:57:17 +02:00
Andreas Troelsen dafae0cf07 Add `/ma addreward` command.
This command takes an arena player and a Thing as input. The Thing is
parsed in the same way as all other rewards are parsed, so it supports
the new `all()` and `random()` functions and the `nothing` keyword.

The "target audience" of the command is mainly scripts. It opens up the
possibility of hooking into MobArena's rewards from command blocks or
other plugins, but with very low coupling.

Closes #643
2020-09-19 10:32:03 +02:00
Andreas Troelsen 3b132d28dd Use ThingPicker for boss rewards.
By using a ThingPicker instead of a Thing, boss rewards can now, just
like regular wave rewards, make use of the new `random()` and `all()`
functions as well as the `nothing` keyword.

Closes #628
2020-08-24 22:53:00 +02:00
Andreas Troelsen d30bd96a2a Add support for picking `nothing`.
This commit introduces the strange concept of a singleton ThingPicker
that only ever picks `null`. The purpose of this picker is to allow for
a type of "loot table" experience similar to that found in other games.
An example would be a piece of equipment that only has a 50 % chance of
dropping. With the current state of MobArena, it would be necessary to
something conjure up a CommandThing or something to emulate nothingness,
but now there is native support for it with the `nothing` keyword.

The nullability of rewards also has the side effect that we got to clean
up the MASpawnThread `addReward` method a bit.

Closes #638
2020-08-22 17:36:30 +02:00
Andreas Troelsen 994ebaff81 Allow for reward grouping.
This commit makes the MAUtils class responsible for parsing reward maps
use the new ThingPickerManager to parse the reward lists. As a result,
the new `all()` and `random()` pickers are available for use in the
rewards section.

This should allow for granting item sets and similar types of "bundles"
as rewards in the arena, e.g. a diamond sword and permission to join a
more difficult arena.

Closes #386
2020-08-22 17:12:29 +02:00
Andreas Troelsen bff1ab5694 Convert rewards to the new ThingPicker framework.
This commit makes breaking changes to the Arena interface to switch to
the new ThingPicker framework for rewards. It is unfortuante that the
Arena interface has so many disparate responsibilities that changes like
these are necessary on such a central component when the change itself
is actually very isolated to just rewards handling.

With this change, rewards are now wrapped in pickers, which should give
way to some grouping and "well-defined entropy".
2020-08-22 17:12:29 +02:00
Andreas Troelsen dd54f70682 Add ThingPickerManager to main plugin class.
Introduces the ThingPicker framework to the plugin by bootstrapping a
manager for it in the main plugin class. By default, we're just running
the group and random picker parsers, but other plugins should be able to
hook in with their own parsers.

Nothing actually _uses_ the pickers yet, but that's next on the menu.
2020-08-22 17:12:29 +02:00
Andreas Troelsen 2d0aad19d6 Add ThingPickerManager.
This little nugget is what we will wire up in the main plugin class once
we're ready to introduce it to the code base for real. Its purpose is
similar to that of the ThingManager, in that it _is_ a parser and can be
passed around wherever a parser is needed, but it also is the main entry
point for anything that is ThingPickerParser instances.
2020-08-22 17:12:29 +02:00
Andreas Troelsen 5566d8fd86 Introduce ThingPickerParser.
To ensure that we are extensible from the get-go, this commit introduces
the parser aspect of the ThingPicker framework with parsers for the two
non-trivial picker implementations.

Nothing is wired up yet.
2020-08-22 17:12:26 +02:00
Andreas Troelsen e8bb8a9e4d Introduce ThingPicker.
Things work best as hardwired, atomic pieces of "stuff", so fitting RNG
into the framework is a little difficult. We could have a RandomThing,
but the issue with that is that the entropy has to live inside of it for
it to be random every time it is given, taken, or checked. This makes it
impossible to make a well-defined, atomic Thing with entropy involved.

Enter the pickers.

The ThingPicker is an early stage extension to the Things framework that
encapsulates the possibilities of entropy and grouping _around_ Things,
a type of Factory pattern.

This introductory stage consists of a "leaf picker" that can only ever
pick a single Thing, a Composite Pattern "group picker" that wraps a
list of other pickers and shoves their resulting Thing instances into a
ThingGroup (introduced in the previous commit).

These simple constructs should now make it possible to introduce entropy
without placing the responsibility on the Thing framework itself. Using
this extension requires adapting code to using the ThingPicker interface
instead of using Thing directly.
2020-08-22 16:10:07 +02:00
Andreas Troelsen e1784552de Add ThingGroup.
Introduces a group of Things as a construct for bundling Things that
should constitute a single unit for whatever reason.

One reason could be to make an _item set_ an atomic reward, e.g. a set
of diamond tools for beating the `workshop` arena. Instead of having to
spread the rewards out into multiple waves or use a different plugin to
create item groups, this component allows MobArena to support that kind
of intent natively.

Note that nothing is wired up in this commit, so really this commit is
just introducing unused code.
2020-08-22 15:00:11 +02:00
Andreas Troelsen 4f11889549 Add per-arena setting `announcer-type`.
Introduces the concept of an Announcer, which is invoked whenever the
`announce` methods on the Arena interface are invoked. Previously, all
announcements would simply be sent to the arena's Messenger, but this
new feature allows us to move them up into titles to help declutter the
somewhat overloaded chat box.

By default, to help people discover the new feature, the announcer type
is `title`, but it is possible to switch back to `chat` for the original
behavior.

Closes #272
2020-08-22 11:32:45 +02:00
Andreas Troelsen 31010c1576 Initiate player leave when `spectate-on-death: false`.
Errata to commit 84a7a2ed8a.

The protocol after the join/leave process rework was:

- `spectate-on-death: true`: leave, then spec
- `spectate-on-death: false`: leave

The protocol now is:

- `spectate-on-death: true`: spec
- `spectate-on-death: false`: spec, then "leave"

I put "leave" in quotes, because _discarding_ the player here does not
invoke the part of the leave protocol that tries to ensure teleports go
through according to plan. By capitalizing on the "leave" part, making
it explicit that that's what we're doing in the next tick after warping
the player to the spectator area, we return to the form of the original
rework where we use coarser-grained state control to make things easier
to reason about.

A side-effect of this change is that if players somehow manage to kill
themselves in the lobby, they will be refunded the entry fee.
2020-08-22 09:42:45 +02:00