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 f9e8358fa23..b63c7e759e7 100644 --- a/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java +++ b/forge-game/src/main/java/forge/game/ability/SpellAbilityEffect.java @@ -891,10 +891,6 @@ public abstract class SpellAbilityEffect { runParams.put(AbilityKey.Cause, sa); runParams.put(AbilityKey.DiscardedBefore, discardedBefore.get(p)); p.getGame().getTriggerHandler().runTrigger(TriggerType.DiscardedAll, runParams, false); - - if (sa.hasParam("RememberDiscardingPlayers")) { - sa.getHostCard().addRemembered(p); - } } } } 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 b0cbd11fc25..e9049e4e859 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 @@ -143,12 +143,12 @@ public class DiscardEffect extends SpellAbilityEffect { continue; } - boolean runDiscard = !sa.hasParam("Optional") - || p.getController().confirmAction(sa, PlayerActionConfirmMode.Random, sa.getParam("DiscardMessage"), null); - if (runDiscard) { - toBeDiscarded = AbilityUtils.getDefinedCards(source, sa.getParam("DefinedCards"), sa); - toBeDiscarded = GameActionUtil.orderCardsByTheirOwners(game, toBeDiscarded, ZoneType.Graveyard, sa); + if (sa.hasParam("Optional") && !p.getController().confirmAction(sa, PlayerActionConfirmMode.Random, sa.getParam("DiscardMessage"), null)) { + continue; } + + toBeDiscarded = AbilityUtils.getDefinedCards(source, sa.getParam("DefinedCards"), sa); + toBeDiscarded = GameActionUtil.orderCardsByTheirOwners(game, toBeDiscarded, ZoneType.Graveyard, sa); } if (mode.equals("Hand")) { @@ -159,6 +159,17 @@ public class DiscardEffect extends SpellAbilityEffect { continue; } + String message = Localizer.getInstance().getMessage("lblDoYouWantDiscardYourHand"); + if (sa.hasParam("Optional")) { + if (!p.getController().confirmAction(sa, PlayerActionConfirmMode.Random, message, null)) { + continue; + } else if (discarders.size() > 1) { + // later players need to know the decision + message = Localizer.getInstance().getMessage("lblPlayerKeepNCardsHand", p.getName(), String.valueOf(p.getZone(ZoneType.Hand).size())); + game.getAction().notifyOfValue(sa, p, message, p); + } + } + toBeDiscarded = GameActionUtil.orderCardsByTheirOwners(game, toBeDiscarded, ZoneType.Graveyard, sa); } @@ -172,16 +183,17 @@ public class DiscardEffect extends SpellAbilityEffect { if (!p.canDiscardBy(sa, true)) { continue; } + String message = Localizer.getInstance().getMessage("lblWouldYouLikeRandomDiscardTargetCard", String.valueOf(numCards)); - boolean runDiscard = !sa.hasParam("Optional") || p.getController().confirmAction(sa, PlayerActionConfirmMode.Random, message, null); - - if (runDiscard) { - final String valid = sa.getParamOrDefault("DiscardValid", "Card"); - List list = CardLists.getValidCards(p.getCardsIn(ZoneType.Hand), valid, source.getController(), source, sa); - - toBeDiscarded = new CardCollection(Aggregates.random(list, numCards)); - toBeDiscarded = GameActionUtil.orderCardsByTheirOwners(game, toBeDiscarded, ZoneType.Graveyard, sa); + if (sa.hasParam("Optional") && !p.getController().confirmAction(sa, PlayerActionConfirmMode.Random, message, null)) { + continue; } + + final String valid = sa.getParamOrDefault("DiscardValid", "Card"); + List list = CardLists.getValidCards(p.getCardsIn(ZoneType.Hand), valid, source.getController(), source, sa); + + toBeDiscarded = new CardCollection(Aggregates.random(list, numCards)); + toBeDiscarded = GameActionUtil.orderCardsByTheirOwners(game, toBeDiscarded, ZoneType.Graveyard, sa); } else if (mode.equals("TgtChoose") && sa.hasParam("UnlessType")) { if (!p.canDiscardBy(sa, true)) { @@ -194,30 +206,27 @@ public class DiscardEffect extends SpellAbilityEffect { } } else if (mode.equals("RevealDiscardAll")) { - // Reveal final CardCollectionView dPHand = p.getCardsIn(ZoneType.Hand); - for (final Player opp : p.getAllOtherPlayers()) { - opp.getController().reveal(dPHand, ZoneType.Hand, p, Localizer.getInstance().getMessage("lblReveal") + " "); + if (dPHand.isEmpty()) { + continue; } + game.getAction().reveal(dPHand, ZoneType.Hand, p, true, Localizer.getInstance().getMessage("lblReveal") + " "); + if (!p.canDiscardBy(sa, true)) { continue; } String valid = sa.getParamOrDefault("DiscardValid", "Card"); - if (valid.contains("X")) { - valid = TextUtil.fastReplace(valid, - "X", Integer.toString(AbilityUtils.calculateAmount(source, "X", sa))); - } - toBeDiscarded = CardLists.getValidCards(dPHand, valid, source.getController(), source, sa); toBeDiscarded = GameActionUtil.orderCardsByTheirOwners(game, toBeDiscarded, ZoneType.Graveyard, sa); } else if (mode.endsWith("YouChoose") || mode.endsWith("TgtChoose")) { CardCollectionView dPHand = p.getCardsIn(ZoneType.Hand); - if (dPHand.isEmpty()) - continue; // for loop over players + if (dPHand.isEmpty()) { + continue; + } if (sa.hasParam("RevealNumber")) { int amount = AbilityUtils.calculateAmount(source, sa.getParam("RevealNumber"), sa); @@ -250,6 +259,10 @@ public class DiscardEffect extends SpellAbilityEffect { toBeDiscarded = max == 0 ? CardCollection.EMPTY : chooser.getController().chooseCardsToDiscardFrom(p, sa, validCards, min, max); + if (toBeDiscarded.isEmpty()) { + continue; + } + toBeDiscarded = GameActionUtil.orderCardsByTheirOwners(game, toBeDiscarded, ZoneType.Graveyard, sa); if (mode.startsWith("Reveal") && p != chooser) { @@ -259,6 +272,10 @@ public class DiscardEffect extends SpellAbilityEffect { discardedMap.put(p, toBeDiscarded); } + if (sa.hasParam("RememberDiscardingPlayers")) { + source.addRemembered(discardedMap.keySet()); + } + Map params = AbilityKey.newMap(); CardZoneTable table = AbilityKey.addCardZoneTableParams(params, sa); diff --git a/forge-gui/res/cardsfolder/r/ruin_grinder.txt b/forge-gui/res/cardsfolder/r/ruin_grinder.txt index df579106569..2b8ec34b3db 100644 --- a/forge-gui/res/cardsfolder/r/ruin_grinder.txt +++ b/forge-gui/res/cardsfolder/r/ruin_grinder.txt @@ -3,13 +3,10 @@ ManaCost:5 R Types:Artifact Creature Construct PT:7/4 K:Menace -T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Battlefield | Destination$ Graveyard | Execute$ TrigChoose | TriggerDescription$ When CARDNAME dies, each player may discard their hand and draw seven cards. -SVar:TrigChoose:DB$ GenericChoice | TempRemember$ Chooser | ShowChoice$ ExceptSelf | Defined$ Player | Choices$ Discard,No | SubAbility$ DBDiscard -SVar:Discard:DB$ Pump | Defined$ Remembered | NoteCards$ Self | NoteCardsFor$ Discard | SpellDescription$ I will discard my hand. -SVar:No:DB$ Pump | SpellDescription$ I will NOT discard my hand. -SVar:DBDiscard:DB$ Discard | Mode$ Hand | Defined$ Player.NotedForDiscard | SubAbility$ DBDraw -SVar:DBDraw:DB$ Draw | Defined$ Player.NotedForDiscard | NumCards$ 7 | SubAbility$ DBClearNotes -SVar:DBClearNotes:DB$ Pump | Defined$ Player | ClearNotedCardsFor$ Discard +T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Battlefield | Destination$ Graveyard | Execute$ TrigDiscard | TriggerDescription$ When CARDNAME dies, each player may discard their hand and draw seven cards. +SVar:TrigDiscard:DB$ Discard | Mode$ Hand | Defined$ Player | Optional$ True | RememberDiscardingPlayers$ True | SubAbility$ DBDraw +SVar:DBDraw:DB$ Draw | Defined$ Remembered | NumCards$ 7 | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True K:TypeCycling:Mountain:2 DeckHas:Ability$Discard Oracle:Menace\nWhen Ruin Grinder dies, each player may discard their hand and draw seven cards.\nMountaincycling {2} ({2}, Discard this card: Search your library for a Mountain card, reveal it, put it into your hand, then shuffle.) diff --git a/forge-gui/res/cardsfolder/s/sail_into_the_west.txt b/forge-gui/res/cardsfolder/s/sail_into_the_west.txt index df646180798..73229a8e0f6 100644 --- a/forge-gui/res/cardsfolder/s/sail_into_the_west.txt +++ b/forge-gui/res/cardsfolder/s/sail_into_the_west.txt @@ -4,11 +4,8 @@ Types:Instant A:SP$ Vote | Defined$ Player | Choices$ DBChangeZone,DBWheel | VoteTiedAbility$ DBWheel | StackDescription$ REP you, each player votes_{p:You}, {p:Player} each vote & each player returns_{p:Player} each return & each player may_{p:Player} may each | SpellDescription$ Will of the council — Starting with you, each player votes for return or embark. If return gets more votes, each player returns up to two cards from their graveyard to their hand, then you exile CARDNAME. If embark gets more votes or the vote is tied, each player may discard their hand and draw seven cards. SVar:DBChangeZone:DB$ ChangeZone | Defined$ Player | Origin$ Graveyard | Destination$ Hand | ChangeNum$ 2 | Hidden$ True | SubAbility$ ExileSelf | SpellDescription$ If return gets more votes, each player returns up to two cards from their graveyard to their hand, then you exile CARDNAME. SVar:ExileSelf:DB$ ChangeZone | Origin$ Stack | Destination$ Exile -SVar:DBWheel:DB$ GenericChoice | TempRemember$ Chooser | ShowChoice$ ExceptSelf | Defined$ Player | Choices$ Discard,No | SubAbility$ DBDiscard | SpellDescription$ If embark gets more votes or the vote is tied, each player may discard their hand and draw seven cards. -SVar:Discard:DB$ Pump | Defined$ Remembered | NoteCards$ Self | NoteCardsFor$ Discard | SpellDescription$ I will discard my hand. -SVar:No:DB$ Pump | SpellDescription$ I will NOT discard my hand. -SVar:DBDiscard:DB$ Discard | Mode$ Hand | Defined$ Player.NotedForDiscard | SubAbility$ DBDraw -SVar:DBDraw:DB$ Draw | Defined$ Player.NotedForDiscard | NumCards$ 7 | SubAbility$ DBClearNotes -SVar:DBClearNotes:DB$ Pump | Defined$ Player | ClearNotedCardsFor$ Discard +SVar:DBWheel:DB$ Discard | Mode$ Hand | Defined$ Player | Optional$ True | RememberDiscardingPlayers$ True | SubAbility$ DBDraw | SpellDescription$ If embark gets more votes or the vote is tied, each player may discard their hand and draw seven cards. +SVar:DBDraw:DB$ Draw | Defined$ Remembered | NumCards$ 7 | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True DeckHas:Ability$Discard|Graveyard Oracle:Will of the council — Starting with you, each player votes for return or embark. If return gets more votes, each player returns up to two cards from their graveyard to their hand, then you exile Sail into the West. If embark gets more votes or the vote is tied, each player may discard their hand and draw seven cards. diff --git a/forge-gui/res/cardsfolder/s/snort.txt b/forge-gui/res/cardsfolder/s/snort.txt index f7c0a69e02a..2127fc2df2e 100644 --- a/forge-gui/res/cardsfolder/s/snort.txt +++ b/forge-gui/res/cardsfolder/s/snort.txt @@ -1,12 +1,9 @@ Name:Snort ManaCost:3 R Types:Sorcery -A:SP$ GenericChoice | TempRemember$ Chooser | ShowChoice$ ExceptSelf | Defined$ Player | Choices$ Discard,No | SubAbility$ DBDiscard | StackDescription$ SpellDescription | SpellDescription$ Each player may discard their hand and draw five cards. Then CARDNAME deals 5 damage to each opponent who discarded their hand this way. -SVar:Discard:DB$ Pump | Defined$ Remembered | NoteCards$ Self | NoteCardsFor$ Discard | SpellDescription$ I will discard my hand. -SVar:No:DB$ Pump | SpellDescription$ I will NOT discard my hand. -SVar:DBDiscard:DB$ Discard | Mode$ Hand | Defined$ Player.NotedForDiscard | SubAbility$ DBDraw -SVar:DBDraw:DB$ Draw | Defined$ Player.NotedForDiscard | NumCards$ 5 | SubAbility$ DBDmg -SVar:DBDmg:DB$ DamageAll | ValidPlayers$ Player.Opponent+NotedForDiscard | NumDmg$ 5 | SubAbility$ DBClearNotes | StackDescription$ None -SVar:DBClearNotes:DB$ Pump | Defined$ Player | ClearNotedCardsFor$ Discard | StackDescription$ None +A:SP$ Discard | Mode$ Hand | Defined$ Player | Optional$ True | RememberDiscardingPlayers$ True | SubAbility$ DBDraw | StackDescription$ SpellDescription | SpellDescription$ Each player may discard their hand and draw five cards. Then CARDNAME deals 5 damage to each opponent who discarded their hand this way. +SVar:DBDraw:DB$ Draw | Defined$ Remembered | NumCards$ 5 | SubAbility$ DBDmg +SVar:DBDmg:DB$ DamageAll | ValidPlayers$ Opponent.IsRemembered | NumDmg$ 5 | SubAbility$ DBCleanup | StackDescription$ None +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True K:Flashback:5 R Oracle:Each player may discard their hand and draw five cards. Then Snort deals 5 damage to each opponent who discarded their hand this way.\nFlashback {5}{R} (You may cast this card from your graveyard for its flashback cost. Then exile it.) diff --git a/forge-gui/res/cardsfolder/w/will_of_the_jeskai.txt b/forge-gui/res/cardsfolder/w/will_of_the_jeskai.txt index 2eb6ff8fef8..86c231d0e28 100644 --- a/forge-gui/res/cardsfolder/w/will_of_the_jeskai.txt +++ b/forge-gui/res/cardsfolder/w/will_of_the_jeskai.txt @@ -2,12 +2,9 @@ Name:Will of the Jeskai ManaCost:3 R Types:Sorcery A:SP$ Charm | MinCharmNum$ 1 | CharmNum$ Count$Compare Y GE1.2.1 | Choices$ DBWheel,DBFlames | AdditionalDescription$ . If you control a commander as you cast this spell, you may choose both instead. -SVar:DBWheel:DB$ GenericChoice | TempRemember$ Chooser | ShowChoice$ ExceptSelf | Defined$ Player | Choices$ Discard,No | SubAbility$ DBDiscard | SpellDescription$ Each player may discard their hand and draw five cards. -SVar:Discard:DB$ Pump | Defined$ Remembered | NoteCards$ Self | NoteCardsFor$ Discard | SpellDescription$ I will discard my hand. -SVar:No:DB$ Pump | SpellDescription$ I will NOT discard my hand. -SVar:DBDiscard:DB$ Discard | Mode$ Hand | Defined$ Player.NotedForDiscard | SubAbility$ DBDraw -SVar:DBDraw:DB$ Draw | Defined$ Player.NotedForDiscard | NumCards$ 5 | SubAbility$ DBClearNotes -SVar:DBClearNotes:DB$ Pump | Defined$ Player | ClearNotedCardsFor$ Discard | StackDescription$ None +SVar:DBWheel:DB$ Discard | Mode$ Hand | Defined$ Player | Optional$ True | RememberDiscardingPlayers$ True | SubAbility$ DBDraw | SpellDescription$ If embark gets more votes or the vote is tied, each player may discard their hand and draw seven cards. +SVar:DBDraw:DB$ Draw | Defined$ Remembered | NumCards$ 7 | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:DBFlames:DB$ PumpAll | ValidCards$ Instant.YouCtrl,Sorcery.YouCtrl | KW$ Flashback | PumpZone$ Graveyard | SpellDescription$ Each instant and sorcery card in your graveyard gains flashback until end of turn. The flashback cost is equal to its mana cost. SVar:Y:Count$Valid Card.IsCommander+YouCtrl DeckHas:Ability$Discard