Make clashing wave resolution randomized.
This commit changes two things; it allows multiple single waves to have the same wave number, and it makes the wave selection procedure pick randomly between multiple valid matches. Effectively, this means that MobArena now picks randomly when clashing recurrent waves _also_ clash on priority (rather than deferring the decision to the arbitrary but deterministic nature of sorted sets), and it also picks randomly between multiple single waves with the same wave number (which was not possible before). This should allow server owners to add variety into their wave setups while maintaining a great deal of control over the randomness involved. For instance, it's now possible to have wave 10 be a boss wave, but the _actual_ boss wave is randomly picked between three different waves all with wave number 10. Upgrade waves could be randomized as well. As for randomized recurrent waves, perhaps instead of having potentially four different mobs in the same wave, a setup could instead have two _pairs_ of mobs that are randomly selected for a different kind of randomness. Closes #795
This commit is contained in:
@@ -11,6 +11,10 @@ These changes will (most likely) be included in the next version.
|
||||
|
||||
|
||||
## [Unreleased]
|
||||
### 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.
|
||||
- Single waves can now be randomized. If two or more single waves clash on wave number, MobArena will now randomly pick between them. This means it is now possible to make randomly selected bosses for boss waves, for instance.
|
||||
|
||||
### Fixed
|
||||
- MobArena no longer throws errors when handling block explosions on Minecraft 1.21.
|
||||
|
||||
|
||||
@@ -4,7 +4,9 @@ import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.waves.enums.WaveBranch;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
import java.util.SortedSet;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.TreeSet;
|
||||
|
||||
public class WaveManager
|
||||
@@ -12,10 +14,11 @@ public class WaveManager
|
||||
private Arena arena;
|
||||
private ConfigurationSection section;
|
||||
|
||||
private Wave defaultWave, currentWave;
|
||||
private TreeSet<Wave> recurrentWaves, singleWaves, singleWavesInstance;
|
||||
private Wave defaultWave, currentWave, nextWave;
|
||||
private TreeSet<Wave> recurrentWaves, singleWaves;
|
||||
|
||||
private int wave, finalWave;
|
||||
private Random random = new Random();
|
||||
|
||||
public WaveManager(Arena arena, ConfigurationSection section) {
|
||||
this.arena = arena;
|
||||
@@ -26,14 +29,10 @@ public class WaveManager
|
||||
reloadWaves();
|
||||
}
|
||||
|
||||
public TreeSet<Wave> getRecurrentWaves() {
|
||||
return recurrentWaves;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
reloadWaves();
|
||||
wave = 0;
|
||||
singleWavesInstance = new TreeSet<>(singleWaves);
|
||||
determineNextWave();
|
||||
}
|
||||
|
||||
public void reloadWaves() {
|
||||
@@ -61,21 +60,77 @@ public class WaveManager
|
||||
}
|
||||
}
|
||||
|
||||
private void determineNextWave() {
|
||||
// Single waves take precedence over recurrent waves
|
||||
List<Wave> singles = findSingleWaveCandidates(wave + 1);
|
||||
if (!singles.isEmpty()) {
|
||||
nextWave = pickRandomWave(singles);
|
||||
return;
|
||||
}
|
||||
|
||||
List<Wave> recurrents = findRecurrentWaveCandidates(wave + 1);
|
||||
if (!recurrents.isEmpty()) {
|
||||
nextWave = pickRandomWave(recurrents);
|
||||
} else {
|
||||
nextWave = defaultWave.copy();
|
||||
}
|
||||
}
|
||||
|
||||
private List<Wave> findSingleWaveCandidates(int wave) {
|
||||
List<Wave> candidates = new ArrayList<>(singleWaves.size());
|
||||
for (Wave w : singleWaves) {
|
||||
if (w.matches(wave)) {
|
||||
candidates.add(w);
|
||||
}
|
||||
}
|
||||
|
||||
return candidates;
|
||||
}
|
||||
|
||||
private List<Wave> findRecurrentWaveCandidates(int wave) {
|
||||
List<Wave> matches = new ArrayList<>(recurrentWaves.size());
|
||||
for (Wave w : recurrentWaves) {
|
||||
if (w.matches(wave)) {
|
||||
matches.add(w);
|
||||
}
|
||||
}
|
||||
|
||||
int priority = 0;
|
||||
for (Wave w : matches) {
|
||||
if (w.getPriority() > priority) {
|
||||
priority = w.getPriority();
|
||||
}
|
||||
}
|
||||
|
||||
List<Wave> candidates = new ArrayList<>(matches.size());
|
||||
for (Wave w : matches) {
|
||||
if (w.getPriority() == priority) {
|
||||
candidates.add(w);
|
||||
}
|
||||
}
|
||||
|
||||
return candidates;
|
||||
}
|
||||
|
||||
private Wave pickRandomWave(List<Wave> candidates) {
|
||||
if (candidates.size() == 1) {
|
||||
return candidates.get(0).copy();
|
||||
}
|
||||
|
||||
int index = random.nextInt(candidates.size());
|
||||
return candidates.get(index).copy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the wave number and get the next Wave to be spawned.
|
||||
* Note that this method is a mutator.
|
||||
* @return the next Wave
|
||||
*/
|
||||
public Wave next() {
|
||||
wave++;
|
||||
currentWave = nextWave;
|
||||
|
||||
if (!singleWavesInstance.isEmpty() && singleWavesInstance.first().matches(wave)) {
|
||||
currentWave = singleWavesInstance.pollFirst().copy();
|
||||
}
|
||||
else {
|
||||
SortedSet<Wave> matches = getMatchingRecurrentWaves(wave);
|
||||
currentWave = (matches.isEmpty() ? defaultWave : matches.last()).copy();
|
||||
}
|
||||
wave++;
|
||||
determineNextWave();
|
||||
|
||||
return currentWave;
|
||||
}
|
||||
@@ -87,14 +142,7 @@ public class WaveManager
|
||||
* @return the next Wave
|
||||
*/
|
||||
public Wave getNext() {
|
||||
int next = wave + 1;
|
||||
|
||||
if (!singleWavesInstance.isEmpty() && singleWavesInstance.first().matches(next)) {
|
||||
return singleWavesInstance.first();
|
||||
}
|
||||
|
||||
SortedSet<Wave> matches = getMatchingRecurrentWaves(wave);
|
||||
return (matches.isEmpty() ? defaultWave : matches.last());
|
||||
return nextWave;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -121,14 +169,4 @@ public class WaveManager
|
||||
public int getFinalWave() {
|
||||
return finalWave;
|
||||
}
|
||||
|
||||
private SortedSet<Wave> getMatchingRecurrentWaves(int wave) {
|
||||
TreeSet<Wave> result = new TreeSet<>(WaveUtils.getRecurrentComparator());
|
||||
for (Wave w : recurrentWaves) {
|
||||
if (w.matches(wave)) {
|
||||
result.add(w);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ public class WaveUtils
|
||||
return -1;
|
||||
else if (w1.getFirstWave() > w2.getFirstWave())
|
||||
return 1;
|
||||
else return 0;
|
||||
else return w1.getName().compareTo(w2.getName());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user