Phasing: store under which control it phased out

This commit is contained in:
tool4EvEr
2022-11-27 12:21:25 +01:00
parent 58ea27bde5
commit fbd2b1eaee
13 changed files with 89 additions and 87 deletions

View File

@@ -446,7 +446,7 @@ public class AiController {
CardCollection nonLandsInHand = CardLists.filter(player.getCardsIn(ZoneType.Hand), Predicates.not(CardPredicates.Presets.LANDS)); CardCollection nonLandsInHand = CardLists.filter(player.getCardsIn(ZoneType.Hand), Predicates.not(CardPredicates.Presets.LANDS));
// Some considerations for Momir/MoJhoSto // Some considerations for Momir/MoJhoSto
boolean hasMomir = player.getZone(ZoneType.Command).contains(CardPredicates.nameEquals("Momir Vig, Simic Visionary Avatar")); boolean hasMomir = player.isCardInCommand("Momir Vig, Simic Visionary Avatar");
if (hasMomir && nonLandsInHand.isEmpty()) { if (hasMomir && nonLandsInHand.isEmpty()) {
// Only do this if we have an all-basic land hand, which covers both stock Momir and MoJhoSto modes // Only do this if we have an all-basic land hand, which covers both stock Momir and MoJhoSto modes
// and also a custom Vanguard setup with a customized basic land deck and Momir as the avatar. // and also a custom Vanguard setup with a customized basic land deck and Momir as the avatar.
@@ -1534,7 +1534,7 @@ public class AiController {
} }
private boolean isSafeToHoldLandDropForMain2(Card landToPlay) { private boolean isSafeToHoldLandDropForMain2(Card landToPlay) {
boolean hasMomir = player.getZone(ZoneType.Command).contains(CardPredicates.nameEquals("Momir Vig, Simic Visionary Avatar")); boolean hasMomir = player.isCardInCommand("Momir Vig, Simic Visionary Avatar");
if (hasMomir) { if (hasMomir) {
// Don't do this in Momir variants since it messes with the AI decision making for the avatar. // Don't do this in Momir variants since it messes with the AI decision making for the avatar.
return false; return false;

View File

@@ -2054,7 +2054,7 @@ public class ComputerUtil {
return finalHandSize; return finalHandSize;
} }
CardCollectionView library = ai.getZone(ZoneType.Library).getCards(); CardCollectionView library = ai.getCardsIn(ZoneType.Library);
int landsInDeck = CardLists.count(library, CardPredicates.isType("Land")); int landsInDeck = CardLists.count(library, CardPredicates.isType("Land"));
// no land deck, can't do anything better // no land deck, can't do anything better

View File

@@ -200,13 +200,13 @@ public abstract class GameState {
// Mark the cards that need their ID remembered for various reasons // Mark the cards that need their ID remembered for various reasons
cardsReferencedByID.clear(); cardsReferencedByID.clear();
for (ZoneType zone : ZONES.keySet()) { for (ZoneType zone : ZONES.keySet()) {
for (Card card : game.getCardsIn(zone)) { for (Card card : game.getCardsIncludePhasingIn(zone)) {
if (card.getExiledWith() != null) { if (card.getExiledWith() != null) {
// Remember the ID of the card that exiled this card // Remember the ID of the card that exiled this card
cardsReferencedByID.add(card.getExiledWith()); cardsReferencedByID.add(card.getExiledWith());
} }
if (zone == ZoneType.Battlefield) { if (zone == ZoneType.Battlefield) {
if (card.hasCardAttachments()) { if (!card.getAllAttachedCards().isEmpty()) {
// Remember the ID of cards that have attachments // Remember the ID of cards that have attachments
cardsReferencedByID.add(card); cardsReferencedByID.add(card);
} }
@@ -240,7 +240,7 @@ public abstract class GameState {
// if the zone had no cards in it (e.g. empty hand). // if the zone had no cards in it (e.g. empty hand).
aiCardTexts.put(zone, ""); aiCardTexts.put(zone, "");
humanCardTexts.put(zone, ""); humanCardTexts.put(zone, "");
for (Card card : game.getCardsIn(zone)) { for (Card card : game.getCardsIncludePhasingIn(zone)) {
if (card.getName().equals("Puzzle Goal") && card.getOracleText().contains("New Puzzle")) { if (card.getName().equals("Puzzle Goal") && card.getOracleText().contains("New Puzzle")) {
puzzleCreatorState = true; puzzleCreatorState = true;
} }
@@ -264,7 +264,7 @@ public abstract class GameState {
return; return;
} }
if (!c.getMergedCards().isEmpty()) { if (c.hasMergedCard()) {
// we have to go by the current top card name here // we have to go by the current top card name here
newText.append(c.getTopMergedCard().getPaperCard().getName()); newText.append(c.getTopMergedCard().getPaperCard().getName());
} else { } else {
@@ -297,7 +297,8 @@ public abstract class GameState {
newText.append("|Monstrous"); newText.append("|Monstrous");
} }
if (c.isPhasedOut()) { if (c.isPhasedOut()) {
newText.append("|PhasedOut"); newText.append("|PhasedOut:");
newText.append(c.getPhasedOut().isAI() ? "AI" : "HUMAN");
} }
if (c.isFaceDown()) { if (c.isFaceDown()) {
newText.append("|FaceDown"); newText.append("|FaceDown");
@@ -1328,7 +1329,10 @@ public abstract class GameState {
} else if (info.startsWith("Monstrous")) { } else if (info.startsWith("Monstrous")) {
c.setMonstrous(true); c.setMonstrous(true);
} else if (info.startsWith("PhasedOut")) { } else if (info.startsWith("PhasedOut")) {
c.setPhasedOut(true); String tgt = info.substring(info.indexOf(':') + 1);
Player human = player.getGame().getPlayers().get(0);
Player ai = player.getGame().getPlayers().get(1);
c.setPhasedOut(tgt.equalsIgnoreCase("AI") ? ai : human);
} else if (info.startsWith("Counters:")) { } else if (info.startsWith("Counters:")) {
applyCountersToGameEntity(c, info.substring(info.indexOf(':') + 1)); applyCountersToGameEntity(c, info.substring(info.indexOf(':') + 1));
} else if (info.startsWith("SummonSick")) { } else if (info.startsWith("SummonSick")) {

View File

@@ -797,7 +797,7 @@ public class PlayerControllerAi extends PlayerController {
case "Never": case "Never":
return false; return false;
case "NothingRemembered": case "NothingRemembered":
if (source.getRememberedCount() == 0) { if (!source.hasRemembered()) {
return true; return true;
} else { } else {
Card rem = (Card) source.getFirstRemembered(); Card rem = (Card) source.getFirstRemembered();
@@ -807,7 +807,7 @@ public class PlayerControllerAi extends PlayerController {
} }
break; break;
case "BetterTgtThanRemembered": case "BetterTgtThanRemembered":
if (source.getRememberedCount() > 0) { if (source.hasRemembered()) {
Card rem = (Card) source.getFirstRemembered(); Card rem = (Card) source.getFirstRemembered();
// avoid pumping opponent creature // avoid pumping opponent creature
if (!rem.isInPlay() || rem.getController().isOpponentOf(source.getController())) { if (!rem.isInPlay() || rem.getController().isOpponentOf(source.getController())) {

View File

@@ -559,7 +559,7 @@ public class Game {
CardCollection cards = new CardCollection(); CardCollection cards = new CardCollection();
for (final Player p : getPlayers()) { for (final Player p : getPlayers()) {
cards.addAll(p.getCardsIncludePhasingIn(zone)); cards.addAll(p.getCardsIn(zone, false));
} }
return cards; return cards;
} }

View File

@@ -419,10 +419,16 @@ public abstract class SpellAbilityEffect {
protected static void addForgetCounterTrigger(final Card card, final String counterType) { protected static void addForgetCounterTrigger(final Card card, final String counterType) {
String trig = "Mode$ CounterRemoved | TriggerZones$ Command | ValidCard$ Card.IsRemembered | CounterType$ " + counterType + " | NewCounterAmount$ 0 | Static$ True"; String trig = "Mode$ CounterRemoved | TriggerZones$ Command | ValidCard$ Card.IsRemembered | CounterType$ " + counterType + " | NewCounterAmount$ 0 | Static$ True";
String trig2 = "Mode$ PhaseOut | TriggerZones$ Command | ValidCard$ Card.phasedOutIsRemembered | Static$ True";
final SpellAbility forgetSA = getForgetSpellAbility(card);
final Trigger parsedTrigger = TriggerHandler.parseTrigger(trig, card, true); final Trigger parsedTrigger = TriggerHandler.parseTrigger(trig, card, true);
parsedTrigger.setOverridingAbility(getForgetSpellAbility(card)); final Trigger parsedTrigger2 = TriggerHandler.parseTrigger(trig2, card, true);
parsedTrigger.setOverridingAbility(forgetSA);
parsedTrigger2.setOverridingAbility(forgetSA);
card.addTrigger(parsedTrigger); card.addTrigger(parsedTrigger);
card.addTrigger(parsedTrigger2);
} }
protected static void addLeaveBattlefieldReplacement(final Card card, final SpellAbility sa, final String zone) { protected static void addLeaveBattlefieldReplacement(final Card card, final SpellAbility sa, final String zone) {
@@ -764,6 +770,9 @@ public abstract class SpellAbilityEffect {
} }
protected static void addUntilCommand(final SpellAbility sa, GameCommand until) { protected static void addUntilCommand(final SpellAbility sa, GameCommand until) {
addUntilCommand(sa, until, sa.getActivatingPlayer());
}
protected static void addUntilCommand(final SpellAbility sa, GameCommand until, Player controller) {
Card host = sa.getHostCard(); Card host = sa.getHostCard();
final Game game = host.getGame(); final Game game = host.getGame();
final String duration = sa.getParam("Duration"); final String duration = sa.getParam("Duration");
@@ -774,19 +783,25 @@ public abstract class SpellAbilityEffect {
if ("UntilEndOfCombat".equals(duration)) { if ("UntilEndOfCombat".equals(duration)) {
game.getEndOfCombat().addUntil(until); game.getEndOfCombat().addUntil(until);
} else if ("UntilEndOfCombatYourNextTurn".equals(duration)) {
game.getEndOfCombat().registerUntilEnd(controller, until);
} else if ("UntilYourNextUpkeep".equals(duration)) { } else if ("UntilYourNextUpkeep".equals(duration)) {
game.getUpkeep().addUntil(sa.getActivatingPlayer(), until); game.getUpkeep().addUntil(controller, until);
} else if ("UntilTheEndOfYourNextUpkeep".equals(duration)) { } else if ("UntilTheEndOfYourNextUpkeep".equals(duration)) {
if (game.getPhaseHandler().is(PhaseType.UPKEEP)) { if (game.getPhaseHandler().is(PhaseType.UPKEEP)) {
game.getUpkeep().registerUntilEnd(host.getController(), until); game.getUpkeep().registerUntilEnd(controller, until);
} else { } else {
game.getUpkeep().addUntilEnd(host.getController(), until); game.getUpkeep().addUntilEnd(controller, until);
} }
} else if ("UntilTheEndOfYourNextTurn".equals(duration)) { } else if ("UntilYourNextEndStep".equals(duration)) {
if (game.getPhaseHandler().isPlayerTurn(sa.getActivatingPlayer())) { game.getEndOfTurn().addUntil(controller, until);
game.getEndOfTurn().registerUntilEnd(sa.getActivatingPlayer(), until); } else if ("UntilYourNextTurn".equals(duration)) {
game.getCleanup().addUntil(controller, until);
} else if ("UntilTheEndOfYourNextTurn".equals(duration)) {
if (game.getPhaseHandler().isPlayerTurn(controller)) {
game.getEndOfTurn().registerUntilEnd(controller, until);
} else { } else {
game.getEndOfTurn().addUntilEnd(sa.getActivatingPlayer(), until); game.getEndOfTurn().addUntilEnd(controller, until);
} }
} else if ("UntilTheEndOfTargetedNextTurn".equals(duration)) { } else if ("UntilTheEndOfTargetedNextTurn".equals(duration)) {
Player targeted = sa.getTargets().getFirstTargetedPlayer(); Player targeted = sa.getTargets().getFirstTargetedPlayer();
@@ -795,6 +810,17 @@ public abstract class SpellAbilityEffect {
} else { } else {
game.getEndOfTurn().addUntilEnd(targeted, until); game.getEndOfTurn().addUntilEnd(targeted, until);
} }
} else if ("ThisTurnAndNextTurn".equals(duration)) {
game.getEndOfTurn().addUntil(new GameCommand() {
private static final long serialVersionUID = -5054153666503075717L;
@Override
public void run() {
game.getEndOfTurn().addUntil(until);
}
});
} else if ("UntilStateBasedActionChecked".equals(duration)) {
game.addSBACheckedCommand(until);
} else if (duration != null && duration.startsWith("UntilAPlayerCastSpell")) { } else if (duration != null && duration.startsWith("UntilAPlayerCastSpell")) {
game.getStack().addCastCommand(duration.split(" ")[1], until); game.getStack().addCastCommand(duration.split(" ")[1], until);
} else if ("UntilHostLeavesPlay".equals(duration)) { } else if ("UntilHostLeavesPlay".equals(duration)) {
@@ -805,9 +831,8 @@ public abstract class SpellAbilityEffect {
} else if ("UntilLoseControlOfHost".equals(duration)) { } else if ("UntilLoseControlOfHost".equals(duration)) {
host.addLeavesPlayCommand(until); host.addLeavesPlayCommand(until);
host.addChangeControllerCommand(until); host.addChangeControllerCommand(until);
} else if ("UntilYourNextTurn".equals(duration)) {
game.getCleanup().addUntil(sa.getActivatingPlayer(), until);
} else if ("UntilUntaps".equals(duration)) { } else if ("UntilUntaps".equals(duration)) {
host.addLeavesPlayCommand(until);
host.addUntapCommand(until); host.addUntapCommand(until);
} else if ("UntilUnattached".equals(duration)) { } else if ("UntilUnattached".equals(duration)) {
host.addLeavesPlayCommand(until); //if it leaves play, it's unattached host.addLeavesPlayCommand(until); //if it leaves play, it's unattached

View File

@@ -55,13 +55,16 @@ public class EffectEffect extends SpellAbilityEffect {
List<Player> effectOwner = null; List<Player> effectOwner = null;
final String duration = sa.getParam("Duration"); final String duration = sa.getParam("Duration");
if (((duration != null && duration.startsWith("UntilHostLeavesPlay")) || "UntilLoseControlOfHost".equals(duration)) if (((duration != null && duration.startsWith("UntilHostLeavesPlay")) || "UntilLoseControlOfHost".equals(duration) || "UntilUntaps".equals(duration))
&& !(hostCard.isInPlay() || hostCard.isInZone(ZoneType.Stack))) { && !(hostCard.isInPlay() || hostCard.isInZone(ZoneType.Stack))) {
return; return;
} }
if ("UntilLoseControlOfHost".equals(duration) && hostCard.getController() != sa.getActivatingPlayer()) { if ("UntilLoseControlOfHost".equals(duration) && hostCard.getController() != sa.getActivatingPlayer()) {
return; return;
} }
if ("UntilUntaps".equals(duration) && !hostCard.isTapped()) {
return;
}
if (sa.hasParam("Abilities")) { if (sa.hasParam("Abilities")) {
effectAbilities = sa.getParam("Abilities").split(","); effectAbilities = sa.getParam("Abilities").split(",");
@@ -94,7 +97,7 @@ public class EffectEffect extends SpellAbilityEffect {
if (sa.hasParam("ForgetCounter")) { if (sa.hasParam("ForgetCounter")) {
CounterType cType = CounterType.getType(sa.getParam("ForgetCounter")); CounterType cType = CounterType.getType(sa.getParam("ForgetCounter"));
rememberList = new FCollection<GameObject>(CardLists.filter(Iterables.filter(rememberList, Card.class), CardPredicates.hasCounter(cType))); rememberList = new FCollection<>(CardLists.filter(Iterables.filter(rememberList, Card.class), CardPredicates.hasCounter(cType)));
} }
// don't create Effect if there is no remembered Objects // don't create Effect if there is no remembered Objects
@@ -294,7 +297,6 @@ public class EffectEffect extends SpellAbilityEffect {
registerDelayedTrigger(sa, sa.getParam("AtEOT"), Lists.newArrayList(hostCard)); registerDelayedTrigger(sa, sa.getParam("AtEOT"), Lists.newArrayList(hostCard));
} }
// Duration
if (duration == null || !duration.equals("Permanent")) { if (duration == null || !duration.equals("Permanent")) {
final GameCommand endEffect = new GameCommand() { final GameCommand endEffect = new GameCommand() {
private static final long serialVersionUID = -5861759814760561373L; private static final long serialVersionUID = -5861759814760561373L;
@@ -305,44 +307,7 @@ public class EffectEffect extends SpellAbilityEffect {
} }
}; };
if (duration == null || duration.equals("EndOfTurn")) { addUntilCommand(sa, endEffect, controller);
game.getEndOfTurn().addUntil(endEffect);
} else if (duration.equals("UntilHostLeavesPlay")) {
hostCard.addLeavesPlayCommand(endEffect);
} else if (duration.equals("UntilHostLeavesPlayOrEOT")) {
game.getEndOfTurn().addUntil(endEffect);
hostCard.addLeavesPlayCommand(endEffect);
} else if (duration.equals("UntilLoseControlOfHost")) {
hostCard.addLeavesPlayCommand(endEffect);
hostCard.addChangeControllerCommand(endEffect);
} else if (duration.equals("UntilYourNextTurn")) {
game.getCleanup().addUntil(controller, endEffect);
} else if (duration.equals("UntilYourNextUpkeep")) {
game.getUpkeep().addUntil(controller, endEffect);
} else if (duration.equals("UntilEndOfCombat")) {
game.getEndOfCombat().addUntil(endEffect);
} else if (duration.equals("UntilEndOfCombatYourNextTurn")) {
game.getEndOfCombat().registerUntilEnd(controller, endEffect);
} else if (duration.equals("UntilYourNextEndStep")) {
game.getEndOfTurn().addUntil(controller, endEffect);
} else if (duration.equals("UntilTheEndOfYourNextTurn")) {
if (game.getPhaseHandler().isPlayerTurn(controller)) {
game.getEndOfTurn().registerUntilEnd(controller, endEffect);
} else {
game.getEndOfTurn().addUntilEnd(controller, endEffect);
}
} else if (duration.equals("ThisTurnAndNextTurn")) {
game.getEndOfTurn().addUntil(new GameCommand() {
private static final long serialVersionUID = -5054153666503075717L;
@Override
public void run() {
game.getEndOfTurn().addUntil(endEffect);
}
});
} else if (duration.equals("UntilStateBasedActionChecked")) {
game.addSBACheckedCommand(endEffect);
}
} }
if (sa.hasParam("ImprintOnHost")) { if (sa.hasParam("ImprintOnHost")) {

View File

@@ -233,7 +233,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
// set for transform and meld, needed for clone effects // set for transform and meld, needed for clone effects
private boolean backside = false; private boolean backside = false;
private boolean phasedOut = false; private Player phasedOut;
private boolean directlyPhasedOut = true; private boolean directlyPhasedOut = true;
private boolean wontPhaseInNormal = false; private boolean wontPhaseInNormal = false;
@@ -4998,9 +4998,15 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
} }
public final boolean isPhasedOut() { public final boolean isPhasedOut() {
return phasedOut != null;
}
public final boolean isPhasedOut(Player turn) {
return turn.equals(phasedOut);
}
public final Player getPhasedOut() {
return phasedOut; return phasedOut;
} }
public final void setPhasedOut(final boolean phasedOut0) { public final void setPhasedOut(final Player phasedOut0) {
if (phasedOut == phasedOut0) { return; } if (phasedOut == phasedOut0) { return; }
phasedOut = phasedOut0; phasedOut = phasedOut0;
view.updatePhasedOut(this); view.updatePhasedOut(this);
@@ -5040,15 +5046,15 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
} }
private boolean switchPhaseState(final boolean fromUntapStep) { private boolean switchPhaseState(final boolean fromUntapStep) {
if (phasedOut && StaticAbilityCantPhaseIn.cantPhaseIn(this)) { if (isPhasedOut() && StaticAbilityCantPhaseIn.cantPhaseIn(this)) {
return false; return false;
} }
if (!phasedOut && StaticAbilityCantPhaseOut.cantPhaseOut(this)) { if (!isPhasedOut() && StaticAbilityCantPhaseOut.cantPhaseOut(this)) {
return false; return false;
} }
if (phasedOut && fromUntapStep && wontPhaseInNormal) { if (isPhasedOut() && fromUntapStep && wontPhaseInNormal) {
return false; return false;
} }
@@ -5061,16 +5067,23 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
// when it doesn't exist the game will no longer see it as tapped // when it doesn't exist the game will no longer see it as tapped
runUntapCommands(); runUntapCommands();
// TODO CR 702.26f need to run LeavesPlay + changeController commands but only when worded "for as long as" // TODO CR 702.26f need to run LeavesPlay + changeController commands but only when worded "for as long as"
// these links also break
clearEncodedCards();
if (isPaired()) {
getPairedWith().setPairedWith(null);
setPairedWith(null);
}
} }
setPhasedOut(!phasedOut); setPhasedOut(isPhasedOut() ? null : getController());
final Combat combat = getGame().getCombat(); final Combat combat = getGame().getCombat();
if (combat != null && phasedOut) { if (combat != null && isPhasedOut()) {
combat.saveLKI(this); combat.saveLKI(this);
combat.removeFromCombat(this); combat.removeFromCombat(this);
} }
if (!phasedOut) { if (!isPhasedOut()) {
// Just phased in, time to run the phased in trigger // Just phased in, time to run the phased in trigger
getGame().getTriggerHandler().registerActiveTrigger(this, false); getGame().getTriggerHandler().registerActiveTrigger(this, false);
getGame().getTriggerHandler().runTrigger(TriggerType.PhaseIn, runParams, false); getGame().getTriggerHandler().runTrigger(TriggerType.PhaseIn, runParams, false);

View File

@@ -239,7 +239,7 @@ public final class CardUtil {
newCopy.setCounters(Maps.newHashMap(in.getCounters())); newCopy.setCounters(Maps.newHashMap(in.getCounters()));
newCopy.setColor(in.getColor().getColor()); newCopy.setColor(in.getColor().getColor());
newCopy.setPhasedOut(in.isPhasedOut()); newCopy.setPhasedOut(in.getPhasedOut());
newCopy.setDamageHistory(in.getDamageHistory()); newCopy.setDamageHistory(in.getDamageHistory());
newCopy.setDamageReceivedThisTurn(in.getDamageReceivedThisTurn()); newCopy.setDamageReceivedThisTurn(in.getDamageReceivedThisTurn());

View File

@@ -192,7 +192,7 @@ public class PhaseHandler implements java.io.Serializable {
game.fireEvent(new GameEventTurnBegan(playerTurn, turn)); game.fireEvent(new GameEventTurnBegan(playerTurn, turn));
// Tokens starting game in play should suffer from Sum. Sickness // Tokens starting game in play should suffer from Sum. Sickness
for (final Card c : playerTurn.getCardsIncludePhasingIn(ZoneType.Battlefield)) { for (final Card c : playerTurn.getCardsIn(ZoneType.Battlefield, false)) {
if (playerTurn.getTurn() > 0 || !c.isStartsGameInPlay()) { if (playerTurn.getTurn() > 0 || !c.isStartsGameInPlay()) {
c.setSickness(false); c.setSickness(false);
} }
@@ -201,8 +201,8 @@ public class PhaseHandler implements java.io.Serializable {
game.getAction().resetActivationsPerTurn(); game.getAction().resetActivationsPerTurn();
final List<Card> lands = CardLists.filter(playerTurn.getLandsInPlay(), Presets.UNTAPPED); final int lands = CardLists.count(playerTurn.getLandsInPlay(), Presets.UNTAPPED);
playerTurn.setNumPowerSurgeLands(lands.size()); playerTurn.setNumPowerSurgeLands(lands);
} }
//update tokens //update tokens
game.fireEvent(new GameEventTokenStateUpdate(playerTurn.getTokensInPlay())); game.fireEvent(new GameEventTokenStateUpdate(playerTurn.getTokensInPlay()));

View File

@@ -253,11 +253,11 @@ public class Untap extends Phase {
private static void doPhasing(final Player turn) { private static void doPhasing(final Player turn) {
// Needs to include phased out cards // Needs to include phased out cards
final List<Card> list = CardLists.filter(turn.getCardsIncludePhasingIn(ZoneType.Battlefield), new Predicate<Card>() { final List<Card> list = CardLists.filter(turn.getGame().getCardsIncludePhasingIn(ZoneType.Battlefield), new Predicate<Card>() {
@Override @Override
public boolean apply(final Card c) { public boolean apply(final Card c) {
return (c.isPhasedOut() && c.isDirectlyPhasedOut()) || c.hasKeyword(Keyword.PHASING); return (c.isPhasedOut(turn) && c.isDirectlyPhasedOut()) || (c.hasKeyword(Keyword.PHASING) && c.getController().equals(turn));
} }
}); });

View File

@@ -1307,10 +1307,6 @@ public class Player extends GameEntity implements Comparable<Player> {
return zone == null ? CardCollection.EMPTY : zone.getCards(filterOutPhasedOut); return zone == null ? CardCollection.EMPTY : zone.getCards(filterOutPhasedOut);
} }
public final CardCollectionView getCardsIncludePhasingIn(final ZoneType zone) {
return getCardsIn(zone, false);
}
/** /**
* gets a list of first N cards in the requested zone. This function makes a CardCollectionView from Card[]. * gets a list of first N cards in the requested zone. This function makes a CardCollectionView from Card[].
*/ */
@@ -2357,9 +2353,8 @@ public class Player extends GameEntity implements Comparable<Player> {
} }
public CardCollectionView getColoredCardsInPlay(final String color) { public CardCollectionView getColoredCardsInPlay(final String color) {
return CardLists.getColor(getCardsIn(ZoneType.Battlefield), MagicColor.fromName(color)); return getColoredCardsInPlay(MagicColor.fromName(color));
} }
public CardCollectionView getColoredCardsInPlay(final byte color) { public CardCollectionView getColoredCardsInPlay(final byte color) {
return CardLists.getColor(getCardsIn(ZoneType.Battlefield), color); return CardLists.getColor(getCardsIn(ZoneType.Battlefield), color);
} }
@@ -2631,7 +2626,7 @@ public class Player extends GameEntity implements Comparable<Player> {
public final void resetCombatantsThisCombat() { public final void resetCombatantsThisCombat() {
// resets the status of attacked/blocked this phase // resets the status of attacked/blocked this phase
CardCollectionView list = getCardsIn(ZoneType.Battlefield); CardCollectionView list = getCardsIn(ZoneType.Battlefield, false);
for (Card c : list) { for (Card c : list) {
if (c.getDamageHistory().getCreatureAttackedThisCombat() > 0) { if (c.getDamageHistory().getCreatureAttackedThisCombat() > 0) {

View File

@@ -200,10 +200,10 @@ public class ReplacementHandler {
if (!replacementEffect.hasRun() if (!replacementEffect.hasRun()
&& (layer == null || replacementEffect.getLayer() == layer) && (layer == null || replacementEffect.getLayer() == layer)
&& event.equals(replacementEffect.getMode()) && event.equals(replacementEffect.getMode())
&& replacementEffect.requirementsCheck(game)
&& replacementEffect.canReplace(runParams)
&& !possibleReplacers.contains(replacementEffect) && !possibleReplacers.contains(replacementEffect)
&& replacementEffect.zonesCheck(cardZone)) { && replacementEffect.zonesCheck(cardZone)
&& replacementEffect.requirementsCheck(game)
&& replacementEffect.canReplace(runParams)) {
possibleReplacers.add(replacementEffect); possibleReplacers.add(replacementEffect);
} }
} }