Add copy() method to Wave interface.
When the WaveManager is queried for the next wave to be spawned via the next() method, it now returns a copy of the wave instead of the wave itself. This is because waves (boss waves in particular) have state, and this state is transferred to the next occurrence of the given wave. This caused recurrent boss waves to inconsistently share state, which resulted in the BossAbilityThread bailing early after the first occurrence of the boss wave it belonged to. By copying the initial wave state in the WaveManager, the issue is fixed. Fixes: http://dev.bukkit.org/bukkit-plugins/mobarena/tickets/1220/
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
name: MobArena
|
||||
author: garbagemule
|
||||
main: com.garbagemule.MobArena.MobArena
|
||||
version: 0.96.2.10
|
||||
version: 0.96.2.11
|
||||
softdepend: [Multiverse-Core,Towny,Heroes,MagicSpells,Vault]
|
||||
commands:
|
||||
ma:
|
||||
|
||||
@@ -152,4 +152,14 @@ public interface Wave
|
||||
* @return true, if the wave should spawn, false otherwise
|
||||
*/
|
||||
public boolean matches(int wave);
|
||||
|
||||
/**
|
||||
* Make a copy of the wave.
|
||||
* <p>
|
||||
* This method is used by the WaveManager in the {@code next()} method to
|
||||
* ensure that boss waves in particular do not share state.
|
||||
*
|
||||
* @return a copy of the wave
|
||||
*/
|
||||
public Wave copy();
|
||||
}
|
||||
@@ -66,11 +66,11 @@ public class WaveManager
|
||||
wave++;
|
||||
|
||||
if (!singleWavesInstance.isEmpty() && singleWavesInstance.first().matches(wave)) {
|
||||
currentWave = singleWavesInstance.pollFirst();
|
||||
currentWave = singleWavesInstance.pollFirst().copy();
|
||||
}
|
||||
else {
|
||||
SortedSet<Wave> matches = getMatchingRecurrentWaves(wave);
|
||||
currentWave = (matches.isEmpty() ? defaultWave : matches.last());
|
||||
currentWave = (matches.isEmpty() ? defaultWave : matches.last()).copy();
|
||||
}
|
||||
|
||||
return currentWave;
|
||||
|
||||
@@ -12,12 +12,8 @@ import org.bukkit.inventory.ItemStack;
|
||||
import com.garbagemule.MobArena.Messenger;
|
||||
import com.garbagemule.MobArena.Msg;
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.waves.AbstractWave;
|
||||
import com.garbagemule.MobArena.waves.BossAbilityThread;
|
||||
import com.garbagemule.MobArena.waves.MABoss;
|
||||
import com.garbagemule.MobArena.waves.MACreature;
|
||||
import com.garbagemule.MobArena.waves.ability.Ability;
|
||||
import com.garbagemule.MobArena.waves.ability.AbilityInfo;
|
||||
import com.garbagemule.MobArena.waves.*;
|
||||
import com.garbagemule.MobArena.waves.ability.*;
|
||||
import com.garbagemule.MobArena.waves.enums.*;
|
||||
|
||||
public class BossWave extends AbstractWave
|
||||
@@ -141,4 +137,19 @@ public class BossWave extends AbstractWave
|
||||
Messenger.announce(arena, Msg.WAVE_BOSS_ABILITY, info.name());
|
||||
}
|
||||
}
|
||||
|
||||
public Wave copy() {
|
||||
BossWave result = new BossWave(this.monster);
|
||||
for (Ability ability : this.abilities) {
|
||||
result.addBossAbility(ability);
|
||||
}
|
||||
result.abilityInterval = this.abilityInterval;
|
||||
result.abilityAnnounce = this.abilityAnnounce;
|
||||
result.useHealthMultiplier = this.useHealthMultiplier;
|
||||
result.healthMultiplier = this.healthMultiplier;
|
||||
result.flatHealth = this.flatHealth;
|
||||
result.reward = this.reward;
|
||||
result.bossName = this.bossName;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.util.*;
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.waves.AbstractWave;
|
||||
import com.garbagemule.MobArena.waves.MACreature;
|
||||
import com.garbagemule.MobArena.waves.Wave;
|
||||
import com.garbagemule.MobArena.waves.enums.*;
|
||||
|
||||
public class DefaultWave extends AbstractWave
|
||||
@@ -84,4 +85,11 @@ public class DefaultWave extends AbstractWave
|
||||
public void setFixed(boolean fixed) {
|
||||
this.fixed = fixed;
|
||||
}
|
||||
|
||||
public Wave copy() {
|
||||
DefaultWave result = new DefaultWave(monsterMap);
|
||||
result.growth = this.growth;
|
||||
result.fixed = this.fixed;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.util.*;
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.waves.AbstractWave;
|
||||
import com.garbagemule.MobArena.waves.MACreature;
|
||||
import com.garbagemule.MobArena.waves.Wave;
|
||||
import com.garbagemule.MobArena.waves.enums.WaveType;
|
||||
|
||||
public class SpecialWave extends AbstractWave
|
||||
@@ -48,4 +49,8 @@ public class SpecialWave extends AbstractWave
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Wave copy() {
|
||||
return new SpecialWave(monsterMap);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.garbagemule.MobArena.waves.types;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import com.garbagemule.MobArena.waves.Wave;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
@@ -58,4 +59,10 @@ public class SupplyWave extends AbstractWave
|
||||
public void setDropList(List<ItemStack> drops) {
|
||||
this.drops = drops;
|
||||
}
|
||||
|
||||
public Wave copy() {
|
||||
SupplyWave result = new SupplyWave(monsterMap);
|
||||
result.drops = new ArrayList<ItemStack>(this.drops);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.util.*;
|
||||
import com.garbagemule.MobArena.framework.Arena;
|
||||
import com.garbagemule.MobArena.waves.AbstractWave;
|
||||
import com.garbagemule.MobArena.waves.MACreature;
|
||||
import com.garbagemule.MobArena.waves.Wave;
|
||||
import com.garbagemule.MobArena.waves.enums.*;
|
||||
|
||||
public class SwarmWave extends AbstractWave
|
||||
@@ -37,4 +38,10 @@ public class SwarmWave extends AbstractWave
|
||||
public void setAmount(SwarmAmount amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
|
||||
public Wave copy() {
|
||||
SwarmWave result = new SwarmWave(monster);
|
||||
result.amount = this.amount;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.garbagemule.MobArena.waves.types;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import com.garbagemule.MobArena.waves.Wave;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
@@ -44,6 +45,16 @@ public class UpgradeWave extends AbstractWave
|
||||
this.giveAll = giveAll;
|
||||
}
|
||||
|
||||
public Wave copy() {
|
||||
Map<String,List<Upgrade>> upgrades = new HashMap<String,List<Upgrade>>();
|
||||
for (Map.Entry<String,List<Upgrade>> entry : this.upgrades.entrySet()) {
|
||||
upgrades.put(entry.getKey(), new ArrayList<Upgrade>(entry.getValue()));
|
||||
}
|
||||
UpgradeWave result = new UpgradeWave(upgrades);
|
||||
result.giveAll = this.giveAll;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an upgrade for an upgrade wave
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user