Fixed empty mana pool handling to handle multiple effects at the same time correctly (fixes #482). Added support for mana that empties only at end of turn.

This commit is contained in:
LevelX2 2014-10-20 17:49:40 +02:00
parent 59702e4867
commit f893503acd
10 changed files with 185 additions and 103 deletions

View file

@ -21,22 +21,30 @@ import mage.players.Player;
public class AddManaToManaPoolEffect extends OneShotEffect {
protected Mana mana;
protected boolean emptyOnlyOnTurnsEnd;
public AddManaToManaPoolEffect(Mana mana, String textManaPoolOwner) {
this(mana, textManaPoolOwner, false);
}
/**
* Adds mana to the mana pool of target pointer player
*
* @param mana mana that will be added to the pool
* @param textManaPoolOwner text that references to the mana pool owner (e.g. "damaged player's")
*/
public AddManaToManaPoolEffect(Mana mana, String textManaPoolOwner) {
* @param emptyOnTurnsEnd if set, the mana will empty only on end of turnstep
*
*/
public AddManaToManaPoolEffect(Mana mana, String textManaPoolOwner, boolean emptyOnTurnsEnd) {
super(Outcome.PutManaInPool);
this.mana = mana;
this.emptyOnlyOnTurnsEnd = emptyOnTurnsEnd;
this.staticText = "add " + mana.toString() + " to " + textManaPoolOwner + " mana pool";
}
public AddManaToManaPoolEffect(final AddManaToManaPoolEffect effect) {
super(effect);
this.mana = effect.mana;
this.emptyOnlyOnTurnsEnd = effect.emptyOnlyOnTurnsEnd;
}
@Override
@ -48,7 +56,7 @@ public class AddManaToManaPoolEffect extends OneShotEffect {
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(getTargetPointer().getFirst(game, source));
if (player != null) {
player.getManaPool().addMana(mana, game, source);
player.getManaPool().addMana(mana, game, source, emptyOnlyOnTurnsEnd);
return true;
}
return false;

View file

@ -13,6 +13,7 @@ public enum Duration {
EndOfTurn("until end of turn"),
UntilYourNextTurn("until your next turn"),
EndOfCombat("until end of combat"),
EndOfStep("until end of phase step"),
Custom("");
private final String text;

View file

@ -1168,11 +1168,9 @@ public abstract class GameImpl implements Game, Serializable {
@Override
public void emptyManaPools() {
if (!replaceEvent(new GameEvent(GameEvent.EventType.EMPTY_MANA_POOLS, null, null, null))) {
for (Player player: getPlayers().values()) {
if (!replaceEvent(new GameEvent(GameEvent.EventType.EMPTY_MANA_POOL, player.getId(), null, player.getId()))) {
player.getManaPool().emptyPool();
}
for (Player player: getPlayers().values()) {
if (!replaceEvent(new GameEvent(GameEvent.EventType.EMPTY_MANA_POOL, player.getId(), null, player.getId()))) {
player.getManaPool().emptyPool(this);
}
}
}
@ -1186,7 +1184,7 @@ public abstract class GameImpl implements Game, Serializable {
public void addEffect(ContinuousEffect continuousEffect, Ability source) {
Ability newAbility = source.copy();
ContinuousEffect newEffect = (ContinuousEffect)continuousEffect.copy();
ContinuousEffect newEffect = continuousEffect.copy();
newEffect.newId();
newEffect.setTimestamp();
newEffect.init(newAbility, this);

View file

@ -75,7 +75,7 @@ public class GameEvent {
END_PHASE, END_PHASE_PRE, END_PHASE_POST,
END_TURN_STEP_PRE, END_TURN_STEP, END_TURN_STEP_POST,
CLEANUP_STEP_PRE, CLEANUP_STEP, CLEANUP_STEP_POST,
EMPTY_MANA_POOLS, EMPTY_MANA_POOL,
EMPTY_MANA_POOL,
AT_END_OF_TURN,
//player events

View file

@ -30,13 +30,17 @@ package mage.players;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import mage.ConditionalMana;
import mage.Mana;
import mage.abilities.Ability;
import mage.constants.AsThoughEffectType;
import mage.constants.Duration;
import mage.constants.ManaType;
import mage.constants.TurnPhase;
import mage.filter.Filter;
import mage.filter.FilterMana;
import mage.game.Game;
@ -54,6 +58,8 @@ public class ManaPool implements Serializable {
private boolean autoPayment; // auto payment from mana pool: true - mode is active
private ManaType unlockedManaType; // type of mana that was selected to pay manually
private final Set<ManaType> doNotEmptyManaTypes = new HashSet<>();
public ManaPool() {
autoPayment = true;
@ -66,6 +72,7 @@ public class ManaPool implements Serializable {
}
this.autoPayment = pool.autoPayment;
this.unlockedManaType = pool.unlockedManaType;
this.doNotEmptyManaTypes.addAll(pool.doNotEmptyManaTypes);
}
public int getRed() {
@ -156,30 +163,35 @@ public class ManaPool implements Serializable {
return get(ManaType.COLORLESS);
}
public int emptyManaType(List<ManaType> manaTypeArray) {
int total = count();
public void clearEmptyManaPoolRules() {
doNotEmptyManaTypes.clear();
}
public void addDoNotEmptyManaType(ManaType manaType) {
doNotEmptyManaTypes.add(manaType);
}
public int emptyPool(Game game) {
int total = 0;
Iterator<ManaPoolItem> it = manaItems.iterator();
while (it.hasNext()) {
ManaPoolItem item = it.next();
for (ManaType manaType: manaTypeArray) {
if (item.get(manaType) > 0) {
total += item.get(manaType);
while (item.get(manaType) > 0) {
item.remove(manaType);
for (ManaType manaType : ManaType.values()) {
if (item.get(manaType) > 0 && !doNotEmptyManaTypes.contains(manaType)) {
if (!item.getDuration().equals(Duration.EndOfTurn) || game.getPhase().getType().equals(TurnPhase.END)) {
if (game.replaceEvent(new GameEvent(GameEvent.EventType.EMPTY_MANA_POOL, null, null, null))) {
int amount = item.get(manaType);
item.clear(manaType);
item.add(ManaType.COLORLESS, amount);
} else {
total += item.get(manaType);
item.clear(manaType);
}
}
}
}
if (item.count() == 0) {
it.remove();
}
}
return total;
}
public int emptyPool() {
int total = count();
manaItems.clear();
return total;
}
return total;
}
private int payX(Ability ability, Game game) {
@ -305,12 +317,24 @@ public class ManaPool implements Serializable {
}
public void addMana(Mana manaToAdd, Game game, Ability source) {
addMana(manaToAdd, game, source, false);
}
public void addMana(Mana manaToAdd, Game game, Ability source, boolean emptyOnTurnsEnd) {
Mana mana = manaToAdd.copy();
if (!game.replaceEvent(new ManaEvent(EventType.ADD_MANA, source.getId(), source.getSourceId(), source.getControllerId(), mana))) {
if (mana instanceof ConditionalMana) {
this.manaItems.add(new ManaPoolItem((ConditionalMana)mana, source.getSourceId()));
ManaPoolItem item = new ManaPoolItem((ConditionalMana)mana, source.getSourceId());
if (emptyOnTurnsEnd) {
item.setDuration(Duration.EndOfTurn);
}
this.manaItems.add(item);
} else {
this.manaItems.add(new ManaPoolItem(mana.getRed(), mana.getGreen(), mana.getBlue(), mana.getWhite(), mana.getBlack(), mana.getColorless(), source.getSourceId(), mana.getFlag()));
ManaPoolItem item = new ManaPoolItem(mana.getRed(), mana.getGreen(), mana.getBlue(), mana.getWhite(), mana.getBlack(), mana.getColorless(), source.getSourceId(), mana.getFlag());
if (emptyOnTurnsEnd) {
item.setDuration(Duration.EndOfTurn);
}
this.manaItems.add(item);
}
GameEvent event = GameEvent.getEvent(GameEvent.EventType.MANA_ADDED, source.getId(), source.getSourceId(), source.getControllerId());
event.setData(mana.toString());

View file

@ -31,6 +31,7 @@ import java.io.Serializable;
import java.util.UUID;
import mage.ConditionalMana;
import mage.Mana;
import mage.constants.Duration;
import mage.constants.ManaType;
/**
@ -48,6 +49,7 @@ public class ManaPoolItem implements Serializable {
private ConditionalMana conditionalMana;
private UUID sourceId;
private boolean flag = false;
private Duration duration;
public ManaPoolItem() {}
@ -60,6 +62,7 @@ public class ManaPoolItem implements Serializable {
this.colorless = colorless;
this.sourceId = sourceId;
this.flag = flag;
this.duration = Duration.EndOfStep;
}
public ManaPoolItem(ConditionalMana conditionalMana, UUID sourceId) {
@ -67,6 +70,7 @@ public class ManaPoolItem implements Serializable {
this.sourceId = sourceId;
this.conditionalMana.setManaProducerId(sourceId);
this.flag = conditionalMana.getFlag();
this.duration = Duration.EndOfStep;
}
public ManaPoolItem(final ManaPoolItem item) {
@ -81,6 +85,7 @@ public class ManaPoolItem implements Serializable {
}
this.sourceId = item.sourceId;
this.flag = item.flag;
this.duration = item.duration;
}
public ManaPoolItem copy() {
@ -242,4 +247,59 @@ public class ManaPoolItem implements Serializable {
break;
}
}
public void clear(ManaType manaType) {
switch(manaType) {
case BLACK:
black = 0;
break;
case BLUE:
blue = 0;
break;
case GREEN:
green = 0;
break;
case RED:
red = 0;
break;
case WHITE:
white = 0;
break;
case COLORLESS:
colorless = 0;
break;
}
}
public void add(ManaType manaType, int amount) {
switch(manaType) {
case BLACK:
black += amount;
break;
case BLUE:
blue += amount;;
break;
case GREEN:
green += amount;;
break;
case RED:
red += amount;;
break;
case WHITE:
white += amount;;
break;
case COLORLESS:
colorless += amount;;
break;
}
}
public Duration getDuration() {
return duration;
}
public void setDuration(Duration duration) {
this.duration = duration;
}
}

View file

@ -433,6 +433,7 @@ public abstract class PlayerImpl implements Player, Serializable {
this.topCardRevealed = false;
this.alternativeSourceCosts.clear();
this.castSourceIdWithoutMana = null;
this.getManaPool().clearEmptyManaPoolRules();
}
@Override