Add tiers wave reward section.

This commit introduces a new optional wave rewards section, `tiers`,
which allows server owners to configure rewards that "upgrade" over
time. This makes it possible to create reward configurations where
(some of) the rewards don't stack as the waves progress, but instead
change into different rewards. The most obvious use case is wanting to
grant an armor set for beating a specific wave, but a _better_ set for
beating a later wave, without granting both sets.

Turns out this was a lot easier than I thought it would be. We didn't
even need a rework of anything, and the Things API didn't even need to
adapt in any way. As an added bonus, we managed to get the associated
GitHub issue wrapped up before it turned 8 years old. Neat!

Closes #346
This commit is contained in:
Andreas Troelsen
2024-10-06 12:42:09 +02:00
parent 0527f116e2
commit 78f5dc0545
7 changed files with 52 additions and 2 deletions
+1
View File
@@ -13,6 +13,7 @@ These changes will (most likely) be included in the next version.
## [Unreleased]
### Added
- MobArena now properly supports Vault economy providers registered after MobArena has started. This should make it possible to use custom economy providers that aren't built into Vault, such as those created with Denizen.
- New wave rewards section `tiers` allows for _non-stacking_ reward tiers for beating certain waves. This allows for configuring reward sets that get "upgraded" as the waves progress, e.g. by granting a full leather armor set for beating wave 15, but beating wave 20 _replaces_ that leather armor set with an iron armor set.
### Changed
- Recurrent waves can now be randomized. If two or more recurrent waves clash on wave number, frequency, _and_ priority, MobArena will now randomly pick between them. This should make it easier to create more varied and interesting wave setups without having to resort to only massively randomized default waves.
@@ -124,7 +124,7 @@ public class ArenaImpl implements Arena
private WaveManager waveManager;
private MASpawnThread spawnThread;
private SheepBouncer sheepBouncer;
private Map<Integer, ThingPicker> everyWaveMap, afterWaveMap;
private Map<Integer, ThingPicker> everyWaveMap, afterWaveMap, waveTiersMap;
// Misc
private ArenaListener eventListener;
@@ -208,6 +208,7 @@ public class ArenaImpl implements Arena
this.waveManager = new WaveManager(this, section.getConfigurationSection("waves"));
this.everyWaveMap = MAUtils.getArenaRewardMap(plugin, section, name, "every");
this.afterWaveMap = MAUtils.getArenaRewardMap(plugin, section, name, "after");
this.waveTiersMap = MAUtils.getArenaRewardMap(plugin, section, name, "tiers");
// Misc
this.eventListener = new ArenaListener(this, plugin);
@@ -351,6 +352,11 @@ public class ArenaImpl implements Arena
return afterWaveMap.get(wave);
}
@Override
public ThingPicker getWaveTierReward(int wave) {
return waveTiersMap.get(wave);
}
@Override
public Set<Player> getPlayersInArena() {
return Collections.unmodifiableSet(arenaPlayers);
@@ -366,6 +366,11 @@ public class MASpawnThread implements Runnable
if (after != null) {
addReward(after);
}
ThingPicker tier = arena.getWaveTierReward(wave);
if (tier != null) {
setRewardTier(tier);
}
}
private void updateStats(int wave) {
@@ -400,4 +405,14 @@ public class MASpawnThread implements Runnable
}
}
}
private void setRewardTier(ThingPicker picker) {
for (Player p : arena.getPlayersInArena()) {
Thing reward = picker.pick();
if (reward != null) {
rewardManager.setTieredReward(p, reward);
arena.getMessenger().tell(p, Msg.WAVE_TIER_REWARD, reward.toString());
}
}
}
}
@@ -78,6 +78,7 @@ public enum Msg {
WAVE_BOSS_KILLED("&a%&r killed the boss!"),
WAVE_BOSS_REWARD_EARNED("You earned: &e%"),
WAVE_REWARD("You just earned a reward: &e%&r"),
WAVE_TIER_REWARD("You just unlocked a new reward tier: &e%&r"),
MISC_REWARD_ADDED("You were just given a reward: &e%&r"),
MISC_LIST_PLAYERS("Live players: &a%&r"),
MISC_LIST_ARENAS("Available arenas: %"),
@@ -14,15 +14,18 @@ import java.util.Set;
public class RewardManager
{
private Map<Player,List<Thing>> players;
private Map<Player,Thing> tiered;
private Set<Player> rewarded;
public RewardManager(Arena arena) {
this.players = new HashMap<>();
this.tiered = new HashMap<>();
this.rewarded = new HashSet<>();
}
public void reset() {
players.clear();
tiered.clear();
rewarded.clear();
}
@@ -33,7 +36,17 @@ public class RewardManager
players.get(p).add(thing);
}
public void setTieredReward(Player p, Thing thing) {
tiered.put(p, thing);
}
public void grantRewards(Player p) {
grantNormalRewards(p);
grantTieredRewards(p);
rewarded.add(p);
}
private void grantNormalRewards(Player p) {
if (rewarded.contains(p)) return;
List<Thing> rewards = players.get(p);
@@ -45,6 +58,14 @@ public class RewardManager
}
reward.giveTo(p);
}
rewarded.add(p);
}
private void grantTieredRewards(Player p) {
if (rewarded.contains(p)) return;
Thing reward = tiered.get(p);
if (reward == null) return;
reward.giveTo(p);
}
}
@@ -70,6 +70,8 @@ public interface Arena
ThingPicker getAfterWaveReward(int wave);
ThingPicker getWaveTierReward(int wave);
Set<Player> getPlayersInArena();
Set<Player> getPlayersInLobby();
+4
View File
@@ -7,3 +7,7 @@ waves:
'7': minecart, chest_minecart, furnace_minecart
'13': iron_sword, iron_pickaxe, iron_shovel
'16': diamond_sword
tiers:
'4': diamond
'11': diamond:10
'17': diamond:25