Skip to content

Commit

Permalink
Make clashing wave resolution randomized.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
garbagemule committed Jun 24, 2024
1 parent ced55b8 commit 9c89787
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 35 deletions.
3 changes: 3 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ 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.

## [0.108] - 2024-01-01
### Added
Expand Down
106 changes: 72 additions & 34 deletions src/main/java/com/garbagemule/MobArena/waves/WaveManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,21 @@
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
{
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;
Expand All @@ -26,14 +29,10 @@ public WaveManager(Arena arena, ConfigurationSection section) {
reloadWaves();
}

public TreeSet<Wave> getRecurrentWaves() {
return recurrentWaves;
}

public void reset() {
reloadWaves();
wave = 0;
singleWavesInstance = new TreeSet<>(singleWaves);
determineNextWave();
}

public void reloadWaves() {
Expand Down Expand Up @@ -61,21 +60,77 @@ public void reloadWaves() {
}
}

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;
}
Expand All @@ -87,14 +142,7 @@ public Wave next() {
* @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;
}

/**
Expand All @@ -121,14 +169,4 @@ public int getWaveNumber() {
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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public int compare(Wave w1, Wave w2)
return -1;
else if (w1.getFirstWave() > w2.getFirstWave())
return 1;
else return 0;
else return w1.getName().compareTo(w2.getName());
}
};
}
Expand Down

0 comments on commit 9c89787

Please sign in to comment.