From 78f5dc05453ed4671e15d07f5e14cbbe2d15ef49 Mon Sep 17 00:00:00 2001 From: Andreas Troelsen Date: Sun, 6 Oct 2024 12:34:37 +0200 Subject: [PATCH] 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 --- changelog.md | 1 + .../com/garbagemule/MobArena/ArenaImpl.java | 8 ++++++- .../garbagemule/MobArena/MASpawnThread.java | 15 ++++++++++++ .../java/com/garbagemule/MobArena/Msg.java | 1 + .../garbagemule/MobArena/RewardManager.java | 23 ++++++++++++++++++- .../garbagemule/MobArena/framework/Arena.java | 2 ++ src/main/resources/res/rewards.yml | 4 ++++ 7 files changed, 52 insertions(+), 2 deletions(-) diff --git a/changelog.md b/changelog.md index 07bbd7f..1b1c8e6 100644 --- a/changelog.md +++ b/changelog.md @@ -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. diff --git a/src/main/java/com/garbagemule/MobArena/ArenaImpl.java b/src/main/java/com/garbagemule/MobArena/ArenaImpl.java index 04ac390..1f4801a 100644 --- a/src/main/java/com/garbagemule/MobArena/ArenaImpl.java +++ b/src/main/java/com/garbagemule/MobArena/ArenaImpl.java @@ -124,7 +124,7 @@ public class ArenaImpl implements Arena private WaveManager waveManager; private MASpawnThread spawnThread; private SheepBouncer sheepBouncer; - private Map everyWaveMap, afterWaveMap; + private Map 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 getPlayersInArena() { return Collections.unmodifiableSet(arenaPlayers); diff --git a/src/main/java/com/garbagemule/MobArena/MASpawnThread.java b/src/main/java/com/garbagemule/MobArena/MASpawnThread.java index ad8bd26..ce71986 100644 --- a/src/main/java/com/garbagemule/MobArena/MASpawnThread.java +++ b/src/main/java/com/garbagemule/MobArena/MASpawnThread.java @@ -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()); + } + } + } } diff --git a/src/main/java/com/garbagemule/MobArena/Msg.java b/src/main/java/com/garbagemule/MobArena/Msg.java index c2e7286..67c3f36 100644 --- a/src/main/java/com/garbagemule/MobArena/Msg.java +++ b/src/main/java/com/garbagemule/MobArena/Msg.java @@ -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: %"), diff --git a/src/main/java/com/garbagemule/MobArena/RewardManager.java b/src/main/java/com/garbagemule/MobArena/RewardManager.java index 5eda785..9cc8a6e 100644 --- a/src/main/java/com/garbagemule/MobArena/RewardManager.java +++ b/src/main/java/com/garbagemule/MobArena/RewardManager.java @@ -14,15 +14,18 @@ import java.util.Set; public class RewardManager { private Map> players; + private Map tiered; private Set 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 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); } } diff --git a/src/main/java/com/garbagemule/MobArena/framework/Arena.java b/src/main/java/com/garbagemule/MobArena/framework/Arena.java index 44c64d1..e0059b4 100644 --- a/src/main/java/com/garbagemule/MobArena/framework/Arena.java +++ b/src/main/java/com/garbagemule/MobArena/framework/Arena.java @@ -70,6 +70,8 @@ public interface Arena ThingPicker getAfterWaveReward(int wave); + ThingPicker getWaveTierReward(int wave); + Set getPlayersInArena(); Set getPlayersInLobby(); diff --git a/src/main/resources/res/rewards.yml b/src/main/resources/res/rewards.yml index f6f278b..cc970b4 100644 --- a/src/main/resources/res/rewards.yml +++ b/src/main/resources/res/rewards.yml @@ -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