From 1a7a135c2ba76c29f03acb175d05af05f6f498e1 Mon Sep 17 00:00:00 2001 From: Northmoc <103371817+Northmoc@users.noreply.github.com> Date: Wed, 15 Nov 2023 11:20:47 -0500 Subject: [PATCH] =?UTF-8?q?LCI=20=E2=80=93=20Discover=20mechanic=20impleme?= =?UTF-8?q?ntation=20(#3992)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * LCI – Discover mechanic implementation * curator_of_suns_creation.txt * wiring improvements * more cards * last cards/tweaks --- .../java/forge/ai/PlayerControllerAi.java | 2 +- .../main/java/forge/game/ability/ApiType.java | 1 + .../game/ability/effects/DiscoverEffect.java | 183 ++++++++++++++++++ .../java/forge/game/card/CounterEnumType.java | 2 + .../forge/game/player/PlayerController.java | 8 +- .../forge/game/trigger/TriggerDiscover.java | 38 ++++ .../java/forge/game/trigger/TriggerType.java | 1 + .../util/PlayerControllerForTests.java | 2 +- .../cardsfolder/b/blow_your_house_down.txt | 4 +- ...nnel_grinder_tecutlan_the_searing_rift.txt | 24 +++ .../cardsfolder/upcoming/buried_treasure.txt | 7 + .../upcoming/caparocti_sunborn.txt | 8 + .../upcoming/chimil_the_inner_sun.txt | 7 + .../cardsfolder/upcoming/contest_of_claws.txt | 8 + .../upcoming/curator_of_suns_creation.txt | 8 + .../cardsfolder/upcoming/daring_discovery.txt | 6 + .../upcoming/digsite_conservator.txt | 9 + .../res/cardsfolder/upcoming/dinosaur_egg.txt | 10 + .../ellie_and_alan_paleontologists.txt | 7 + .../res/cardsfolder/upcoming/etalis_favor.txt | 9 + .../upcoming/geological_appraiser.txt | 7 + .../cardsfolder/upcoming/hidden_cataract.txt | 8 + .../cardsfolder/upcoming/hidden_courtyard.txt | 8 + .../upcoming/hidden_necropolis.txt | 8 + .../cardsfolder/upcoming/hidden_nursery.txt | 8 + .../cardsfolder/upcoming/hidden_volcano.txt | 8 + .../upcoming/hit_the_mother_lode.txt | 8 + .../upcoming/hurl_into_history.txt | 8 + .../upcoming/pantlaza_sun_favored.txt | 9 + .../upcoming/primordial_gnawer.txt | 7 + .../cardsfolder/upcoming/quintorius_kand.txt | 18 ++ .../upcoming/swashbucklers_whip.txt | 8 + .../upcoming/trumpeting_carnosaur.txt | 10 + .../upcoming/walk_with_the_ancestors.txt | 7 + .../res/cardsfolder/upcoming/zoetic_glyph.txt | 11 ++ .../cardsfolder/upcoming/zoyowas_justice.txt | 8 + forge-gui/res/languages/de-DE.properties | 2 + forge-gui/res/languages/en-US.properties | 2 + forge-gui/res/languages/es-ES.properties | 2 + forge-gui/res/languages/fr-FR.properties | 2 + forge-gui/res/languages/it-IT.properties | 2 + forge-gui/res/languages/ja-JP.properties | 2 + forge-gui/res/languages/pt-BR.properties | 2 + forge-gui/res/languages/zh-CN.properties | 2 + forge-gui/res/lists/TypeLists.txt | 1 + .../forge/player/PlayerControllerHuman.java | 5 +- 46 files changed, 499 insertions(+), 8 deletions(-) create mode 100644 forge-game/src/main/java/forge/game/ability/effects/DiscoverEffect.java create mode 100644 forge-game/src/main/java/forge/game/trigger/TriggerDiscover.java create mode 100644 forge-gui/res/cardsfolder/upcoming/brasss_tunnel_grinder_tecutlan_the_searing_rift.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/buried_treasure.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/caparocti_sunborn.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/chimil_the_inner_sun.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/contest_of_claws.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/curator_of_suns_creation.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/daring_discovery.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/digsite_conservator.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/dinosaur_egg.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/ellie_and_alan_paleontologists.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/etalis_favor.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/geological_appraiser.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/hidden_cataract.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/hidden_courtyard.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/hidden_necropolis.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/hidden_nursery.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/hidden_volcano.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/hit_the_mother_lode.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/hurl_into_history.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/pantlaza_sun_favored.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/primordial_gnawer.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/quintorius_kand.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/swashbucklers_whip.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/trumpeting_carnosaur.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/walk_with_the_ancestors.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/zoetic_glyph.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/zoyowas_justice.txt diff --git a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java index 0a3d3310067..eec62cff8f9 100644 --- a/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java +++ b/forge-ai/src/main/java/forge/ai/PlayerControllerAi.java @@ -242,7 +242,7 @@ public class PlayerControllerAi extends PlayerController { } @Override - public boolean confirmAction(SpellAbility sa, PlayerActionConfirmMode mode, String message, Card cardToShow, Map params) { + public boolean confirmAction(SpellAbility sa, PlayerActionConfirmMode mode, String message, List options, Card cardToShow, Map params) { return getAi().confirmAction(sa, mode, message, params); } diff --git a/forge-game/src/main/java/forge/game/ability/ApiType.java b/forge-game/src/main/java/forge/game/ability/ApiType.java index bb84f0a4286..c9e27e6116a 100644 --- a/forge-game/src/main/java/forge/game/ability/ApiType.java +++ b/forge-game/src/main/java/forge/game/ability/ApiType.java @@ -72,6 +72,7 @@ public enum ApiType { DigMultiple (DigMultipleEffect.class), DigUntil (DigUntilEffect.class), Discard (DiscardEffect.class), + Discover (DiscoverEffect.class), DrainMana (DrainManaEffect.class), Draft (DraftEffect.class), Draw (DrawEffect.class), diff --git a/forge-game/src/main/java/forge/game/ability/effects/DiscoverEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DiscoverEffect.java new file mode 100644 index 00000000000..e71e622a6f0 --- /dev/null +++ b/forge-game/src/main/java/forge/game/ability/effects/DiscoverEffect.java @@ -0,0 +1,183 @@ +package forge.game.ability.effects; + +import com.google.common.base.Predicates; +import com.google.common.collect.Iterables; +import forge.game.Game; +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.CardLists; +import forge.game.card.CardZoneTable; +import forge.game.cost.CostDiscard; +import forge.game.cost.CostPart; +import forge.game.cost.CostReveal; +import forge.game.player.Player; +import forge.game.player.PlayerCollection; +import forge.game.spellability.LandAbility; +import forge.game.spellability.SpellAbility; +import forge.game.trigger.TriggerType; +import forge.game.zone.PlayerZone; +import forge.game.zone.Zone; +import forge.game.zone.ZoneType; +import forge.util.CardTranslation; +import forge.util.Lang; +import forge.util.Localizer; + +import org.apache.commons.lang3.StringUtils; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +public class DiscoverEffect extends SpellAbilityEffect { + + @Override + protected String getStackDescription(SpellAbility sa) { + final PlayerCollection players = getDefinedPlayersOrTargeted(sa); + final String verb = players.size() == 1 ? " discovers " : " discover "; + + return Lang.joinHomogenous(players) + verb + sa.getParamOrDefault("Num", "1") + "."; + } + + @Override + public void resolve(SpellAbility sa) { + final Card host = sa.getHostCard(); + final Game game = host.getGame(); + final PlayerCollection players = getDefinedPlayersOrTargeted(sa); + + // Exile cards from the top of your library until you exile a nonland card with mana value or less. + final int num = AbilityUtils.calculateAmount(host, sa.getParamOrDefault("Num", "1"), sa); + + for (final Player p : players) { + if (p == null || !p.isInGame()) return; + + Card found = null; + CardCollection exiled = new CardCollection(); + CardCollection rest = new CardCollection(); + + final PlayerZone library = p.getZone(ZoneType.Library); + + for (final Card c : library) { + exiled.add(c); + if (!c.isLand() && c.getCMC() <= num) { + found = c; + if (sa.hasParam("RememberDiscovered")) + host.addRemembered(c); + break; + } else { + rest.add(c); + } + } + + if (exiled.size() > 0) { + game.getAction().reveal(exiled, p, false); + } + + changeZone(exiled, ZoneType.Exile, game, sa); + + // Cast it without paying its mana cost or put it into your hand. + if (found != null) { + String prompt = Localizer.getInstance().getMessage("lblDiscoverChoice", + CardTranslation.getTranslatedName(found.getName())); + final Zone origin = found.getZone(); + List options = + Arrays.asList(StringUtils.capitalize(Localizer.getInstance().getMessage("lblCast")), + StringUtils.capitalize(Localizer.getInstance().getMessage("lblHandZone"))); + final boolean play = p.getController().confirmAction(sa, null, prompt, options, found, null); + boolean cancel = false; + + if (play) { + // get basic spells (no flashback, etc.) + List sas = AbilityUtils.getBasicSpellsFromPlayEffect(found, p); + + // filter out land abilities due to MDFC or similar + Iterables.removeIf(sas, Predicates.instanceOf(LandAbility.class)); + // the spell must also have a mana value equal to or less than the discover number + sas.removeIf(sp -> sp.getPayCosts().getTotalMana().getCMC() > num); + + if (sas.isEmpty()) { // shouldn't happen! + System.err.println("DiscoverEffect Error: " + host + " found " + found + " but couldn't play sa"); + } else { + SpellAbility tgtSA = p.getController().getAbilityToPlay(found, sas); + + if (tgtSA == null) { // in case player canceled from choice dialog + cancel = true; + } else { + tgtSA = tgtSA.copyWithNoManaCost(); + + // 118.8c + boolean optional = false; + for (CostPart cost : tgtSA.getPayCosts().getCostParts()) { + if ((cost instanceof CostDiscard || cost instanceof CostReveal) + && !cost.getType().equals("Card") && !cost.getType().equals("Random")) { + optional = true; + break; + } + } + if (!optional) { + tgtSA.getPayCosts().setMandatory(true); + } + + if (tgtSA.usesTargeting() && !optional) { + tgtSA.getTargetRestrictions().setMandatory(true); + } + + tgtSA.setSVar("IsCastFromPlayEffect", "True"); + + if (p.getController().playSaFromPlayEffect(tgtSA)) { + final Card played = tgtSA.getHostCard(); + // add remember successfully played here if ever needed + final Zone zone = game.getCardState(played).getZone(); + if (!origin.equals(zone)) { + CardZoneTable trigList = new CardZoneTable(); + trigList.put(origin.getZoneType(), zone.getZoneType(), game.getCardState(found)); + trigList.triggerChangesZoneAll(game, sa); + } + } + } + } + } + if (!play || cancel) changeZone(new CardCollection(found), ZoneType.Hand, game, sa); + } + + // Put the rest on the bottom in a random order. + changeZone(rest, ZoneType.Library, game, sa); + + // Run discover triggers + final Map runParams = AbilityKey.mapFromPlayer(p); + runParams.put(AbilityKey.Amount, num); + game.getTriggerHandler().runTrigger(TriggerType.Discover, runParams, false); + } + } + + private void changeZone(CardCollection cards, ZoneType zone, Game game, SpellAbility sa) { + CardZoneTable table = new CardZoneTable(); + Map moveParams = AbilityKey.newMap(); + moveParams.put(AbilityKey.LastStateBattlefield, game.copyLastStateBattlefield()); + moveParams.put(AbilityKey.LastStateGraveyard, game.copyLastStateGraveyard()); + int pos = 0; + final boolean exileSeq = ZoneType.Exile.equals(zone); + + if (ZoneType.Library.equals(zone)) { // bottom of library in a random order + pos = -1; + CardLists.shuffle(cards); + } + + for (Card c : cards) { + final ZoneType origin = c.getZone().getZoneType(); + + Card m = game.getAction().moveTo(zone, c, pos, sa, moveParams); + + if (m != null && !origin.equals(m.getZone().getZoneType())) { + table.put(origin, m.getZone().getZoneType(), m); + if (exileSeq) { // exile cards one at a time + table.triggerChangesZoneAll(game, sa); + table.clear(); + } + } + } + if (!exileSeq) table.triggerChangesZoneAll(game, sa); + } +} diff --git a/forge-game/src/main/java/forge/game/card/CounterEnumType.java b/forge-game/src/main/java/forge/game/card/CounterEnumType.java index b8fa3d8e07c..890cc4ba22b 100644 --- a/forge-game/src/main/java/forge/game/card/CounterEnumType.java +++ b/forge-game/src/main/java/forge/game/card/CounterEnumType.java @@ -57,6 +57,8 @@ public enum CounterEnumType { BLOODLINE("BLDLN", 224, 44, 44), + BORE("BORE", 98, 47, 34), + BOUNTY("BOUNT", 255, 158, 0), BRIBERY("BRIBE", 172, 201, 235), 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 3137d138c83..2f301ca5ffe 100644 --- a/forge-game/src/main/java/forge/game/player/PlayerController.java +++ b/forge-game/src/main/java/forge/game/player/PlayerController.java @@ -5,6 +5,7 @@ import java.util.Collection; import java.util.List; import java.util.Map; +import com.google.common.collect.Lists; import forge.game.*; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; @@ -132,9 +133,12 @@ public abstract class PlayerController { public abstract List chooseEntitiesForEffect(FCollectionView optionList, int min, int max, DelayedReveal delayedReveal, SpellAbility sa, String title, Player relatedPlayer, Map params); public final boolean confirmAction(SpellAbility sa, PlayerActionConfirmMode mode, String message, Map params) { - return confirmAction(sa, mode, message, null, params); + return confirmAction(sa, mode, message, Lists.newArrayList(), null, params); } - public abstract boolean confirmAction(SpellAbility sa, PlayerActionConfirmMode mode, String message, Card cardToShow, Map params); + public final boolean confirmAction(SpellAbility sa, PlayerActionConfirmMode mode, String message, Card cardToShow, Map params) { + return confirmAction(sa, mode, message, Lists.newArrayList(), cardToShow, params); + } + public abstract boolean confirmAction(SpellAbility sa, PlayerActionConfirmMode mode, String message, List options, Card cardToShow, Map params); public abstract boolean confirmBidAction(SpellAbility sa, PlayerActionConfirmMode bidlife, String string, int bid, Player winner); public abstract boolean confirmReplacementEffect(ReplacementEffect replacementEffect, SpellAbility effectSA, GameEntity affected, String question); public abstract boolean confirmStaticApplication(Card hostCard, PlayerActionConfirmMode mode, String message, String logic); diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerDiscover.java b/forge-game/src/main/java/forge/game/trigger/TriggerDiscover.java new file mode 100644 index 00000000000..86d07517c8e --- /dev/null +++ b/forge-game/src/main/java/forge/game/trigger/TriggerDiscover.java @@ -0,0 +1,38 @@ +package forge.game.trigger; + +import forge.game.ability.AbilityKey; +import forge.game.card.Card; +import forge.game.spellability.SpellAbility; +import forge.util.Localizer; + +import java.util.Map; + +public class TriggerDiscover extends Trigger { + public TriggerDiscover(final Map params, final Card host, final boolean intrinsic) { + super(params, host, intrinsic); + } + + @Override + public boolean performTest(Map runParams) { + if (!matchesValidParam("ValidPlayer", runParams.get(AbilityKey.Player))) { + return false; + } + return true; + } + + @Override + public void setTriggeringObjects(SpellAbility sa, Map runParams) { + sa.setTriggeringObjectsFrom(runParams, AbilityKey.Player, AbilityKey.Amount); + } + + @Override + public String getImportantStackObjects(SpellAbility sa) { + StringBuilder sb = new StringBuilder(); + sb.append(Localizer.getInstance().getMessage("lblPlayer")).append(": "); + sb.append(sa.getTriggeringObject(AbilityKey.Player)).append(", "); + sb.append(Localizer.getInstance().getMessage("lblAmount")).append(": "); + sb.append(sa.getTriggeringObject(AbilityKey.Amount)); + return sb.toString(); + } + +} diff --git a/forge-game/src/main/java/forge/game/trigger/TriggerType.java b/forge-game/src/main/java/forge/game/trigger/TriggerType.java index 5ce3252b7d7..37bddffb2b8 100644 --- a/forge-game/src/main/java/forge/game/trigger/TriggerType.java +++ b/forge-game/src/main/java/forge/game/trigger/TriggerType.java @@ -64,6 +64,7 @@ public enum TriggerType { Devoured(TriggerDevoured.class), Discarded(TriggerDiscarded.class), DiscardedAll(TriggerDiscardedAll.class), + Discover(TriggerDiscover.class), Drawn(TriggerDrawn.class), DungeonCompleted(TriggerCompletedDungeon.class), Evolved(TriggerEvolved.class), diff --git a/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java b/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java index 678f0da267f..7d4fa94ed6c 100644 --- a/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java +++ b/forge-gui-desktop/src/test/java/forge/gamesimulationtests/util/PlayerControllerForTests.java @@ -187,7 +187,7 @@ public class PlayerControllerForTests extends PlayerController { } @Override - public boolean confirmAction(SpellAbility sa, PlayerActionConfirmMode mode, String message, Card cardToShow, Map params) { + public boolean confirmAction(SpellAbility sa, PlayerActionConfirmMode mode, String message, List options, Card cardToShow, Map params) { return true; } diff --git a/forge-gui/res/cardsfolder/b/blow_your_house_down.txt b/forge-gui/res/cardsfolder/b/blow_your_house_down.txt index 25d448380e4..193bb9b6b06 100644 --- a/forge-gui/res/cardsfolder/b/blow_your_house_down.txt +++ b/forge-gui/res/cardsfolder/b/blow_your_house_down.txt @@ -1,7 +1,7 @@ Name:Blow Your House Down ManaCost:2 R Types:Sorcery -A:SP$ Pump | Cost$ 2 R | ValidTgts$ Creature | TargetMin$ 0 | TargetMax$ 3 | RememberTargets$ True | KW$ HIDDEN CARDNAME can't block. | IsCurse$ True | TgtPrompt$ Select target creature | SubAbility$ DBDestroy | SpellDescription$ Up to three target creatures can't block this turn. Destroy any of them that are Walls. -SVar:DBDestroy:DB$ DestroyAll | ValidCards$ Wall.IsRemembered | SubAbility$ DBCleanup +A:SP$ Pump | ValidTgts$ Creature | TargetMin$ 0 | TargetMax$ 3 | RememberTargets$ True | KW$ HIDDEN CARDNAME can't block. | IsCurse$ True | TgtPrompt$ Select up to three target creatures | SubAbility$ DBDestroy | StackDescription$ REP Up to three target creatures_{c:Targeted} | SpellDescription$ Up to three target creatures can't block this turn. +SVar:DBDestroy:DB$ DestroyAll | ValidCards$ Wall.IsRemembered | SubAbility$ DBCleanup | StackDescription$ SpellDescription | SpellDescription$ Destroy any of them that are Walls. SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True Oracle:Up to three target creatures can't block this turn. Destroy any of them that are Walls. diff --git a/forge-gui/res/cardsfolder/upcoming/brasss_tunnel_grinder_tecutlan_the_searing_rift.txt b/forge-gui/res/cardsfolder/upcoming/brasss_tunnel_grinder_tecutlan_the_searing_rift.txt new file mode 100644 index 00000000000..70cdb7dab4c --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/brasss_tunnel_grinder_tecutlan_the_searing_rift.txt @@ -0,0 +1,24 @@ +Name:Brass's Tunnel-Grinder +ManaCost:2 R +Types:Legendary Artifact +T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | Execute$ TrigDiscard | TriggerDescription$ When CARDNAME enters the battlefield, discard any number of cards, then draw that many cards plus one. +SVar:TrigDiscard:DB$ Discard | AnyNumber$ True | Optional$ True | Mode$ TgtChoose | RememberDiscarded$ True | SubAbility$ DBDraw +SVar:DBDraw:DB$ Draw | Defined$ You | NumCards$ Remembered$Amount/Plus.1 | SubAbility$ DBCleanup +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You.descended | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ At the beginning of your end step, if you descended this turn, put a bore counter on CARDNAME. Then if there are three or more bore counters on it, remove those counters and transform it. (You descended if a permanent card was put into your graveyard from anywhere.) +SVar:TrigPutCounter:DB$ PutCounter | CounterType$ BORE | SubAbility$ DBBranch +SVar:DBBranch:DB$ Branch | BranchConditionSVar$ Count$CardCounters.BORE | BranchConditionSVarCompare$ GE3 | TrueSubAbility$ DBRemoveCounter +SVar:DBRemoveCounter:DB$ RemoveCounter | CounterType$ BORE | CounterNum$ All | SubAbility$ DBTransform +SVar:DBTransform:DB$ SetState | Defined$ Self | Mode$ Transform +AlternateMode:DoubleFaced +Oracle:When Brass's Tunnel-Grinder enters the battlefield, discard any number of cards, then draw that many cards plus one.\nAt the beginning of your end step, if you descended this turn, put a bore counter on Brass's Tunnel-Grinder. Then if there are three or more bore counters on it, remove those counters and transform it. (You descended if a permanent card was put into your graveyard from anywhere.) + +ALTERNATE + +Name:Tecutlan, the Searing Rift +ManaCost:no cost +Types:Legendary Land Cave +A:AB$ Mana | Cost$ T | Produced$ R | SpellDescription$ Add {R}. +T:Mode$ SpellCast | ValidCard$ Permanent | ValidSA$ Spell.ManaFromCard.StrictlySelf | ValidActivatingPlayer$ You | Execute$ TrigDiscover | TriggerDescription$ Whenever you cast a permanent spell using mana produced by CARDNAME, discover X, where X is that spell's mana value. +SVar:TrigDiscover:DB$ Discover | Num$ TriggeredStackInstance$CardManaCostLKI +Oracle:(Transforms from Brass's Tunnel-Grinder.)\n{T}: Add {R}.\nWhenever you cast a permanent spell using mana produced by Tecutlan, the Searing Rift, discover X, where X is that spell's mana value. diff --git a/forge-gui/res/cardsfolder/upcoming/buried_treasure.txt b/forge-gui/res/cardsfolder/upcoming/buried_treasure.txt new file mode 100644 index 00000000000..b1a35d5443e --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/buried_treasure.txt @@ -0,0 +1,7 @@ +Name:Buried Treasure +ManaCost:2 +Types:Artifact Treasure +A:AB$ Mana | Cost$ T Sac<1/CARDNAME> | Produced$ Any | SpellDescription$ Add one mana of any color. +A:AB$ Discover | Cost$ 5 ExileFromGrave<1/CARDNAME> | Num$ 5 | ActivationZone$ Graveyard | SorcerySpeed$ True | SpellDescription$ Discover 5. Activate only as a sorcery. (Exile cards from the top of your library until you exile a nonland card with mana value 5 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) +DeckHas:Ability$Sacrifice +Oracle:{T}, Sacrifice Buried Treasure: Add one mana of any color.\n{5}, Exile Buried Treasure from your graveyard: Discover 5. Activate only as a sorcery. (Exile cards from the top of your library until you exile a nonland card with mana value 5 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) diff --git a/forge-gui/res/cardsfolder/upcoming/caparocti_sunborn.txt b/forge-gui/res/cardsfolder/upcoming/caparocti_sunborn.txt new file mode 100644 index 00000000000..91949f8f6a1 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/caparocti_sunborn.txt @@ -0,0 +1,8 @@ +Name:Caparocti Sunborn +ManaCost:2 R W +Types:Legendary Creature Human Soldier +PT:4/4 +T:Mode$ Attacks | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigDiscover | TriggerDescription$ Whenever CARDNAME attacks, you may tap two untapped artifacts and/or creatures you control. If you do, discover 3. (Exile cards from the top of your library until you exile a nonland card with mana value 3 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) +SVar:TrigDiscover:AB$ Discover | Cost$ tapXType<2/Artifact;Creature/artifacts and/or creatures> | Num$ 3 +DeckHints:Type$Artifact|Token +Oracle:Whenever Caparocti Sunborn attacks, you may tap two untapped artifacts and/or creatures you control. If you do, discover 3. (Exile cards from the top of your library until you exile a nonland card with mana value 3 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) diff --git a/forge-gui/res/cardsfolder/upcoming/chimil_the_inner_sun.txt b/forge-gui/res/cardsfolder/upcoming/chimil_the_inner_sun.txt new file mode 100644 index 00000000000..dbc1a9a9835 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/chimil_the_inner_sun.txt @@ -0,0 +1,7 @@ +Name:Chimil, the Inner Sun +ManaCost:6 +Types:Legendary Artifact +S:Mode$ Continuous | Affected$ Card.YouCtrl | AffectedZone$ Stack | AddHiddenKeyword$ This spell can't be countered. | Description$ Spells you control can't be countered. +T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDiscover | TriggerDescription$ At the beginning of your end step, discover 5. (Exile cards from the top of your library until you exile a nonland card with mana value 5 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) +SVar:TrigDiscover:DB$ Discover | Num$ 5 +Oracle:Spells you control can't be countered.\nAt the beginning of your end step, discover 5. (Exile cards from the top of your library until you exile a nonland card with mana value 5 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) diff --git a/forge-gui/res/cardsfolder/upcoming/contest_of_claws.txt b/forge-gui/res/cardsfolder/upcoming/contest_of_claws.txt new file mode 100644 index 00000000000..ba81d47484e --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/contest_of_claws.txt @@ -0,0 +1,8 @@ +Name:Contest of Claws +ManaCost:1 G +Types:Sorcery +A:SP$ Pump | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | SubAbility$ DBDamage | AILogic$ PowerDmg | StackDescription$ {c:ThisTargetedCard} | SpellDescription$ Target creature you control +SVar:DBDamage:DB$ DealDamage | ValidTgts$ Creature | TgtPrompt$ Select another target creature | TargetUnique$ True | AILogic$ PowerDmg | NumDmg$ X | DamageSource$ ParentTarget | ExcessSVar$ Excess | SubAbility$ DBDiscover | StackDescription$ REP another target creature_{c:ThisTargetedCard} | SpellDescription$ deals damage equal to its power to another target creature. +SVar:DBDiscover:DB$ Discover | Num$ Excess | StackDescription$ SpellDescription | SpellDescription$ If excess damage was dealt this way, discover X, where X is that excess damage. (Exile cards from the top of your library until you exile a nonland card with that mana value or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) +SVar:X:ParentTargeted$CardPower +Oracle:Target creature you control deals damage equal to its power to another target creature. If excess damage was dealt this way, discover X, where X is that excess damage. (Exile cards from the top of your library until you exile a nonland card with that mana value or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) diff --git a/forge-gui/res/cardsfolder/upcoming/curator_of_suns_creation.txt b/forge-gui/res/cardsfolder/upcoming/curator_of_suns_creation.txt new file mode 100644 index 00000000000..efdfdca7044 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/curator_of_suns_creation.txt @@ -0,0 +1,8 @@ +Name:Curator of Sun's Creation +ManaCost:3 R +Types:Creature Human Artificer +PT:3/3 +T:Mode$ Discover | ValidPlayer$ You | TriggerZone$ Battlefield | Execute$ TrigDiscover | ActivationLimit$ 1 | TriggerDescription$ Whenever you discover, discover again for the same value. This ability triggers only once each turn. +SVar:TrigDiscover:DB$ Discover | Num$ X +SVar:X:TriggerCount$Amount +Oracle:Whenever you discover, discover again for the same value. This ability triggers only once each turn. diff --git a/forge-gui/res/cardsfolder/upcoming/daring_discovery.txt b/forge-gui/res/cardsfolder/upcoming/daring_discovery.txt new file mode 100644 index 00000000000..5717e7407d7 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/daring_discovery.txt @@ -0,0 +1,6 @@ +Name:Daring Discovery +ManaCost:4 R +Types:Sorcery +A:SP$ Pump | ValidTgts$ Creature | TargetMin$ 0 | TargetMax$ 3 | KW$ HIDDEN CARDNAME can't block. | IsCurse$ True | TgtPrompt$ Select up to three target creatures | SubAbility$ DBDiscover | StackDescription$ REP Up to three target creatures_{c:Targeted} | SpellDescription$ Up to three target creatures can't block this turn. +SVar:DBDiscover:DB$ Discover | Num$ 4 | SpellDescription$ Discover 4. (Exile cards from the top of your library until you exile a nonland card with mana value 4 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) +Oracle:Up to three target creatures can't block this turn.\nDiscover 4. (Exile cards from the top of your library until you exile a nonland card with mana value 4 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) diff --git a/forge-gui/res/cardsfolder/upcoming/digsite_conservator.txt b/forge-gui/res/cardsfolder/upcoming/digsite_conservator.txt new file mode 100644 index 00000000000..2fe3b62b2ac --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/digsite_conservator.txt @@ -0,0 +1,9 @@ +Name:Digsite Conservator +ManaCost:2 +Types:Artifact Creature Gnome +PT:2/1 +A:AB$ ChangeZone | Cost$ Sac<1/CARDNAME> | TargetMin$ 0 | TargetMax$ 4 | TargetsFromSingleZone$ True | Origin$ Graveyard | Destination$ Exile | TgtPrompt$ Select up to four target cards from a single graveyard | ValidTgts$ Card | SorcerySpeed$ True | SpellDescription$ Exile up to four target cards from a single graveyard. Activate only as a sorcery. +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigDiscover | TriggerDescription$ When CARDNAME dies, you may pay {4}. If you do, discover 4. (Exile cards from the top of your library until you exile a nonland card with mana value 4 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) +SVar:TrigDiscover:AB$ Discover | Cost$ 4 | Num$ 4 +DeckHas:Ability$Sacrifice +Oracle:Sacrifice Digsite Conservator: Exile up to four target cards from a single graveyard. Activate only as a sorcery.\nWhen Digsite Conservator dies, you may pay {4}. If you do, discover 4. (Exile cards from the top of your library until you exile a nonland card with mana value 4 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) diff --git a/forge-gui/res/cardsfolder/upcoming/dinosaur_egg.txt b/forge-gui/res/cardsfolder/upcoming/dinosaur_egg.txt new file mode 100644 index 00000000000..5c29090f017 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/dinosaur_egg.txt @@ -0,0 +1,10 @@ +Name:Dinosaur Egg +ManaCost:1 G +Types:Creature Dinosaur Egg +PT:0/3 +K:Evolve +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigDiscover | OptionalDecider$ You | TriggerDescription$ When CARDNAME dies, you may discover X, where X is its toughness. +SVar:TrigDiscover:DB$ Discover | Num$ X +SVar:X:TriggeredCard$CardToughness +DeckHas:Ability$Counters +Oracle:Evolve (Whenever a creature enters the battlefield under your control, if that creature has greater power or toughness than this creature, put a +1/+1 counter on this creature.)\nWhen Dinosaur Egg dies, you may discover X, where X is its toughness. diff --git a/forge-gui/res/cardsfolder/upcoming/ellie_and_alan_paleontologists.txt b/forge-gui/res/cardsfolder/upcoming/ellie_and_alan_paleontologists.txt new file mode 100644 index 00000000000..3f05a614365 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/ellie_and_alan_paleontologists.txt @@ -0,0 +1,7 @@ +Name:Ellie and Alan, Paleontologists +ManaCost:2 G W U +Types:Legendary Creature Human Scientist +PT:2/5 +A:AB$ Discover | Cost$ T ExileFromGrave<1/Creature> | Num$ X | SorcerySpeed$ True | StackDescription$ {p:You} discovers X, where X is the mana value of the exiled card. | SpellDescription$ Discover X, where X is the mana value of the exiled card. Activate only as a sorcery. (Exile cards from the top of your library until you exile a nonland card with that mana value or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) +SVar:X:Exiled$CardManaCost +Oracle:{T}, Exile a creature card from your graveyard: Discover X, where X is the mana value of the exiled card. Activate only as a sorcery. (Exile cards from the top of your library until you exile a nonland card with that mana value or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) diff --git a/forge-gui/res/cardsfolder/upcoming/etalis_favor.txt b/forge-gui/res/cardsfolder/upcoming/etalis_favor.txt new file mode 100644 index 00000000000..c1dd8ee871f --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/etalis_favor.txt @@ -0,0 +1,9 @@ +Name:Etali's Favor +ManaCost:2 R +Types:Enchantment Aura +K:Enchant creature you control +A:SP$ Attach | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | AILogic$ Pump +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDiscover | TriggerDescription$ When CARDNAME enters the battlefield, discover 3. (Exile cards from the top of your library until you exile a nonland card with mana value 3 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) +SVar:TrigDiscover:DB$ Discover | Num$ 3 +S:Mode$ Continuous | Affected$ Card.EnchantedBy | AddPower$ 1 | AddToughness$ 1 | AddKeyword$ Trample | Description$ Enchanted creature gets +1/+1 and has trample. +Oracle:Enchant creature you control\nWhen Etali's Favor enters the battlefield, discover 3. (Exile cards from the top of your library until you exile a nonland card with mana value 3 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.)\nEnchanted creature gets +1/+1 and has trample. diff --git a/forge-gui/res/cardsfolder/upcoming/geological_appraiser.txt b/forge-gui/res/cardsfolder/upcoming/geological_appraiser.txt new file mode 100644 index 00000000000..04ef4b7571d --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/geological_appraiser.txt @@ -0,0 +1,7 @@ +Name:Geological Appraiser +ManaCost:2 R R +Types:Creature Human Artificer +PT:3/2 +T:Mode$ ChangesZone | Destination$ Battlefield | ValidCard$ Card.Self+wasCastByYou | Execute$ TrigDiscover | TriggerZones$ Battlefield | TriggerDescription$ When CARDNAME enters the battlefield, if you cast it, discover 3. (Exile cards from the top of your library until you exile a nonland card with mana value 3 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) +SVar:TrigDiscover:AB$ Discover | Num$ 3 +Oracle:When Geological Appraiser enters the battlefield, if you cast it, discover 3. (Exile cards from the top of your library until you exile a nonland card with mana value 3 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) diff --git a/forge-gui/res/cardsfolder/upcoming/hidden_cataract.txt b/forge-gui/res/cardsfolder/upcoming/hidden_cataract.txt new file mode 100644 index 00000000000..e6d702e16ab --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/hidden_cataract.txt @@ -0,0 +1,8 @@ +Name:Hidden Cataract +ManaCost:no cost +Types:Land Cave +K:CARDNAME enters the battlefield tapped. +A:AB$ Mana | Cost$ T | Produced$ U | SpellDescription$ Add {U}. +A:AB$ Discover | Cost$ 4 U T Sac<1/CARDNAME> | Num$ 4 | SorcerySpeed$ True | SpellDescription$ Discover 4. Activate only as a sorcery. (Exile cards from the top of your library until you exile a nonland card with mana value 4 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) +DeckHas:Ability$Sacrifice +Oracle:Hidden Cataract enters the battlefield tapped.\n{T}: Add {U}.\n{4}{U}, {T}, Sacrifice Hidden Cataract: Discover 4. Activate only as a sorcery. (Exile cards from the top of your library until you exile a nonland card with mana value 4 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) diff --git a/forge-gui/res/cardsfolder/upcoming/hidden_courtyard.txt b/forge-gui/res/cardsfolder/upcoming/hidden_courtyard.txt new file mode 100644 index 00000000000..64fe177478b --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/hidden_courtyard.txt @@ -0,0 +1,8 @@ +Name:Hidden Courtyard +ManaCost:no cost +Types:Land Cave +K:CARDNAME enters the battlefield tapped. +A:AB$ Mana | Cost$ T | Produced$ W | SpellDescription$ Add {W}. +A:AB$ Discover | Cost$ 4 W T Sac<1/CARDNAME> | Num$ 4 | SorcerySpeed$ True | SpellDescription$ Discover 4. Activate only as a sorcery. (Exile cards from the top of your library until you exile a nonland card with mana value 4 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) +DeckHas:Ability$Sacrifice +Oracle:Hidden Courtyard enters the battlefield tapped.\n{T}: Add {W}.\n{4}{W}, {T}, Sacrifice Hidden Courtyard: Discover 4. Activate only as a sorcery. (Exile cards from the top of your library until you exile a nonland card with mana value 4 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) diff --git a/forge-gui/res/cardsfolder/upcoming/hidden_necropolis.txt b/forge-gui/res/cardsfolder/upcoming/hidden_necropolis.txt new file mode 100644 index 00000000000..f485b8c7101 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/hidden_necropolis.txt @@ -0,0 +1,8 @@ +Name:Hidden Necropolis +ManaCost:no cost +Types:Land Cave +K:CARDNAME enters the battlefield tapped. +A:AB$ Mana | Cost$ T | Produced$ B | SpellDescription$ Add {B}. +A:AB$ Discover | Cost$ 4 B T Sac<1/CARDNAME> | Num$ 4 | SorcerySpeed$ True | SpellDescription$ Discover 4. Activate only as a sorcery. (Exile cards from the top of your library until you exile a nonland card with mana value 4 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) +DeckHas:Ability$Sacrifice +Oracle:Hidden Necropolis enters the battlefield tapped.\n{T}: Add {B}.\n{4}{B}, {T}, Sacrifice Hidden Necropolis: Discover 4. Activate only as a sorcery. (Exile cards from the top of your library until you exile a nonland card with mana value 4 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) diff --git a/forge-gui/res/cardsfolder/upcoming/hidden_nursery.txt b/forge-gui/res/cardsfolder/upcoming/hidden_nursery.txt new file mode 100644 index 00000000000..633e750f19d --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/hidden_nursery.txt @@ -0,0 +1,8 @@ +Name:Hidden Nursery +ManaCost:no cost +Types:Land Cave +K:CARDNAME enters the battlefield tapped. +A:AB$ Mana | Cost$ T | Produced$ G | SpellDescription$ Add {G}. +A:AB$ Discover | Cost$ 4 G T Sac<1/CARDNAME> | Num$ 4 | SorcerySpeed$ True | SpellDescription$ Discover 4. Activate only as a sorcery. (Exile cards from the top of your library until you exile a nonland card with mana value 4 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) +DeckHas:Ability$Sacrifice +Oracle:Hidden Nursery enters the battlefield tapped.\n{T}: Add {G}.\n{4}{G}, {T}, Sacrifice Hidden Nursery: Discover 4. Activate only as a sorcery. (Exile cards from the top of your library until you exile a nonland card with mana value 4 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) diff --git a/forge-gui/res/cardsfolder/upcoming/hidden_volcano.txt b/forge-gui/res/cardsfolder/upcoming/hidden_volcano.txt new file mode 100644 index 00000000000..74839da2fea --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/hidden_volcano.txt @@ -0,0 +1,8 @@ +Name:Hidden Volcano +ManaCost:no cost +Types:Land Cave +K:CARDNAME enters the battlefield tapped. +A:AB$ Mana | Cost$ T | Produced$ R | SpellDescription$ Add {R}. +A:AB$ Discover | Cost$ 4 R T Sac<1/CARDNAME> | Num$ 4 | SorcerySpeed$ True | SpellDescription$ Discover 4. Activate only as a sorcery. (Exile cards from the top of your library until you exile a nonland card with mana value 4 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) +DeckHas:Ability$Sacrifice +Oracle:Hidden Volcano enters the battlefield tapped.\n{T}: Add {R}.\n{4}{R}, {T}, Sacrifice Hidden Volcano: Discover 4. Activate only as a sorcery. (Exile cards from the top of your library until you exile a nonland card with mana value 4 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) diff --git a/forge-gui/res/cardsfolder/upcoming/hit_the_mother_lode.txt b/forge-gui/res/cardsfolder/upcoming/hit_the_mother_lode.txt new file mode 100644 index 00000000000..df7a36f3fea --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/hit_the_mother_lode.txt @@ -0,0 +1,8 @@ +Name:Hit the Mother Lode +ManaCost:4 R R R +Types:Sorcery +A:SP$ Discover | Num$ 10 | SubAbility$ DBTreasure | RememberDiscovered$ True | SpellDescription$ Discover 10. +SVar:DBTreasure:DB$ Token | ConditionDefined$ Remembered | ConditionPresent$ Card.cmcLT10 | TokenScript$ c_a_treasure_sac | TokenAmount$ Remembered$CardManaCost/NMinus.10 | TokenTapped$ True | SubAbility$ DBCleanup | SpellDescription$ If the discovered card's mana value is less than 10, create a number of tapped Treasure tokens equal to the difference. +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | StackDescription$ None | SpellDescription$ (To discover 10, exile cards from the top of your library until you exile a nonland card with mana value 10 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) +DeckHas:Type$Artifact|Treasure & Ability$Sacrifice|Token +Oracle:Discover 10. If the discovered card's mana value is less than 10, create a number of tapped Treasure tokens equal to the difference. (To discover 10, exile cards from the top of your library until you exile a nonland card with mana value 10 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) diff --git a/forge-gui/res/cardsfolder/upcoming/hurl_into_history.txt b/forge-gui/res/cardsfolder/upcoming/hurl_into_history.txt new file mode 100644 index 00000000000..7f18bf01d9b --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/hurl_into_history.txt @@ -0,0 +1,8 @@ +Name:Hurl into History +ManaCost:3 U U +Types:Instant +A:SP$ Counter | TargetType$ Spell | TgtPrompt$ Select target artifact or creature spell | ValidTgts$ Artifact,Creature | RememberCounteredCMC$ True | SubAbility$ DBDiscover | SpellDescription$ Counter target artifact or creature spell. +SVar:DBDiscover:DB$ Discover | Num$ X | SubAbility$ DBCleanup | StackDescription$ REP Discover_{p:You} discovers | SpellDescription$ Discover X, where X is that spell's mana value. (Exile cards from the top of your library until you exile a nonland card with that mana value or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:X:Count$RememberedNumber +Oracle:Counter target artifact or creature spell. Discover X, where X is that spell's mana value. (Exile cards from the top of your library until you exile a nonland card with that mana value or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) diff --git a/forge-gui/res/cardsfolder/upcoming/pantlaza_sun_favored.txt b/forge-gui/res/cardsfolder/upcoming/pantlaza_sun_favored.txt new file mode 100644 index 00000000000..cd882581053 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/pantlaza_sun_favored.txt @@ -0,0 +1,9 @@ +Name:Pantlaza, Sun-Favored +ManaCost:2 R G W +Types:Legendary Creature Dinosaur +PT:4/4 +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self,Dinosaur.YouCtrl+Other | OptionalDecider$ You | ResolvedLimit$ 1 | Execute$ TrigDiscover | TriggerDescription$ Whenever CARDNAME or another Dinosaur enters the battlefield under your control, you may discover X, where X is that creature's toughness. Do this only once each turn. (Exile cards from the top of your library until you exile a nonland card with that mana value or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) +SVar:TrigDiscover:DB$ Discover | Num$ X +SVar:X:TriggeredCard$CardToughness +DeckHints:Type$Dinosaur +Oracle:Whenever Pantlaza, Sun-Favored or another Dinosaur enters the battlefield under your control, you may discover X, where X is that creature's toughness. Do this only once each turn. (Exile cards from the top of your library until you exile a nonland card with that mana value or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) diff --git a/forge-gui/res/cardsfolder/upcoming/primordial_gnawer.txt b/forge-gui/res/cardsfolder/upcoming/primordial_gnawer.txt new file mode 100644 index 00000000000..49949d7885d --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/primordial_gnawer.txt @@ -0,0 +1,7 @@ +Name:Primordial Gnawer +ManaCost:4 B +Types:Creature Insect Horror +PT:5/2 +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigDiscover | TriggerDescription$ When CARDNAME dies, discover 3. (Exile cards from the top of your library until you exile a nonland card with mana value 3 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) +SVar:TrigDiscover:DB$ Discover | Num$ 3 +Oracle:When Primordial Gnawer dies, discover 3. (Exile cards from the top of your library until you exile a nonland card with mana value 3 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) diff --git a/forge-gui/res/cardsfolder/upcoming/quintorius_kand.txt b/forge-gui/res/cardsfolder/upcoming/quintorius_kand.txt new file mode 100644 index 00000000000..d95c4cf757a --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/quintorius_kand.txt @@ -0,0 +1,18 @@ +Name:Quintorius Kand +ManaCost:3 R W +Types:Legendary Planeswalker Quintorius +Loyalty:4 +T:Mode$ SpellCast | ValidCard$ Card.wasCastFromExile | ValidActivatingPlayer$ You | Execute$ TrigDamage | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a spell from exile, CARDNAME deals 2 damage to each opponent and you gain 2 life. +SVar:TrigDamage:DB$ DealDamage | Defined$ Opponent | NumDmg$ 2 | SubAbility$ DBGainLife +SVar:DBGainLife:DB$ GainLife | LifeAmount$ 2 +A:AB$ Token | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | TokenScript$ rw_3_2_spirit | SpellDescription$ Create a 3/2 red and white Spirit creature token. +A:AB$ Discover | Cost$ SubCounter<3/LOYALTY> | Planeswalker$ True | Num$ 4 | SpellDescription$ Discover 4. +A:AB$ ChangeZone | Cost$ SubCounter<6/LOYALTY> | Planeswalker$ True | Ultimate$ True | Origin$ Graveyard | Destination$ Exile | TargetMin$ 0 | TargetMax$ Yard | TgtPrompt$ Select any number of target cards in your graveyard | ValidTgts$ Card.YouOwn | RememberChanged$ True | StackDescription$ SpellDescription | SpellDescription$ Exile any number of target cards from your graveyard. Add {R} for each card exiled this way. You may play those cards this turn. +SVar:DBMana:DB$ Mana | Produced$ R | Amount$ X | SubAbility$ DBEffect +SVar:DBEffect:DB$ Effect | RememberObjects$ Remembered | StaticAbilities$ STMayPlay | SubAbility$ DBCleanup | ForgetOnMoved$ Exile +SVar:STMayPlay:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play those cards. +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:Yard:Count$InYourYard +SVar:X:Remembered$Amount +DeckHas:Ability$LifeGain|Token & Type$Spirit +Oracle:Whenever you cast a spell from exile, Quintorius Kand deals 2 damage to each opponent and you gain 2 life.\n[+1]: Create a 3/2 red and white Spirit creature token.\n[−3]: Discover 4.\n[−6]: Exile any number of target cards from your graveyard. Add {R} for each card exiled this way. You may play those cards this turn. diff --git a/forge-gui/res/cardsfolder/upcoming/swashbucklers_whip.txt b/forge-gui/res/cardsfolder/upcoming/swashbucklers_whip.txt new file mode 100644 index 00000000000..5107ef82c94 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/swashbucklers_whip.txt @@ -0,0 +1,8 @@ +Name:Swashbuckler's Whip +ManaCost:1 +Types:Artifact Equipment +S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddKeyword$ Reach | AddAbility$ ABTap & ABDiscover | Description$ Equipped creature has reach, "{2}, {T}: Tap target artifact or creature," and "{8}, {T}: Discover 10." (Exile cards from the top of your library until you exile a nonland card with mana value 10 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) +SVar:ABTap:AB$ Tap | Cost$ 2 T | ValidTgts$ Artifact,Creature | TgtPrompt$ Select target artifact or creature | SpellDescription$ Tap target artifact or creature. +SVar:ABDiscover:AB$ Discover | Cost$ 8 T | Num$ 10 | SpellDescription$ Discover 10. +K:Equip:1 +Oracle:Equipped creature has reach, "{2}, {T}: Tap target artifact or creature," and "{8}, {T}: Discover 10." (Exile cards from the top of your library until you exile a nonland card with mana value 10 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.)\nEquip {1} diff --git a/forge-gui/res/cardsfolder/upcoming/trumpeting_carnosaur.txt b/forge-gui/res/cardsfolder/upcoming/trumpeting_carnosaur.txt new file mode 100644 index 00000000000..e6adfd3349a --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/trumpeting_carnosaur.txt @@ -0,0 +1,10 @@ +Name:Trumpeting Carnosaur +ManaCost:4 R R +Types:Creature Dinosaur +PT:7/6 +K:Trample +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDiscover | TriggerDescription$ When CARDNAME enters the battlefield, discover 5. +SVar:TrigDiscover:DB$ Discover | Num$ 5 +A:AB$ DealDamage | Cost$ 2 R Discard<1/CARDNAME> | ActivationZone$ Hand | NumDmg$ 3 | ValidTgts$ Creature,Planeswalker | TgtPrompt$ Select target creature or planeswalker | SpellDescription$ It deals 3 damage to target creature or planeswalker. +DeckHas:Ability$Discard +Oracle:Trample\nWhen Trumpeting Carnosaur enters the battlefield, discover 5.\n{2}{R}, Discard Trumpeting Carnosaur: It deals 3 damage to target creature or planeswalker. diff --git a/forge-gui/res/cardsfolder/upcoming/walk_with_the_ancestors.txt b/forge-gui/res/cardsfolder/upcoming/walk_with_the_ancestors.txt new file mode 100644 index 00000000000..5d29e8a9ae0 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/walk_with_the_ancestors.txt @@ -0,0 +1,7 @@ +Name:Walk with the Ancestors +ManaCost:4 G +Types:Sorcery +A:SP$ ChangeZone | Origin$ Graveyard | Destination$ Hand | ValidTgts$ Permanent.YouOwn | TargetMin$ 0 | TargetMax$ 1 | TgtPrompt$ Select target up to one target permanent from your graveyard | SubAbility$ DBDiscover | SpellDescription$ Return up to one target permanent card from your graveyard to your hand. +SVar:DBDiscover:DB$ Discover | Num$ 4 | SpellDescription$ Discover 4. (Exile cards from the top of your library until you exile a nonland card with mana value 4 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) +DeckHas:Ability$Graveyard +Oracle:Return up to one target permanent card from your graveyard to your hand. Discover 4. (Exile cards from the top of your library until you exile a nonland card with mana value 4 or less. Cast it without paying its mana cost or put it into your hand. Put the rest on the bottom in a random order.) diff --git a/forge-gui/res/cardsfolder/upcoming/zoetic_glyph.txt b/forge-gui/res/cardsfolder/upcoming/zoetic_glyph.txt new file mode 100644 index 00000000000..4394e7f024e --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/zoetic_glyph.txt @@ -0,0 +1,11 @@ +Name:Zoetic Glyph +ManaCost:2 U +Types:Enchantment Aura +K:Enchant artifact +A:SP$ Attach | ValidTgts$ Artifact | TgtPrompt$ Select target artifact | AILogic$ Animate +S:Mode$ Continuous | Affected$ Artifact.EnchantedBy | AddType$ Creature & Golem | SetPower$ 5 | SetToughness$ 4 | Description$ Enchanted artifact is a Golem creature with base power and toughness 5/4 in addition to its other types. +T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigDiscover | TriggerDescription$ When CARDNAME is put into a graveyard from the battlefield, discover 3. +SVar:TrigDiscover:DB$ Discover | Num$ 3 +DeckHas:Type$Golem +DeckNeeds:Type$Artifact +Oracle:Enchant artifact\nEnchanted artifact is a Golem creature with base power and toughness 5/4 in addition to its other types.\nWhen Zoetic Glyph is put into a graveyard from the battlefield, discover 3. diff --git a/forge-gui/res/cardsfolder/upcoming/zoyowas_justice.txt b/forge-gui/res/cardsfolder/upcoming/zoyowas_justice.txt new file mode 100644 index 00000000000..25419693274 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/zoyowas_justice.txt @@ -0,0 +1,8 @@ +Name:Zoyowa's Justice +ManaCost:1 R +Types:Instant +A:SP$ ChangeZone | ValidTgts$ Artifact.cmcGE1,Creature.cmcGE1 | TgtPrompt$ Select target artifact or creature with mana value 1 or greater | Origin$ Battlefield | Destination$ Library | Shuffle$ True | RememberLKI$ True | SubAbility$ DBDiscover | StackDescription$ {p:TargetedOwner} shuffles {c:Targeted} into their library. | SpellDescription$ The owner of target artifact or creature with mana value 1 or greater shuffles it into their library. +SVar:DBDiscover:DB$ Discover | Defined$ TargetedOwner | Num$ X | SubAbility$ DBCleanup | StackDescription$ REP that player_{p:TargetedOwner} | SpellDescription$ Then that player discovers X, where X is its mana value. (They exile cards from the top of their library until they exile a nonland card with that mana value or less. They cast it without paying its mana cost or put it into their hand. They put the rest on the bottom in a random order.) +SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True +SVar:X:RememberedLKI$CardManaCost +Oracle:The owner of target artifact or creature with mana value 1 or greater shuffles it into their library. Then that player discovers X, where X is its mana value. (They exile cards from the top of their library until they exile a nonland card with that mana value or less. They cast it without paying its mana cost or put it into their hand. They put the rest on the bottom in a random order.) diff --git a/forge-gui/res/languages/de-DE.properties b/forge-gui/res/languages/de-DE.properties index 3df8bc10431..52814d789f0 100644 --- a/forge-gui/res/languages/de-DE.properties +++ b/forge-gui/res/languages/de-DE.properties @@ -1985,6 +1985,8 @@ lblMustChoose=Wähle mindestens eine Karte. #DiscardEffect.java lblWouldYouLikeRandomDiscardTargetCard=Möchtest du {0} zufällige Karte(n) abwerfen? lblPlayerHasChosenCardsFrom={0} hat Karte(n) gewählt von +#DiscoverEffect.java +lblDiscoverChoice=Willst du {0} wirken, ohne seine Manakosten zu bezahlen, oder willst du ihn auf die Hand nehmen? #DrawEffect.java lblDoYouWantDrawCards=Möchtest du {0} ziehen? lblHowManyCardDoYouWantDraw=Wie viele Karten möchtest du ziehen? diff --git a/forge-gui/res/languages/en-US.properties b/forge-gui/res/languages/en-US.properties index d1a38fbf994..492873f1829 100644 --- a/forge-gui/res/languages/en-US.properties +++ b/forge-gui/res/languages/en-US.properties @@ -1990,6 +1990,8 @@ lblMustChoose=You must choose at least one card. #DiscardEffect.java lblWouldYouLikeRandomDiscardTargetCard=Would you like to discard {0} random card(s)? lblPlayerHasChosenCardsFrom={0} has chosen card(s) from +#DiscoverEffect.java +lblDiscoverChoice=Do you want to cast {0} without paying its mana cost or put it into your hand? #DrawEffect.java lblDoYouWantDrawCards=Do you want to draw {0}? lblHowManyCardDoYouWantDraw=How many cards do you want to draw? diff --git a/forge-gui/res/languages/es-ES.properties b/forge-gui/res/languages/es-ES.properties index 63b5d05f4e1..78871d0ce8c 100644 --- a/forge-gui/res/languages/es-ES.properties +++ b/forge-gui/res/languages/es-ES.properties @@ -1986,6 +1986,8 @@ lblMustChoose=You must choose at least one card. #DiscardEffect.java lblWouldYouLikeRandomDiscardTargetCard=¿Te gustaría descartar {0} carta(s) aleatoria(s)? lblPlayerHasChosenCardsFrom={0} ha elegido una o varias cartas de +#DiscoverEffect.java +lblDiscoverChoice=¿Quieres lanzar {0} sin pagar su coste de maná o ponerlo en tu mano? #DrawEffect.java lblDoYouWantDrawCards=¿Quieres robar {0}? lblHowManyCardDoYouWantDraw=¿Cuántas cartas quieres robar? diff --git a/forge-gui/res/languages/fr-FR.properties b/forge-gui/res/languages/fr-FR.properties index 27c8aee6e63..68e4f87fb67 100644 --- a/forge-gui/res/languages/fr-FR.properties +++ b/forge-gui/res/languages/fr-FR.properties @@ -1989,6 +1989,8 @@ lblMustChoose=You must choose at least one card. #DiscardEffect.java lblWouldYouLikeRandomDiscardTargetCard=Voulez-vous défausser {0} carte(s) aléatoire(s) ? lblPlayerHasChosenCardsFrom={0} a choisi une ou plusieurs cartes parmi +#DiscoverEffect.java +lblDiscoverChoice=Voulez-vous lancer {0} sans payer son coût de mana ou le mettre dans votre main? #DrawEffect.java lblDoYouWantDrawCards=Voulez-vous tirer {0} ? lblHowManyCardDoYouWantDraw=Combien de cartes voulez-vous piocher ? diff --git a/forge-gui/res/languages/it-IT.properties b/forge-gui/res/languages/it-IT.properties index c2b3ae7138c..7a4f3d67644 100644 --- a/forge-gui/res/languages/it-IT.properties +++ b/forge-gui/res/languages/it-IT.properties @@ -1986,6 +1986,8 @@ lblMustChoose=You must choose at least one card. #DiscardEffect.java lblWouldYouLikeRandomDiscardTargetCard=Vuoi scartare {0} carta/e a caso? lblPlayerHasChosenCardsFrom={0}ha scelto delle carte da +#DiscoverEffect.java +lblDiscoverChoice=Vuoi lanciare {0} senza pagare il suo costo in mana o metterlo nella tua mano? #DrawEffect.java lblDoYouWantDrawCards=Vuoi pescare {0}? lblHowManyCardDoYouWantDraw=Quante carte vuoi pescare? diff --git a/forge-gui/res/languages/ja-JP.properties b/forge-gui/res/languages/ja-JP.properties index e6bb14075dd..747e039ca93 100644 --- a/forge-gui/res/languages/ja-JP.properties +++ b/forge-gui/res/languages/ja-JP.properties @@ -1985,6 +1985,8 @@ lblMustChoose=You must choose at least one card. #DiscardEffect.java lblWouldYouLikeRandomDiscardTargetCard=不作為に {0}枚のカードを捨てますか? lblPlayerHasChosenCardsFrom={0}がカードを選択した: +#DiscoverEffect.java +lblDiscoverChoice=あなたは {0}をマナ・コストを払わずに唱えたいのか、それともあなたの手札に置きたいのか? #DrawEffect.java lblDoYouWantDrawCards={0}を引きますか? lblHowMayCardDoYouWantDraw=何枚のカードを引きますか? diff --git a/forge-gui/res/languages/pt-BR.properties b/forge-gui/res/languages/pt-BR.properties index 20a15763b92..518de081b6d 100644 --- a/forge-gui/res/languages/pt-BR.properties +++ b/forge-gui/res/languages/pt-BR.properties @@ -2047,6 +2047,8 @@ lblMustChoose=You must choose at least one card. #DiscardEffect.java lblWouldYouLikeRandomDiscardTargetCard=Descartar {0} carta(s) aleatoriamente? lblPlayerHasChosenCardsFrom={0} escolheu carta(s) de +#DiscoverEffect.java +lblDiscoverChoice=Você quer lançar {0} sem pagar seu custo de mana ou colocá-lo em sua mão? #DrawEffect.java lblDoYouWantDrawCards=Quer comprar {0}? lblHowManyCardDoYouWantDraw=Quantas cartas você quer comprar? diff --git a/forge-gui/res/languages/zh-CN.properties b/forge-gui/res/languages/zh-CN.properties index a6815030944..ad614fd33f4 100644 --- a/forge-gui/res/languages/zh-CN.properties +++ b/forge-gui/res/languages/zh-CN.properties @@ -1990,6 +1990,8 @@ lblMustChoose=你必须至少选择一张牌。 #DiscardEffect.java lblWouldYouLikeRandomDiscardTargetCard=你想随机弃掉%d张牌吗? lblPlayerHasChosenCardsFrom={0}选择了牌自 +#DiscoverEffect.java +lblDiscoverChoice=你想在不支付魔法消耗的情况下施放{0}还是把它放在你的手里? #DrawEffect.java lblDoYouWantDrawCards=你想抓{0}张牌吗? lblHowManyCardDoYouWantDraw=你想怎么抓牌? diff --git a/forge-gui/res/lists/TypeLists.txt b/forge-gui/res/lists/TypeLists.txt index f50ca017a73..e86ceca84e0 100644 --- a/forge-gui/res/lists/TypeLists.txt +++ b/forge-gui/res/lists/TypeLists.txt @@ -390,6 +390,7 @@ Niko Nissa Nixilis Oko +Quintorius Ral Rowan Saheeli diff --git a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java index 41119d232d1..ba37f8aef78 100644 --- a/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java +++ b/forge-gui/src/main/java/forge/player/PlayerControllerHuman.java @@ -773,11 +773,12 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont */ @Override public boolean confirmAction(final SpellAbility sa, final PlayerActionConfirmMode mode, final String message, - Card cardToShow, Map params) { + List options, Card cardToShow, Map params) { // Another card should be displayed in the prompt on mouse over rather than the SA source if (cardToShow != null) { tempShowCard(cardToShow); - boolean result = InputConfirm.confirm(this, cardToShow.getView(), sa, message); + boolean result = options.isEmpty() ? InputConfirm.confirm(this, cardToShow.getView(), sa, message) + : InputConfirm.confirm(this, cardToShow.getView(), message, true, options); endTempShowCards(); return result; }