From a2a5fda9af6ec5e0a09420e72be72337f604a332 Mon Sep 17 00:00:00 2001 From: Tim Mocny Date: Sun, 20 Feb 2022 04:18:43 +0000 Subject: [PATCH] NEO: Discover the Impossible and support (and StackDescription improvements) --- .../java/forge/game/ability/AbilityUtils.java | 24 +++++++------ .../ability/effects/ChangeZoneEffect.java | 22 +++++------- .../forge/game/ability/effects/DigEffect.java | 34 ++++++++++++++----- .../game/ability/effects/PlayEffect.java | 19 ++++++++--- .../upcoming/discover_the_impossible.txt | 8 +++++ 5 files changed, 72 insertions(+), 35 deletions(-) create mode 100644 forge-gui/res/cardsfolder/upcoming/discover_the_impossible.txt diff --git a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java index 242df235f0c..0e471cf514b 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java @@ -2967,19 +2967,23 @@ public class AbilityUtils { List list = Lists.newArrayList(tgtCard.getBasicSpells()); CardState original = tgtCard.getState(CardStateName.Original); - if (tgtCard.isLand()) { - LandAbility la = new LandAbility(tgtCard, controller, null); - la.setCardState(original); - list.add(la); - } - if (tgtCard.isModal()) { - CardState modal = tgtCard.getState(CardStateName.Modal); - list.addAll(Lists.newArrayList(tgtCard.getBasicSpells(modal))); - if (modal.getType().isLand()) { + if (tgtCard.isFaceDown()) { + list.addAll(Lists.newArrayList(tgtCard.getBasicSpells(original))); + } else { + if (tgtCard.isLand()) { LandAbility la = new LandAbility(tgtCard, controller, null); - la.setCardState(modal); + la.setCardState(original); list.add(la); } + if (tgtCard.isModal()) { + CardState modal = tgtCard.getState(CardStateName.Modal); + list.addAll(Lists.newArrayList(tgtCard.getBasicSpells(modal))); + if (modal.getType().isLand()) { + LandAbility la = new LandAbility(tgtCard, controller, null); + la.setCardState(modal); + list.add(la); + } + } } for (SpellAbility s : list) { 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 e4e903a1be7..d8defdf441e 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 @@ -291,11 +291,11 @@ public class ChangeZoneEffect extends SpellAbilityEffect { Iterable tgts; if (sa.usesTargeting()) { tgts = sa.getTargets().getTargetCards(); - } else { - // otherwise add self to list and go from there + } else { // otherwise add self to list and go from there tgts = sa.knownDetermineDefined(sa.getParam("Defined")); } - sbTargets.append(" ").append(StringUtils.join(tgts, ", ")); + + sbTargets.append(" ").append(sa.getParamOrDefault("DefinedDesc", StringUtils.join(tgts, ", "))); final String targetname = sbTargets.toString(); @@ -305,14 +305,9 @@ public class ChangeZoneEffect extends SpellAbilityEffect { if (destination.equals(ZoneType.Battlefield)) { if (ZoneType.Graveyard.equals(origin)) { - sb.append("Return").append(targetname); + sb.append("Return").append(targetname).append(fromGraveyard).append(" to the battlefield"); } else { - sb.append("Put").append(targetname); - } - if (ZoneType.Graveyard.equals(origin)) { - sb.append(fromGraveyard).append(" to the battlefield"); - } else { - sb.append(" onto the battlefield"); + sb.append("Put").append(targetname).append(" onto the battlefield"); } if (sa.hasParam("Tapped")) { sb.append(" tapped"); @@ -324,11 +319,12 @@ public class ChangeZoneEffect extends SpellAbilityEffect { } if (destination.equals(ZoneType.Hand)) { - sb.append("Return").append(targetname); if (ZoneType.Graveyard.equals(origin)) { - sb.append(fromGraveyard); + sb.append("Return").append(targetname).append(fromGraveyard).append(" to"); + } else { + sb.append("Put").append(targetname).append(" in"); } - sb.append(" to").append(pronoun).append("owner's hand."); + sb.append(pronoun).append("owner's hand."); } if (destination.equals(ZoneType.Library)) { 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 665516a989a..4167f9ead8d 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 @@ -12,13 +12,7 @@ import forge.game.GameEntityCounterTable; import forge.game.ability.AbilityKey; 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.CardLists; -import forge.game.card.CardPredicates; -import forge.game.card.CardZoneTable; -import forge.game.card.CounterType; +import forge.game.card.*; import forge.game.event.GameEventCombatChanged; import forge.game.player.DelayedReveal; import forge.game.player.Player; @@ -40,12 +34,15 @@ public class DigEffect extends SpellAbilityEffect { final Card host = sa.getHostCard(); final StringBuilder sb = new StringBuilder(); final int numToDig = AbilityUtils.calculateAmount(host, sa.getParam("DigNum"), sa); + final int numToChange = (sa.hasParam("ChangeNum") ? + AbilityUtils.calculateAmount(host, sa.getParam("ChangeNum"), sa) : 1); final List tgtPlayers = getTargetPlayers(sa); String verb = " looks at "; if (sa.hasParam("Reveal") && sa.getParam("Reveal").equals("True")) { verb = " reveals "; - } else if (sa.hasParam("DestinationZone") && sa.getParam("DestinationZone").equals("Exile")) { + } else if (sa.hasParam("DestinationZone") && sa.getParam("DestinationZone").equals("Exile") && + numToDig == numToChange) { verb = " exiles "; } sb.append(host.getController()).append(verb).append("the top "); @@ -59,6 +56,27 @@ public class DigEffect extends SpellAbilityEffect { } } sb.append("library."); + + if (numToDig != numToChange) { + String destZone1 = sa.hasParam("DestinationZone") ? + sa.getParam("DestinationZone").toLowerCase() : "hand"; + String destZone2 = sa.hasParam("DestinationZone2") ? + sa.getParam("DestinationZone2").toLowerCase() : "on the bottom of their library in any order."; + if (sa.hasParam("RestRandomOrder")) { + destZone2 = destZone2.replace("any", "a random"); + } + + String verb2 = "put "; + String where = "in their hand "; + if (destZone1.equals("exile")) { + verb2 = "exile "; + where = ""; + } + sb.append(" They ").append(verb2).append(Lang.getNumeral(numToChange)).append(" of them ").append(where); + sb.append(sa.hasParam("ExileFaceDown") ? "face down " : "").append("and put the rest "); + sb.append(destZone2); + } + return sb.toString(); } diff --git a/forge-game/src/main/java/forge/game/ability/effects/PlayEffect.java b/forge-game/src/main/java/forge/game/ability/effects/PlayEffect.java index 5befcfaad0b..2d6cf609816 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/PlayEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/PlayEffect.java @@ -50,17 +50,28 @@ public class PlayEffect extends SpellAbilityEffect { @Override protected String getStackDescription(final SpellAbility sa) { final StringBuilder sb = new StringBuilder(); + sb.append(sa.getActivatingPlayer().toString()).append(" "); - sb.append("Play "); - final List tgtCards = getTargetCards(sa); + if (sa.hasParam("ValidSA")) { + sb.append(sa.hasParam("Optional") ? "may cast " : "cast "); + } else { + sb.append(sa.hasParam("Optional") ? "may play " : "plays "); + } + + final List tgtCards = getDefinedCardsOrTargeted(sa); if (sa.hasParam("Valid")) { sb.append("cards"); + } else if (sa.hasParam("DefinedDesc")) { + sb.append(sa.getParam("DefinedDesc")); } else { - sb.append(StringUtils.join(tgtCards, ", ")); + sb.append(Lang.joinHomogenous(tgtCards)); } if (sa.hasParam("WithoutManaCost")) { - sb.append(" without paying the mana cost"); + sb.append(" without paying ").append(tgtCards.size()==1 ? "its" : "their").append(" mana cost "); + } + if (sa.hasParam("IfDesc")) { + sb.append(sa.getParam("IfDesc")); } sb.append("."); return sb.toString(); diff --git a/forge-gui/res/cardsfolder/upcoming/discover_the_impossible.txt b/forge-gui/res/cardsfolder/upcoming/discover_the_impossible.txt new file mode 100644 index 00000000000..00713eb481e --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/discover_the_impossible.txt @@ -0,0 +1,8 @@ +Name:Discover the Impossible +ManaCost:2 U +Types:Instant +A:SP$ Dig | Defined$ You | DigNum$ 5 | DestinationZone$ Exile | ExileFaceDown$ True | RememberChanged$ True | RestRandomOrder$ True | SubAbility$ DBCast | SpellDescription$ Look at the top five cards of your library. Exile one of them face down and put the rest on the bottom of your library in a random order. You may cast the exiled card without paying its mana cost if it's an instant spell with mana value 2 or less. If you don't, put that card into your hand. +SVar:DBCast:DB$ Play | Optional$ True | Defined$ Remembered | DefinedDesc$ the exiled card | ValidSA$ Instant.cmcLE2 | WithoutManaCost$ True | IfDesc$ if it's an instant spell with mana value 2 or less | ForgetTargetRemembered$ True | SubAbility$ DBChangeZone +SVar:DBChangeZone:DB$ ChangeZone | Origin$ Exile | Destination$ Hand | Defined$ Remembered | DefinedDesc$ that card | ForgetChanged$ True | ConditionDescription$ If not, +DeckHints:Types$Instant +Oracle:Look at the top five cards of your library. Exile one of them face down and put the rest on the bottom of your library in a random order. You may cast the exiled card without paying its mana cost if it's an instant spell with mana value 2 or less. If you don't, put that card into your hand.