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:
garbagemule
2014-02-24 17:22:20 +01:00
parent 92c4ce1a8b
commit f85f9e20d7
9 changed files with 68 additions and 9 deletions
+1 -1
View File
@@ -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
*/