ExiledWith: fix clone interaction (#2395)

* Fix Volo's Journal for Changeling

* ExiledWith: fix clone interaction
This commit is contained in:
tool4ever
2023-02-10 20:43:55 +01:00
committed by GitHub
parent 7e3f8ad9e4
commit fd4573eed3
16 changed files with 56 additions and 110 deletions

View File

@@ -890,6 +890,24 @@ public abstract class SpellAbilityEffect {
} else {
options = activator.getAllOtherPlayers();
}
return activator.getController().chooseSingleEntityForEffect(options, sa, Localizer.getInstance().getMessage("lblChoosePlayer") , null);
return activator.getController().chooseSingleEntityForEffect(options, sa, Localizer.getInstance().getMessage("lblChoosePlayer"), null);
}
public void handleExiledWith(final Card movedCard, final SpellAbility cause) {
Card exilingSource = cause.getHostCard();
// during replacement LKI might be used
if (cause.isReplacementAbility() && exilingSource.isLKI()) {
exilingSource = exilingSource.getGame().getCardState(exilingSource);
}
// only want this on permanents
if (exilingSource.isImmutable() || exilingSource.isInPlay()) {
exilingSource.addExiledCard(movedCard);
}
// if ability was granted use that source so they can be kept apart later
if (cause.isCopiedTrait()) {
exilingSource = cause.getOriginalHost();
}
movedCard.setExiledWith(exilingSource);
movedCard.setExiledBy(cause.getActivatingPlayer());
}
}

View File

