diff --git a/forge-ai/src/main/java/forge/ai/AiCostDecision.java b/forge-ai/src/main/java/forge/ai/AiCostDecision.java index 646f53fe467..88a3ca7d5fa 100644 --- a/forge-ai/src/main/java/forge/ai/AiCostDecision.java +++ b/forge-ai/src/main/java/forge/ai/AiCostDecision.java @@ -88,7 +88,7 @@ public class AiCostDecision extends CostDecisionMakerBase { } else if (type.equals("Hand")) { if (hand.size() > 1 && ability.getActivatingPlayer() != null) { - hand = ability.getActivatingPlayer().getController().orderMoveToZoneList(hand, ZoneType.Graveyard); + hand = ability.getActivatingPlayer().getController().orderMoveToZoneList(hand, ZoneType.Graveyard, ability); } return PaymentDecision.card(hand); } @@ -104,7 +104,7 @@ public class AiCostDecision extends CostDecisionMakerBase { if (type.equals("Random")) { CardCollectionView randomSubset = CardLists.getRandomSubList(new CardCollection(hand), c); if (randomSubset.size() > 1 && ability.getActivatingPlayer() != null) { - randomSubset = ability.getActivatingPlayer().getController().orderMoveToZoneList(randomSubset, ZoneType.Graveyard); + randomSubset = ability.getActivatingPlayer().getController().orderMoveToZoneList(randomSubset, ZoneType.Graveyard, ability); } return PaymentDecision.card(randomSubset); } diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index 55fd0e7b103..d1d224633c9 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -316,9 +316,9 @@ public class GameAction { cards.set(cards.indexOf(c), copied); // 721.3b if (cause != null && zoneTo.getZoneType() == ZoneType.Exile) { - cards = (CardCollection) cause.getHostCard().getController().getController().orderMoveToZoneList(cards, zoneTo.getZoneType()); + cards = (CardCollection) cause.getHostCard().getController().getController().orderMoveToZoneList(cards, zoneTo.getZoneType(), cause); } else { - cards = (CardCollection) c.getOwner().getController().orderMoveToZoneList(cards, zoneTo.getZoneType()); + cards = (CardCollection) c.getOwner().getController().orderMoveToZoneList(cards, zoneTo.getZoneType(), cause); } cards.set(cards.indexOf(copied), c); if (zoneTo.is(ZoneType.Library)) { @@ -1169,7 +1169,7 @@ public class GameAction { if (noRegCreats != null) { if (noRegCreats.size() > 1 && !orderedNoRegCreats) { - noRegCreats = (CardCollection) GameActionUtil.orderCardsByTheirOwners(game, noRegCreats, ZoneType.Graveyard); + noRegCreats = (CardCollection) GameActionUtil.orderCardsByTheirOwners(game, noRegCreats, ZoneType.Graveyard, null); orderedNoRegCreats = true; } for (Card c : noRegCreats) { @@ -1180,7 +1180,7 @@ public class GameAction { if (desCreats.size() > 1 && !orderedDesCreats) { desCreats = CardLists.filter(desCreats, CardPredicates.Presets.CAN_BE_DESTROYED); if (!desCreats.isEmpty()) { - desCreats = (CardCollection) GameActionUtil.orderCardsByTheirOwners(game, desCreats, ZoneType.Graveyard); + desCreats = (CardCollection) GameActionUtil.orderCardsByTheirOwners(game, desCreats, ZoneType.Graveyard, null); } orderedDesCreats = true; } diff --git a/forge-game/src/main/java/forge/game/GameActionUtil.java b/forge-game/src/main/java/forge/game/GameActionUtil.java index 1cc5b9565bf..c547c496705 100644 --- a/forge-game/src/main/java/forge/game/GameActionUtil.java +++ b/forge-game/src/main/java/forge/game/GameActionUtil.java @@ -625,7 +625,7 @@ public final class GameActionUtil { return sb.toString(); } - public static CardCollectionView orderCardsByTheirOwners(Game game, CardCollectionView list, ZoneType dest) { + public static CardCollectionView orderCardsByTheirOwners(Game game, CardCollectionView list, ZoneType dest, SpellAbility sa) { CardCollection completeList = new CardCollection(); for (Player p : game.getPlayers()) { CardCollection subList = new CardCollection(); @@ -636,7 +636,7 @@ public final class GameActionUtil { } CardCollectionView subListView = subList; if (subList.size() > 1) { - subListView = p.getController().orderMoveToZoneList(subList, dest); + subListView = p.getController().orderMoveToZoneList(subList, dest, sa); } completeList.addAll(subListView); } diff --git a/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java b/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java index 4826163b1d8..c506d8d2162 100644 --- a/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java +++ b/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java @@ -238,7 +238,7 @@ public abstract class SpellAbilityEffect { } - protected static void registerDelayedTrigger(final SpellAbility sa, String location, final List crds) { + protected static void registerDelayedTrigger(final SpellAbility sa, String location, final Iterable crds) { boolean intrinsic = sa.isIntrinsic(); boolean your = location.startsWith("Your"); boolean combat = location.endsWith("Combat"); @@ -298,9 +298,9 @@ public abstract class SpellAbilityEffect { if (location.equals("Hand")) { trigSA = "DB$ ChangeZone | Defined$ DelayTriggerRememberedLKI | Origin$ Battlefield | Destination$ Hand"; } else if (location.equals("SacrificeCtrl")) { - trigSA = "DB$ SacrificeAll | Defined$ DelayTriggerRemembered"; + trigSA = "DB$ SacrificeAll | Defined$ DelayTriggerRememberedLKI"; } else if (location.equals("Sacrifice")) { - trigSA = "DB$ SacrificeAll | Defined$ DelayTriggerRemembered | Controller$ You"; + trigSA = "DB$ SacrificeAll | Defined$ DelayTriggerRememberedLKI | Controller$ You"; } else if (location.equals("Exile")) { trigSA = "DB$ ChangeZone | Defined$ DelayTriggerRememberedLKI | Origin$ Battlefield | Destination$ Exile"; } else if (location.equals("Destroy")) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneAllEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneAllEffect.java index 200fc15c6b4..b33e6c4b51c 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneAllEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneAllEffect.java @@ -126,14 +126,14 @@ public class ChangeZoneAllEffect extends SpellAbilityEffect { if ((destination == ZoneType.Library || destination == ZoneType.PlanarDeck) && !sa.hasParam("Shuffle") && cards.size() >= 2 && !random) { Player p = AbilityUtils.getDefinedPlayers(source, sa.getParamOrDefault("DefinedPlayer", "You"), sa).get(0); - cards = (CardCollection) p.getController().orderMoveToZoneList(cards, destination); + cards = (CardCollection) p.getController().orderMoveToZoneList(cards, destination, sa); //the last card in this list will be the closest to the top, but we want the first card to be closest. //so reverse it here before moving them to the library. java.util.Collections.reverse(cards); } if (destination == ZoneType.Graveyard) { - cards = (CardCollection) GameActionUtil.orderCardsByTheirOwners(game, cards, ZoneType.Graveyard); + cards = (CardCollection) GameActionUtil.orderCardsByTheirOwners(game, cards, ZoneType.Graveyard, sa); } if (destination.equals(ZoneType.Library) && random) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java index eaf6c980f49..7e8f35ded82 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/ChangeZoneEffect.java @@ -797,6 +797,10 @@ public class ChangeZoneEffect extends SpellAbilityEffect { triggerList.triggerChangesZoneAll(game); counterTable.triggerCountersPutAll(game); + if (sa.hasParam("AtEOT") && !triggerList.isEmpty()) { + registerDelayedTrigger(sa, sa.getParam("AtEOT"), triggerList.allCards()); + } + // for things like Gaea's Blessing if (destination.equals(ZoneType.Library) && sa.hasParam("Shuffle") && "True".equals(sa.getParam("Shuffle"))) { PlayerCollection pl = new PlayerCollection(); @@ -1374,6 +1378,10 @@ public class ChangeZoneEffect extends SpellAbilityEffect { player.shuffle(sa); } + if (sa.hasParam("AtEOT") && !movedCards.isEmpty()) { + registerDelayedTrigger(sa, sa.getParam("AtEOT"), movedCards); + } + if (combatChanged) { game.updateCombatForView(); game.fireEvent(new GameEventCombatChanged()); diff --git a/forge-game/src/main/java/forge/game/ability/effects/DestroyAllEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DestroyAllEffect.java index d836cf66f88..5fb434fe4bf 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DestroyAllEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DestroyAllEffect.java @@ -86,7 +86,7 @@ public class DestroyAllEffect extends SpellAbilityEffect { list = CardLists.filter(list, CardPredicates.Presets.CAN_BE_DESTROYED); if (list.size() > 1) { - list = GameActionUtil.orderCardsByTheirOwners(game, list, ZoneType.Graveyard); + list = GameActionUtil.orderCardsByTheirOwners(game, list, ZoneType.Graveyard, sa); } CardZoneTable table = new CardZoneTable(); diff --git a/forge-game/src/main/java/forge/game/ability/effects/DestroyEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DestroyEffect.java index 3b0e339c9e1..dba2774c908 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DestroyEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DestroyEffect.java @@ -76,7 +76,7 @@ public class DestroyEffect extends SpellAbilityEffect { CardCollection untargetedCards = CardUtil.getRadiance(sa); if (tgtCards.size() > 1) { - tgtCards = (CardCollection) GameActionUtil.orderCardsByTheirOwners(game, tgtCards, ZoneType.Graveyard); + tgtCards = (CardCollection) GameActionUtil.orderCardsByTheirOwners(game, tgtCards, ZoneType.Graveyard, sa); } CardZoneTable table = new CardZoneTable(); @@ -95,7 +95,7 @@ public class DestroyEffect extends SpellAbilityEffect { } if (untargetedCards.size() > 1) { - untargetedCards = (CardCollection) GameActionUtil.orderCardsByTheirOwners(game, untargetedCards, ZoneType.Graveyard); + untargetedCards = (CardCollection) GameActionUtil.orderCardsByTheirOwners(game, untargetedCards, ZoneType.Graveyard, sa); } for (final Card unTgtC : untargetedCards) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/DigEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DigEffect.java index 474726c08d8..c58532ed15f 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DigEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DigEffect.java @@ -353,9 +353,9 @@ public class DigEffect extends SpellAbilityEffect { CardLists.shuffle(afterOrder); } else if (!skipReorder && rest.size() > 1) { if (destZone2 == ZoneType.Graveyard) { - afterOrder = (CardCollection) GameActionUtil.orderCardsByTheirOwners(game, rest, destZone2); + afterOrder = (CardCollection) GameActionUtil.orderCardsByTheirOwners(game, rest, destZone2, sa); } else { - afterOrder = (CardCollection) chooser.getController().orderMoveToZoneList(rest, destZone2); + afterOrder = (CardCollection) chooser.getController().orderMoveToZoneList(rest, destZone2, sa); } } if (libraryPosition2 != -1) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/DigUntilEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DigUntilEffect.java index 90997aa65e9..9f31cf91ffe 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DigUntilEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DigUntilEffect.java @@ -162,7 +162,7 @@ public class DigUntilEffect extends SpellAbilityEffect { if (foundDest != null) { // Allow ordering of found cards if ((foundDest.isKnown()) && found.size() >= 2 && !foundDest.equals(ZoneType.Exile)) { - found = (CardCollection)p.getController().orderMoveToZoneList(found, foundDest); + found = (CardCollection)p.getController().orderMoveToZoneList(found, foundDest, sa); } final Iterator itr = found.iterator(); @@ -213,11 +213,11 @@ public class DigUntilEffect extends SpellAbilityEffect { if (sa.hasParam("NoneFoundDestination") && found.size() < untilAmount) { // Allow ordering the revealed cards if ((noneFoundDest.isKnown()) && revealed.size() >= 2) { - revealed = (CardCollection)p.getController().orderMoveToZoneList(revealed, noneFoundDest); + revealed = (CardCollection)p.getController().orderMoveToZoneList(revealed, noneFoundDest, sa); } if (noneFoundDest == ZoneType.Library && !shuffle && !sa.hasParam("RevealRandomOrder") && revealed.size() >= 2) { - revealed = (CardCollection)p.getController().orderMoveToZoneList(revealed, noneFoundDest); + revealed = (CardCollection)p.getController().orderMoveToZoneList(revealed, noneFoundDest, sa); } final Iterator itr = revealed.iterator(); @@ -232,11 +232,11 @@ public class DigUntilEffect extends SpellAbilityEffect { } else { // Allow ordering the rest of the revealed cards if ((revealedDest.isKnown()) && revealed.size() >= 2) { - revealed = (CardCollection)p.getController().orderMoveToZoneList(revealed, revealedDest); + revealed = (CardCollection)p.getController().orderMoveToZoneList(revealed, revealedDest, sa); } if (revealedDest == ZoneType.Library && !shuffle && !sa.hasParam("RevealRandomOrder") && revealed.size() >= 2) { - revealed = (CardCollection)p.getController().orderMoveToZoneList(revealed, revealedDest); + revealed = (CardCollection)p.getController().orderMoveToZoneList(revealed, revealedDest, sa); } final Iterator itr = revealed.iterator(); diff --git a/forge-game/src/main/java/forge/game/ability/effects/DiscardEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DiscardEffect.java index 62a02bd2e60..890a6a57712 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DiscardEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DiscardEffect.java @@ -145,7 +145,7 @@ public class DiscardEffect extends SpellAbilityEffect { CardCollectionView toDiscard = AbilityUtils.getDefinedCards(source, sa.getParam("DefinedCards"), sa); if (toDiscard.size() > 1) { - toDiscard = GameActionUtil.orderCardsByTheirOwners(game, toDiscard, ZoneType.Graveyard); + toDiscard = GameActionUtil.orderCardsByTheirOwners(game, toDiscard, ZoneType.Graveyard, sa); } for (final Card c : toDiscard) { @@ -164,7 +164,7 @@ public class DiscardEffect extends SpellAbilityEffect { CardCollectionView toDiscard = p.getCardsIn(ZoneType.Hand); if (toDiscard.size() > 1) { - toDiscard = GameActionUtil.orderCardsByTheirOwners(game, toDiscard, ZoneType.Graveyard); + toDiscard = GameActionUtil.orderCardsByTheirOwners(game, toDiscard, ZoneType.Graveyard, sa); } for(Card c : Lists.newArrayList(toDiscard)) { // without copying will get concurrent modification exception @@ -181,7 +181,7 @@ public class DiscardEffect extends SpellAbilityEffect { } CardCollectionView dPHand = CardLists.getValidCards(p.getCardsIn(ZoneType.Hand), "Card.IsNotRemembered", p, source); if (dPHand.size() > 1) { - dPHand = GameActionUtil.orderCardsByTheirOwners(game, dPHand, ZoneType.Graveyard); + dPHand = GameActionUtil.orderCardsByTheirOwners(game, dPHand, ZoneType.Graveyard, sa); } for (final Card c : dPHand) { @@ -221,7 +221,7 @@ public class DiscardEffect extends SpellAbilityEffect { CardCollectionView toDiscardView = toDiscard; if (toDiscard.size() > 1) { - toDiscardView = GameActionUtil.orderCardsByTheirOwners(game, toDiscard, ZoneType.Graveyard); + toDiscardView = GameActionUtil.orderCardsByTheirOwners(game, toDiscard, ZoneType.Graveyard, sa); } for (Card c : toDiscardView) { @@ -242,7 +242,7 @@ public class DiscardEffect extends SpellAbilityEffect { CardCollectionView toDiscard = p.getController().chooseCardsToDiscardUnlessType(Math.min(numCards, numCardsInHand), hand, sa.getParam("UnlessType"), sa); if (toDiscard.size() > 1) { - toDiscard = GameActionUtil.orderCardsByTheirOwners(game, toDiscard, ZoneType.Graveyard); + toDiscard = GameActionUtil.orderCardsByTheirOwners(game, toDiscard, ZoneType.Graveyard, sa); } for (Card c : toDiscard) { @@ -275,7 +275,7 @@ public class DiscardEffect extends SpellAbilityEffect { CardCollectionView dPChHand = CardLists.getValidCards(dPHand, valid.split(","), source.getController(), source, sa); dPChHand = CardLists.filter(dPChHand, Presets.NON_TOKEN); if (dPChHand.size() > 1) { - dPChHand = GameActionUtil.orderCardsByTheirOwners(game, dPChHand, ZoneType.Graveyard); + dPChHand = GameActionUtil.orderCardsByTheirOwners(game, dPChHand, ZoneType.Graveyard, sa); } // Reveal cards that will be discarded? @@ -322,7 +322,7 @@ public class DiscardEffect extends SpellAbilityEffect { if (toBeDiscarded != null) { if (toBeDiscarded.size() > 1) { - toBeDiscarded = GameActionUtil.orderCardsByTheirOwners(game, toBeDiscarded, ZoneType.Graveyard); + toBeDiscarded = GameActionUtil.orderCardsByTheirOwners(game, toBeDiscarded, ZoneType.Graveyard, sa); } if (mode.startsWith("Reveal") ) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/PumpAllEffect.java b/forge-game/src/main/java/forge/game/ability/effects/PumpAllEffect.java index 9bda62c3a75..46cef1e27f7 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/PumpAllEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/PumpAllEffect.java @@ -5,10 +5,10 @@ import forge.game.Game; import forge.game.ability.AbilityUtils; import forge.game.ability.SpellAbilityEffect; import forge.game.card.Card; -import forge.game.card.CardCollection; +import forge.game.card.CardCollectionView; import forge.game.card.CardFactoryUtil; import forge.game.event.GameEventCardStatsChanged; -import forge.game.player.Player; +import forge.game.player.PlayerCollection; import forge.game.spellability.SpellAbility; import forge.game.zone.ZoneType; import forge.util.TextUtil; @@ -16,11 +16,12 @@ import forge.util.TextUtil; import java.util.Arrays; import java.util.List; +import com.google.common.collect.Iterables; import com.google.common.collect.Lists; public class PumpAllEffect extends SpellAbilityEffect { private static void applyPumpAll(final SpellAbility sa, - final List list, final int a, final int d, + final Iterable list, final int a, final int d, final List keywords, final List affectedZones) { final Game game = sa.getActivatingPlayer().getGame(); @@ -109,6 +110,10 @@ public class PumpAllEffect extends SpellAbilityEffect { game.fireEvent(new GameEventCardStatsChanged(tgtC)); } + + if (sa.hasParam("AtEOT") && !Iterables.isEmpty(list)) { + registerDelayedTrigger(sa, sa.getParam("AtEOT"), list); + } } @Override @@ -127,7 +132,7 @@ public class PumpAllEffect extends SpellAbilityEffect { @Override public void resolve(final SpellAbility sa) { - final List tgtPlayers = getTargetPlayers(sa); + final PlayerCollection tgtPlayers = getTargetPlayers(sa); final List affectedZones = Lists.newArrayList(); final Game game = sa.getActivatingPlayer().getGame(); @@ -137,17 +142,11 @@ public class PumpAllEffect extends SpellAbilityEffect { affectedZones.add(ZoneType.Battlefield); } - CardCollection list = new CardCollection(); + CardCollectionView list; if (!sa.usesTargeting() && !sa.hasParam("Defined")) { - for (final ZoneType zone : affectedZones) { - list.addAll(game.getCardsIn(zone)); - } + list = game.getCardsIn(affectedZones); } else { - for (final ZoneType zone : affectedZones) { - for (final Player p : tgtPlayers) { - list.addAll(p.getCardsIn(zone)); - } - } + list = tgtPlayers.getCardsIn(affectedZones); } String valid = ""; @@ -155,7 +154,7 @@ public class PumpAllEffect extends SpellAbilityEffect { valid = sa.getParam("ValidCards"); } - list = (CardCollection)AbilityUtils.filterListByType(list, valid, sa); + list = AbilityUtils.filterListByType(list, valid, sa); List keywords = Lists.newArrayList(); if (sa.hasParam("KW")) { @@ -174,6 +173,6 @@ public class PumpAllEffect extends SpellAbilityEffect { applyPumpAll(sa, list, a, d, keywords, affectedZones); replaceDying(sa); - } // pumpAllResolve() + } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/RearrangeTopOfLibraryEffect.java b/forge-game/src/main/java/forge/game/ability/effects/RearrangeTopOfLibraryEffect.java index 2048fb7ed28..d2528511d08 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/RearrangeTopOfLibraryEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/RearrangeTopOfLibraryEffect.java @@ -112,7 +112,7 @@ public class RearrangeTopOfLibraryEffect extends SpellAbilityEffect { CardCollection topCards = player.getTopXCardsFromLibrary(numCards); int maxCards = topCards.size(); - CardCollectionView orderedCards = activator.getController().orderMoveToZoneList(topCards, ZoneType.Library); + CardCollectionView orderedCards = activator.getController().orderMoveToZoneList(topCards, ZoneType.Library, sa); for (int i = maxCards - 1; i >= 0; i--) { Card next = orderedCards.get(i); player.getGame().getAction().moveToLibrary(next, 0, sa); diff --git a/forge-game/src/main/java/forge/game/ability/effects/RepeatEachEffect.java b/forge-game/src/main/java/forge/game/ability/effects/RepeatEachEffect.java index 12a155ffaa8..6e1f0782511 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/RepeatEachEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/RepeatEachEffect.java @@ -89,7 +89,7 @@ public class RepeatEachEffect extends SpellAbilityEffect { if (loopOverCards) { if (sa.hasParam("ChooseOrder") && repeatCards.size() >= 2) { - repeatCards = player.getController().orderMoveToZoneList(repeatCards, ZoneType.Stack); + repeatCards = player.getController().orderMoveToZoneList(repeatCards, ZoneType.Stack, sa); } for (Card card : repeatCards) { diff --git a/forge-game/src/main/java/forge/game/ability/effects/SacrificeAllEffect.java b/forge-game/src/main/java/forge/game/ability/effects/SacrificeAllEffect.java index f389b79ff4f..ad63e69fdf2 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/SacrificeAllEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/SacrificeAllEffect.java @@ -40,39 +40,56 @@ public class SacrificeAllEffect extends SpellAbilityEffect { final Player activator = sa.getActivatingPlayer(); final Game game = activator.getGame(); - String valid = ""; - - if (sa.hasParam("ValidCards")) { - valid = sa.getParam("ValidCards"); - } - CardCollectionView list; if (sa.hasParam("Defined")) { list = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("Defined"), sa); + } else { + list = game.getCardsIn(ZoneType.Battlefield); + if (sa.hasParam("ValidCards")) { + list = AbilityUtils.filterListByType(list, sa.getParam("ValidCards"), sa); + } } - else { - list = AbilityUtils.filterListByType(game.getCardsIn(ZoneType.Battlefield), valid, sa); - } - if (sa.hasParam("Controller")) { - list = CardLists.filterControlledBy(list, AbilityUtils.getDefinedPlayers(sa.getHostCard(), sa.getParam("Controller"), sa)); - } - list = CardLists.filter(list, CardPredicates.canBeSacrificedBy(sa)); final boolean remSacrificed = sa.hasParam("RememberSacrificed"); if (remSacrificed) { card.clearRemembered(); } + // update cards that where using LKI + CardCollection gameList = new CardCollection(); + for (Card sac : list) { + final Card gameCard = game.getCardState(sac, null); + // gameCard is LKI in that case, the card is not in game anymore + // or the timestamp did change + // this should check Self too + if (gameCard == null || !sac.equalsWithTimestamp(gameCard) || !gameCard.canBeSacrificedBy(sa)) { + continue; + } + gameList.add(gameCard); + } + + list = gameList; + + // Do controller check after LKI got updated + if (sa.hasParam("Controller")) { + list = CardLists.filterControlledBy(list, AbilityUtils.getDefinedPlayers(sa.getHostCard(), sa.getParam("Controller"), sa)); + } + if (list.size() > 1) { - list = GameActionUtil.orderCardsByTheirOwners(game, list, ZoneType.Graveyard); + list = GameActionUtil.orderCardsByTheirOwners(game, list, ZoneType.Graveyard, sa); } CardZoneTable table = new CardZoneTable(); Map cachedMap = Maps.newHashMap(); for (Card sac : list) { final Card lKICopy = CardUtil.getLKICopy(sac, cachedMap); - if (game.getAction().sacrifice(sac, sa, table) != null && remSacrificed) { - card.addRemembered(lKICopy); + if (game.getAction().sacrifice(sac, sa, table) != null) { + if (remSacrificed) { + card.addRemembered(lKICopy); + } + if (sa.hasParam("ImprintSacrificed")) { + card.addImprintedCard(lKICopy); + } } } table.triggerChangesZoneAll(game); diff --git a/forge-game/src/main/java/forge/game/ability/effects/SacrificeEffect.java b/forge-game/src/main/java/forge/game/ability/effects/SacrificeEffect.java index f7c48857914..bef5257778b 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/SacrificeEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/SacrificeEffect.java @@ -138,7 +138,7 @@ public class SacrificeEffect extends SpellAbilityEffect { } if (choosenToSacrifice.size() > 1) { - choosenToSacrifice = GameActionUtil.orderCardsByTheirOwners(game, choosenToSacrifice, ZoneType.Graveyard); + choosenToSacrifice = GameActionUtil.orderCardsByTheirOwners(game, choosenToSacrifice, ZoneType.Graveyard, sa); } Map cachedMap = Maps.newHashMap(); 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 7d73ce72fa6..279b721fced 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -1136,7 +1136,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { newTop = c; } } - + if (newTop != null) { removeMutatedStates(); newTop.mergedCards = mergedCards; @@ -6265,24 +6265,15 @@ public class Card extends GameEntity implements Comparable, IHasSVars { return true; } - if (isCreature() && source.getActivatingPlayer().hasKeyword("You can't sacrifice creatures to cast spells or activate abilities.")) { - Cost srcCost = source.getPayCosts(); - if (srcCost != null) { - if (srcCost.hasSpecificCostType(CostSacrifice.class)) { - return false; - } + if ((source.isSpell() || source.isActivatedAbility()) && source.getPayCosts().hasSpecificCostType(CostSacrifice.class)) { + if (isCreature() && source.getActivatingPlayer().hasKeyword("You can't sacrifice creatures to cast spells or activate abilities.")) { + return false; + } + + if (isPermanent() && !isLand() && source.getActivatingPlayer().hasKeyword("You can't sacrifice nonland permanents to cast spells or activate abilities.")) { + return false; } } - - if (isPermanent() && !isLand() && source.getActivatingPlayer().hasKeyword("You can't sacrifice nonland permanents to cast spells or activate abilities.")) { - Cost srcCost = source.getPayCosts(); - if (srcCost != null) { - if (srcCost.hasSpecificCostType(CostSacrifice.class)) { - return false; - } - } - } - return getController().canSacrificeBy(source); } diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java index 3afcec29133..47b965d42ae 100644 --- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java +++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java @@ -3327,7 +3327,7 @@ public class CardFactoryUtil { + " the controller of the permanent it becomes sacrifices it at the beginning of the next cleanup step."; final String strDelay = "DB$ DelayedTrigger | Mode$ Phase | Phase$ Cleanup | TriggerDescription$ At the beginning of the next cleanup step, sacrifice CARDNAME."; - final String strSac = "DB$ SacrificeAll | ValidCards$ Card.Self"; + final String strSac = "DB$ SacrificeAll | Defined$ Self"; SpellAbility saDelay = AbilityFactory.getAbility(strDelay, card); saDelay.setAdditionalAbility("Execute", (AbilitySub) AbilityFactory.getAbility(strSac, card)); @@ -4433,7 +4433,7 @@ public class CardFactoryUtil { final String delTrigStr = "DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | RememberObjects$ Imprinted " + "| StackDescription$ None | TriggerDescription$ Sacrifice them at the beginning of the next end step."; - final String sacStr = "DB$ SacrificeAll | Defined$ DelayTriggerRemembered"; + final String sacStr = "DB$ SacrificeAll | Defined$ DelayTriggerRememberedLKI"; final String cleanupStr = "DB$ Cleanup | ClearRemembered$ True | ClearImprinted$ True"; diff --git a/forge-game/src/main/java/forge/game/card/CardZoneTable.java b/forge-game/src/main/java/forge/game/card/CardZoneTable.java index 177cd669ba8..9ad790b5126 100644 --- a/forge-game/src/main/java/forge/game/card/CardZoneTable.java +++ b/forge-game/src/main/java/forge/game/card/CardZoneTable.java @@ -7,6 +7,7 @@ import java.util.Map; import com.google.common.collect.ForwardingTable; import com.google.common.collect.HashBasedTable; +import com.google.common.collect.Iterables; import com.google.common.collect.Table; import forge.game.Game; @@ -94,4 +95,8 @@ public class CardZoneTable extends ForwardingTable allCards() { + return Iterables.concat(values()); + } } diff --git a/forge-game/src/main/java/forge/game/player/Player.java b/forge-game/src/main/java/forge/game/player/Player.java index 167113adc7e..66f18bcdb13 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -1780,7 +1780,7 @@ public class Player extends GameEntity implements Comparable { CardCollectionView milledView = milled; if (destination == ZoneType.Graveyard && milled.size() > 1) { - milledView = GameActionUtil.orderCardsByTheirOwners(game, milled, ZoneType.Graveyard); + milledView = GameActionUtil.orderCardsByTheirOwners(game, milled, ZoneType.Graveyard, sa); } for (Card m : milledView) { diff --git a/forge-game/src/main/java/forge/game/player/PlayerCollection.java b/forge-game/src/main/java/forge/game/player/PlayerCollection.java index 5ec5e53efa7..784a1a60b38 100644 --- a/forge-game/src/main/java/forge/game/player/PlayerCollection.java +++ b/forge-game/src/main/java/forge/game/player/PlayerCollection.java @@ -31,6 +31,14 @@ public class PlayerCollection extends FCollection { } return result; } + + public final CardCollection getCardsIn(Iterable zones) { + CardCollection result = new CardCollection(); + for (Player p : this) { + result.addAll(p.getCardsIn(zones)); + } + return result; + } public final CardCollection getCreaturesInPlay() { CardCollection result = new CardCollection(); diff --git a/forge-game/src/main/java/forge/game/player/PlayerController.java b/forge-game/src/main/java/forge/game/player/PlayerController.java index b09df0a2b7b..dd110de1f9d 100644 --- a/forge-game/src/main/java/forge/game/player/PlayerController.java +++ b/forge-game/src/main/java/forge/game/player/PlayerController.java @@ -163,9 +163,6 @@ public abstract class PlayerController { public abstract ImmutablePair arrangeForSurveil(CardCollection topN); public abstract boolean willPutCardOnTop(Card c); - public final CardCollectionView orderMoveToZoneList(CardCollectionView cards, ZoneType destinationZone) { - return orderMoveToZoneList(cards, destinationZone, null); - } public abstract CardCollectionView orderMoveToZoneList(CardCollectionView cards, ZoneType destinationZone, SpellAbility source); /** p = target player, validCards - possible discards, min cards to discard */ diff --git a/forge-game/src/main/java/forge/game/trigger/WrappedAbility.java b/forge-game/src/main/java/forge/game/trigger/WrappedAbility.java index b614f346934..521eae25647 100644 --- a/forge-game/src/main/java/forge/game/trigger/WrappedAbility.java +++ b/forge-game/src/main/java/forge/game/trigger/WrappedAbility.java @@ -42,7 +42,8 @@ public class WrappedAbility extends Ability { ApiType.Destroy, ApiType.Token, ApiType.SetState, - ApiType.Play + ApiType.Play, + ApiType.SacrificeAll ); private final SpellAbility sa; diff --git a/forge-gui/res/cardsfolder/a/angrath_the_flame_chained.txt b/forge-gui/res/cardsfolder/a/angrath_the_flame_chained.txt index 0991f1815b5..80bee13b128 100644 --- a/forge-gui/res/cardsfolder/a/angrath_the_flame_chained.txt +++ b/forge-gui/res/cardsfolder/a/angrath_the_flame_chained.txt @@ -6,10 +6,9 @@ A:AB$ Discard | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | Defined$ Play SVar:DBLoseLife:DB$ LoseLife | LifeAmount$ 2 | Defined$ Player.Opponent A:AB$ GainControl | Cost$ SubCounter<3/LOYALTY> | Planeswalker$ True | ValidTgts$ Creature | TgtPrompt$ Select target creature | LoseControl$ EOT | Untap$ True | AddKWs$ Haste | SubAbility$ DelTrig | SpellDescription$ Gain control of target creature until end of turn. Untap it. It gains haste until end of turn. Sacrifice it at the beginning of the next end step if it has converted mana cost 3 or less. SVar:DelTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | ValidPlayer$ Player | Execute$ TrigSac | RememberObjects$ Targeted | TriggerDescription$ Sacrifice that creature at the beginning of the next end step if it has converted mana cost 3 or less. -SVar:TrigSac:DB$ SacrificeAll | Defined$ DelayTriggerRemembered | Controller$ You | ConditionDefined$ DelayTriggerRemembered | ConditionPresent$ Card.cmcLE3 +SVar:TrigSac:DB$ SacrificeAll | Defined$ DelayTriggerRememberedLKI | Controller$ You | ConditionDefined$ DelayTriggerRememberedLKI | ConditionPresent$ Card.cmcLE3 A:AB$ RepeatEach | Cost$ SubCounter<8/LOYALTY> | Planeswalker$ True | Ultimate$ True | RepeatPlayers$ Player.Opponent | RepeatSubAbility$ DBLoseLife2 | SpellDescription$ Each opponent loses life equal to the number of cards in their graveyard. SVar:DBLoseLife2:DB$ LoseLife | Defined$ Player.IsRemembered | LifeAmount$ X | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True -SVar:X:Count$ValidGraveyard Card.RememberedPlayerCtrl -SVar:Picture:http://www.wizards.com/global/images/magic/general/angrath_the_flame_chained.jpg +SVar:X:Count$ValidGraveyard Card.RememberedPlayerCtrl Oracle:[+1]: Each opponent discards a card and loses 2 life.\n[−3]: Gain control of target creature until end of turn. Untap it. It gains haste until end of turn. Sacrifice it at the beginning of the next end step if it has converted mana cost 3 or less.\n[−8]: Each opponent loses life equal to the number of cards in their graveyard. diff --git a/forge-gui/res/cardsfolder/b/booby_trap.txt b/forge-gui/res/cardsfolder/b/booby_trap.txt index 62cccad30e7..bde00c1b33a 100644 --- a/forge-gui/res/cardsfolder/b/booby_trap.txt +++ b/forge-gui/res/cardsfolder/b/booby_trap.txt @@ -9,9 +9,7 @@ SVar:RevealedDraw:DB$ Draw | Defined$ Player.Chosen | NumCards$ 1 | SubAbility$ SVar:TrigReveal:DB$ Reveal | Defined$ Player.Chosen | RevealValid$ Card.IsRemembered | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True T:Mode$ Drawn | ValidCard$ Card.NamedCard+OwnedBy Player.Chosen | TriggerZones$ Battlefield | Execute$ TrapTriggered | TriggerDescription$ When the chosen player draws a card with the chosen name, sacrifice CARDNAME. If you do, CARDNAME deals 10 damage to that player. -SVar:TrapTriggered:DB$ SacrificeAll | ValidCards$ Card.Self | RememberSacrificed$ True | SubAbility$ Explosion -SVar:Explosion:DB$ DealDamage | NumDmg$ 10 | Defined$ Player.Chosen | ConditionCheckSVar$ X | ConditionSVarCompare$ GE1 | SubAbility$ DBCleanup -SVar:X:Remembered$Amount +SVar:TrapTriggered:DB$ SacrificeAll | Defined$ Self | RememberSacrificed$ True | SubAbility$ Explosion +SVar:Explosion:DB$ DealDamage | NumDmg$ 10 | Defined$ Player.Chosen | ConditionDefined$ Remembered | ConditionPresent$ Card | SubAbility$ DBCleanup AI:RemoveDeck:Random -SVar:Picture:http://www.wizards.com/global/images/magic/general/booby_trap.jpg Oracle:As Booby Trap enters the battlefield, choose an opponent and a card name other than a basic land card name.\nThe chosen player reveals each card they draw.\nWhen the chosen player draws a card with the chosen name, sacrifice Booby Trap. If you do, Booby Trap deals 10 damage to that player. diff --git a/forge-gui/res/cardsfolder/f/force_of_rage.txt b/forge-gui/res/cardsfolder/f/force_of_rage.txt index 8559d0ed0e3..a928ef068b3 100644 --- a/forge-gui/res/cardsfolder/f/force_of_rage.txt +++ b/forge-gui/res/cardsfolder/f/force_of_rage.txt @@ -4,7 +4,7 @@ Types:Instant SVar:AltCost:Cost$ ExileFromHand<1/Card.Red+Other> | OpponentTurn$ True | Description$ If it's not your turn, you may exile a red card from your hand rather than pay this spell's mana cost. A:SP$ Token | Cost$ 1 R R | TokenAmount$ 2 | TokenScript$ r_3_1_elemental_trample_haste | TokenOwner$ You | LegacyImage$ r 3 1 elemental trample haste mh1 | SubAbility$ DelayedSac | RememberTokens$ True | SpellDescription$ Create two 3/1 red Elemental creature tokens with trample and haste. Sacrifice those tokens at the beginning of your next upkeep. SVar:DelayedSac:DB$ DelayedTrigger | Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ DBSacToken | RememberObjects$ Remembered | SubAbility$ DBCleanup | TriggerDescription$ Sacrifice those tokens at the beginning of your next upkeep. -SVar:DBSacToken:DB$ SacrificeAll | Defined$ DelayTriggerRemembered | Controller$ You +SVar:DBSacToken:DB$ SacrificeAll | Defined$ DelayTriggerRememberedLKI | Controller$ You SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True DeckHas:Ability$Token Oracle:If it's not your turn, you may exile a red card from your hand rather than pay this spell's mana cost.\nCreate two 3/1 red Elemental creature tokens with trample and haste. Sacrifice those tokens at the beginning of your next upkeep. diff --git a/forge-gui/res/cardsfolder/g/goblin_kites.txt b/forge-gui/res/cardsfolder/g/goblin_kites.txt index b9207e07e82..dba90f6139a 100644 --- a/forge-gui/res/cardsfolder/g/goblin_kites.txt +++ b/forge-gui/res/cardsfolder/g/goblin_kites.txt @@ -4,6 +4,5 @@ Types:Enchantment A:AB$ Pump | Cost$ R | ValidTgts$ Creature.YouCtrl+toughnessLE2 | TgtPrompt$ Choose creature you control with toughness 2 or less | KW$ Flying | SubAbility$ DelTrig | SpellDescription$ Target creature you control with toughness 2 or less gains flying until end of turn. Flip a coin at the beginning of the next end step. If you lose the flip, sacrifice that creature. SVar:DelTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | Execute$ TrigFlip | RememberObjects$ Targeted | TriggerDescription$ Flip a coin at the beginning of the next end step. If you lose the flip, sacrifice that creature. SVar:TrigFlip:DB$ FlipACoin | LoseSubAbility$ DBSacrifice -SVar:DBSacrifice:DB$ SacrificeAll | Controller$ You | Defined$ DelayTriggerRemembered -SVar:Picture:http://www.wizards.com/global/images/magic/general/goblin_kites.jpg +SVar:DBSacrifice:DB$ SacrificeAll | Controller$ You | Defined$ DelayTriggerRememberedLKI Oracle:{R}: Target creature you control with toughness 2 or less gains flying until end of turn. Flip a coin at the beginning of the next end step. If you lose the flip, sacrifice that creature. diff --git a/forge-gui/res/cardsfolder/g/grave_peril.txt b/forge-gui/res/cardsfolder/g/grave_peril.txt index 551c67221ec..f2fff0bf33c 100644 --- a/forge-gui/res/cardsfolder/g/grave_peril.txt +++ b/forge-gui/res/cardsfolder/g/grave_peril.txt @@ -2,9 +2,9 @@ Name:Grave Peril ManaCost:1 B Types:Enchantment T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.nonBlack |TriggerZones$ Battlefield | Execute$ TrigSac | TriggerDescription$ When a nonblack creature enters the battlefield, sacrifice Grave Peril. If you do, destroy that creature. -SVar:TrigSac:DB$ SacrificeAll | ValidCards$ Card.Self | SubAbility$ DBDestroy | RememberSacrificed$ True -SVar:DBDestroy:DB$ Destroy | Defined$ TriggeredCardLKICopy | ConditionDefined$ Remembered | ConditionPresent$ Card +SVar:TrigSac:DB$ SacrificeAll | Defined$ Self | SubAbility$ DBDestroy | RememberSacrificed$ True +SVar:DBDestroy:DB$ Destroy | Defined$ TriggeredCardLKICopy | ConditionDefined$ Remembered | ConditionPresent$ Card | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:NonStackingEffect:True AI:RemoveDeck:Random -SVar:Picture:http://www.wizards.com/global/images/magic/general/grave_peril.jpg Oracle:When a nonblack creature enters the battlefield, sacrifice Grave Peril. If you do, destroy that creature. diff --git a/forge-gui/res/cardsfolder/i/ilharg_the_raze_boar.txt b/forge-gui/res/cardsfolder/i/ilharg_the_raze_boar.txt index 927c6298492..8d061943ab4 100644 --- a/forge-gui/res/cardsfolder/i/ilharg_the_raze_boar.txt +++ b/forge-gui/res/cardsfolder/i/ilharg_the_raze_boar.txt @@ -4,9 +4,7 @@ Types:Legendary Creature Boar God PT:6/6 K:Trample T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigChange | TriggerZones$ Battlefield | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME attacks, you may put a creature card from your hand onto the battlefield tapped and attacking. Return that creature to your hand at the beginning of the next end step. -SVar:TrigChange:DB$ChangeZone | Origin$ Hand | Destination$ Battlefield | ChangeType$ Creature.YouCtrl | Tapped$ True | Attacking$ True | RememberChanged$ True | SubAbility$ DBPump -SVar:DBPump:DB$ Animate | AtEOT$ Hand | Defined$ Remembered | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:TrigChange:DB$ChangeZone | Origin$ Hand | Destination$ Battlefield | ChangeType$ Creature.YouCtrl | Tapped$ True | Attacking$ True | AtEOT$ Hand SVar:HasAttackEffect:TRUE T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard,Exile | ValidCard$ Card.Self | Execute$ TriReturn | OptionalDecider$ You | TriggerController$ TriggeredCardController | TriggerDescription$ When CARDNAME dies or is put into exile from the battlefield, you may put it into its owner's library third from the top. SVar:TriReturn:DB$ ChangeZone | Defined$ TriggeredNewCardLKICopy | Destination$ Library | LibraryPosition$ 2 diff --git a/forge-gui/res/cardsfolder/k/knowledge_vault.txt b/forge-gui/res/cardsfolder/k/knowledge_vault.txt index 38968c1d159..75c37673bdc 100644 --- a/forge-gui/res/cardsfolder/k/knowledge_vault.txt +++ b/forge-gui/res/cardsfolder/k/knowledge_vault.txt @@ -2,12 +2,11 @@ Name:Knowledge Vault ManaCost:4 Types:Artifact A:AB$ ChangeZone | Cost$ 2 T | Defined$ TopOfLibrary | Origin$ Library | Destination$ Exile | ExileFaceDown$ True | RememberChanged$ True | SpellDescription$ Exile the top card of your library face down. -A:AB$ SacrificeAll | Cost$ 0 | ValidCards$ Card.Self | RememberSacrificed$ True | SubAbility$ DBDiscardHand | SpellDescription$ Sacrifice CARDNAME. If you do, discard your hand, then put all cards exiled with CARDNAME into their owner's hand. -SVar:DBDiscardHand:DB$ Discard | Mode$ Hand | SubAbility$ DBChangeZoneAll | ConditionCheckSVar$ VaultX | ConditionSVarCompare$ GT0 -SVar:DBChangeZoneAll:DB$ ChangeZoneAll | ChangeType$ Remembered | Origin$ Exile | Destination$ Hand | ConditionCheckSVar$ VaultX | ConditionSVarCompare$ GT0 +A:AB$ SacrificeAll | Cost$ 0 | Defined$ Self | ImprintSacrificed$ True | SubAbility$ DBDiscardHand | SpellDescription$ Sacrifice CARDNAME. If you do, discard your hand, then put all cards exiled with CARDNAME into their owner's hand. +SVar:DBDiscardHand:DB$ Discard | Mode$ Hand | SubAbility$ DBChangeZoneAll | ConditionDefined$ Imprinted | ConditionPresent$ Card +SVar:DBChangeZoneAll:DB$ ChangeZoneAll | ChangeType$ Remembered | Origin$ Exile | Destination$ Hand | ConditionDefined$ Imprinted | ConditionPresent$ Card | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | ClearImprinted$ True T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Battlefield | Destination$ Any | Hidden$ True | Execute$ TrigGraveyard | TriggerController$ TriggeredCardController | TriggerDescription$ When CARDNAME leaves the battlefield, put all cards exiled with CARDNAME into their owner's graveyard. SVar:TrigGraveyard:DB$ ChangeZoneAll | ChangeType$ Remembered | Origin$ Exile | Destination$ Graveyard -SVar:VaultX:Remembered$Valid Card.Self AI:RemoveDeck:All -SVar:Picture:http://www.wizards.com/global/images/magic/general/knowledge_vault.jpg Oracle:{2}, {T}: Exile the top card of your library face down.\n{0}: Sacrifice Knowledge Vault. If you do, discard your hand, then put all cards exiled with Knowledge Vault into their owner's hand.\nWhen Knowledge Vault leaves the battlefield, put all cards exiled with Knowledge Vault into their owner's graveyard. diff --git a/forge-gui/res/cardsfolder/k/krovikan_vampire.txt b/forge-gui/res/cardsfolder/k/krovikan_vampire.txt index 3b683d2723a..9e1977be737 100644 --- a/forge-gui/res/cardsfolder/k/krovikan_vampire.txt +++ b/forge-gui/res/cardsfolder/k/krovikan_vampire.txt @@ -11,7 +11,7 @@ T:Mode$ TurnBegin | Execute$ DBCleanup | Static$ True T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ Player | TriggerZones$ Battlefield | CheckSVar$ X | SVarCompare$ GE1 | IsPresent$ Card.Self | Execute$ TrigChange | TriggerDescription$ At the beginning of each end step, if a creature dealt damage by CARDNAME this turn died, put that card onto the battlefield under your control. Sacrifice it when you lose control of CARDNAME. SVar:TrigChange:DB$ ChangeZoneAll | ChangeType$ Creature.IsRemembered+ThisTurnEnteredFrom_Battlefield | Origin$ Graveyard | Destination$ Battlefield | GainControl$ True | RememberChanged$ True | ForgetOtherRemembered$ True | SubAbility$ TrigDelay SVar:TrigDelay:DB$ DelayedTrigger | Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.Self | RememberObjects$ Remembered | Execute$ TrigSac | Secondary$ True | SubAbility$ DBCleanup | SpellDescription$ Sacrifice it when you lose control of CARDNAME. -SVar:TrigSac:DB$ SacrificeAll | Defined$ DelayTriggerRemembered | SubAbility$ DBCleanup +SVar:TrigSac:DB$ SacrificeAll | Defined$ DelayTriggerRememberedLKI | Controller$ You SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:X:Remembered$Amount Oracle:At the beginning of each end step, if a creature dealt damage by Krovikan Vampire this turn died, put that card onto the battlefield under your control. Sacrifice it when you lose control of Krovikan Vampire. diff --git a/forge-gui/res/cardsfolder/p/planebound_accomplice.txt b/forge-gui/res/cardsfolder/p/planebound_accomplice.txt index c5901a170f5..263eafbcda1 100644 --- a/forge-gui/res/cardsfolder/p/planebound_accomplice.txt +++ b/forge-gui/res/cardsfolder/p/planebound_accomplice.txt @@ -2,8 +2,6 @@ Name:Planebound Accomplice ManaCost:2 R Types:Creature Human Wizard PT:1/3 -A:AB$ ChangeZone | Cost$ R | Origin$ Hand | Destination$ Battlefield | ChangeType$ Planeswalker.YouOwn | RememberChanged$ True | Optional$ True | SubAbility$ DBPump | AILogic$ BeforeCombat | SpellDescription$ You may put a planeswalker card from your hand onto the battlefield. Sacrifice it at the beginning of the next end step. -SVar:DBPump:DB$ Pump | Defined$ Remembered | AtEOT$ Sacrifice | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +A:AB$ ChangeZone | Cost$ R | Origin$ Hand | Destination$ Battlefield | ChangeType$ Planeswalker.YouOwn | Optional$ True | AtEOT$ Sacrifice | AILogic$ BeforeCombat | SpellDescription$ You may put a planeswalker card from your hand onto the battlefield. Sacrifice it at the beginning of the next end step. AI:RemoveDeck:Random Oracle:{R}: You may put a planeswalker card from your hand onto the battlefield. Sacrifice it at the beginning of the next end step. diff --git a/forge-gui/res/cardsfolder/p/promise_of_bunrei.txt b/forge-gui/res/cardsfolder/p/promise_of_bunrei.txt index 4b42d464612..f3eadbd61bb 100644 --- a/forge-gui/res/cardsfolder/p/promise_of_bunrei.txt +++ b/forge-gui/res/cardsfolder/p/promise_of_bunrei.txt @@ -2,9 +2,7 @@ Name:Promise of Bunrei ManaCost:2 W Types:Enchantment T:Mode$ ChangesZone | ValidCard$ Creature.YouCtrl | Origin$ Battlefield | Destination$ Graveyard | Execute$ TrigSac | TriggerZones$ Battlefield | TriggerDescription$ When a creature you control dies, sacrifice CARDNAME. If you do, create four 1/1 colorless Spirit creature tokens. -SVar:TrigSac:DB$ SacrificeAll | ValidCards$ Card.Self | RememberSacrificed$ True | SubAbility$ DBToken -SVar:DBToken:DB$ Token | TokenAmount$ 4 | TokenScript$ c_1_1_spirit | TokenOwner$ You | LegacyImage$ c 1 1 spirit sok | ConditionCheckSVar$ X | ConditionSVarCompare$ GE1 | SubAbility$ DBCleanup +SVar:TrigSac:DB$ SacrificeAll | Defined$ Self | RememberSacrificed$ True | SubAbility$ DBToken +SVar:DBToken:DB$ Token | TokenAmount$ 4 | TokenScript$ c_1_1_spirit | TokenOwner$ You | LegacyImage$ c 1 1 spirit sok | ConditionDefined$ Remembered | ConditionPresent$ Card | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True -SVar:X:Remembered$Amount -SVar:Picture:http://www.wizards.com/global/images/magic/general/promise_of_bunrei.jpg Oracle:When a creature you control dies, sacrifice Promise of Bunrei. If you do, create four 1/1 colorless Spirit creature tokens. diff --git a/forge-gui/res/cardsfolder/p/purphoros_bronze_blooded.txt b/forge-gui/res/cardsfolder/p/purphoros_bronze_blooded.txt index 6c878c58521..af0cddda3c4 100644 --- a/forge-gui/res/cardsfolder/p/purphoros_bronze_blooded.txt +++ b/forge-gui/res/cardsfolder/p/purphoros_bronze_blooded.txt @@ -7,7 +7,5 @@ S:Mode$ Continuous | Affected$ Card.Self | RemoveType$ Creature | CheckSVar$ X | SVar:X:Count$Devotion.Red SVar:BuffedBy:Permanent.Red S:Mode$ Continuous | Affected$ Creature.YouCtrl+Other | AddKeyword$ Haste | Description$ Other creatures you control have haste. -A:AB$ ChangeZone | Cost$ 2 R | Origin$ Hand | Destination$ Battlefield | ChangeType$ Creature.Red,Creature.Artifact | ChangeNum$ 1 | Optional$ You | RememberChanged$ True | SubAbility$ DBPump | StackDescription$ SpellDescription | SpellDescription$ You may put a red creature card or an artifact creature card from your hand onto the battlefield. Sacrifice it at the beginning of the next end step. -SVar:DBPump:DB$ Pump | Defined$ Remembered | AtEOT$ Sacrifice | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +A:AB$ ChangeZone | Cost$ 2 R | Origin$ Hand | Destination$ Battlefield | ChangeType$ Creature.Red,Creature.Artifact | ChangeNum$ 1 | Optional$ You | AtEOT$ Sacrifice | StackDescription$ SpellDescription | SpellDescription$ You may put a red creature card or an artifact creature card from your hand onto the battlefield. Sacrifice it at the beginning of the next end step. Oracle:Indestructible\nAs long as your devotion to red is less than five, Purphoros isn't a creature.\nOther creatures you control have haste.\n{2}{R}: You may put a red creature card or an artifact creature card from your hand onto the battlefield. Sacrifice it at the beginning of the next end step. diff --git a/forge-gui/res/cardsfolder/p/purphoross_intervention.txt b/forge-gui/res/cardsfolder/p/purphoross_intervention.txt index 19c6be6eb11..aa6ae3fadbf 100644 --- a/forge-gui/res/cardsfolder/p/purphoross_intervention.txt +++ b/forge-gui/res/cardsfolder/p/purphoross_intervention.txt @@ -2,9 +2,7 @@ Name:Purphoros's Intervention ManaCost:X R Types:Sorcery A:SP$ Charm | Cost$ X R | Choices$ DBToken,DBDealDamage -SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenScript$ r_x_1_elemental_trample_haste | TokenOwner$ You | TokenPower$ X | LegacyImage$ r x 1 elemental trample haste thb | RememberTokens$ True | SubAbility$ DBPump | SpellDescription$ Create an X/1 red Elemental creature token with trample and haste. Sacrifice it at the beginning of the next end step. -SVar:DBPump:DB$ Pump | Defined$ Remembered | AtEOT$ Sacrifice | SubAbility$ DBCleanup -SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenScript$ r_x_1_elemental_trample_haste | TokenOwner$ You | TokenPower$ X | LegacyImage$ r x 1 elemental trample haste thb | AtEOT$ Sacrifice | SpellDescription$ Create an X/1 red Elemental creature token with trample and haste. Sacrifice it at the beginning of the next end step. SVar:DBDealDamage:DB$ DealDamage | ValidTgts$ Creature,Planeswalker | TgtPrompt$ Select target creature or planeswalker | NumDmg$ XX | SpellDescription$ CARDNAME deals twice X damage to target creature or planeswalker. SVar:X:Count$xPaid SVar:XX:SVar$X/Twice diff --git a/forge-gui/res/cardsfolder/s/shifty_doppelganger.txt b/forge-gui/res/cardsfolder/s/shifty_doppelganger.txt index 8a91d5d9932..d8c6cab42a5 100644 --- a/forge-gui/res/cardsfolder/s/shifty_doppelganger.txt +++ b/forge-gui/res/cardsfolder/s/shifty_doppelganger.txt @@ -5,9 +5,8 @@ PT:1/1 A:AB$ ChangeZone | Cost$ 3 U Exile<1/CARDNAME> | Origin$ Hand | Destination$ Battlefield | ChangeType$ Creature.YouOwn | Optional$ True | RememberChanged$ True | SubAbility$ DBPump | SpellDescription$ You may put a creature card from your hand onto the battlefield. If you do, that creature gains haste until end of turn. At the beginning of the next end step, sacrifice that creature. If you do, return CARDNAME to the battlefield. SVar:DBPump:DB$ Pump | Defined$ Remembered | KW$ Haste | ConditionDefined$ Remembered | ConditionPresent$ Creature | ConditionCompare$ EQ1 | SubAbility$ DBDelTrig SVar:DBDelTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | Execute$ TrigSac | TriggerDescription$ At the beginning of the next end step, sacrifice that creature. | RememberObjects$ Remembered | ConditionDefined$ Remembered | ConditionPresent$ Creature | SubAbility$ DBCleanup -SVar:TrigSac:DB$ SacrificeAll | Defined$ DelayTriggerRemembered | Controller$ You | RememberSacrificed$ True | SubAbility$ DBBounce -SVar:DBBounce:DB$ ChangeZone | Origin$ Exile | Defined$ Self | Destination$ Battlefield | ConditionDefined$ Remembered | ConditionPresent$ Card | SubAbility$ DBCleanup +SVar:TrigSac:DB$ SacrificeAll | Defined$ DelayTriggerRememberedLKI | Controller$ You | RememberSacrificed$ True | SubAbility$ DBBounce +SVar:DBBounce:DB$ ChangeZone | Origin$ Exile | Defined$ Self | Destination$ Battlefield | ConditionDefined$ Remembered | ConditionPresent$ Card SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True AI:RemoveDeck:All -SVar:Picture:http://www.wizards.com/global/images/magic/general/shifty_doppelganger.jpg Oracle:{3}{U}, Exile Shifty Doppelganger: You may put a creature card from your hand onto the battlefield. If you do, that creature gains haste until end of turn. At the beginning of the next end step, sacrifice that creature. If you do, return Shifty Doppelganger to the battlefield. diff --git a/forge-gui/res/cardsfolder/s/skirk_alarmist.txt b/forge-gui/res/cardsfolder/s/skirk_alarmist.txt index 7a6ccda105f..ba869be08e9 100644 --- a/forge-gui/res/cardsfolder/s/skirk_alarmist.txt +++ b/forge-gui/res/cardsfolder/s/skirk_alarmist.txt @@ -4,9 +4,6 @@ Types:Creature Human Wizard PT:1/2 K:Haste A:AB$ SetState | Cost$ T | ValidTgts$ Creature.YouCtrl+faceDown | Mode$ TurnFace | SubAbility$ DBDelTrig | SpellDescription$ Turn target face-down creature you control face up. At the beginning of the next end step, sacrifice it. -SVar:DBDelTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | Execute$ TrigSac | RememberObjects$ Targeted | TriggerDescription$ At the beginning of the next end step, sacrifice it. | SubAbility$ DBCleanup -SVar:TrigSac:DB$ SacrificeAll | Defined$ DelayTriggerRemembered -SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:DBPump:DB$ Pump | Defined$ Targeted | AtEOT$ Sacrifice AI:RemoveDeck:All -SVar:Picture:http://www.wizards.com/global/images/magic/general/skirk_alarmist.jpg Oracle:Haste\n{T}: Turn target face-down creature you control face up. At the beginning of the next end step, sacrifice it. diff --git a/forge-gui/res/cardsfolder/s/spinal_embrace.txt b/forge-gui/res/cardsfolder/s/spinal_embrace.txt index b19172db3af..4c44da17cd9 100644 --- a/forge-gui/res/cardsfolder/s/spinal_embrace.txt +++ b/forge-gui/res/cardsfolder/s/spinal_embrace.txt @@ -4,10 +4,9 @@ Types:Instant A:SP$ GainControl | Cost$ 3 U U B | ValidTgts$ Creature.YouDontCtrl | TgtPrompt$ Select target creature you don't control | ActivationPhases$ BeginCombat->EndCombat | Untap$ True | AddKWs$ Haste | SubAbility$ DBAnimate | SpellDescription$ Cast this spell only during combat. Untap target creature you don't control and gain control of it. It gains haste until end of turn. At the beginning of the next end step, sacrifice it. If you do, you gain life equal to its toughness. SVar:DBAnimate:DB$ Animate | Defined$ Targeted | Keywords$ Haste | sVars$ SneakAttackEOT | SubAbility$ DelTrig SVar:DelTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ End Of Turn | Execute$ TrigSac | RememberObjects$ Targeted | TriggerDescription$ At the beginning of the next end step, sacrifice it. If you do, you gain life equal to its toughness. | AILogic$ Always | ConditionDefined$ Targeted | ConditionPresent$ Card | ConditionCompare$ GE1 -SVar:TrigSac:DB$ SacrificeAll | Defined$ DelayTriggerRemembered | Controller$ You | RememberSacrificed$ True | SubAbility$ DBGainLife +SVar:TrigSac:DB$ SacrificeAll | Defined$ DelayTriggerRememberedLKI | Controller$ You | RememberSacrificed$ True | SubAbility$ DBGainLife SVar:DBGainLife:DB$ GainLife | LifeAmount$ X | SubAbility$ DBCleanup | ConditionDefined$ Remembered | ConditionPresent$ Card SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:X:RememberedLKI$CardToughness SVar:SneakAttackEOT:SVar:EndOfTurnLeavePlay:AtEOT -SVar:Picture:http://www.wizards.com/global/images/magic/general/spinal_embrace.jpg Oracle:Cast this spell only during combat.\nUntap target creature you don't control and gain control of it. It gains haste until end of turn. At the beginning of the next end step, sacrifice it. If you do, you gain life equal to its toughness. diff --git a/forge-gui/res/cardsfolder/t/tears_of_rage.txt b/forge-gui/res/cardsfolder/t/tears_of_rage.txt index 57f9117bc0c..5665090d61c 100644 --- a/forge-gui/res/cardsfolder/t/tears_of_rage.txt +++ b/forge-gui/res/cardsfolder/t/tears_of_rage.txt @@ -2,10 +2,7 @@ Name:Tears of Rage ManaCost:2 R R Types:Instant Text:Cast this spell only during the declare attackers step.\r\n -A:SP$ PumpAll | Cost$ 2 R R | ActivationPhases$ Declare Attackers | ValidCards$ Creature.attacking+YouCtrl | NumAtt$ +X | SubAbility$ DelTrig | SpellDescription$ Attacking creatures you control get +X/+0 until end of turn, where X is the number of attacking creatures. Sacrifice those creatures at the beginning of the next end step. -SVar:DelTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ End Of Turn | Execute$ TrigSac | RememberObjects$ Valid Creature.attacking+YouCtrl | TriggerDescription$ CARDNAME - Sacrifice those creature at the beginning of the next end step. | AILogic$ Always -SVar:TrigSac:DB$ SacrificeAll | Defined$ DelayTriggerRemembered | Controller$ You +A:SP$ PumpAll | Cost$ 2 R R | ActivationPhases$ Declare Attackers | ValidCards$ Creature.attacking+YouCtrl | NumAtt$ +X | AtEOT$ Sacrifice | SpellDescription$ Attacking creatures you control get +X/+0 until end of turn, where X is the number of attacking creatures. Sacrifice those creatures at the beginning of the next end step. SVar:X:Count$Valid Creature.attacking+YouCtrl AI:RemoveDeck:All -SVar:Picture:http://www.wizards.com/global/images/magic/general/tears_of_rage.jpg Oracle:Cast this spell only during the declare attackers step.\nAttacking creatures you control get +X/+0 until end of turn, where X is the number of attacking creatures. Sacrifice those creatures at the beginning of the next end step. diff --git a/forge-gui/res/cardsfolder/t/thalakos_deceiver.txt b/forge-gui/res/cardsfolder/t/thalakos_deceiver.txt index 8aa1964f628..c87c8e4c5dd 100644 --- a/forge-gui/res/cardsfolder/t/thalakos_deceiver.txt +++ b/forge-gui/res/cardsfolder/t/thalakos_deceiver.txt @@ -4,9 +4,7 @@ Types:Creature Thalakos Wizard PT:1/1 K:Shadow T:Mode$ AttackerUnblocked | ValidCard$ Card.Self | Execute$ TrigSacrifice | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME attacks and isn't blocked, you may sacrifice it. If you do, gain control of target creature. (This effect lasts indefinitely.) -SVar:TrigSacrifice:DB$ SacrificeAll | ValidCards$ Card.Self | RememberSacrificed$ True | SubAbility$ DBGainControl -SVar:DBGainControl:DB$ GainControl | ValidTgts$ Creature | TgtPrompt$ Select target creature | ConditionCheckSVar$ X | ConditionSVarCompare$ EQ1 | SubAbility$ DBCleanup +SVar:TrigSacrifice:DB$ SacrificeAll | Defined$ Self | RememberSacrificed$ True | SubAbility$ DBGainControl +SVar:DBGainControl:DB$ GainControl | ValidTgts$ Creature | TgtPrompt$ Select target creature | ConditionDefined$ Remembered | ConditionPresent$ Card | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True -SVar:X:Remembered$Amount -SVar:Picture:http://www.wizards.com/global/images/magic/general/thalakos_deceiver.jpg Oracle:Shadow (This creature can block or be blocked by only creatures with shadow.)\nWhenever Thalakos Deceiver attacks and isn't blocked, you may sacrifice it. If you do, gain control of target creature. (This effect lasts indefinitely.) diff --git a/forge-gui/res/cardsfolder/t/thunderkin_awakener.txt b/forge-gui/res/cardsfolder/t/thunderkin_awakener.txt index ee5ac79c925..89fe2b7e0a7 100644 --- a/forge-gui/res/cardsfolder/t/thunderkin_awakener.txt +++ b/forge-gui/res/cardsfolder/t/thunderkin_awakener.txt @@ -4,9 +4,6 @@ Types:Creature Elemental Shaman PT:1/2 K:Haste T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigChange | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME attacks, choose target Elemental creature card in your graveyard with toughness less than CARDNAME's toughness. Return that card to the battlefield tapped and attacking. Sacrifice it at the beginning of the next end step. -SVar:TrigChange:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | ValidTgts$ Creature.Elemental+YouCtrl+toughnessLTX | TgtPrompt$ Select target Elemental creature card in your graveyard | Mandatory$ True | Tapped$ True | Attacking$ True | RememberChanged$ True | SubAbility$ DelTrig -SVar:DelTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | Execute$ TrigSac | RememberObjects$ Remembered | TriggerDescription$ Sacrifice it at the beginning of the next end step | SubAbility$ DBCleanup -SVar:TrigSac:DB$ SacrificeAll | Defined$ DelayTriggerRemembered | Controller$ You -SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:TrigChange:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | ValidTgts$ Creature.Elemental+YouCtrl+toughnessLTX | TgtPrompt$ Select target Elemental creature card in your graveyard | Mandatory$ True | Tapped$ True | Attacking$ True | AtEOT$ Sacrifice SVar:X:Count$CardToughness Oracle:Haste\nWhenever Thunderkin Awakener attacks, choose target Elemental creature card in your graveyard with toughness less than Thunderkin Awakener's toughness. Return that card to the battlefield tapped and attacking. Sacrifice it at the beginning of the next end step. diff --git a/forge-gui/res/cardsfolder/w/whispering_specter.txt b/forge-gui/res/cardsfolder/w/whispering_specter.txt index b4b07531be6..19c53eaab0b 100644 --- a/forge-gui/res/cardsfolder/w/whispering_specter.txt +++ b/forge-gui/res/cardsfolder/w/whispering_specter.txt @@ -5,10 +5,8 @@ PT:1/1 K:Flying K:Infect T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | OptionalDecider$ You | Execute$ TrigSacrifice | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, you may sacrifice it. If you do, that player discards a card for each poison counter they have. -SVar:TrigSacrifice:DB$ SacrificeAll | ValidCards$ Card.Self | RememberSacrificed$ True | SubAbility$ DBDiscard -SVar:DBDiscard:DB$ Discard | Defined$ TriggeredTarget | NumCards$ X | Mode$ TgtChoose | ConditionCheckSVar$ Y | ConditionSVarCompare$ EQ1 | SubAbility$ DBCleanup +SVar:TrigSacrifice:DB$ SacrificeAll | Defined$ Self | RememberSacrificed$ True | SubAbility$ DBDiscard +SVar:DBDiscard:DB$ Discard | Defined$ TriggeredTarget | NumCards$ X | Mode$ TgtChoose | ConditionDefined$ Remembered | ConditionPresent$ Card | SubAbility$ DBCleanup SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:X:TriggeredTarget$PoisonCounters -SVar:Y:Remembered$Amount -SVar:Picture:http://www.wizards.com/global/images/magic/general/whispering_specter.jpg Oracle:Flying\nInfect (This creature deals damage to creatures in the form of -1/-1 counters and to players in the form of poison counters.)\nWhenever Whispering Specter deals combat damage to a player, you may sacrifice it. If you do, that player discards a card for each poison counter they have. diff --git a/forge-gui/src/main/java/forge/player/HumanCostDecision.java b/forge-gui/src/main/java/forge/player/HumanCostDecision.java index f536459e504..f44f4e561a3 100644 --- a/forge-gui/src/main/java/forge/player/HumanCostDecision.java +++ b/forge-gui/src/main/java/forge/player/HumanCostDecision.java @@ -86,7 +86,7 @@ public class HumanCostDecision extends CostDecisionMakerBase { if (discardType.equals("Hand")) { if (hand.size() > 1 && ability.getActivatingPlayer() != null) { - hand = ability.getActivatingPlayer().getController().orderMoveToZoneList(hand, ZoneType.Graveyard); + hand = ability.getActivatingPlayer().getController().orderMoveToZoneList(hand, ZoneType.Graveyard, ability); } return PaymentDecision.card(hand); } @@ -105,7 +105,7 @@ public class HumanCostDecision extends CostDecisionMakerBase { CardCollectionView randomSubset = Aggregates.random(hand, c, new CardCollection()); if (randomSubset.size() > 1 && ability.getActivatingPlayer() != null) { - randomSubset = ability.getActivatingPlayer().getController().orderMoveToZoneList(randomSubset, ZoneType.Graveyard); + randomSubset = ability.getActivatingPlayer().getController().orderMoveToZoneList(randomSubset, ZoneType.Graveyard, ability); } return PaymentDecision.card(randomSubset); }