diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index aa7f3b098f8..3b03baed89f 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -233,13 +233,15 @@ public class Card extends GameEntity implements Comparable { // Zone-changing spells should store card's zone here private Zone currentZone = null; + // LKI copies of cards are allowed to store the LKI about the zone the card was known to be in last. + // For all cards except LKI copies this should always be null. + private Zone savedLastKnownZone = null; + private int countersAdded = 0; private CardRules cardRules; private final CardView view; - private boolean isTemporaryCopy = false; - // Enumeration for CMC request types public enum SplitCMCMode { CurrentSideCMC, @@ -6706,7 +6708,7 @@ public class Card extends GameEntity implements Comparable { } public boolean isInPlay() { - return isInZone(ZoneType.Battlefield) && !isTemporaryCopy; + return isInZone(ZoneType.Battlefield); } public void onCleanupPhase(final Player turn) { @@ -7100,11 +7102,24 @@ public class Card extends GameEntity implements Comparable { return goad.values(); } - public final boolean getIsTemporaryCopy() { - return this.isTemporaryCopy; + /** + * Returns the last known zone information for the card. If the card is a LKI copy of another card, + * then it stores the relevant information in savedLastKnownZone, which is returned. If the card is + * not a LKI copy (e.g. an ordinary card in the game), it does not have this information and then + * the last known zone is assumed to be the current zone the card is currently in. + * @return last known zone of the card (either LKI, if present, or the current zone). + */ + public final Zone getLastKnownZone() { + return this.savedLastKnownZone != null ? this.savedLastKnownZone : getZone(); } - public final void setIsTemporaryCopy(boolean temp) { - this.isTemporaryCopy = temp; + /** + * Sets the last known zone information for the card. Should only be used by LKI copies of cards + * obtained via CardUtil::getLKICopy. Otherwise should be null, which means that current zone the + * card is in is the last known zone. + * @param zone last known zone information for the card. + */ + public final void setLastKnownZone(Zone zone) { + this.savedLastKnownZone = zone; } } diff --git a/forge-game/src/main/java/forge/game/card/CardUtil.java b/forge-game/src/main/java/forge/game/card/CardUtil.java index ae04e7167ce..03a321e469f 100644 --- a/forge-game/src/main/java/forge/game/card/CardUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardUtil.java @@ -321,9 +321,7 @@ public final class CardUtil { newCopy.setMeldedWith(in.getMeldedWith()); - newCopy.setZone(in.getZone()); - - newCopy.setIsTemporaryCopy(true); // signals that this card should not be considered to be in play + newCopy.setLastKnownZone(in.getZone()); // used for the purpose of cards that care about the zone the card was known to be in last return newCopy; } diff --git a/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java b/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java index 549ea68d6b0..c89d1fe669f 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplacementHandler.java @@ -25,13 +25,12 @@ import forge.game.ability.AbilityUtils; import forge.game.card.Card; import forge.game.player.Player; import forge.game.spellability.SpellAbility; +import forge.game.zone.Zone; import forge.game.zone.ZoneType; import forge.util.FileSection; import forge.util.Visitor; - -import org.apache.commons.lang3.StringUtils; - import java.util.*; +import org.apache.commons.lang3.StringUtils; public class ReplacementHandler { private final Game game; @@ -113,14 +112,14 @@ public class ReplacementHandler { // when testing ReplaceMoved effects, make sure to check last known information since the host card // could have been moved, e.g. via a mass removal event (e.g. Kalitas, Traitor of Ghet + Wrath of God) - Card zoneCheckCard = replacementEffect instanceof ReplaceMoved ? game.getChangeZoneLKIInfo(crd) : crd; + Zone cardZone = replacementEffect instanceof ReplaceMoved ? game.getChangeZoneLKIInfo(crd).getLastKnownZone() : game.getZoneOf(crd); if (!replacementEffect.hasRun() && replacementEffect.getLayer() == layer && replacementEffect.requirementsCheck(game) && replacementEffect.canReplace(runParams) && !possibleReplacers.contains(replacementEffect) - && replacementEffect.zonesCheck(game.getZoneOf(zoneCheckCard))) { + && replacementEffect.zonesCheck(cardZone)) { possibleReplacers.add(replacementEffect); } }