@@ -187,13 +187,7 @@ public class ChangeZoneAllEffect extends SpellAbilityEffect {
} else {
movedCard = game.getAction().moveTo(destination, c, libraryPos, sa, moveParams);
if (destination == ZoneType.Exile && !c.isToken()) {
Card host = sa.getOriginalHost();
if (host == null) {
host = sa.getHostCard();
}
host.addExiledCard(movedCard);
movedCard.setExiledWith(host);
movedCard.setExiledBy(host.getController());
handleExiledWith(movedCard, sa);
}
if (sa.hasParam("ExileFaceDown")) {
movedCard.turnFaceDown(true);

View File

@@ -725,16 +725,10 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
}
} else {
// might set before card is moved only for nontoken
Card host = null;
if (destination.equals(ZoneType.Exile) && !gameCard.isToken()) {
host = sa.getOriginalHost();
if (host == null) {
host = sa.getHostCard();
}
host.addExiledCard(gameCard);
gameCard.setExiledWith(host);
gameCard.setExiledBy(host.getController());
handleExiledWith(gameCard, sa);
}
Map<AbilityKey, Object> moveParams = AbilityKey.newMap();
moveParams.put(AbilityKey.LastStateBattlefield, lastStateBattlefield);
moveParams.put(AbilityKey.LastStateGraveyard, lastStateGraveyard);
@@ -756,11 +750,8 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
// might set after card is moved again if something has changed
if (destination.equals(ZoneType.Exile) && !movedCard.isToken()) {
movedCard.setExiledWith(host);
if (host != null) {
host.addExiledCard(movedCard);
movedCard.setExiledBy(host.getController());
}
// need to remove first?
handleExiledWith(movedCard, sa);
}
if (sa.hasParam("WithCountersType")) {
@@ -893,7 +884,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
* @param sa
* a {@link forge.game.spellability.SpellAbility} object.
*/
private static void changeHiddenOriginResolve(final SpellAbility sa) {
private void changeHiddenOriginResolve(final SpellAbility sa) {
List<Player> fetchers;
if (sa.hasParam("DefinedPlayer")) {
@@ -918,7 +909,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
changeZonePlayerInvariant(chooser, sa, fetchers);
}
private static void changeZonePlayerInvariant(Player chooser, SpellAbility sa, List<Player> fetchers) {
private void changeZonePlayerInvariant(Player chooser, SpellAbility sa, List<Player> fetchers) {
final Card source = sa.getHostCard();
final Game game = source.getGame();
final boolean defined = sa.hasParam("Defined");
@@ -1423,13 +1414,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
else if (destination.equals(ZoneType.Exile)) {
movedCard = game.getAction().exile(c, sa, moveParams);
if (!c.isToken()) {
Card host = sa.getOriginalHost();
if (host == null) {
host = sa.getHostCard();
}
host.addExiledCard(movedCard);
movedCard.setExiledWith(host);
movedCard.setExiledBy(host.getController());
handleExiledWith(movedCard, sa);
}
if (sa.hasParam("ExileFaceDown")) {
movedCard.turnFaceDown(true);
@@ -1574,7 +1559,7 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
* object.
* @param game
*/
private static void removeFromStack(final SpellAbility tgtSA, final SpellAbility srcSA, final SpellAbilityStackInstance si, final Game game, CardZoneTable triggerList, GameEntityCounterTable counterTable) {
private void removeFromStack(final SpellAbility tgtSA, final SpellAbility srcSA, final SpellAbilityStackInstance si, final Game game, CardZoneTable triggerList, GameEntityCounterTable counterTable) {
final Card tgtHost = tgtSA.getHostCard();
final Zone originZone = tgtHost.getZone();
game.getStack().remove(si);
@@ -1592,14 +1577,8 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
} else if (srcSA.getParam("Destination").equals("Graveyard")) {
movedCard = game.getAction().moveToGraveyard(tgtHost, srcSA, params);
} else if (srcSA.getParam("Destination").equals("Exile")) {
Card host = srcSA.getOriginalHost();
if (host == null) {
host = srcSA.getHostCard();
}
movedCard = game.getAction().exile(tgtHost, srcSA, params);
host.addExiledCard(movedCard);
movedCard.setExiledWith(host);
movedCard.setExiledBy(host.getController());
handleExiledWith(movedCard, srcSA);
} else if (srcSA.getParam("Destination").equals("TopOfLibrary")) {
movedCard = game.getAction().moveToLibrary(tgtHost, srcSA, params);
} else if (srcSA.getParam("Destination").equals("Hand")) {

View File

@@ -53,11 +53,7 @@ public class ChooseTypeEffect extends SpellAbilityEffect {
case "Creature":
if (sa.hasParam("TypesFromDefined")) {
for (final Card c : AbilityUtils.getDefinedCards(card, sa.getParam("TypesFromDefined"), sa)) {
for (String t : c.getType()) {
if (CardType.isACreatureType(t)) {
validTypes.add(t);
}
}
validTypes.addAll(c.getType().getCreatureTypes());
}
} else if (sa.hasParam("MostPrevalentInDefinedZone")) {
final String[] info = sa.getParam("MostPrevalentInDefinedZone").split("_");
@@ -67,7 +63,6 @@ public class ChooseTypeEffect extends SpellAbilityEffect {
for (String s : CardFactoryUtil.getMostProminentCreatureType(zoneCards)) {
validTypes.add(s);
}
} else {
validTypes.addAll(CardType.getAllCreatureTypes());
}

View File

@@ -390,10 +390,6 @@ public class DigEffect extends SpellAbilityEffect {
movedCards = (CardCollection) GameActionUtil.orderCardsByTheirOwners(game, movedCards, destZone1, sa);
}
Card effectHost = sa.getOriginalHost();
if (effectHost == null) {
effectHost = sa.getHostCard();
}
for (Card c : movedCards) {
final ZoneType origin = c.getZone().getZoneType();
final PlayerZone zone = c.getOwner().getZone(destZone1);
@@ -434,9 +430,7 @@ public class DigEffect extends SpellAbilityEffect {
if (sa.hasParam("ExileWithCounter")) {
c.addCounter(CounterType.getType(sa.getParam("ExileWithCounter")), 1, player, counterTable);
}
effectHost.addExiledCard(c);
c.setExiledWith(effectHost);
c.setExiledBy(effectHost.getController());
handleExiledWith(c, sa);
}
}
if (!origin.equals(c.getZone().getZoneType())) {
@@ -507,9 +501,7 @@ public class DigEffect extends SpellAbilityEffect {
if (sa.hasParam("ExileWithCounter")) {
c.addCounter(CounterType.getType(sa.getParam("ExileWithCounter")), 1, player, counterTable);
}
effectHost.addExiledCard(c);
c.setExiledWith(effectHost);
c.setExiledBy(effectHost.getController());
handleExiledWith(c, sa);
if (remZone2) {
host.addRemembered(c);
}

View File

@@ -71,9 +71,7 @@ import java.util.*;
for (final Card c : drafted) {
Card made = game.getAction().moveTo(zone, c, sa, moveParams);
if (zone.equals(ZoneType.Exile)) {
source.addExiledCard(made);
made.setExiledWith(source);
made.setExiledBy(source.getController());
handleExiledWith(made, sa);
if (sa.hasParam("ExileFaceDown")) {
made.turnFaceDown(true);
}

View File

@@ -67,13 +67,8 @@ public class MillEffect extends SpellAbilityEffect {
p.getGame().getGameLog().add(GameLogEntryType.ZONE_CHANGE, sb.toString());
}
if (destination.equals(ZoneType.Exile)) {
Card host = sa.getOriginalHost();
if (host == null) {
host = sa.getHostCard();
}
for (final Card c : milled) {
host.addExiledCard(c);
c.setExiledWith(host);
handleExiledWith(c, sa);
if (facedown) {
c.turnFaceDown(true);
}

View File

@@ -293,6 +293,8 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
private String sector = null;
private String chosenSector = null;
// points to the host that exiled this card, usually the one that has this object it its exiledCards field
// however it could also be a different card which isn't an error but means the exiling SA was gained
private Card exiledWith;
private Player exiledBy;
@@ -1733,7 +1735,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
public final boolean hasChosenNumber() {
return chosenNumber != null;
}
public final Integer getChosenNumber() {
return chosenNumber;
}
@@ -1754,6 +1755,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
return;
}
// TODO this may not find the right card in case the ability was granted
exiledWith.removeExiledCard(this);
exiledWith.removeUntilLeavesBattlefield(this);
@@ -1766,16 +1768,13 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
exiledBy = ep;
}
// used for cards like Belbe's Portal, Conspiracy, Cover of Darkness, etc.
public final String getChosenType() {
return chosenType;
}
public final void setChosenType(final String s) {
chosenType = s;
view.updateChosenType(this);
}
public final boolean hasChosenType() {
return chosenType != null && !chosenType.isEmpty();
}
@@ -1784,12 +1783,10 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
public final String getChosenType2() {
return chosenType2;
}
public final void setChosenType2(final String s) {
chosenType2 = s;
view.updateChosenType2(this);
}
public final boolean hasChosenType2() {
return chosenType2 != null && !chosenType2.isEmpty();
}

View File

@@ -221,7 +221,9 @@ public class CardFactory {
copySA.setCopied(true);
// 707.10b
copySA.setOriginalAbility(targetSA);
if (targetSA.isAbility()) {
copySA.setOriginalAbility(targetSA);
}
// Copied spell is not cast face down
if (copySA instanceof Spell) {

View File

@@ -370,8 +370,7 @@ public class CardProperty {
host = spellAbility.getHostCard();
}
}
if (!card.getExiledWith().equalsWithTimestamp(host)) {
if (!source.hasExiledCard(card) || !card.getExiledWith().equalsWithTimestamp(host)) {
return false;
}
} else if (property.equals("ExiledWithEffectSource")) {

View File

@@ -260,7 +260,6 @@ public class ReplacementHandler {
}
return ReplacementResult.NotReplaced;
}
private ReplacementResult run(final ReplacementType event, final Map<AbilityKey, Object> runParams, final ReplacementLayer layer, final Player decider) {

View File

@@ -2,15 +2,11 @@ Name:Ashiok, Nightmare Weaver
ManaCost:1 U B
Types:Legendary Planeswalker Ashiok
Loyalty:3
A:AB$ Dig | Cost$ AddCounter<2/LOYALTY> | Planeswalker$ True | ValidTgts$ Opponent | DigNum$ 3 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True | SpellDescription$ Exile the top three cards of target opponent's library.
A:AB$ ChooseCard | Cost$ SubCounter<X/LOYALTY> | Choices$ Creature.cmcEQX+IsRemembered+ExiledWithSource | ChoiceZone$ Exile | Planeswalker$ True | SubAbility$ DBChangeZone | AILogic$ Ashiok | SpellDescription$ Put a creature card with mana value X exiled with CARDNAME onto the battlefield under your control. That creature is a Nightmare in addition to its other types.
SVar:DBChangeZone:DB$ ChangeZone | Defined$ ChosenCard | Origin$ Exile | Destination$ Battlefield | ChangeType$ Creature.cmcEQX+IsRemembered+ExiledWithSource | GainControl$ True | AnimateSubAbility$ DBAnimate | SubAbility$ DBCleanMinus
SVar:DBAnimate:DB$ Animate | Defined$ ChosenCard | Types$ Nightmare | Duration$ Permanent
SVar:DBCleanMinus:DB$ Cleanup | ForgetDefined$ ChosenCard | ClearChosenCard$ True
A:AB$ Dig | Cost$ AddCounter<2/LOYALTY> | Planeswalker$ True | ValidTgts$ Opponent | DigNum$ 3 | ChangeNum$ All | DestinationZone$ Exile | SpellDescription$ Exile the top three cards of target opponent's library.
A:AB$ ChooseCard | Cost$ SubCounter<X/LOYALTY> | Choices$ Creature.cmcEQX+ExiledWithSource | ChoiceZone$ Exile | Planeswalker$ True | SubAbility$ DBChangeZone | AILogic$ Ashiok | SpellDescription$ Put a creature card with mana value X exiled with CARDNAME onto the battlefield under your control. That creature is a Nightmare in addition to its other types.
SVar:DBChangeZone:DB$ ChangeZone | Defined$ ChosenCard | Origin$ Exile | Destination$ Battlefield | GainControl$ True | AnimateSubAbility$ DBAnimate | SubAbility$ DBCleanMinus
SVar:DBAnimate:DB$ Animate | Defined$ Remembered | Types$ Nightmare | Duration$ Permanent
SVar:DBCleanMinus:DB$ Cleanup | ClearChosenCard$ True
SVar:X:Count$xPaid
A:AB$ ChangeZoneAll | Cost$ SubCounter<10/LOYALTY> | ChangeType$ Card.OppCtrl | Origin$ Graveyard,Hand | Destination$ Exile | RememberChanged$ True | Planeswalker$ True | Ultimate$ True | SpellDescription$ Exile all cards from all opponents' hands and graveyards.
T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered+ExiledWithSource | Execute$ DBForget
SVar:DBForget:DB$ Pump | ForgetObjects$ TriggeredCard
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | Static$ True | ValidCard$ Card.Self | Execute$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
Oracle:[+2]: Exile the top three cards of target opponent's library.\n[-X]: Put a creature card with mana value X exiled with Ashiok, Nightmare Weaver onto the battlefield under your control. That creature is a Nightmare in addition to its other types.\n[-10]: Exile all cards from all opponents' hands and graveyards.

View File

@@ -3,13 +3,7 @@ ManaCost:1 U B
Types:Creature Human Rogue
PT:0/3
A:AB$ Draw | Cost$ T | NumCards$ 1 | SubAbility$ DBExile | SpellDescription$ Draw a card, then exile a card from your hand face down.
SVar:DBExile:DB$ ChangeZone | Origin$ Hand | Destination$ Exile | ChangeType$ Card | ChangeNum$ 1 | ExileFaceDown$ True | Mandatory$ True | RememberChanged$ True
S:Mode$ Continuous | Affected$ Card.IsRemembered+ExiledWithSource | AffectedZone$ Exile | MayLookAt$ You | Description$ You may look at cards exiled with CARDNAME.
A:AB$ ChooseCard | Cost$ U B T | Defined$ You | Amount$ 1 | Mandatory$ True | AILogic$ AtLeast1 | ChoiceTitle$ Choose a card to put into your hand | Choices$ Card.IsRemembered+ExiledWithSource | ChoiceZone$ Exile | SubAbility$ MoveChosen | SpellDescription$ Return a card exiled with CARDNAME to its owner's hand.
SVar:MoveChosen:DB$ ChangeZone | Origin$ Exile | Destination$ Hand | Defined$ ChosenCard | ForgetChanged$ True | SubAbility$ DBCleanupChosen
SVar:DBCleanupChosen:DB$ Cleanup | ClearChosenCard$ True
T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered+ExiledWithSource | Execute$ DBForget
SVar:DBForget:DB$ Pump | ForgetObjects$ TriggeredCard
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | Static$ True | ValidCard$ Card.Self | Execute$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
SVar:DBExile:DB$ ChangeZone | Origin$ Hand | Destination$ Exile | ChangeType$ Card | ChangeNum$ 1 | ExileFaceDown$ True | Mandatory$ True
S:Mode$ Continuous | Affected$ Card.ExiledWithSource | AffectedZone$ Exile | MayLookAt$ You | Description$ You may look at cards exiled with CARDNAME.
A:AB$ ChangeZone | Cost$ U B T | Origin$ Exile | Destination$ Hand | Mandatory$ True | Hidden$ True | ChangeType$ Card.ExiledWithSource | SpellDescription$ Return a card exiled with CARDNAME to its owner's hand.
Oracle:{T}: Draw a card, then exile a card from your hand face down.\nYou may look at cards exiled with Bane Alley Broker.\n{U}{B}, {T}: Return a card exiled with Bane Alley Broker to its owner's hand.

View File

@@ -1,10 +1,8 @@
Name:Profane Procession
ManaCost:1 W B
Types:Legendary Enchantment
A:AB$ ChangeZone | Cost$ 3 W B | ValidTgts$ Creature | TgtPrompt$ Choose target creature. | Origin$ Battlefield | Destination$ Exile | RememberTargets$ True | SubAbility$ DBTransform | SpellDescription$ Exile target creature. Then if there are three or more cards exiled with CARDNAME, transform it.
SVar:DBTransform:DB$ SetState | ConditionDefined$ Remembered | ConditionPresent$ Card.ExiledWithSource | ConditionCompare$ GE3 | Defined$ Self | Mode$ Transform
T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Battlefield | Destination$ Any | Execute$ DBCleanup | Static$ True | Secondary$ True | TriggerDescription$ Forget all remembered cards.
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
A:AB$ ChangeZone | Cost$ 3 W B | ValidTgts$ Creature | Origin$ Battlefield | Destination$ Exile | SubAbility$ DBTransform | SpellDescription$ Exile target creature. Then if there are three or more cards exiled with CARDNAME, transform it.
SVar:DBTransform:DB$ SetState | ConditionZone$ Exile | ConditionPresent$ Card.ExiledWithSource | ConditionCompare$ GE3 | Defined$ Self | Mode$ Transform
AlternateMode:DoubleFaced
Oracle:{3}{W}{B}: Exile target creature. Then if there are three or more cards exiled with Profane Procession, transform it.
@@ -14,6 +12,5 @@ Name:Tomb of the Dusk Rose
ManaCost:no cost
Types:Legendary Land
A:AB$ Mana | Cost$ T | Produced$ Any | Amount$ 1 | SpellDescription$ Add one mana of any color.
A:AB$ ChooseCard | Cost$ 2 W B T | Choices$ Creature.IsRemembered+ExiledWithSource | ChoiceZone$ Exile | SubAbility$ DBChangeZone | AILogic$ AtLeast1 | Mandatory$ True | SpellDescription$ Put a creature card exiled with this permanent onto the battlefield under your control.
SVar:DBChangeZone:DB$ ChangeZone | Defined$ ChosenCard | Origin$ Exile | Destination$ Battlefield | ChangeType$ Creature.IsRemembered+ExiledWithSource | ChangeNum$ 1 | GainControl$ True
A:AB$ ChangeZone | Cost$ 2 W B T | ChangeType$ Creature.ExiledWithSource | GainControl$ True | Hidden$ True | Origin$ Exile | Destination$ Battlefield | Mandatory$ True | SpellDescription$ Put a creature card exiled with this permanent onto the battlefield under your control.
Oracle:(Transforms from Profane Procession.)\n{T}: Add one mana of any color.\n{2}{W}{B}, {T}: Put a creature card exiled with this permanent onto the battlefield under your control.

View File

@@ -3,11 +3,6 @@ ManaCost:4 B B G G
Types:Legendary Creature Gorgon
PT:7/5
A:AB$ MustBlock | Cost$ G | ValidTgts$ Creature | TgtPrompt$ Select target creature | SpellDescription$ Target creature blocks CARDNAME this turn if able.
A:AB$ ChangeZone | Cost$ B G | Origin$ Battlefield | Destination$ Exile | ValidTgts$ Creature.blockingSource,Creature.blockedBySource | TgtPrompt$ Select target creature blocking Sisters of Stone Death | RememberTargets$ True | SpellDescription$ Exile target creature blocking or blocked by CARDNAME.
A:AB$ ChooseCard | Cost$ 2 B | Choices$ Creature.IsRemembered+ExiledWithSource | ChoiceZone$ Exile | AILogic$ AtLeast1 | Mandatory$ True | SubAbility$ DBChangeZone | SpellDescription$ Put a creature card exiled with CARDNAME onto the battlefield under your control.
SVar:DBChangeZone:DB$ ChangeZone | Defined$ ChosenCard | Origin$ Exile | Destination$ Battlefield | ChangeType$ Creature.IsRemembered+ExiledWithSource | ChangeNum$ 1 | GainControl$ True
T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered+ExiledWithSource | Execute$ DBForget
SVar:DBForget:DB$ Pump | ForgetImprinted$ TriggeredCard
T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Battlefield | Destination$ Any | Execute$ DBCleanup | Static$ True | Secondary$ True | TriggerDescription$ Forget all remembered cards.
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
A:AB$ ChangeZone | Cost$ B G | Origin$ Battlefield | Destination$ Exile | ValidTgts$ Creature.blockingSource,Creature.blockedBySource | TgtPrompt$ Select target creature blocking Sisters of Stone Death | SpellDescription$ Exile target creature blocking or blocked by CARDNAME.
A:AB$ ChangeZone | Cost$ 2 B | Origin$ Exile | Destination$ Battlefield | ChangeType$ Creature.ExiledWithSource | Hidden$ True | Mandatory$ True | ChangeNum$ 1 | GainControl$ True | SpellDescription$ Put a creature card exiled with CARDNAME onto the battlefield under your control.
Oracle:{G}: Target creature blocks Sisters of Stone Death this turn if able.\n{B}{G}: Exile target creature blocking or blocked by Sisters of Stone Death.\n{2}{B}: Put a creature card exiled with Sisters of Stone Death onto the battlefield under your control.

View File

@@ -5,13 +5,9 @@ PT:3/1
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigConnive | TriggerDescription$ When CARDNAME enters the battlefield, it connives. (Draw a card, then discard a card. If you discarded a nonland card, put a +1/+1 counter on this creature.)
SVar:TrigConnive:DB$ Connive
T:Mode$ DiscardedAll | ValidPlayer$ You | ValidCard$ Card | TriggerZones$ Battlefield | Execute$ TrigExile | TriggerDescription$ Whenever you discard one or more cards, exile them from your graveyard.
SVar:TrigExile:DB$ ChangeZoneAll | Origin$ Graveyard | Destination$ Exile | ChangeType$ Card.TriggeredCards | RememberChanged$ True
SVar:TrigExile:DB$ ChangeZoneAll | Origin$ Graveyard | Destination$ Exile | ChangeType$ Card.TriggeredCards
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerDescription$ When NICKNAME dies, put the cards exiled with it into their owner's hand.
SVar:TrigReturn:DB$ ChangeZoneAll | ChangeType$ Card.IsRemembered+ExiledWithSource | Origin$ Exile | Destination$ Hand
T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered+ExiledWithSource | Execute$ DBForget
SVar:DBForget:DB$ Pump | ForgetObjects$ TriggeredCard
T:Mode$ ChangesZone | Origin$ Battlefield | ExcludedDestinations$ Graveyard | Static$ True | Destination$ Any | ValidCard$ Card.Self | Execute$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
SVar:TrigReturn:DB$ ChangeZoneAll | ChangeType$ Card.ExiledWithSource | Origin$ Exile | Destination$ Hand
DeckHas:Ability$Discard|Counters
DeckHints:Ability$Discard
Oracle:When Toluz, Clever Conductor enters the battlefield, it connives. (Draw a card, then discard a card. If you discarded a nonland card, put a +1/+1 counter on this creature.)\nWhenever you discard one or more cards, exile them from your graveyard.\nWhen Toluz dies, put the cards exiled with it into their owner's hand.